public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Mike Pagano" <mpagano@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/linux-patches:5.18 commit in: /
Date: Tue, 12 Jul 2022 15:58:04 +0000 (UTC)	[thread overview]
Message-ID: <1657641434.eca2f342ada520977a8ae1535efc2e3944602e51.mpagano@gentoo> (raw)

commit:     eca2f342ada520977a8ae1535efc2e3944602e51
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Tue Jul 12 15:57:14 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Tue Jul 12 15:57:14 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=eca2f342

Linux patch 5.18.11

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 0000_README              |    4 +
 1010_linux-5.18.11.patch | 4955 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 4959 insertions(+)

diff --git a/0000_README b/0000_README
index 30a7b58d..be72894f 100644
--- a/0000_README
+++ b/0000_README
@@ -83,6 +83,10 @@ Patch:  1009_linux-5.18.10.patch
 From:   http://www.kernel.org
 Desc:   Linux 5.18.10
 
+Patch:  1010_linux-5.18.11.patch
+From:   http://www.kernel.org
+Desc:   Linux 5.18.11
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1010_linux-5.18.11.patch b/1010_linux-5.18.11.patch
new file mode 100644
index 00000000..1ff85521
--- /dev/null
+++ b/1010_linux-5.18.11.patch
@@ -0,0 +1,4955 @@
+diff --git a/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml b/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml
+index b6e1ebfaf3666..bb3cbc30d9121 100644
+--- a/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml
++++ b/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml
+@@ -64,7 +64,7 @@ if:
+ then:
+   properties:
+     clocks:
+-      maxItems: 2
++      minItems: 2
+ 
+   required:
+     - clock-names
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 8e6622ed6de69..2b70e2d214057 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -426,7 +426,6 @@ F:	drivers/acpi/*thermal*
+ ACPI VIOT DRIVER
+ M:	Jean-Philippe Brucker <jean-philippe@linaro.org>
+ L:	linux-acpi@vger.kernel.org
+-L:	iommu@lists.linux-foundation.org
+ L:	iommu@lists.linux.dev
+ S:	Maintained
+ F:	drivers/acpi/viot.c
+@@ -960,7 +959,6 @@ F:	drivers/video/fbdev/geode/
+ AMD IOMMU (AMD-VI)
+ M:	Joerg Roedel <joro@8bytes.org>
+ R:	Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+-L:	iommu@lists.linux-foundation.org
+ L:	iommu@lists.linux.dev
+ S:	Maintained
+ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
+@@ -5899,7 +5897,6 @@ DMA MAPPING HELPERS
+ M:	Christoph Hellwig <hch@lst.de>
+ M:	Marek Szyprowski <m.szyprowski@samsung.com>
+ R:	Robin Murphy <robin.murphy@arm.com>
+-L:	iommu@lists.linux-foundation.org
+ L:	iommu@lists.linux.dev
+ S:	Supported
+ W:	http://git.infradead.org/users/hch/dma-mapping.git
+@@ -5912,7 +5909,6 @@ F:	kernel/dma/
+ 
+ DMA MAPPING BENCHMARK
+ M:	Xiang Chen <chenxiang66@hisilicon.com>
+-L:	iommu@lists.linux-foundation.org
+ L:	iommu@lists.linux.dev
+ F:	kernel/dma/map_benchmark.c
+ F:	tools/testing/selftests/dma/
+@@ -7479,7 +7475,6 @@ F:	drivers/gpu/drm/exynos/exynos_dp*
+ 
+ EXYNOS SYSMMU (IOMMU) driver
+ M:	Marek Szyprowski <m.szyprowski@samsung.com>
+-L:	iommu@lists.linux-foundation.org
+ L:	iommu@lists.linux.dev
+ S:	Maintained
+ F:	drivers/iommu/exynos-iommu.c
+@@ -9879,7 +9874,6 @@ F:	drivers/hid/intel-ish-hid/
+ INTEL IOMMU (VT-d)
+ M:	David Woodhouse <dwmw2@infradead.org>
+ M:	Lu Baolu <baolu.lu@linux.intel.com>
+-L:	iommu@lists.linux-foundation.org
+ L:	iommu@lists.linux.dev
+ S:	Supported
+ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
+@@ -10258,7 +10252,6 @@ F:	include/linux/iomap.h
+ IOMMU DRIVERS
+ M:	Joerg Roedel <joro@8bytes.org>
+ M:	Will Deacon <will@kernel.org>
+-L:	iommu@lists.linux-foundation.org
+ L:	iommu@lists.linux.dev
+ S:	Maintained
+ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
+@@ -12375,7 +12368,6 @@ F:	drivers/i2c/busses/i2c-mt65xx.c
+ 
+ MEDIATEK IOMMU DRIVER
+ M:	Yong Wu <yong.wu@mediatek.com>
+-L:	iommu@lists.linux-foundation.org
+ L:	iommu@lists.linux.dev
+ L:	linux-mediatek@lists.infradead.org (moderated for non-subscribers)
+ S:	Supported
+@@ -16361,7 +16353,6 @@ F:	drivers/i2c/busses/i2c-qcom-cci.c
+ 
+ QUALCOMM IOMMU
+ M:	Rob Clark <robdclark@gmail.com>
+-L:	iommu@lists.linux-foundation.org
+ L:	iommu@lists.linux.dev
+ L:	linux-arm-msm@vger.kernel.org
+ S:	Maintained
+@@ -18947,7 +18938,6 @@ F:	arch/x86/boot/video*
+ 
+ SWIOTLB SUBSYSTEM
+ M:	Christoph Hellwig <hch@infradead.org>
+-L:	iommu@lists.linux-foundation.org
+ L:	iommu@lists.linux.dev
+ S:	Supported
+ W:	http://git.infradead.org/users/hch/dma-mapping.git
+@@ -21618,7 +21608,6 @@ XEN SWIOTLB SUBSYSTEM
+ M:	Juergen Gross <jgross@suse.com>
+ M:	Stefano Stabellini <sstabellini@kernel.org>
+ L:	xen-devel@lists.xenproject.org (moderated for non-subscribers)
+-L:	iommu@lists.linux-foundation.org
+ L:	iommu@lists.linux.dev
+ S:	Supported
+ F:	arch/x86/xen/*swiotlb*
+diff --git a/Makefile b/Makefile
+index 088b84f99203c..323032d60ac34 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 5
+ PATCHLEVEL = 18
+-SUBLEVEL = 10
++SUBLEVEL = 11
+ EXTRAVERSION =
+ NAME = Superb Owl
+ 
+diff --git a/arch/arm/boot/dts/at91-sam9x60ek.dts b/arch/arm/boot/dts/at91-sam9x60ek.dts
+index 7719ea3d4933c..81ccb0636a009 100644
+--- a/arch/arm/boot/dts/at91-sam9x60ek.dts
++++ b/arch/arm/boot/dts/at91-sam9x60ek.dts
+@@ -233,10 +233,9 @@
+ 		status = "okay";
+ 
+ 		eeprom@53 {
+-			compatible = "atmel,24c32";
++			compatible = "atmel,24c02";
+ 			reg = <0x53>;
+ 			pagesize = <16>;
+-			size = <128>;
+ 			status = "okay";
+ 		};
+ 	};
+diff --git a/arch/arm/boot/dts/at91-sama5d2_icp.dts b/arch/arm/boot/dts/at91-sama5d2_icp.dts
+index 806eb1d911d7c..164201a8fbf2d 100644
+--- a/arch/arm/boot/dts/at91-sama5d2_icp.dts
++++ b/arch/arm/boot/dts/at91-sama5d2_icp.dts
+@@ -329,21 +329,21 @@
+ 	status = "okay";
+ 
+ 	eeprom@50 {
+-		compatible = "atmel,24c32";
++		compatible = "atmel,24c02";
+ 		reg = <0x50>;
+ 		pagesize = <16>;
+ 		status = "okay";
+ 	};
+ 
+ 	eeprom@52 {
+-		compatible = "atmel,24c32";
++		compatible = "atmel,24c02";
+ 		reg = <0x52>;
+ 		pagesize = <16>;
+ 		status = "disabled";
+ 	};
+ 
+ 	eeprom@53 {
+-		compatible = "atmel,24c32";
++		compatible = "atmel,24c02";
+ 		reg = <0x53>;
+ 		pagesize = <16>;
+ 		status = "disabled";
+diff --git a/arch/arm/boot/dts/stm32mp151.dtsi b/arch/arm/boot/dts/stm32mp151.dtsi
+index f9aa9af31efdc..9c2bbf115f4cc 100644
+--- a/arch/arm/boot/dts/stm32mp151.dtsi
++++ b/arch/arm/boot/dts/stm32mp151.dtsi
+@@ -1474,7 +1474,7 @@
+ 		usbh_ohci: usb@5800c000 {
+ 			compatible = "generic-ohci";
+ 			reg = <0x5800c000 0x1000>;
+-			clocks = <&rcc USBH>, <&usbphyc>;
++			clocks = <&usbphyc>, <&rcc USBH>;
+ 			resets = <&rcc USBH_R>;
+ 			interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+ 			status = "disabled";
+@@ -1483,7 +1483,7 @@
+ 		usbh_ehci: usb@5800d000 {
+ 			compatible = "generic-ehci";
+ 			reg = <0x5800d000 0x1000>;
+-			clocks = <&rcc USBH>;
++			clocks = <&usbphyc>, <&rcc USBH>;
+ 			resets = <&rcc USBH_R>;
+ 			interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ 			companion = <&usbh_ohci>;
+diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig
+index ca32446b187f5..f53086ddc48b0 100644
+--- a/arch/arm/configs/mxs_defconfig
++++ b/arch/arm/configs/mxs_defconfig
+@@ -93,6 +93,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
+ CONFIG_DRM=y
+ CONFIG_DRM_PANEL_SEIKO_43WVF1G=y
+ CONFIG_DRM_MXSFB=y
++CONFIG_FB=y
+ CONFIG_FB_MODE_HELPERS=y
+ CONFIG_LCD_CLASS_DEVICE=y
+ CONFIG_BACKLIGHT_CLASS_DEVICE=y
+diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
+index 0fd609e26615a..32f224f723a5d 100644
+--- a/arch/arm/mach-at91/pm.c
++++ b/arch/arm/mach-at91/pm.c
+@@ -146,7 +146,7 @@ static const struct wakeup_source_info ws_info[] = {
+ 
+ static const struct of_device_id sama5d2_ws_ids[] = {
+ 	{ .compatible = "atmel,sama5d2-gem",		.data = &ws_info[0] },
+-	{ .compatible = "atmel,at91rm9200-rtc",		.data = &ws_info[1] },
++	{ .compatible = "atmel,sama5d2-rtc",		.data = &ws_info[1] },
+ 	{ .compatible = "atmel,sama5d3-udc",		.data = &ws_info[2] },
+ 	{ .compatible = "atmel,at91rm9200-ohci",	.data = &ws_info[2] },
+ 	{ .compatible = "usb-ohci",			.data = &ws_info[2] },
+@@ -157,24 +157,24 @@ static const struct of_device_id sama5d2_ws_ids[] = {
+ };
+ 
+ static const struct of_device_id sam9x60_ws_ids[] = {
+-	{ .compatible = "atmel,at91sam9x5-rtc",		.data = &ws_info[1] },
++	{ .compatible = "microchip,sam9x60-rtc",	.data = &ws_info[1] },
+ 	{ .compatible = "atmel,at91rm9200-ohci",	.data = &ws_info[2] },
+ 	{ .compatible = "usb-ohci",			.data = &ws_info[2] },
+ 	{ .compatible = "atmel,at91sam9g45-ehci",	.data = &ws_info[2] },
+ 	{ .compatible = "usb-ehci",			.data = &ws_info[2] },
+-	{ .compatible = "atmel,at91sam9260-rtt",	.data = &ws_info[4] },
++	{ .compatible = "microchip,sam9x60-rtt",	.data = &ws_info[4] },
+ 	{ .compatible = "cdns,sam9x60-macb",		.data = &ws_info[5] },
+ 	{ /* sentinel */ }
+ };
+ 
+ static const struct of_device_id sama7g5_ws_ids[] = {
+-	{ .compatible = "atmel,at91sam9x5-rtc",		.data = &ws_info[1] },
++	{ .compatible = "microchip,sama7g5-rtc",	.data = &ws_info[1] },
+ 	{ .compatible = "microchip,sama7g5-ohci",	.data = &ws_info[2] },
+ 	{ .compatible = "usb-ohci",			.data = &ws_info[2] },
+ 	{ .compatible = "atmel,at91sam9g45-ehci",	.data = &ws_info[2] },
+ 	{ .compatible = "usb-ehci",			.data = &ws_info[2] },
+ 	{ .compatible = "microchip,sama7g5-sdhci",	.data = &ws_info[3] },
+-	{ .compatible = "atmel,at91sam9260-rtt",	.data = &ws_info[4] },
++	{ .compatible = "microchip,sama7g5-rtt",	.data = &ws_info[4] },
+ 	{ /* sentinel */ }
+ };
+ 
+diff --git a/arch/arm/mach-meson/platsmp.c b/arch/arm/mach-meson/platsmp.c
+index 4b8ad728bb42a..32ac60b89fdcc 100644
+--- a/arch/arm/mach-meson/platsmp.c
++++ b/arch/arm/mach-meson/platsmp.c
+@@ -71,6 +71,7 @@ static void __init meson_smp_prepare_cpus(const char *scu_compatible,
+ 	}
+ 
+ 	sram_base = of_iomap(node, 0);
++	of_node_put(node);
+ 	if (!sram_base) {
+ 		pr_err("Couldn't map SRAM registers\n");
+ 		return;
+@@ -91,6 +92,7 @@ static void __init meson_smp_prepare_cpus(const char *scu_compatible,
+ 	}
+ 
+ 	scu_base = of_iomap(node, 0);
++	of_node_put(node);
+ 	if (!scu_base) {
+ 		pr_err("Couldn't map SCU registers\n");
+ 		return;
+diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
+index 4c3ac4214a2cd..5744fa76e9b2e 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
+@@ -395,21 +395,21 @@
+ &iomuxc {
+ 	pinctrl_eqos: eqosgrp {
+ 		fsl,pins = <
+-			MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC				0x3
+-			MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO				0x3
+-			MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0			0x91
+-			MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1			0x91
+-			MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2			0x91
+-			MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3			0x91
+-			MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK	0x91
+-			MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL			0x91
+-			MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0			0x1f
+-			MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1			0x1f
+-			MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2			0x1f
+-			MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3			0x1f
+-			MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL			0x1f
+-			MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK	0x1f
+-			MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22				0x19
++			MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC				0x2
++			MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO				0x2
++			MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0			0x90
++			MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1			0x90
++			MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2			0x90
++			MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3			0x90
++			MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK	0x90
++			MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL			0x90
++			MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0			0x16
++			MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1			0x16
++			MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2			0x16
++			MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3			0x16
++			MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL			0x16
++			MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK	0x16
++			MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22				0x10
+ 		>;
+ 	};
+ 
+@@ -461,28 +461,28 @@
+ 
+ 	pinctrl_gpio_led: gpioledgrp {
+ 		fsl,pins = <
+-			MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16	0x19
++			MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16	0x140
+ 		>;
+ 	};
+ 
+ 	pinctrl_i2c1: i2c1grp {
+ 		fsl,pins = <
+-			MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL		0x400001c3
+-			MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA		0x400001c3
++			MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL		0x400001c2
++			MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA		0x400001c2
+ 		>;
+ 	};
+ 
+ 	pinctrl_i2c3: i2c3grp {
+ 		fsl,pins = <
+-			MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL		0x400001c3
+-			MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA		0x400001c3
++			MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL		0x400001c2
++			MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA		0x400001c2
+ 		>;
+ 	};
+ 
+ 	pinctrl_i2c5: i2c5grp {
+ 		fsl,pins = <
+-			MX8MP_IOMUXC_SPDIF_RX__I2C5_SDA         0x400001c3
+-			MX8MP_IOMUXC_SPDIF_TX__I2C5_SCL         0x400001c3
++			MX8MP_IOMUXC_SPDIF_RX__I2C5_SDA         0x400001c2
++			MX8MP_IOMUXC_SPDIF_TX__I2C5_SCL         0x400001c2
+ 		>;
+ 	};
+ 
+@@ -500,20 +500,20 @@
+ 
+ 	pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
+ 		fsl,pins = <
+-			MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19	0x41
++			MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19	0x40
+ 		>;
+ 	};
+ 
+ 	pinctrl_uart2: uart2grp {
+ 		fsl,pins = <
+-			MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX	0x49
+-			MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX	0x49
++			MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX	0x140
++			MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX	0x140
+ 		>;
+ 	};
+ 
+ 	pinctrl_usb1_vbus: usb1grp {
+ 		fsl,pins = <
+-			MX8MP_IOMUXC_GPIO1_IO14__USB2_OTG_PWR	0x19
++			MX8MP_IOMUXC_GPIO1_IO14__USB2_OTG_PWR	0x10
+ 		>;
+ 	};
+ 
+@@ -525,7 +525,7 @@
+ 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1	0x1d0
+ 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2	0x1d0
+ 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3	0x1d0
+-			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc1
++			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc0
+ 		>;
+ 	};
+ 
+@@ -537,7 +537,7 @@
+ 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1	0x1d4
+ 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2	0x1d4
+ 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3	0x1d4
+-			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc1
++			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0
+ 		>;
+ 	};
+ 
+@@ -549,7 +549,7 @@
+ 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1	0x1d6
+ 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2	0x1d6
+ 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3	0x1d6
+-			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc1
++			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0
+ 		>;
+ 	};
+ 
+diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
+index 984a6b9ded8d7..6aa720bafe289 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
+@@ -116,48 +116,48 @@
+ &iomuxc {
+ 	pinctrl_eqos: eqosgrp {
+ 		fsl,pins = <
+-			MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC			0x3
+-			MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO			0x3
+-			MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0		0x91
+-			MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1		0x91
+-			MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2		0x91
+-			MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3		0x91
+-			MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK	0x91
+-			MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL		0x91
+-			MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0		0x1f
+-			MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1		0x1f
+-			MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2		0x1f
+-			MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3		0x1f
+-			MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL		0x1f
+-			MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK	0x1f
++			MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC			0x2
++			MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO			0x2
++			MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0		0x90
++			MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1		0x90
++			MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2		0x90
++			MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3		0x90
++			MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK	0x90
++			MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL		0x90
++			MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0		0x16
++			MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1		0x16
++			MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2		0x16
++			MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3		0x16
++			MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL		0x16
++			MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK	0x16
+ 			MX8MP_IOMUXC_SAI1_MCLK__GPIO4_IO20			0x10
+ 		>;
+ 	};
+ 
+ 	pinctrl_i2c2: i2c2grp {
+ 		fsl,pins = <
+-			MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL		0x400001c3
+-			MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA		0x400001c3
++			MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL		0x400001c2
++			MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA		0x400001c2
+ 		>;
+ 	};
+ 
+ 	pinctrl_i2c2_gpio: i2c2gpiogrp {
+ 		fsl,pins = <
+-			MX8MP_IOMUXC_I2C2_SCL__GPIO5_IO16	0x1e3
+-			MX8MP_IOMUXC_I2C2_SDA__GPIO5_IO17	0x1e3
++			MX8MP_IOMUXC_I2C2_SCL__GPIO5_IO16	0x1e2
++			MX8MP_IOMUXC_I2C2_SDA__GPIO5_IO17	0x1e2
+ 		>;
+ 	};
+ 
+ 	pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
+ 		fsl,pins = <
+-			MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19	0x41
++			MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19	0x40
+ 		>;
+ 	};
+ 
+ 	pinctrl_uart1: uart1grp {
+ 		fsl,pins = <
+-			MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX	0x49
+-			MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX	0x49
++			MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX	0x40
++			MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX	0x40
+ 		>;
+ 	};
+ 
+@@ -175,7 +175,7 @@
+ 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1	0x1d0
+ 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2	0x1d0
+ 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3	0x1d0
+-			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc1
++			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc0
+ 		>;
+ 	};
+ 
+@@ -187,7 +187,7 @@
+ 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1	0x1d4
+ 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2	0x1d4
+ 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3	0x1d4
+-			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc1
++			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc0
+ 		>;
+ 	};
+ 
+@@ -199,7 +199,7 @@
+ 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1	0x1d6
+ 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2	0x1d6
+ 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3	0x1d6
+-			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc1
++			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc0
+ 		>;
+ 	};
+ };
+diff --git a/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi b/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi
+index 3b0cc85d66742..71e373b11de9d 100644
+--- a/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi
+@@ -74,7 +74,7 @@
+ 		vdd_l17_29-supply = <&vph_pwr>;
+ 		vdd_l20_21-supply = <&vph_pwr>;
+ 		vdd_l25-supply = <&pm8994_s5>;
+-		vdd_lvs1_2 = <&pm8994_s4>;
++		vdd_lvs1_2-supply = <&pm8994_s4>;
+ 
+ 		/* S1, S2, S6 and S12 are managed by RPMPD */
+ 
+diff --git a/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts b/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts
+index 84558ab5fe86b..ae882bfbf48dc 100644
+--- a/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts
++++ b/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts
+@@ -143,7 +143,7 @@
+ 		vdd_l17_29-supply = <&vph_pwr>;
+ 		vdd_l20_21-supply = <&vph_pwr>;
+ 		vdd_l25-supply = <&pm8994_s5>;
+-		vdd_lvs1_2 = <&pm8994_s4>;
++		vdd_lvs1_2-supply = <&pm8994_s4>;
+ 
+ 		/* S1, S2, S6 and S12 are managed by RPMPD */
+ 
+diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi
+index b1e595cb4b901..6b76321288d01 100644
+--- a/arch/arm64/boot/dts/qcom/msm8994.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi
+@@ -93,7 +93,7 @@
+ 		CPU6: cpu@102 {
+ 			device_type = "cpu";
+ 			compatible = "arm,cortex-a57";
+-			reg = <0x0 0x101>;
++			reg = <0x0 0x102>;
+ 			enable-method = "psci";
+ 			next-level-cache = <&L2_1>;
+ 		};
+@@ -101,7 +101,7 @@
+ 		CPU7: cpu@103 {
+ 			device_type = "cpu";
+ 			compatible = "arm,cortex-a57";
+-			reg = <0x0 0x101>;
++			reg = <0x0 0x103>;
+ 			enable-method = "psci";
+ 			next-level-cache = <&L2_1>;
+ 		};
+diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
+index b31bf62e86809..ad21cf465c986 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
+@@ -4238,7 +4238,7 @@
+ 
+ 			power-domains = <&dispcc MDSS_GDSC>;
+ 
+-			clocks = <&gcc GCC_DISP_AHB_CLK>,
++			clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
+ 				 <&dispcc DISP_CC_MDSS_MDP_CLK>;
+ 			clock-names = "iface", "core";
+ 
+diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi
+index e63b7b0458cf8..7a14eb89e4ca0 100644
+--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi
+@@ -1383,8 +1383,8 @@
+ 
+ 			iommus = <&apps_smmu 0xe0 0x0>;
+ 
+-			interconnects = <&aggre1_noc MASTER_UFS_MEM &mc_virt SLAVE_EBI1>,
+-					<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_UFS_MEM_CFG>;
++			interconnects = <&aggre1_noc MASTER_UFS_MEM 0 &mc_virt SLAVE_EBI1 0>,
++					<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_UFS_MEM_CFG 0>;
+ 			interconnect-names = "ufs-ddr", "cpu-ufs";
+ 			clock-names =
+ 				"core_clk",
+diff --git a/arch/powerpc/platforms/powernv/rng.c b/arch/powerpc/platforms/powernv/rng.c
+index 463c78c52cc5d..3805ad13b8f3d 100644
+--- a/arch/powerpc/platforms/powernv/rng.c
++++ b/arch/powerpc/platforms/powernv/rng.c
+@@ -176,12 +176,8 @@ static int __init pnv_get_random_long_early(unsigned long *v)
+ 		    NULL) != pnv_get_random_long_early)
+ 		return 0;
+ 
+-	for_each_compatible_node(dn, NULL, "ibm,power-rng") {
+-		if (rng_create(dn))
+-			continue;
+-		/* Create devices for hwrng driver */
+-		of_platform_device_create(dn, NULL, NULL);
+-	}
++	for_each_compatible_node(dn, NULL, "ibm,power-rng")
++		rng_create(dn);
+ 
+ 	if (!ppc_md.get_random_seed)
+ 		return 0;
+@@ -205,10 +201,18 @@ void __init pnv_rng_init(void)
+ 
+ static int __init pnv_rng_late_init(void)
+ {
++	struct device_node *dn;
+ 	unsigned long v;
++
+ 	/* In case it wasn't called during init for some other reason. */
+ 	if (ppc_md.get_random_seed == pnv_get_random_long_early)
+ 		pnv_get_random_long_early(&v);
++
++	if (ppc_md.get_random_seed == powernv_get_random_long) {
++		for_each_compatible_node(dn, NULL, "ibm,power-rng")
++			of_platform_device_create(dn, NULL, NULL);
++	}
++
+ 	return 0;
+ }
+ machine_subsys_initcall(powernv, pnv_rng_late_init);
+diff --git a/arch/x86/kernel/acpi/cppc.c b/arch/x86/kernel/acpi/cppc.c
+index df1644d9b3b66..3677df836e910 100644
+--- a/arch/x86/kernel/acpi/cppc.c
++++ b/arch/x86/kernel/acpi/cppc.c
+@@ -11,6 +11,16 @@
+ 
+ /* Refer to drivers/acpi/cppc_acpi.c for the description of functions */
+ 
++bool cpc_supported_by_cpu(void)
++{
++	switch (boot_cpu_data.x86_vendor) {
++	case X86_VENDOR_AMD:
++	case X86_VENDOR_HYGON:
++		return boot_cpu_has(X86_FEATURE_CPPC);
++	}
++	return false;
++}
++
+ bool cpc_ffh_supported(void)
+ {
+ 	return true;
+diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
+index 3e58b613a2c41..6c735cfa7d433 100644
+--- a/drivers/acpi/bus.c
++++ b/drivers/acpi/bus.c
+@@ -278,13 +278,27 @@ bool osc_sb_apei_support_acked;
+ bool osc_pc_lpi_support_confirmed;
+ EXPORT_SYMBOL_GPL(osc_pc_lpi_support_confirmed);
+ 
++/*
++ * ACPI 6.2 Section 6.2.11.2 'Platform-Wide OSPM Capabilities':
++ *   Starting with ACPI Specification 6.2, all _CPC registers can be in
++ *   PCC, System Memory, System IO, or Functional Fixed Hardware address
++ *   spaces. OSPM support for this more flexible register space scheme is
++ *   indicated by the “Flexible Address Space for CPPC Registers” _OSC bit.
++ *
++ * Otherwise (cf ACPI 6.1, s8.4.7.1.1.X), _CPC registers must be in:
++ * - PCC or Functional Fixed Hardware address space if defined
++ * - SystemMemory address space (NULL register) if not defined
++ */
++bool osc_cpc_flexible_adr_space_confirmed;
++EXPORT_SYMBOL_GPL(osc_cpc_flexible_adr_space_confirmed);
++
+ /*
+  * ACPI 6.4 Operating System Capabilities for USB.
+  */
+ bool osc_sb_native_usb4_support_confirmed;
+ EXPORT_SYMBOL_GPL(osc_sb_native_usb4_support_confirmed);
+ 
+-bool osc_sb_cppc_not_supported;
++bool osc_sb_cppc2_support_acked;
+ 
+ static u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48";
+ static void acpi_bus_osc_negotiate_platform_control(void)
+@@ -315,12 +329,15 @@ static void acpi_bus_osc_negotiate_platform_control(void)
+ #endif
+ #ifdef CONFIG_X86
+ 	capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_GENERIC_INITIATOR_SUPPORT;
+-	if (boot_cpu_has(X86_FEATURE_HWP)) {
+-		capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_SUPPORT;
+-		capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPCV2_SUPPORT;
+-	}
+ #endif
+ 
++#ifdef CONFIG_ACPI_CPPC_LIB
++	capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_SUPPORT;
++	capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPCV2_SUPPORT;
++#endif
++
++	capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_FLEXIBLE_ADR_SPACE;
++
+ 	if (IS_ENABLED(CONFIG_SCHED_MC_PRIO))
+ 		capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_DIVERSE_HIGH_SUPPORT;
+ 
+@@ -341,12 +358,6 @@ static void acpi_bus_osc_negotiate_platform_control(void)
+ 		return;
+ 	}
+ 
+-#ifdef CONFIG_X86
+-	if (boot_cpu_has(X86_FEATURE_HWP))
+-		osc_sb_cppc_not_supported = !(capbuf_ret[OSC_SUPPORT_DWORD] &
+-				(OSC_SB_CPC_SUPPORT | OSC_SB_CPCV2_SUPPORT));
+-#endif
+-
+ 	/*
+ 	 * Now run _OSC again with query flag clear and with the caps
+ 	 * supported by both the OS and the platform.
+@@ -360,12 +371,18 @@ static void acpi_bus_osc_negotiate_platform_control(void)
+ 
+ 	capbuf_ret = context.ret.pointer;
+ 	if (context.ret.length > OSC_SUPPORT_DWORD) {
++#ifdef CONFIG_ACPI_CPPC_LIB
++		osc_sb_cppc2_support_acked = capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_CPCV2_SUPPORT;
++#endif
++
+ 		osc_sb_apei_support_acked =
+ 			capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_APEI_SUPPORT;
+ 		osc_pc_lpi_support_confirmed =
+ 			capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_PCLPI_SUPPORT;
+ 		osc_sb_native_usb4_support_confirmed =
+ 			capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_NATIVE_USB4_SUPPORT;
++		osc_cpc_flexible_adr_space_confirmed =
++			capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_CPC_FLEXIBLE_ADR_SPACE;
+ 	}
+ 
+ 	kfree(context.ret.pointer);
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index 34576ab0e2e1d..57ca7aa0e169a 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -559,6 +559,19 @@ bool __weak cpc_ffh_supported(void)
+ 	return false;
+ }
+ 
++/**
++ * cpc_supported_by_cpu() - check if CPPC is supported by CPU
++ *
++ * Check if the architectural support for CPPC is present even
++ * if the _OSC hasn't prescribed it
++ *
++ * Return: true for supported, false for not supported
++ */
++bool __weak cpc_supported_by_cpu(void)
++{
++	return false;
++}
++
+ /**
+  * pcc_data_alloc() - Allocate the pcc_data memory for pcc subspace
+  *
+@@ -666,8 +679,11 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
+ 	acpi_status status;
+ 	int ret = -ENODATA;
+ 
+-	if (osc_sb_cppc_not_supported)
+-		return -ENODEV;
++	if (!osc_sb_cppc2_support_acked) {
++		pr_debug("CPPC v2 _OSC not acked\n");
++		if (!cpc_supported_by_cpu())
++			return -ENODEV;
++	}
+ 
+ 	/* Parse the ACPI _CPC table for this CPU. */
+ 	status = acpi_evaluate_object_typed(handle, "_CPC", NULL, &output,
+@@ -746,6 +762,11 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
+ 				if (gas_t->address) {
+ 					void __iomem *addr;
+ 
++					if (!osc_cpc_flexible_adr_space_confirmed) {
++						pr_debug("Flexible address space capability not supported\n");
++						goto out_free;
++					}
++
+ 					addr = ioremap(gas_t->address, gas_t->bit_width/8);
+ 					if (!addr)
+ 						goto out_free;
+@@ -768,6 +789,10 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
+ 						 gas_t->address);
+ 					goto out_free;
+ 				}
++				if (!osc_cpc_flexible_adr_space_confirmed) {
++					pr_debug("Flexible address space capability not supported\n");
++					goto out_free;
++				}
+ 			} else {
+ 				if (gas_t->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE || !cpc_ffh_supported()) {
+ 					/* Support only PCC, SystemMemory, SystemIO, and FFH type regs. */
+diff --git a/drivers/base/core.c b/drivers/base/core.c
+index 3d6430eb0c6a1..9dc0ca3db61d1 100644
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -485,7 +485,18 @@ static void device_link_release_fn(struct work_struct *work)
+ 	/* Ensure that all references to the link object have been dropped. */
+ 	device_link_synchronize_removal();
+ 
+-	pm_runtime_release_supplier(link, true);
++	pm_runtime_release_supplier(link);
++	/*
++	 * If supplier_preactivated is set, the link has been dropped between
++	 * the pm_runtime_get_suppliers() and pm_runtime_put_suppliers() calls
++	 * in __driver_probe_device().  In that case, drop the supplier's
++	 * PM-runtime usage counter to remove the reference taken by
++	 * pm_runtime_get_suppliers().
++	 */
++	if (link->supplier_preactivated)
++		pm_runtime_put_noidle(link->supplier);
++
++	pm_request_idle(link->supplier);
+ 
+ 	put_device(link->consumer);
+ 	put_device(link->supplier);
+diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
+index d4059e6ffeaec..2e3aa9a2e33c9 100644
+--- a/drivers/base/power/runtime.c
++++ b/drivers/base/power/runtime.c
+@@ -308,13 +308,10 @@ static int rpm_get_suppliers(struct device *dev)
+ /**
+  * pm_runtime_release_supplier - Drop references to device link's supplier.
+  * @link: Target device link.
+- * @check_idle: Whether or not to check if the supplier device is idle.
+  *
+- * Drop all runtime PM references associated with @link to its supplier device
+- * and if @check_idle is set, check if that device is idle (and so it can be
+- * suspended).
++ * Drop all runtime PM references associated with @link to its supplier device.
+  */
+-void pm_runtime_release_supplier(struct device_link *link, bool check_idle)
++void pm_runtime_release_supplier(struct device_link *link)
+ {
+ 	struct device *supplier = link->supplier;
+ 
+@@ -327,9 +324,6 @@ void pm_runtime_release_supplier(struct device_link *link, bool check_idle)
+ 	while (refcount_dec_not_one(&link->rpm_active) &&
+ 	       atomic_read(&supplier->power.usage_count) > 0)
+ 		pm_runtime_put_noidle(supplier);
+-
+-	if (check_idle)
+-		pm_request_idle(supplier);
+ }
+ 
+ static void __rpm_put_suppliers(struct device *dev, bool try_to_suspend)
+@@ -337,8 +331,11 @@ static void __rpm_put_suppliers(struct device *dev, bool try_to_suspend)
+ 	struct device_link *link;
+ 
+ 	list_for_each_entry_rcu(link, &dev->links.suppliers, c_node,
+-				device_links_read_lock_held())
+-		pm_runtime_release_supplier(link, try_to_suspend);
++				device_links_read_lock_held()) {
++		pm_runtime_release_supplier(link);
++		if (try_to_suspend)
++			pm_request_idle(link->supplier);
++	}
+ }
+ 
+ static void rpm_put_suppliers(struct device *dev)
+@@ -1740,7 +1737,6 @@ void pm_runtime_get_suppliers(struct device *dev)
+ 		if (link->flags & DL_FLAG_PM_RUNTIME) {
+ 			link->supplier_preactivated = true;
+ 			pm_runtime_get_sync(link->supplier);
+-			refcount_inc(&link->rpm_active);
+ 		}
+ 
+ 	device_links_read_unlock(idx);
+@@ -1760,19 +1756,8 @@ void pm_runtime_put_suppliers(struct device *dev)
+ 	list_for_each_entry_rcu(link, &dev->links.suppliers, c_node,
+ 				device_links_read_lock_held())
+ 		if (link->supplier_preactivated) {
+-			bool put;
+-
+ 			link->supplier_preactivated = false;
+-
+-			spin_lock_irq(&dev->power.lock);
+-
+-			put = pm_runtime_status_suspended(dev) &&
+-			      refcount_dec_not_one(&link->rpm_active);
+-
+-			spin_unlock_irq(&dev->power.lock);
+-
+-			if (put)
+-				pm_runtime_put(link->supplier);
++			pm_runtime_put(link->supplier);
+ 		}
+ 
+ 	device_links_read_unlock(idx);
+@@ -1807,7 +1792,8 @@ void pm_runtime_drop_link(struct device_link *link)
+ 		return;
+ 
+ 	pm_runtime_drop_link_count(link->consumer);
+-	pm_runtime_release_supplier(link, true);
++	pm_runtime_release_supplier(link);
++	pm_request_idle(link->supplier);
+ }
+ 
+ static bool pm_runtime_need_not_resume(struct device *dev)
+diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
+index 5d33ce24fe09f..ef68ee664b674 100644
+--- a/drivers/cxl/cxlmem.h
++++ b/drivers/cxl/cxlmem.h
+@@ -252,13 +252,13 @@ struct cxl_mbox_identify {
+ } __packed;
+ 
+ struct cxl_mbox_get_lsa {
+-	u32 offset;
+-	u32 length;
++	__le32 offset;
++	__le32 length;
+ } __packed;
+ 
+ struct cxl_mbox_set_lsa {
+-	u32 offset;
+-	u32 reserved;
++	__le32 offset;
++	__le32 reserved;
+ 	u8 data[];
+ } __packed;
+ 
+diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
+index 44e899f06094c..cb111bcfe8c6c 100644
+--- a/drivers/cxl/mem.c
++++ b/drivers/cxl/mem.c
+@@ -46,6 +46,7 @@ static int create_endpoint(struct cxl_memdev *cxlmd,
+ {
+ 	struct cxl_dev_state *cxlds = cxlmd->cxlds;
+ 	struct cxl_port *endpoint;
++	int rc;
+ 
+ 	endpoint = devm_cxl_add_port(&parent_port->dev, &cxlmd->dev,
+ 				     cxlds->component_reg_phys, parent_port);
+@@ -54,13 +55,17 @@ static int create_endpoint(struct cxl_memdev *cxlmd,
+ 
+ 	dev_dbg(&cxlmd->dev, "add: %s\n", dev_name(&endpoint->dev));
+ 
++	rc = cxl_endpoint_autoremove(cxlmd, endpoint);
++	if (rc)
++		return rc;
++
+ 	if (!endpoint->dev.driver) {
+ 		dev_err(&cxlmd->dev, "%s failed probe\n",
+ 			dev_name(&endpoint->dev));
+ 		return -ENXIO;
+ 	}
+ 
+-	return cxl_endpoint_autoremove(cxlmd, endpoint);
++	return 0;
+ }
+ 
+ /**
+diff --git a/drivers/cxl/pmem.c b/drivers/cxl/pmem.c
+index 15ad666ab03e3..6d85b54747abd 100644
+--- a/drivers/cxl/pmem.c
++++ b/drivers/cxl/pmem.c
+@@ -108,8 +108,8 @@ static int cxl_pmem_get_config_data(struct cxl_dev_state *cxlds,
+ 		return -EINVAL;
+ 
+ 	get_lsa = (struct cxl_mbox_get_lsa) {
+-		.offset = cmd->in_offset,
+-		.length = cmd->in_length,
++		.offset = cpu_to_le32(cmd->in_offset),
++		.length = cpu_to_le32(cmd->in_length),
+ 	};
+ 
+ 	rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_GET_LSA, &get_lsa,
+@@ -139,7 +139,7 @@ static int cxl_pmem_set_config_data(struct cxl_dev_state *cxlds,
+ 		return -ENOMEM;
+ 
+ 	*set_lsa = (struct cxl_mbox_set_lsa) {
+-		.offset = cmd->in_offset,
++		.offset = cpu_to_le32(cmd->in_offset),
+ 	};
+ 	memcpy(set_lsa->data, cmd->in_buf, cmd->in_length);
+ 
+diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
+index def564d1e8faf..678a3d4c6ec63 100644
+--- a/drivers/dma/at_xdmac.c
++++ b/drivers/dma/at_xdmac.c
+@@ -1893,6 +1893,11 @@ static int at_xdmac_alloc_chan_resources(struct dma_chan *chan)
+ 	for (i = 0; i < init_nr_desc_per_channel; i++) {
+ 		desc = at_xdmac_alloc_desc(chan, GFP_KERNEL);
+ 		if (!desc) {
++			if (i == 0) {
++				dev_warn(chan2dev(chan),
++					 "can't allocate any descriptors\n");
++				return -EIO;
++			}
+ 			dev_warn(chan2dev(chan),
+ 				"only %d descriptors have been allocated\n", i);
+ 			break;
+diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+index e9c9bcb1f5c20..c741da02b67e9 100644
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+@@ -1164,8 +1164,9 @@ static int dma_chan_pause(struct dma_chan *dchan)
+ 			BIT(chan->id) << DMAC_CHAN_SUSP_WE_SHIFT;
+ 		axi_dma_iowrite32(chan->chip, DMAC_CHEN, val);
+ 	} else {
+-		val = BIT(chan->id) << DMAC_CHAN_SUSP2_SHIFT |
+-		      BIT(chan->id) << DMAC_CHAN_SUSP2_WE_SHIFT;
++		val = axi_dma_ioread32(chan->chip, DMAC_CHSUSPREG);
++		val |= BIT(chan->id) << DMAC_CHAN_SUSP2_SHIFT |
++			BIT(chan->id) << DMAC_CHAN_SUSP2_WE_SHIFT;
+ 		axi_dma_iowrite32(chan->chip, DMAC_CHSUSPREG, val);
+ 	}
+ 
+@@ -1190,12 +1191,13 @@ static inline void axi_chan_resume(struct axi_dma_chan *chan)
+ {
+ 	u32 val;
+ 
+-	val = axi_dma_ioread32(chan->chip, DMAC_CHEN);
+ 	if (chan->chip->dw->hdata->reg_map_8_channels) {
++		val = axi_dma_ioread32(chan->chip, DMAC_CHEN);
+ 		val &= ~(BIT(chan->id) << DMAC_CHAN_SUSP_SHIFT);
+ 		val |=  (BIT(chan->id) << DMAC_CHAN_SUSP_WE_SHIFT);
+ 		axi_dma_iowrite32(chan->chip, DMAC_CHEN, val);
+ 	} else {
++		val = axi_dma_ioread32(chan->chip, DMAC_CHSUSPREG);
+ 		val &= ~(BIT(chan->id) << DMAC_CHAN_SUSP2_SHIFT);
+ 		val |=  (BIT(chan->id) << DMAC_CHAN_SUSP2_WE_SHIFT);
+ 		axi_dma_iowrite32(chan->chip, DMAC_CHSUSPREG, val);
+diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c
+index f652da6ab47df..58490289efc35 100644
+--- a/drivers/dma/idxd/device.c
++++ b/drivers/dma/idxd/device.c
+@@ -698,10 +698,7 @@ static void idxd_device_wqs_clear_state(struct idxd_device *idxd)
+ 	for (i = 0; i < idxd->max_wqs; i++) {
+ 		struct idxd_wq *wq = idxd->wqs[i];
+ 
+-		if (wq->state == IDXD_WQ_ENABLED) {
+-			idxd_wq_disable_cleanup(wq);
+-			wq->state = IDXD_WQ_DISABLED;
+-		}
++		idxd_wq_disable_cleanup(wq);
+ 		idxd_wq_device_reset_cleanup(wq);
+ 	}
+ }
+diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
+index 6196a7b3956b1..89694c704bd58 100644
+--- a/drivers/dma/imx-sdma.c
++++ b/drivers/dma/imx-sdma.c
+@@ -872,7 +872,7 @@ static void sdma_update_channel_loop(struct sdma_channel *sdmac)
+ 	 * SDMA stops cyclic channel when DMA request triggers a channel and no SDMA
+ 	 * owned buffer is available (i.e. BD_DONE was set too late).
+ 	 */
+-	if (!is_sdma_channel_enabled(sdmac->sdma, sdmac->channel)) {
++	if (sdmac->desc && !is_sdma_channel_enabled(sdmac->sdma, sdmac->channel)) {
+ 		dev_warn(sdmac->sdma->dev, "restart cyclic channel %d\n", sdmac->channel);
+ 		sdma_enable_channel(sdmac->sdma, sdmac->channel);
+ 	}
+@@ -2280,7 +2280,7 @@ MODULE_DESCRIPTION("i.MX SDMA driver");
+ #if IS_ENABLED(CONFIG_SOC_IMX6Q)
+ MODULE_FIRMWARE("imx/sdma/sdma-imx6q.bin");
+ #endif
+-#if IS_ENABLED(CONFIG_SOC_IMX7D)
++#if IS_ENABLED(CONFIG_SOC_IMX7D) || IS_ENABLED(CONFIG_SOC_IMX8M)
+ MODULE_FIRMWARE("imx/sdma/sdma-imx7d.bin");
+ #endif
+ MODULE_LICENSE("GPL");
+diff --git a/drivers/dma/lgm/lgm-dma.c b/drivers/dma/lgm/lgm-dma.c
+index efe8bd3a0e2aa..9b9184f964be3 100644
+--- a/drivers/dma/lgm/lgm-dma.c
++++ b/drivers/dma/lgm/lgm-dma.c
+@@ -1593,11 +1593,12 @@ static int intel_ldma_probe(struct platform_device *pdev)
+ 	d->core_clk = devm_clk_get_optional(dev, NULL);
+ 	if (IS_ERR(d->core_clk))
+ 		return PTR_ERR(d->core_clk);
+-	clk_prepare_enable(d->core_clk);
+ 
+ 	d->rst = devm_reset_control_get_optional(dev, NULL);
+ 	if (IS_ERR(d->rst))
+ 		return PTR_ERR(d->rst);
++
++	clk_prepare_enable(d->core_clk);
+ 	reset_control_deassert(d->rst);
+ 
+ 	ret = devm_add_action_or_reset(dev, ldma_clk_disable, d);
+diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
+index 858400e42ec05..09915a5cba3ea 100644
+--- a/drivers/dma/pl330.c
++++ b/drivers/dma/pl330.c
+@@ -2589,7 +2589,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
+ 
+ 	/* If the DMAC pool is empty, alloc new */
+ 	if (!desc) {
+-		DEFINE_SPINLOCK(lock);
++		static DEFINE_SPINLOCK(lock);
+ 		LIST_HEAD(pool);
+ 
+ 		if (!add_desc(&pool, &lock, GFP_ATOMIC, 1))
+diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
+index 87f6ca1541cff..2ff787df513e6 100644
+--- a/drivers/dma/qcom/bam_dma.c
++++ b/drivers/dma/qcom/bam_dma.c
+@@ -558,14 +558,6 @@ static int bam_alloc_chan(struct dma_chan *chan)
+ 	return 0;
+ }
+ 
+-static int bam_pm_runtime_get_sync(struct device *dev)
+-{
+-	if (pm_runtime_enabled(dev))
+-		return pm_runtime_get_sync(dev);
+-
+-	return 0;
+-}
+-
+ /**
+  * bam_free_chan - Frees dma resources associated with specific channel
+  * @chan: specified channel
+@@ -581,7 +573,7 @@ static void bam_free_chan(struct dma_chan *chan)
+ 	unsigned long flags;
+ 	int ret;
+ 
+-	ret = bam_pm_runtime_get_sync(bdev->dev);
++	ret = pm_runtime_get_sync(bdev->dev);
+ 	if (ret < 0)
+ 		return;
+ 
+@@ -784,7 +776,7 @@ static int bam_pause(struct dma_chan *chan)
+ 	unsigned long flag;
+ 	int ret;
+ 
+-	ret = bam_pm_runtime_get_sync(bdev->dev);
++	ret = pm_runtime_get_sync(bdev->dev);
+ 	if (ret < 0)
+ 		return ret;
+ 
+@@ -810,7 +802,7 @@ static int bam_resume(struct dma_chan *chan)
+ 	unsigned long flag;
+ 	int ret;
+ 
+-	ret = bam_pm_runtime_get_sync(bdev->dev);
++	ret = pm_runtime_get_sync(bdev->dev);
+ 	if (ret < 0)
+ 		return ret;
+ 
+@@ -919,7 +911,7 @@ static irqreturn_t bam_dma_irq(int irq, void *data)
+ 	if (srcs & P_IRQ)
+ 		tasklet_schedule(&bdev->task);
+ 
+-	ret = bam_pm_runtime_get_sync(bdev->dev);
++	ret = pm_runtime_get_sync(bdev->dev);
+ 	if (ret < 0)
+ 		return IRQ_NONE;
+ 
+@@ -1037,7 +1029,7 @@ static void bam_start_dma(struct bam_chan *bchan)
+ 	if (!vd)
+ 		return;
+ 
+-	ret = bam_pm_runtime_get_sync(bdev->dev);
++	ret = pm_runtime_get_sync(bdev->dev);
+ 	if (ret < 0)
+ 		return;
+ 
+@@ -1374,11 +1366,6 @@ static int bam_dma_probe(struct platform_device *pdev)
+ 	if (ret)
+ 		goto err_unregister_dma;
+ 
+-	if (!bdev->bamclk) {
+-		pm_runtime_disable(&pdev->dev);
+-		return 0;
+-	}
+-
+ 	pm_runtime_irq_safe(&pdev->dev);
+ 	pm_runtime_set_autosuspend_delay(&pdev->dev, BAM_DMA_AUTOSUSPEND_DELAY);
+ 	pm_runtime_use_autosuspend(&pdev->dev);
+@@ -1462,10 +1449,8 @@ static int __maybe_unused bam_dma_suspend(struct device *dev)
+ {
+ 	struct bam_device *bdev = dev_get_drvdata(dev);
+ 
+-	if (bdev->bamclk) {
+-		pm_runtime_force_suspend(dev);
+-		clk_unprepare(bdev->bamclk);
+-	}
++	pm_runtime_force_suspend(dev);
++	clk_unprepare(bdev->bamclk);
+ 
+ 	return 0;
+ }
+@@ -1475,13 +1460,11 @@ static int __maybe_unused bam_dma_resume(struct device *dev)
+ 	struct bam_device *bdev = dev_get_drvdata(dev);
+ 	int ret;
+ 
+-	if (bdev->bamclk) {
+-		ret = clk_prepare(bdev->bamclk);
+-		if (ret)
+-			return ret;
++	ret = clk_prepare(bdev->bamclk);
++	if (ret)
++		return ret;
+ 
+-		pm_runtime_force_resume(dev);
+-	}
++	pm_runtime_force_resume(dev);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/dma/ti/dma-crossbar.c b/drivers/dma/ti/dma-crossbar.c
+index 71d24fc07c003..f744ddbbbad7f 100644
+--- a/drivers/dma/ti/dma-crossbar.c
++++ b/drivers/dma/ti/dma-crossbar.c
+@@ -245,6 +245,7 @@ static void *ti_dra7_xbar_route_allocate(struct of_phandle_args *dma_spec,
+ 	if (dma_spec->args[0] >= xbar->xbar_requests) {
+ 		dev_err(&pdev->dev, "Invalid XBAR request number: %d\n",
+ 			dma_spec->args[0]);
++		put_device(&pdev->dev);
+ 		return ERR_PTR(-EINVAL);
+ 	}
+ 
+@@ -252,12 +253,14 @@ static void *ti_dra7_xbar_route_allocate(struct of_phandle_args *dma_spec,
+ 	dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0);
+ 	if (!dma_spec->np) {
+ 		dev_err(&pdev->dev, "Can't get DMA master\n");
++		put_device(&pdev->dev);
+ 		return ERR_PTR(-EINVAL);
+ 	}
+ 
+ 	map = kzalloc(sizeof(*map), GFP_KERNEL);
+ 	if (!map) {
+ 		of_node_put(dma_spec->np);
++		put_device(&pdev->dev);
+ 		return ERR_PTR(-ENOMEM);
+ 	}
+ 
+@@ -268,6 +271,8 @@ static void *ti_dra7_xbar_route_allocate(struct of_phandle_args *dma_spec,
+ 		mutex_unlock(&xbar->mutex);
+ 		dev_err(&pdev->dev, "Run out of free DMA requests\n");
+ 		kfree(map);
++		of_node_put(dma_spec->np);
++		put_device(&pdev->dev);
+ 		return ERR_PTR(-ENOMEM);
+ 	}
+ 	set_bit(map->xbar_out, xbar->dma_inuse);
+diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c
+index b4c1ad19cdaec..3d6f8ee355bfc 100644
+--- a/drivers/i2c/busses/i2c-cadence.c
++++ b/drivers/i2c/busses/i2c-cadence.c
+@@ -1338,6 +1338,7 @@ static int cdns_i2c_probe(struct platform_device *pdev)
+ 	return 0;
+ 
+ err_clk_dis:
++	clk_notifier_unregister(id->clk, &id->clk_rate_change_nb);
+ 	clk_disable_unprepare(id->clk);
+ 	pm_runtime_disable(&pdev->dev);
+ 	pm_runtime_set_suspended(&pdev->dev);
+diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
+index ac8e7d60672a1..39cb1b7bb8656 100644
+--- a/drivers/i2c/busses/i2c-piix4.c
++++ b/drivers/i2c/busses/i2c-piix4.c
+@@ -161,7 +161,6 @@ static const char *piix4_aux_port_name_sb800 = " port 1";
+ 
+ struct sb800_mmio_cfg {
+ 	void __iomem *addr;
+-	struct resource *res;
+ 	bool use_mmio;
+ };
+ 
+@@ -179,13 +178,11 @@ static int piix4_sb800_region_request(struct device *dev,
+ 				      struct sb800_mmio_cfg *mmio_cfg)
+ {
+ 	if (mmio_cfg->use_mmio) {
+-		struct resource *res;
+ 		void __iomem *addr;
+ 
+-		res = request_mem_region_muxed(SB800_PIIX4_FCH_PM_ADDR,
+-					       SB800_PIIX4_FCH_PM_SIZE,
+-					       "sb800_piix4_smb");
+-		if (!res) {
++		if (!request_mem_region_muxed(SB800_PIIX4_FCH_PM_ADDR,
++					      SB800_PIIX4_FCH_PM_SIZE,
++					      "sb800_piix4_smb")) {
+ 			dev_err(dev,
+ 				"SMBus base address memory region 0x%x already in use.\n",
+ 				SB800_PIIX4_FCH_PM_ADDR);
+@@ -195,12 +192,12 @@ static int piix4_sb800_region_request(struct device *dev,
+ 		addr = ioremap(SB800_PIIX4_FCH_PM_ADDR,
+ 			       SB800_PIIX4_FCH_PM_SIZE);
+ 		if (!addr) {
+-			release_resource(res);
++			release_mem_region(SB800_PIIX4_FCH_PM_ADDR,
++					   SB800_PIIX4_FCH_PM_SIZE);
+ 			dev_err(dev, "SMBus base address mapping failed.\n");
+ 			return -ENOMEM;
+ 		}
+ 
+-		mmio_cfg->res = res;
+ 		mmio_cfg->addr = addr;
+ 
+ 		return 0;
+@@ -222,7 +219,8 @@ static void piix4_sb800_region_release(struct device *dev,
+ {
+ 	if (mmio_cfg->use_mmio) {
+ 		iounmap(mmio_cfg->addr);
+-		release_resource(mmio_cfg->res);
++		release_mem_region(SB800_PIIX4_FCH_PM_ADDR,
++				   SB800_PIIX4_FCH_PM_SIZE);
+ 		return;
+ 	}
+ 
+diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
+index 4de960834a1b2..497c5bd95caf8 100644
+--- a/drivers/iommu/intel/dmar.c
++++ b/drivers/iommu/intel/dmar.c
+@@ -383,7 +383,7 @@ static int dmar_pci_bus_notifier(struct notifier_block *nb,
+ 
+ static struct notifier_block dmar_pci_bus_nb = {
+ 	.notifier_call = dmar_pci_bus_notifier,
+-	.priority = INT_MIN,
++	.priority = 1,
+ };
+ 
+ static struct dmar_drhd_unit *
+diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
+index ba9a63cac47cc..c7ec5177cf78a 100644
+--- a/drivers/iommu/intel/iommu.c
++++ b/drivers/iommu/intel/iommu.c
+@@ -320,30 +320,6 @@ EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
+ DEFINE_SPINLOCK(device_domain_lock);
+ static LIST_HEAD(device_domain_list);
+ 
+-/*
+- * Iterate over elements in device_domain_list and call the specified
+- * callback @fn against each element.
+- */
+-int for_each_device_domain(int (*fn)(struct device_domain_info *info,
+-				     void *data), void *data)
+-{
+-	int ret = 0;
+-	unsigned long flags;
+-	struct device_domain_info *info;
+-
+-	spin_lock_irqsave(&device_domain_lock, flags);
+-	list_for_each_entry(info, &device_domain_list, global) {
+-		ret = fn(info, data);
+-		if (ret) {
+-			spin_unlock_irqrestore(&device_domain_lock, flags);
+-			return ret;
+-		}
+-	}
+-	spin_unlock_irqrestore(&device_domain_lock, flags);
+-
+-	return 0;
+-}
+-
+ const struct iommu_ops intel_iommu_ops;
+ 
+ static bool translation_pre_enabled(struct intel_iommu *iommu)
+diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
+index f8d215d85695b..723f3cd8fe729 100644
+--- a/drivers/iommu/intel/pasid.c
++++ b/drivers/iommu/intel/pasid.c
+@@ -86,54 +86,6 @@ void vcmd_free_pasid(struct intel_iommu *iommu, u32 pasid)
+ /*
+  * Per device pasid table management:
+  */
+-static inline void
+-device_attach_pasid_table(struct device_domain_info *info,
+-			  struct pasid_table *pasid_table)
+-{
+-	info->pasid_table = pasid_table;
+-	list_add(&info->table, &pasid_table->dev);
+-}
+-
+-static inline void
+-device_detach_pasid_table(struct device_domain_info *info,
+-			  struct pasid_table *pasid_table)
+-{
+-	info->pasid_table = NULL;
+-	list_del(&info->table);
+-}
+-
+-struct pasid_table_opaque {
+-	struct pasid_table	**pasid_table;
+-	int			segment;
+-	int			bus;
+-	int			devfn;
+-};
+-
+-static int search_pasid_table(struct device_domain_info *info, void *opaque)
+-{
+-	struct pasid_table_opaque *data = opaque;
+-
+-	if (info->iommu->segment == data->segment &&
+-	    info->bus == data->bus &&
+-	    info->devfn == data->devfn &&
+-	    info->pasid_table) {
+-		*data->pasid_table = info->pasid_table;
+-		return 1;
+-	}
+-
+-	return 0;
+-}
+-
+-static int get_alias_pasid_table(struct pci_dev *pdev, u16 alias, void *opaque)
+-{
+-	struct pasid_table_opaque *data = opaque;
+-
+-	data->segment = pci_domain_nr(pdev->bus);
+-	data->bus = PCI_BUS_NUM(alias);
+-	data->devfn = alias & 0xff;
+-
+-	return for_each_device_domain(&search_pasid_table, data);
+-}
+ 
+ /*
+  * Allocate a pasid table for @dev. It should be called in a
+@@ -143,28 +95,18 @@ int intel_pasid_alloc_table(struct device *dev)
+ {
+ 	struct device_domain_info *info;
+ 	struct pasid_table *pasid_table;
+-	struct pasid_table_opaque data;
+ 	struct page *pages;
+ 	u32 max_pasid = 0;
+-	int ret, order;
+-	int size;
++	int order, size;
+ 
+ 	might_sleep();
+ 	info = dev_iommu_priv_get(dev);
+ 	if (WARN_ON(!info || !dev_is_pci(dev) || info->pasid_table))
+ 		return -EINVAL;
+ 
+-	/* DMA alias device already has a pasid table, use it: */
+-	data.pasid_table = &pasid_table;
+-	ret = pci_for_each_dma_alias(to_pci_dev(dev),
+-				     &get_alias_pasid_table, &data);
+-	if (ret)
+-		goto attach_out;
+-
+ 	pasid_table = kzalloc(sizeof(*pasid_table), GFP_KERNEL);
+ 	if (!pasid_table)
+ 		return -ENOMEM;
+-	INIT_LIST_HEAD(&pasid_table->dev);
+ 
+ 	if (info->pasid_supported)
+ 		max_pasid = min_t(u32, pci_max_pasids(to_pci_dev(dev)),
+@@ -182,9 +124,7 @@ int intel_pasid_alloc_table(struct device *dev)
+ 	pasid_table->table = page_address(pages);
+ 	pasid_table->order = order;
+ 	pasid_table->max_pasid = 1 << (order + PAGE_SHIFT + 3);
+-
+-attach_out:
+-	device_attach_pasid_table(info, pasid_table);
++	info->pasid_table = pasid_table;
+ 
+ 	return 0;
+ }
+@@ -202,10 +142,7 @@ void intel_pasid_free_table(struct device *dev)
+ 		return;
+ 
+ 	pasid_table = info->pasid_table;
+-	device_detach_pasid_table(info, pasid_table);
+-
+-	if (!list_empty(&pasid_table->dev))
+-		return;
++	info->pasid_table = NULL;
+ 
+ 	/* Free scalable mode PASID directory tables: */
+ 	dir = pasid_table->table;
+diff --git a/drivers/iommu/intel/pasid.h b/drivers/iommu/intel/pasid.h
+index ab4408c824a5a..3d62d84aced47 100644
+--- a/drivers/iommu/intel/pasid.h
++++ b/drivers/iommu/intel/pasid.h
+@@ -74,7 +74,6 @@ struct pasid_table {
+ 	void			*table;		/* pasid table pointer */
+ 	int			order;		/* page order of pasid table */
+ 	u32			max_pasid;	/* max pasid */
+-	struct list_head	dev;		/* device list */
+ };
+ 
+ /* Get PRESENT bit of a PASID directory entry. */
+diff --git a/drivers/misc/cardreader/rtsx_usb.c b/drivers/misc/cardreader/rtsx_usb.c
+index 1ef9b61077c44..f150d8769f198 100644
+--- a/drivers/misc/cardreader/rtsx_usb.c
++++ b/drivers/misc/cardreader/rtsx_usb.c
+@@ -631,16 +631,20 @@ static int rtsx_usb_probe(struct usb_interface *intf,
+ 
+ 	ucr->pusb_dev = usb_dev;
+ 
+-	ucr->iobuf = usb_alloc_coherent(ucr->pusb_dev, IOBUF_SIZE,
+-			GFP_KERNEL, &ucr->iobuf_dma);
+-	if (!ucr->iobuf)
++	ucr->cmd_buf = kmalloc(IOBUF_SIZE, GFP_KERNEL);
++	if (!ucr->cmd_buf)
+ 		return -ENOMEM;
+ 
++	ucr->rsp_buf = kmalloc(IOBUF_SIZE, GFP_KERNEL);
++	if (!ucr->rsp_buf) {
++		ret = -ENOMEM;
++		goto out_free_cmd_buf;
++	}
++
+ 	usb_set_intfdata(intf, ucr);
+ 
+ 	ucr->vendor_id = id->idVendor;
+ 	ucr->product_id = id->idProduct;
+-	ucr->cmd_buf = ucr->rsp_buf = ucr->iobuf;
+ 
+ 	mutex_init(&ucr->dev_mutex);
+ 
+@@ -668,8 +672,11 @@ static int rtsx_usb_probe(struct usb_interface *intf,
+ 
+ out_init_fail:
+ 	usb_set_intfdata(ucr->pusb_intf, NULL);
+-	usb_free_coherent(ucr->pusb_dev, IOBUF_SIZE, ucr->iobuf,
+-			ucr->iobuf_dma);
++	kfree(ucr->rsp_buf);
++	ucr->rsp_buf = NULL;
++out_free_cmd_buf:
++	kfree(ucr->cmd_buf);
++	ucr->cmd_buf = NULL;
+ 	return ret;
+ }
+ 
+@@ -682,8 +689,12 @@ static void rtsx_usb_disconnect(struct usb_interface *intf)
+ 	mfd_remove_devices(&intf->dev);
+ 
+ 	usb_set_intfdata(ucr->pusb_intf, NULL);
+-	usb_free_coherent(ucr->pusb_dev, IOBUF_SIZE, ucr->iobuf,
+-			ucr->iobuf_dma);
++
++	kfree(ucr->cmd_buf);
++	ucr->cmd_buf = NULL;
++
++	kfree(ucr->rsp_buf);
++	ucr->rsp_buf = NULL;
+ }
+ 
+ #ifdef CONFIG_PM
+diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
+index 5215bd9b2c80d..804dd1d480506 100644
+--- a/drivers/net/can/grcan.c
++++ b/drivers/net/can/grcan.c
+@@ -1646,7 +1646,6 @@ static int grcan_probe(struct platform_device *ofdev)
+ 	 */
+ 	sysid_parent = of_find_node_by_path("/ambapp0");
+ 	if (sysid_parent) {
+-		of_node_get(sysid_parent);
+ 		err = of_property_read_u32(sysid_parent, "systemid", &sysid);
+ 		if (!err && ((sysid & GRLIB_VERSION_MASK) >=
+ 			     GRCAN_TXBUG_SAFE_GRLIB_VERSION))
+diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
+index 088bb1bcf1efb..928958b7e6f60 100644
+--- a/drivers/net/can/m_can/m_can.c
++++ b/drivers/net/can/m_can/m_can.c
+@@ -532,7 +532,7 @@ static int m_can_read_fifo(struct net_device *dev, u32 rxfs)
+ 	/* acknowledge rx fifo 0 */
+ 	m_can_write(cdev, M_CAN_RXF0A, fgi);
+ 
+-	timestamp = FIELD_GET(RX_BUF_RXTS_MASK, fifo_header.dlc);
++	timestamp = FIELD_GET(RX_BUF_RXTS_MASK, fifo_header.dlc) << 16;
+ 
+ 	m_can_receive_skb(cdev, skb, timestamp);
+ 
+@@ -1036,7 +1036,7 @@ static int m_can_echo_tx_event(struct net_device *dev)
+ 		}
+ 
+ 		msg_mark = FIELD_GET(TX_EVENT_MM_MASK, txe);
+-		timestamp = FIELD_GET(TX_EVENT_TXTS_MASK, txe);
++		timestamp = FIELD_GET(TX_EVENT_TXTS_MASK, txe) << 16;
+ 
+ 		/* ack txe element */
+ 		m_can_write(cdev, M_CAN_TXEFA, FIELD_PREP(TXEFA_EFAI_MASK,
+@@ -1360,7 +1360,9 @@ static void m_can_chip_config(struct net_device *dev)
+ 	/* enable internal timestamp generation, with a prescalar of 16. The
+ 	 * prescalar is applied to the nominal bit timing
+ 	 */
+-	m_can_write(cdev, M_CAN_TSCC, FIELD_PREP(TSCC_TCP_MASK, 0xf));
++	m_can_write(cdev, M_CAN_TSCC,
++		    FIELD_PREP(TSCC_TCP_MASK, 0xf) |
++		    FIELD_PREP(TSCC_TSS_MASK, TSCC_TSS_INTERNAL));
+ 
+ 	m_can_config_endisable(cdev, false);
+ 
+diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
+index 1e121e04208cc..589996cef5db3 100644
+--- a/drivers/net/can/rcar/rcar_canfd.c
++++ b/drivers/net/can/rcar/rcar_canfd.c
+@@ -1334,7 +1334,10 @@ static void rcar_canfd_set_bittiming(struct net_device *dev)
+ 		cfg = (RCANFD_DCFG_DTSEG1(gpriv, tseg1) | RCANFD_DCFG_DBRP(brp) |
+ 		       RCANFD_DCFG_DSJW(sjw) | RCANFD_DCFG_DTSEG2(gpriv, tseg2));
+ 
+-		rcar_canfd_write(priv->base, RCANFD_F_DCFG(ch), cfg);
++		if (is_v3u(gpriv))
++			rcar_canfd_write(priv->base, RCANFD_V3U_DCFG(ch), cfg);
++		else
++			rcar_canfd_write(priv->base, RCANFD_F_DCFG(ch), cfg);
+ 		netdev_dbg(priv->ndev, "drate: brp %u, sjw %u, tseg1 %u, tseg2 %u\n",
+ 			   brp, sjw, tseg1, tseg2);
+ 	} else {
+diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
+index f9dd8fdba12bc..1bbb43d77a728 100644
+--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
+@@ -12,6 +12,7 @@
+ // Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org>
+ //
+ 
++#include <asm/unaligned.h>
+ #include <linux/bitfield.h>
+ #include <linux/clk.h>
+ #include <linux/device.h>
+@@ -1641,6 +1642,7 @@ static int mcp251xfd_stop(struct net_device *ndev)
+ 	netif_stop_queue(ndev);
+ 	set_bit(MCP251XFD_FLAGS_DOWN, priv->flags);
+ 	hrtimer_cancel(&priv->rx_irq_timer);
++	hrtimer_cancel(&priv->tx_irq_timer);
+ 	mcp251xfd_chip_interrupts_disable(priv);
+ 	free_irq(ndev->irq, priv);
+ 	can_rx_offload_disable(&priv->offload);
+@@ -1768,7 +1770,7 @@ mcp251xfd_register_get_dev_id(const struct mcp251xfd_priv *priv, u32 *dev_id,
+ 	xfer[0].len = sizeof(buf_tx->cmd);
+ 	xfer[0].speed_hz = priv->spi_max_speed_hz_slow;
+ 	xfer[1].rx_buf = buf_rx->data;
+-	xfer[1].len = sizeof(dev_id);
++	xfer[1].len = sizeof(*dev_id);
+ 	xfer[1].speed_hz = priv->spi_max_speed_hz_fast;
+ 
+ 	mcp251xfd_spi_cmd_read_nocrc(&buf_tx->cmd, MCP251XFD_REG_DEVID);
+@@ -1777,7 +1779,7 @@ mcp251xfd_register_get_dev_id(const struct mcp251xfd_priv *priv, u32 *dev_id,
+ 	if (err)
+ 		goto out_kfree_buf_tx;
+ 
+-	*dev_id = be32_to_cpup((__be32 *)buf_rx->data);
++	*dev_id = get_unaligned_le32(buf_rx->data);
+ 	*effective_speed_hz_slow = xfer[0].effective_speed_hz;
+ 	*effective_speed_hz_fast = xfer[1].effective_speed_hz;
+ 
+diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c
+index 217510c12af55..92b7bc7f14b9e 100644
+--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c
++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c
+@@ -334,19 +334,21 @@ mcp251xfd_regmap_crc_read(void *context,
+ 		 * register. It increments once per SYS clock tick,
+ 		 * which is 20 or 40 MHz.
+ 		 *
+-		 * Observation shows that if the lowest byte (which is
+-		 * transferred first on the SPI bus) of that register
+-		 * is 0x00 or 0x80 the calculated CRC doesn't always
+-		 * match the transferred one.
++		 * Observation on the mcp2518fd shows that if the
++		 * lowest byte (which is transferred first on the SPI
++		 * bus) of that register is 0x00 or 0x80 the
++		 * calculated CRC doesn't always match the transferred
++		 * one. On the mcp2517fd this problem is not limited
++		 * to the first byte being 0x00 or 0x80.
+ 		 *
+ 		 * If the highest bit in the lowest byte is flipped
+ 		 * the transferred CRC matches the calculated one. We
+-		 * assume for now the CRC calculation in the chip
+-		 * works on wrong data and the transferred data is
+-		 * correct.
++		 * assume for now the CRC operates on the correct
++		 * data.
+ 		 */
+ 		if (reg == MCP251XFD_REG_TBC &&
+-		    (buf_rx->data[0] == 0x0 || buf_rx->data[0] == 0x80)) {
++		    ((buf_rx->data[0] & 0xf8) == 0x0 ||
++		     (buf_rx->data[0] & 0xf8) == 0x80)) {
+ 			/* Flip highest bit in lowest byte of le32 */
+ 			buf_rx->data[0] ^= 0x80;
+ 
+@@ -356,10 +358,8 @@ mcp251xfd_regmap_crc_read(void *context,
+ 								  val_len);
+ 			if (!err) {
+ 				/* If CRC is now correct, assume
+-				 * transferred data was OK, flip bit
+-				 * back to original value.
++				 * flipped data is OK.
+ 				 */
+-				buf_rx->data[0] ^= 0x80;
+ 				goto out;
+ 			}
+ 		}
+diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
+index b29ba9138866b..d3a658b444b5f 100644
+--- a/drivers/net/can/usb/gs_usb.c
++++ b/drivers/net/can/usb/gs_usb.c
+@@ -268,6 +268,8 @@ struct gs_can {
+ 
+ 	struct usb_anchor tx_submitted;
+ 	atomic_t active_tx_urbs;
++	void *rxbuf[GS_MAX_RX_URBS];
++	dma_addr_t rxbuf_dma[GS_MAX_RX_URBS];
+ };
+ 
+ /* usb interface struct */
+@@ -742,6 +744,7 @@ static int gs_can_open(struct net_device *netdev)
+ 		for (i = 0; i < GS_MAX_RX_URBS; i++) {
+ 			struct urb *urb;
+ 			u8 *buf;
++			dma_addr_t buf_dma;
+ 
+ 			/* alloc rx urb */
+ 			urb = usb_alloc_urb(0, GFP_KERNEL);
+@@ -752,7 +755,7 @@ static int gs_can_open(struct net_device *netdev)
+ 			buf = usb_alloc_coherent(dev->udev,
+ 						 dev->parent->hf_size_rx,
+ 						 GFP_KERNEL,
+-						 &urb->transfer_dma);
++						 &buf_dma);
+ 			if (!buf) {
+ 				netdev_err(netdev,
+ 					   "No memory left for USB buffer\n");
+@@ -760,6 +763,8 @@ static int gs_can_open(struct net_device *netdev)
+ 				return -ENOMEM;
+ 			}
+ 
++			urb->transfer_dma = buf_dma;
++
+ 			/* fill, anchor, and submit rx urb */
+ 			usb_fill_bulk_urb(urb,
+ 					  dev->udev,
+@@ -781,10 +786,17 @@ static int gs_can_open(struct net_device *netdev)
+ 					   "usb_submit failed (err=%d)\n", rc);
+ 
+ 				usb_unanchor_urb(urb);
++				usb_free_coherent(dev->udev,
++						  sizeof(struct gs_host_frame),
++						  buf,
++						  buf_dma);
+ 				usb_free_urb(urb);
+ 				break;
+ 			}
+ 
++			dev->rxbuf[i] = buf;
++			dev->rxbuf_dma[i] = buf_dma;
++
+ 			/* Drop reference,
+ 			 * USB core will take care of freeing it
+ 			 */
+@@ -842,13 +854,20 @@ static int gs_can_close(struct net_device *netdev)
+ 	int rc;
+ 	struct gs_can *dev = netdev_priv(netdev);
+ 	struct gs_usb *parent = dev->parent;
++	unsigned int i;
+ 
+ 	netif_stop_queue(netdev);
+ 
+ 	/* Stop polling */
+ 	parent->active_channels--;
+-	if (!parent->active_channels)
++	if (!parent->active_channels) {
+ 		usb_kill_anchored_urbs(&parent->rx_submitted);
++		for (i = 0; i < GS_MAX_RX_URBS; i++)
++			usb_free_coherent(dev->udev,
++					  sizeof(struct gs_host_frame),
++					  dev->rxbuf[i],
++					  dev->rxbuf_dma[i]);
++	}
+ 
+ 	/* Stop sending URBs */
+ 	usb_kill_anchored_urbs(&dev->tx_submitted);
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
+index 3a49257f9fa65..eefcbe3aadce7 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
+@@ -35,9 +35,10 @@
+ #define KVASER_USB_RX_BUFFER_SIZE		3072
+ #define KVASER_USB_MAX_NET_DEVICES		5
+ 
+-/* USB devices features */
+-#define KVASER_USB_HAS_SILENT_MODE		BIT(0)
+-#define KVASER_USB_HAS_TXRX_ERRORS		BIT(1)
++/* Kvaser USB device quirks */
++#define KVASER_USB_QUIRK_HAS_SILENT_MODE	BIT(0)
++#define KVASER_USB_QUIRK_HAS_TXRX_ERRORS	BIT(1)
++#define KVASER_USB_QUIRK_IGNORE_CLK_FREQ	BIT(2)
+ 
+ /* Device capabilities */
+ #define KVASER_USB_CAP_BERR_CAP			0x01
+@@ -65,12 +66,7 @@ struct kvaser_usb_dev_card_data_hydra {
+ struct kvaser_usb_dev_card_data {
+ 	u32 ctrlmode_supported;
+ 	u32 capabilities;
+-	union {
+-		struct {
+-			enum kvaser_usb_leaf_family family;
+-		} leaf;
+-		struct kvaser_usb_dev_card_data_hydra hydra;
+-	};
++	struct kvaser_usb_dev_card_data_hydra hydra;
+ };
+ 
+ /* Context for an outstanding, not yet ACKed, transmission */
+@@ -83,7 +79,7 @@ struct kvaser_usb {
+ 	struct usb_device *udev;
+ 	struct usb_interface *intf;
+ 	struct kvaser_usb_net_priv *nets[KVASER_USB_MAX_NET_DEVICES];
+-	const struct kvaser_usb_dev_ops *ops;
++	const struct kvaser_usb_driver_info *driver_info;
+ 	const struct kvaser_usb_dev_cfg *cfg;
+ 
+ 	struct usb_endpoint_descriptor *bulk_in, *bulk_out;
+@@ -165,6 +161,12 @@ struct kvaser_usb_dev_ops {
+ 				  u16 transid);
+ };
+ 
++struct kvaser_usb_driver_info {
++	u32 quirks;
++	enum kvaser_usb_leaf_family family;
++	const struct kvaser_usb_dev_ops *ops;
++};
++
+ struct kvaser_usb_dev_cfg {
+ 	const struct can_clock clock;
+ 	const unsigned int timestamp_freq;
+@@ -184,4 +186,7 @@ int kvaser_usb_send_cmd_async(struct kvaser_usb_net_priv *priv, void *cmd,
+ 			      int len);
+ 
+ int kvaser_usb_can_rx_over_error(struct net_device *netdev);
++
++extern const struct can_bittiming_const kvaser_usb_flexc_bittiming_const;
++
+ #endif /* KVASER_USB_H */
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+index e67658b53d02f..f211bfcb1d97e 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+@@ -61,8 +61,6 @@
+ #define USB_USBCAN_R_V2_PRODUCT_ID		294
+ #define USB_LEAF_LIGHT_R_V2_PRODUCT_ID		295
+ #define USB_LEAF_LIGHT_HS_V2_OEM2_PRODUCT_ID	296
+-#define USB_LEAF_PRODUCT_ID_END \
+-	USB_LEAF_LIGHT_HS_V2_OEM2_PRODUCT_ID
+ 
+ /* Kvaser USBCan-II devices product ids */
+ #define USB_USBCAN_REVB_PRODUCT_ID		2
+@@ -89,116 +87,153 @@
+ #define USB_USBCAN_PRO_4HS_PRODUCT_ID		276
+ #define USB_HYBRID_CANLIN_PRODUCT_ID		277
+ #define USB_HYBRID_PRO_CANLIN_PRODUCT_ID	278
+-#define USB_HYDRA_PRODUCT_ID_END \
+-	USB_HYBRID_PRO_CANLIN_PRODUCT_ID
+ 
+-static inline bool kvaser_is_leaf(const struct usb_device_id *id)
+-{
+-	return (id->idProduct >= USB_LEAF_DEVEL_PRODUCT_ID &&
+-		id->idProduct <= USB_CAN_R_PRODUCT_ID) ||
+-		(id->idProduct >= USB_LEAF_LITE_V2_PRODUCT_ID &&
+-		 id->idProduct <= USB_LEAF_PRODUCT_ID_END);
+-}
++static const struct kvaser_usb_driver_info kvaser_usb_driver_info_hydra = {
++	.quirks = 0,
++	.ops = &kvaser_usb_hydra_dev_ops,
++};
+ 
+-static inline bool kvaser_is_usbcan(const struct usb_device_id *id)
+-{
+-	return id->idProduct >= USB_USBCAN_REVB_PRODUCT_ID &&
+-	       id->idProduct <= USB_MEMORATOR_PRODUCT_ID;
+-}
++static const struct kvaser_usb_driver_info kvaser_usb_driver_info_usbcan = {
++	.quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS |
++		  KVASER_USB_QUIRK_HAS_SILENT_MODE,
++	.family = KVASER_USBCAN,
++	.ops = &kvaser_usb_leaf_dev_ops,
++};
+ 
+-static inline bool kvaser_is_hydra(const struct usb_device_id *id)
+-{
+-	return id->idProduct >= USB_BLACKBIRD_V2_PRODUCT_ID &&
+-	       id->idProduct <= USB_HYDRA_PRODUCT_ID_END;
+-}
++static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf = {
++	.quirks = KVASER_USB_QUIRK_IGNORE_CLK_FREQ,
++	.family = KVASER_LEAF,
++	.ops = &kvaser_usb_leaf_dev_ops,
++};
++
++static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err = {
++	.quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS |
++		  KVASER_USB_QUIRK_IGNORE_CLK_FREQ,
++	.family = KVASER_LEAF,
++	.ops = &kvaser_usb_leaf_dev_ops,
++};
++
++static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err_listen = {
++	.quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS |
++		  KVASER_USB_QUIRK_HAS_SILENT_MODE |
++		  KVASER_USB_QUIRK_IGNORE_CLK_FREQ,
++	.family = KVASER_LEAF,
++	.ops = &kvaser_usb_leaf_dev_ops,
++};
++
++static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leafimx = {
++	.quirks = 0,
++	.ops = &kvaser_usb_leaf_dev_ops,
++};
+ 
+ static const struct usb_device_id kvaser_usb_table[] = {
+-	/* Leaf USB product IDs */
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_DEVEL_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_PRODUCT_ID) },
++	/* Leaf M32C USB product IDs */
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_DEVEL_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
+ 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_PRODUCT_ID),
+-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |
+-			       KVASER_USB_HAS_SILENT_MODE },
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },
+ 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_SPRO_PRODUCT_ID),
+-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |
+-			       KVASER_USB_HAS_SILENT_MODE },
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },
+ 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_LS_PRODUCT_ID),
+-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |
+-			       KVASER_USB_HAS_SILENT_MODE },
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },
+ 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_SWC_PRODUCT_ID),
+-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |
+-			       KVASER_USB_HAS_SILENT_MODE },
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },
+ 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_LIN_PRODUCT_ID),
+-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |
+-			       KVASER_USB_HAS_SILENT_MODE },
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },
+ 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_SPRO_LS_PRODUCT_ID),
+-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |
+-			       KVASER_USB_HAS_SILENT_MODE },
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },
+ 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_SPRO_SWC_PRODUCT_ID),
+-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |
+-			       KVASER_USB_HAS_SILENT_MODE },
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },
+ 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO2_DEVEL_PRODUCT_ID),
+-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |
+-			       KVASER_USB_HAS_SILENT_MODE },
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },
+ 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO2_HSHS_PRODUCT_ID),
+-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |
+-			       KVASER_USB_HAS_SILENT_MODE },
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },
+ 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_UPRO_HSHS_PRODUCT_ID),
+-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_GI_PRODUCT_ID) },
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_GI_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
+ 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_OBDII_PRODUCT_ID),
+-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |
+-			       KVASER_USB_HAS_SILENT_MODE },
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },
+ 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO2_HSLS_PRODUCT_ID),
+-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },
+ 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_CH_PRODUCT_ID),
+-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },
+ 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_BLACKBIRD_SPRO_PRODUCT_ID),
+-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },
+ 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_OEM_MERCURY_PRODUCT_ID),
+-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },
+ 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_OEM_LEAF_PRODUCT_ID),
+-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },
+ 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_CAN_R_PRODUCT_ID),
+-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_V2_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_2HS_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_2HS_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_R_V2_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_R_V2_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM2_PRODUCT_ID) },
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },
++
++	/* Leaf i.MX28 USB product IDs */
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_V2_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_2HS_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_2HS_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_R_V2_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_R_V2_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM2_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
+ 
+ 	/* USBCANII USB product IDs */
+ 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN2_PRODUCT_ID),
+-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan },
+ 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_REVB_PRODUCT_ID),
+-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan },
+ 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMORATOR_PRODUCT_ID),
+-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan },
+ 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_VCI2_PRODUCT_ID),
+-		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan },
+ 
+ 	/* Minihydra USB product IDs */
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_BLACKBIRD_V2_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_5HS_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_5HS_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_4HS_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_HS_V2_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_2HS_V2_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_2HS_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_2HS_V2_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_2CANLIN_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_USBCAN_PRO_2HS_V2_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_MEMO_PRO_2HS_V2_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_PRO_2CANLIN_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_U100_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_U100P_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_U100S_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_4HS_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_CANLIN_PRODUCT_ID) },
+-	{ USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_PRO_CANLIN_PRODUCT_ID) },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_BLACKBIRD_V2_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_5HS_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_5HS_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_4HS_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_HS_V2_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_2HS_V2_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_2HS_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_2HS_V2_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_2CANLIN_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_USBCAN_PRO_2HS_V2_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_MEMO_PRO_2HS_V2_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_PRO_2CANLIN_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_U100_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_U100P_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_U100S_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_4HS_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_CANLIN_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
++	{ USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_PRO_CANLIN_PRODUCT_ID),
++		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },
+ 	{ }
+ };
+ MODULE_DEVICE_TABLE(usb, kvaser_usb_table);
+@@ -285,6 +320,7 @@ int kvaser_usb_can_rx_over_error(struct net_device *netdev)
+ static void kvaser_usb_read_bulk_callback(struct urb *urb)
+ {
+ 	struct kvaser_usb *dev = urb->context;
++	const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;
+ 	int err;
+ 	unsigned int i;
+ 
+@@ -301,8 +337,8 @@ static void kvaser_usb_read_bulk_callback(struct urb *urb)
+ 		goto resubmit_urb;
+ 	}
+ 
+-	dev->ops->dev_read_bulk_callback(dev, urb->transfer_buffer,
+-					 urb->actual_length);
++	ops->dev_read_bulk_callback(dev, urb->transfer_buffer,
++				    urb->actual_length);
+ 
+ resubmit_urb:
+ 	usb_fill_bulk_urb(urb, dev->udev,
+@@ -396,6 +432,7 @@ static int kvaser_usb_open(struct net_device *netdev)
+ {
+ 	struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
+ 	struct kvaser_usb *dev = priv->dev;
++	const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;
+ 	int err;
+ 
+ 	err = open_candev(netdev);
+@@ -406,11 +443,11 @@ static int kvaser_usb_open(struct net_device *netdev)
+ 	if (err)
+ 		goto error;
+ 
+-	err = dev->ops->dev_set_opt_mode(priv);
++	err = ops->dev_set_opt_mode(priv);
+ 	if (err)
+ 		goto error;
+ 
+-	err = dev->ops->dev_start_chip(priv);
++	err = ops->dev_start_chip(priv);
+ 	if (err) {
+ 		netdev_warn(netdev, "Cannot start device, error %d\n", err);
+ 		goto error;
+@@ -467,22 +504,23 @@ static int kvaser_usb_close(struct net_device *netdev)
+ {
+ 	struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
+ 	struct kvaser_usb *dev = priv->dev;
++	const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;
+ 	int err;
+ 
+ 	netif_stop_queue(netdev);
+ 
+-	err = dev->ops->dev_flush_queue(priv);
++	err = ops->dev_flush_queue(priv);
+ 	if (err)
+ 		netdev_warn(netdev, "Cannot flush queue, error %d\n", err);
+ 
+-	if (dev->ops->dev_reset_chip) {
+-		err = dev->ops->dev_reset_chip(dev, priv->channel);
++	if (ops->dev_reset_chip) {
++		err = ops->dev_reset_chip(dev, priv->channel);
+ 		if (err)
+ 			netdev_warn(netdev, "Cannot reset card, error %d\n",
+ 				    err);
+ 	}
+ 
+-	err = dev->ops->dev_stop_chip(priv);
++	err = ops->dev_stop_chip(priv);
+ 	if (err)
+ 		netdev_warn(netdev, "Cannot stop device, error %d\n", err);
+ 
+@@ -521,6 +559,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
+ {
+ 	struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
+ 	struct kvaser_usb *dev = priv->dev;
++	const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;
+ 	struct net_device_stats *stats = &netdev->stats;
+ 	struct kvaser_usb_tx_urb_context *context = NULL;
+ 	struct urb *urb;
+@@ -563,8 +602,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
+ 		goto freeurb;
+ 	}
+ 
+-	buf = dev->ops->dev_frame_to_cmd(priv, skb, &cmd_len,
+-					 context->echo_index);
++	buf = ops->dev_frame_to_cmd(priv, skb, &cmd_len, context->echo_index);
+ 	if (!buf) {
+ 		stats->tx_dropped++;
+ 		dev_kfree_skb(skb);
+@@ -648,15 +686,16 @@ static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev)
+ 	}
+ }
+ 
+-static int kvaser_usb_init_one(struct kvaser_usb *dev,
+-			       const struct usb_device_id *id, int channel)
++static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
+ {
+ 	struct net_device *netdev;
+ 	struct kvaser_usb_net_priv *priv;
++	const struct kvaser_usb_driver_info *driver_info = dev->driver_info;
++	const struct kvaser_usb_dev_ops *ops = driver_info->ops;
+ 	int err;
+ 
+-	if (dev->ops->dev_reset_chip) {
+-		err = dev->ops->dev_reset_chip(dev, channel);
++	if (ops->dev_reset_chip) {
++		err = ops->dev_reset_chip(dev, channel);
+ 		if (err)
+ 			return err;
+ 	}
+@@ -685,20 +724,19 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev,
+ 	priv->can.state = CAN_STATE_STOPPED;
+ 	priv->can.clock.freq = dev->cfg->clock.freq;
+ 	priv->can.bittiming_const = dev->cfg->bittiming_const;
+-	priv->can.do_set_bittiming = dev->ops->dev_set_bittiming;
+-	priv->can.do_set_mode = dev->ops->dev_set_mode;
+-	if ((id->driver_info & KVASER_USB_HAS_TXRX_ERRORS) ||
++	priv->can.do_set_bittiming = ops->dev_set_bittiming;
++	priv->can.do_set_mode = ops->dev_set_mode;
++	if ((driver_info->quirks & KVASER_USB_QUIRK_HAS_TXRX_ERRORS) ||
+ 	    (priv->dev->card_data.capabilities & KVASER_USB_CAP_BERR_CAP))
+-		priv->can.do_get_berr_counter = dev->ops->dev_get_berr_counter;
+-	if (id->driver_info & KVASER_USB_HAS_SILENT_MODE)
++		priv->can.do_get_berr_counter = ops->dev_get_berr_counter;
++	if (driver_info->quirks & KVASER_USB_QUIRK_HAS_SILENT_MODE)
+ 		priv->can.ctrlmode_supported |= CAN_CTRLMODE_LISTENONLY;
+ 
+ 	priv->can.ctrlmode_supported |= dev->card_data.ctrlmode_supported;
+ 
+ 	if (priv->can.ctrlmode_supported & CAN_CTRLMODE_FD) {
+ 		priv->can.data_bittiming_const = dev->cfg->data_bittiming_const;
+-		priv->can.do_set_data_bittiming =
+-					dev->ops->dev_set_data_bittiming;
++		priv->can.do_set_data_bittiming = ops->dev_set_data_bittiming;
+ 	}
+ 
+ 	netdev->flags |= IFF_ECHO;
+@@ -729,29 +767,22 @@ static int kvaser_usb_probe(struct usb_interface *intf,
+ 	struct kvaser_usb *dev;
+ 	int err;
+ 	int i;
++	const struct kvaser_usb_driver_info *driver_info;
++	const struct kvaser_usb_dev_ops *ops;
++
++	driver_info = (const struct kvaser_usb_driver_info *)id->driver_info;
++	if (!driver_info)
++		return -ENODEV;
+ 
+ 	dev = devm_kzalloc(&intf->dev, sizeof(*dev), GFP_KERNEL);
+ 	if (!dev)
+ 		return -ENOMEM;
+ 
+-	if (kvaser_is_leaf(id)) {
+-		dev->card_data.leaf.family = KVASER_LEAF;
+-		dev->ops = &kvaser_usb_leaf_dev_ops;
+-	} else if (kvaser_is_usbcan(id)) {
+-		dev->card_data.leaf.family = KVASER_USBCAN;
+-		dev->ops = &kvaser_usb_leaf_dev_ops;
+-	} else if (kvaser_is_hydra(id)) {
+-		dev->ops = &kvaser_usb_hydra_dev_ops;
+-	} else {
+-		dev_err(&intf->dev,
+-			"Product ID (%d) is not a supported Kvaser USB device\n",
+-			id->idProduct);
+-		return -ENODEV;
+-	}
+-
+ 	dev->intf = intf;
++	dev->driver_info = driver_info;
++	ops = driver_info->ops;
+ 
+-	err = dev->ops->dev_setup_endpoints(dev);
++	err = ops->dev_setup_endpoints(dev);
+ 	if (err) {
+ 		dev_err(&intf->dev, "Cannot get usb endpoint(s)");
+ 		return err;
+@@ -765,22 +796,22 @@ static int kvaser_usb_probe(struct usb_interface *intf,
+ 
+ 	dev->card_data.ctrlmode_supported = 0;
+ 	dev->card_data.capabilities = 0;
+-	err = dev->ops->dev_init_card(dev);
++	err = ops->dev_init_card(dev);
+ 	if (err) {
+ 		dev_err(&intf->dev,
+ 			"Failed to initialize card, error %d\n", err);
+ 		return err;
+ 	}
+ 
+-	err = dev->ops->dev_get_software_info(dev);
++	err = ops->dev_get_software_info(dev);
+ 	if (err) {
+ 		dev_err(&intf->dev,
+ 			"Cannot get software info, error %d\n", err);
+ 		return err;
+ 	}
+ 
+-	if (dev->ops->dev_get_software_details) {
+-		err = dev->ops->dev_get_software_details(dev);
++	if (ops->dev_get_software_details) {
++		err = ops->dev_get_software_details(dev);
+ 		if (err) {
+ 			dev_err(&intf->dev,
+ 				"Cannot get software details, error %d\n", err);
+@@ -798,14 +829,14 @@ static int kvaser_usb_probe(struct usb_interface *intf,
+ 
+ 	dev_dbg(&intf->dev, "Max outstanding tx = %d URBs\n", dev->max_tx_urbs);
+ 
+-	err = dev->ops->dev_get_card_info(dev);
++	err = ops->dev_get_card_info(dev);
+ 	if (err) {
+ 		dev_err(&intf->dev, "Cannot get card info, error %d\n", err);
+ 		return err;
+ 	}
+ 
+-	if (dev->ops->dev_get_capabilities) {
+-		err = dev->ops->dev_get_capabilities(dev);
++	if (ops->dev_get_capabilities) {
++		err = ops->dev_get_capabilities(dev);
+ 		if (err) {
+ 			dev_err(&intf->dev,
+ 				"Cannot get capabilities, error %d\n", err);
+@@ -815,7 +846,7 @@ static int kvaser_usb_probe(struct usb_interface *intf,
+ 	}
+ 
+ 	for (i = 0; i < dev->nchannels; i++) {
+-		err = kvaser_usb_init_one(dev, id, i);
++		err = kvaser_usb_init_one(dev, i);
+ 		if (err) {
+ 			kvaser_usb_remove_interfaces(dev);
+ 			return err;
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+index a26823c5b62ad..5d70844ac0300 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+@@ -375,7 +375,7 @@ static const struct can_bittiming_const kvaser_usb_hydra_kcan_bittiming_c = {
+ 	.brp_inc = 1,
+ };
+ 
+-static const struct can_bittiming_const kvaser_usb_hydra_flexc_bittiming_c = {
++const struct can_bittiming_const kvaser_usb_flexc_bittiming_const = {
+ 	.name = "kvaser_usb_flex",
+ 	.tseg1_min = 4,
+ 	.tseg1_max = 16,
+@@ -2052,7 +2052,7 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_flexc = {
+ 		.freq = 24 * MEGA /* Hz */,
+ 	},
+ 	.timestamp_freq = 1,
+-	.bittiming_const = &kvaser_usb_hydra_flexc_bittiming_c,
++	.bittiming_const = &kvaser_usb_flexc_bittiming_const,
+ };
+ 
+ static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_rt = {
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index c805b999c5436..cc809ecd1e622 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -101,16 +101,6 @@
+ #define USBCAN_ERROR_STATE_RX_ERROR	BIT(1)
+ #define USBCAN_ERROR_STATE_BUSERROR	BIT(2)
+ 
+-/* bittiming parameters */
+-#define KVASER_USB_TSEG1_MIN		1
+-#define KVASER_USB_TSEG1_MAX		16
+-#define KVASER_USB_TSEG2_MIN		1
+-#define KVASER_USB_TSEG2_MAX		8
+-#define KVASER_USB_SJW_MAX		4
+-#define KVASER_USB_BRP_MIN		1
+-#define KVASER_USB_BRP_MAX		64
+-#define KVASER_USB_BRP_INC		1
+-
+ /* ctrl modes */
+ #define KVASER_CTRL_MODE_NORMAL		1
+ #define KVASER_CTRL_MODE_SILENT		2
+@@ -343,48 +333,68 @@ struct kvaser_usb_err_summary {
+ 	};
+ };
+ 
+-static const struct can_bittiming_const kvaser_usb_leaf_bittiming_const = {
+-	.name = "kvaser_usb",
+-	.tseg1_min = KVASER_USB_TSEG1_MIN,
+-	.tseg1_max = KVASER_USB_TSEG1_MAX,
+-	.tseg2_min = KVASER_USB_TSEG2_MIN,
+-	.tseg2_max = KVASER_USB_TSEG2_MAX,
+-	.sjw_max = KVASER_USB_SJW_MAX,
+-	.brp_min = KVASER_USB_BRP_MIN,
+-	.brp_max = KVASER_USB_BRP_MAX,
+-	.brp_inc = KVASER_USB_BRP_INC,
++static const struct can_bittiming_const kvaser_usb_leaf_m16c_bittiming_const = {
++	.name = "kvaser_usb_ucii",
++	.tseg1_min = 4,
++	.tseg1_max = 16,
++	.tseg2_min = 2,
++	.tseg2_max = 8,
++	.sjw_max = 4,
++	.brp_min = 1,
++	.brp_max = 16,
++	.brp_inc = 1,
++};
++
++static const struct can_bittiming_const kvaser_usb_leaf_m32c_bittiming_const = {
++	.name = "kvaser_usb_leaf",
++	.tseg1_min = 3,
++	.tseg1_max = 16,
++	.tseg2_min = 2,
++	.tseg2_max = 8,
++	.sjw_max = 4,
++	.brp_min = 2,
++	.brp_max = 128,
++	.brp_inc = 2,
+ };
+ 
+-static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_8mhz = {
++static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_usbcan_dev_cfg = {
+ 	.clock = {
+ 		.freq = 8 * MEGA /* Hz */,
+ 	},
+ 	.timestamp_freq = 1,
+-	.bittiming_const = &kvaser_usb_leaf_bittiming_const,
++	.bittiming_const = &kvaser_usb_leaf_m16c_bittiming_const,
++};
++
++static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_m32c_dev_cfg = {
++	.clock = {
++		.freq = 16 * MEGA /* Hz */,
++	},
++	.timestamp_freq = 1,
++	.bittiming_const = &kvaser_usb_leaf_m32c_bittiming_const,
+ };
+ 
+-static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_16mhz = {
++static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_16mhz = {
+ 	.clock = {
+ 		.freq = 16 * MEGA /* Hz */,
+ 	},
+ 	.timestamp_freq = 1,
+-	.bittiming_const = &kvaser_usb_leaf_bittiming_const,
++	.bittiming_const = &kvaser_usb_flexc_bittiming_const,
+ };
+ 
+-static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_24mhz = {
++static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_24mhz = {
+ 	.clock = {
+ 		.freq = 24 * MEGA /* Hz */,
+ 	},
+ 	.timestamp_freq = 1,
+-	.bittiming_const = &kvaser_usb_leaf_bittiming_const,
++	.bittiming_const = &kvaser_usb_flexc_bittiming_const,
+ };
+ 
+-static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_32mhz = {
++static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_32mhz = {
+ 	.clock = {
+ 		.freq = 32 * MEGA /* Hz */,
+ 	},
+ 	.timestamp_freq = 1,
+-	.bittiming_const = &kvaser_usb_leaf_bittiming_const,
++	.bittiming_const = &kvaser_usb_flexc_bittiming_const,
+ };
+ 
+ static void *
+@@ -404,7 +414,7 @@ kvaser_usb_leaf_frame_to_cmd(const struct kvaser_usb_net_priv *priv,
+ 				      sizeof(struct kvaser_cmd_tx_can);
+ 		cmd->u.tx_can.channel = priv->channel;
+ 
+-		switch (dev->card_data.leaf.family) {
++		switch (dev->driver_info->family) {
+ 		case KVASER_LEAF:
+ 			cmd_tx_can_flags = &cmd->u.tx_can.leaf.flags;
+ 			break;
+@@ -524,16 +534,23 @@ static void kvaser_usb_leaf_get_software_info_leaf(struct kvaser_usb *dev,
+ 	dev->fw_version = le32_to_cpu(softinfo->fw_version);
+ 	dev->max_tx_urbs = le16_to_cpu(softinfo->max_outstanding_tx);
+ 
+-	switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) {
+-	case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK:
+-		dev->cfg = &kvaser_usb_leaf_dev_cfg_16mhz;
+-		break;
+-	case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK:
+-		dev->cfg = &kvaser_usb_leaf_dev_cfg_24mhz;
+-		break;
+-	case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK:
+-		dev->cfg = &kvaser_usb_leaf_dev_cfg_32mhz;
+-		break;
++	if (dev->driver_info->quirks & KVASER_USB_QUIRK_IGNORE_CLK_FREQ) {
++		/* Firmware expects bittiming parameters calculated for 16MHz
++		 * clock, regardless of the actual clock
++		 */
++		dev->cfg = &kvaser_usb_leaf_m32c_dev_cfg;
++	} else {
++		switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) {
++		case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK:
++			dev->cfg = &kvaser_usb_leaf_imx_dev_cfg_16mhz;
++			break;
++		case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK:
++			dev->cfg = &kvaser_usb_leaf_imx_dev_cfg_24mhz;
++			break;
++		case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK:
++			dev->cfg = &kvaser_usb_leaf_imx_dev_cfg_32mhz;
++			break;
++		}
+ 	}
+ }
+ 
+@@ -550,7 +567,7 @@ static int kvaser_usb_leaf_get_software_info_inner(struct kvaser_usb *dev)
+ 	if (err)
+ 		return err;
+ 
+-	switch (dev->card_data.leaf.family) {
++	switch (dev->driver_info->family) {
+ 	case KVASER_LEAF:
+ 		kvaser_usb_leaf_get_software_info_leaf(dev, &cmd.u.leaf.softinfo);
+ 		break;
+@@ -558,7 +575,7 @@ static int kvaser_usb_leaf_get_software_info_inner(struct kvaser_usb *dev)
+ 		dev->fw_version = le32_to_cpu(cmd.u.usbcan.softinfo.fw_version);
+ 		dev->max_tx_urbs =
+ 			le16_to_cpu(cmd.u.usbcan.softinfo.max_outstanding_tx);
+-		dev->cfg = &kvaser_usb_leaf_dev_cfg_8mhz;
++		dev->cfg = &kvaser_usb_leaf_usbcan_dev_cfg;
+ 		break;
+ 	}
+ 
+@@ -597,7 +614,7 @@ static int kvaser_usb_leaf_get_card_info(struct kvaser_usb *dev)
+ 
+ 	dev->nchannels = cmd.u.cardinfo.nchannels;
+ 	if (dev->nchannels > KVASER_USB_MAX_NET_DEVICES ||
+-	    (dev->card_data.leaf.family == KVASER_USBCAN &&
++	    (dev->driver_info->family == KVASER_USBCAN &&
+ 	     dev->nchannels > MAX_USBCAN_NET_DEVICES))
+ 		return -EINVAL;
+ 
+@@ -730,7 +747,7 @@ kvaser_usb_leaf_rx_error_update_can_state(struct kvaser_usb_net_priv *priv,
+ 	    new_state < CAN_STATE_BUS_OFF)
+ 		priv->can.can_stats.restarts++;
+ 
+-	switch (dev->card_data.leaf.family) {
++	switch (dev->driver_info->family) {
+ 	case KVASER_LEAF:
+ 		if (es->leaf.error_factor) {
+ 			priv->can.can_stats.bus_error++;
+@@ -809,7 +826,7 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
+ 		}
+ 	}
+ 
+-	switch (dev->card_data.leaf.family) {
++	switch (dev->driver_info->family) {
+ 	case KVASER_LEAF:
+ 		if (es->leaf.error_factor) {
+ 			cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT;
+@@ -999,7 +1016,7 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev,
+ 	stats = &priv->netdev->stats;
+ 
+ 	if ((cmd->u.rx_can_header.flag & MSG_FLAG_ERROR_FRAME) &&
+-	    (dev->card_data.leaf.family == KVASER_LEAF &&
++	    (dev->driver_info->family == KVASER_LEAF &&
+ 	     cmd->id == CMD_LEAF_LOG_MESSAGE)) {
+ 		kvaser_usb_leaf_leaf_rx_error(dev, cmd);
+ 		return;
+@@ -1015,7 +1032,7 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev,
+ 		return;
+ 	}
+ 
+-	switch (dev->card_data.leaf.family) {
++	switch (dev->driver_info->family) {
+ 	case KVASER_LEAF:
+ 		rx_data = cmd->u.leaf.rx_can.data;
+ 		break;
+@@ -1030,7 +1047,7 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev,
+ 		return;
+ 	}
+ 
+-	if (dev->card_data.leaf.family == KVASER_LEAF && cmd->id ==
++	if (dev->driver_info->family == KVASER_LEAF && cmd->id ==
+ 	    CMD_LEAF_LOG_MESSAGE) {
+ 		cf->can_id = le32_to_cpu(cmd->u.leaf.log_message.id);
+ 		if (cf->can_id & KVASER_EXTENDED_FRAME)
+@@ -1128,14 +1145,14 @@ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev,
+ 		break;
+ 
+ 	case CMD_LEAF_LOG_MESSAGE:
+-		if (dev->card_data.leaf.family != KVASER_LEAF)
++		if (dev->driver_info->family != KVASER_LEAF)
+ 			goto warn;
+ 		kvaser_usb_leaf_rx_can_msg(dev, cmd);
+ 		break;
+ 
+ 	case CMD_CHIP_STATE_EVENT:
+ 	case CMD_CAN_ERROR_EVENT:
+-		if (dev->card_data.leaf.family == KVASER_LEAF)
++		if (dev->driver_info->family == KVASER_LEAF)
+ 			kvaser_usb_leaf_leaf_rx_error(dev, cmd);
+ 		else
+ 			kvaser_usb_leaf_usbcan_rx_error(dev, cmd);
+@@ -1147,12 +1164,12 @@ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev,
+ 
+ 	/* Ignored commands */
+ 	case CMD_USBCAN_CLOCK_OVERFLOW_EVENT:
+-		if (dev->card_data.leaf.family != KVASER_USBCAN)
++		if (dev->driver_info->family != KVASER_USBCAN)
+ 			goto warn;
+ 		break;
+ 
+ 	case CMD_FLUSH_QUEUE_REPLY:
+-		if (dev->card_data.leaf.family != KVASER_LEAF)
++		if (dev->driver_info->family != KVASER_LEAF)
+ 			goto warn;
+ 		break;
+ 
+diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
+index 22b328bd7cd51..8c93dd710efc5 100644
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -2372,7 +2372,7 @@ static int
+ qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
+ {
+ 	struct qca8k_priv *priv = ds->priv;
+-	int i, mtu = 0;
++	int ret, i, mtu = 0;
+ 
+ 	priv->port_mtu[port] = new_mtu;
+ 
+@@ -2380,8 +2380,27 @@ qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
+ 		if (priv->port_mtu[i] > mtu)
+ 			mtu = priv->port_mtu[i];
+ 
++	/* To change the MAX_FRAME_SIZE the cpu ports must be off or
++	 * the switch panics.
++	 * Turn off both cpu ports before applying the new value to prevent
++	 * this.
++	 */
++	if (priv->port_sts[0].enabled)
++		qca8k_port_set_status(priv, 0, 0);
++
++	if (priv->port_sts[6].enabled)
++		qca8k_port_set_status(priv, 6, 0);
++
+ 	/* Include L2 header / FCS length */
+-	return qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN);
++	ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN);
++
++	if (priv->port_sts[0].enabled)
++		qca8k_port_set_status(priv, 0, 1);
++
++	if (priv->port_sts[6].enabled)
++		qca8k_port_set_status(priv, 6, 1);
++
++	return ret;
+ }
+ 
+ static int
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index 5c5931dba51d7..c4221f89ab188 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -5774,6 +5774,15 @@ static int ibmvnic_reset_init(struct ibmvnic_adapter *adapter, bool reset)
+ 			release_sub_crqs(adapter, 0);
+ 			rc = init_sub_crqs(adapter);
+ 		} else {
++			/* no need to reinitialize completely, but we do
++			 * need to clean up transmits that were in flight
++			 * when we processed the reset.  Failure to do so
++			 * will confound the upper layer, usually TCP, by
++			 * creating the illusion of transmits that are
++			 * awaiting completion.
++			 */
++			clean_tx_pools(adapter);
++
+ 			rc = reset_sub_crq_queues(adapter);
+ 		}
+ 	} else {
+diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
+index 55c6bce5da61e..615aff0798d3f 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e.h
++++ b/drivers/net/ethernet/intel/i40e/i40e.h
+@@ -37,6 +37,7 @@
+ #include <net/tc_act/tc_mirred.h>
+ #include <net/udp_tunnel.h>
+ #include <net/xdp_sock.h>
++#include <linux/bitfield.h>
+ #include "i40e_type.h"
+ #include "i40e_prototype.h"
+ #include <linux/net/intel/i40e_client.h>
+@@ -1091,6 +1092,21 @@ static inline void i40e_write_fd_input_set(struct i40e_pf *pf,
+ 			  (u32)(val & 0xFFFFFFFFULL));
+ }
+ 
++/**
++ * i40e_get_pf_count - get PCI PF count.
++ * @hw: pointer to a hw.
++ *
++ * Reports the function number of the highest PCI physical
++ * function plus 1 as it is loaded from the NVM.
++ *
++ * Return: PCI PF count.
++ **/
++static inline u32 i40e_get_pf_count(struct i40e_hw *hw)
++{
++	return FIELD_GET(I40E_GLGEN_PCIFCNCNT_PCIPFCNT_MASK,
++			 rd32(hw, I40E_GLGEN_PCIFCNCNT));
++}
++
+ /* needed by i40e_ethtool.c */
+ int i40e_up(struct i40e_vsi *vsi);
+ void i40e_down(struct i40e_vsi *vsi);
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index 46bb1169a004d..77eb9c7262053 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -549,6 +549,47 @@ void i40e_pf_reset_stats(struct i40e_pf *pf)
+ 	pf->hw_csum_rx_error = 0;
+ }
+ 
++/**
++ * i40e_compute_pci_to_hw_id - compute index form PCI function.
++ * @vsi: ptr to the VSI to read from.
++ * @hw: ptr to the hardware info.
++ **/
++static u32 i40e_compute_pci_to_hw_id(struct i40e_vsi *vsi, struct i40e_hw *hw)
++{
++	int pf_count = i40e_get_pf_count(hw);
++
++	if (vsi->type == I40E_VSI_SRIOV)
++		return (hw->port * BIT(7)) / pf_count + vsi->vf_id;
++
++	return hw->port + BIT(7);
++}
++
++/**
++ * i40e_stat_update64 - read and update a 64 bit stat from the chip.
++ * @hw: ptr to the hardware info.
++ * @hireg: the high 32 bit reg to read.
++ * @loreg: the low 32 bit reg to read.
++ * @offset_loaded: has the initial offset been loaded yet.
++ * @offset: ptr to current offset value.
++ * @stat: ptr to the stat.
++ *
++ * Since the device stats are not reset at PFReset, they will not
++ * be zeroed when the driver starts.  We'll save the first values read
++ * and use them as offsets to be subtracted from the raw values in order
++ * to report stats that count from zero.
++ **/
++static void i40e_stat_update64(struct i40e_hw *hw, u32 hireg, u32 loreg,
++			       bool offset_loaded, u64 *offset, u64 *stat)
++{
++	u64 new_data;
++
++	new_data = rd64(hw, loreg);
++
++	if (!offset_loaded || new_data < *offset)
++		*offset = new_data;
++	*stat = new_data - *offset;
++}
++
+ /**
+  * i40e_stat_update48 - read and update a 48 bit stat from the chip
+  * @hw: ptr to the hardware info
+@@ -620,6 +661,34 @@ static void i40e_stat_update_and_clear32(struct i40e_hw *hw, u32 reg, u64 *stat)
+ 	*stat += new_data;
+ }
+ 
++/**
++ * i40e_stats_update_rx_discards - update rx_discards.
++ * @vsi: ptr to the VSI to be updated.
++ * @hw: ptr to the hardware info.
++ * @stat_idx: VSI's stat_counter_idx.
++ * @offset_loaded: ptr to the VSI's stat_offsets_loaded.
++ * @stat_offset: ptr to stat_offset to store first read of specific register.
++ * @stat: ptr to VSI's stat to be updated.
++ **/
++static void
++i40e_stats_update_rx_discards(struct i40e_vsi *vsi, struct i40e_hw *hw,
++			      int stat_idx, bool offset_loaded,
++			      struct i40e_eth_stats *stat_offset,
++			      struct i40e_eth_stats *stat)
++{
++	u64 rx_rdpc, rx_rxerr;
++
++	i40e_stat_update32(hw, I40E_GLV_RDPC(stat_idx), offset_loaded,
++			   &stat_offset->rx_discards, &rx_rdpc);
++	i40e_stat_update64(hw,
++			   I40E_GL_RXERR1H(i40e_compute_pci_to_hw_id(vsi, hw)),
++			   I40E_GL_RXERR1L(i40e_compute_pci_to_hw_id(vsi, hw)),
++			   offset_loaded, &stat_offset->rx_discards_other,
++			   &rx_rxerr);
++
++	stat->rx_discards = rx_rdpc + rx_rxerr;
++}
++
+ /**
+  * i40e_update_eth_stats - Update VSI-specific ethernet statistics counters.
+  * @vsi: the VSI to be updated
+@@ -679,6 +748,10 @@ void i40e_update_eth_stats(struct i40e_vsi *vsi)
+ 			   I40E_GLV_BPTCL(stat_idx),
+ 			   vsi->stat_offsets_loaded,
+ 			   &oes->tx_broadcast, &es->tx_broadcast);
++
++	i40e_stats_update_rx_discards(vsi, hw, stat_idx,
++				      vsi->stat_offsets_loaded, oes, es);
++
+ 	vsi->stat_offsets_loaded = true;
+ }
+ 
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_register.h b/drivers/net/ethernet/intel/i40e/i40e_register.h
+index 1908eed4fa5ee..7339003aa17cd 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_register.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_register.h
+@@ -211,6 +211,11 @@
+ #define I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT 0
+ #define I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT 16
+ #define I40E_GLGEN_MSRWD_MDIRDDATA_MASK I40E_MASK(0xFFFF, I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT)
++#define I40E_GLGEN_PCIFCNCNT                0x001C0AB4 /* Reset: PCIR */
++#define I40E_GLGEN_PCIFCNCNT_PCIPFCNT_SHIFT 0
++#define I40E_GLGEN_PCIFCNCNT_PCIPFCNT_MASK  I40E_MASK(0x1F, I40E_GLGEN_PCIFCNCNT_PCIPFCNT_SHIFT)
++#define I40E_GLGEN_PCIFCNCNT_PCIVFCNT_SHIFT 16
++#define I40E_GLGEN_PCIFCNCNT_PCIVFCNT_MASK  I40E_MASK(0xFF, I40E_GLGEN_PCIFCNCNT_PCIVFCNT_SHIFT)
+ #define I40E_GLGEN_RSTAT 0x000B8188 /* Reset: POR */
+ #define I40E_GLGEN_RSTAT_DEVSTATE_SHIFT 0
+ #define I40E_GLGEN_RSTAT_DEVSTATE_MASK I40E_MASK(0x3, I40E_GLGEN_RSTAT_DEVSTATE_SHIFT)
+@@ -643,6 +648,14 @@
+ #define I40E_VFQF_HKEY1_MAX_INDEX 12
+ #define I40E_VFQF_HLUT1(_i, _VF) (0x00220000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...15, _VF=0...127 */ /* Reset: CORER */
+ #define I40E_VFQF_HLUT1_MAX_INDEX 15
++#define I40E_GL_RXERR1H(_i)             (0x00318004 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
++#define I40E_GL_RXERR1H_MAX_INDEX       143
++#define I40E_GL_RXERR1H_RXERR1H_SHIFT   0
++#define I40E_GL_RXERR1H_RXERR1H_MASK    I40E_MASK(0xFFFFFFFF, I40E_GL_RXERR1H_RXERR1H_SHIFT)
++#define I40E_GL_RXERR1L(_i)             (0x00318000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
++#define I40E_GL_RXERR1L_MAX_INDEX       143
++#define I40E_GL_RXERR1L_RXERR1L_SHIFT   0
++#define I40E_GL_RXERR1L_RXERR1L_MASK    I40E_MASK(0xFFFFFFFF, I40E_GL_RXERR1L_RXERR1L_SHIFT)
+ #define I40E_GLPRT_BPRCH(_i) (0x003005E4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
+ #define I40E_GLPRT_BPRCL(_i) (0x003005E0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
+ #define I40E_GLPRT_BPTCH(_i) (0x00300A04 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h
+index 36a4ca1ffb1a9..7b3f30beb757a 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_type.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_type.h
+@@ -1172,6 +1172,7 @@ struct i40e_eth_stats {
+ 	u64 tx_broadcast;		/* bptc */
+ 	u64 tx_discards;		/* tdpc */
+ 	u64 tx_errors;			/* tepc */
++	u64 rx_discards_other;          /* rxerr1 */
+ };
+ 
+ /* Statistics collected per VEB per TC */
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+index 033ea71763e3d..86b0f21287dc8 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+@@ -2147,6 +2147,10 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg)
+ 		/* VFs only use TC 0 */
+ 		vfres->vsi_res[0].qset_handle
+ 					  = le16_to_cpu(vsi->info.qs_handle[0]);
++		if (!(vf->driver_caps & VIRTCHNL_VF_OFFLOAD_USO) && !vf->pf_set_mac) {
++			i40e_del_mac_filter(vsi, vf->default_lan_addr.addr);
++			eth_zero_addr(vf->default_lan_addr.addr);
++		}
+ 		ether_addr_copy(vfres->vsi_res[0].default_mac_addr,
+ 				vf->default_lan_addr.addr);
+ 	}
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+index ec2dfecd7f0f1..c016510474480 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+@@ -4503,13 +4503,6 @@ static int mlx5e_policer_validate(const struct flow_action *action,
+ 		return -EOPNOTSUPP;
+ 	}
+ 
+-	if (act->police.notexceed.act_id != FLOW_ACTION_PIPE &&
+-	    act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
+-		NL_SET_ERR_MSG_MOD(extack,
+-				   "Offload not supported when conform action is not pipe or ok");
+-		return -EOPNOTSUPP;
+-	}
+-
+ 	if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
+ 	    !flow_action_is_last_entry(action, act)) {
+ 		NL_SET_ERR_MSG_MOD(extack,
+@@ -4560,6 +4553,12 @@ static int scan_tc_matchall_fdb_actions(struct mlx5e_priv *priv,
+ 	flow_action_for_each(i, act, flow_action) {
+ 		switch (act->id) {
+ 		case FLOW_ACTION_POLICE:
++			if (act->police.notexceed.act_id != FLOW_ACTION_CONTINUE) {
++				NL_SET_ERR_MSG_MOD(extack,
++						   "Offload not supported when conform action is not continue");
++				return -EOPNOTSUPP;
++			}
++
+ 			err = mlx5e_policer_validate(flow_action, act, extack);
+ 			if (err)
+ 				return err;
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+index f180a157eea49..05d759ba0c5c8 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+@@ -979,7 +979,7 @@ static int lan966x_probe(struct platform_device *pdev)
+ 	struct fwnode_handle *ports, *portnp;
+ 	struct lan966x *lan966x;
+ 	u8 mac_addr[ETH_ALEN];
+-	int err, i;
++	int err;
+ 
+ 	lan966x = devm_kzalloc(&pdev->dev, sizeof(*lan966x), GFP_KERNEL);
+ 	if (!lan966x)
+@@ -1010,11 +1010,7 @@ static int lan966x_probe(struct platform_device *pdev)
+ 	if (err)
+ 		return dev_err_probe(&pdev->dev, err, "Reset failed");
+ 
+-	i = 0;
+-	fwnode_for_each_available_child_node(ports, portnp)
+-		++i;
+-
+-	lan966x->num_phys_ports = i;
++	lan966x->num_phys_ports = NUM_PHYS_PORTS;
+ 	lan966x->ports = devm_kcalloc(&pdev->dev, lan966x->num_phys_ports,
+ 				      sizeof(struct lan966x_port *),
+ 				      GFP_KERNEL);
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
+index ae282da1da748..a240f13e052b8 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
+@@ -31,6 +31,7 @@
+ /* Reserved amount for (SRC, PRIO) at index 8*SRC + PRIO */
+ #define QSYS_Q_RSRV			95
+ 
++#define NUM_PHYS_PORTS			8
+ #define CPU_PORT			8
+ 
+ /* Reserved PGIDs */
+diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
+index 33f5c5698ccbf..642e435c70311 100644
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -4190,7 +4190,6 @@ static void rtl8169_tso_csum_v1(struct sk_buff *skb, u32 *opts)
+ static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp,
+ 				struct sk_buff *skb, u32 *opts)
+ {
+-	u32 transport_offset = (u32)skb_transport_offset(skb);
+ 	struct skb_shared_info *shinfo = skb_shinfo(skb);
+ 	u32 mss = shinfo->gso_size;
+ 
+@@ -4207,7 +4206,7 @@ static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp,
+ 			WARN_ON_ONCE(1);
+ 		}
+ 
+-		opts[0] |= transport_offset << GTTCPHO_SHIFT;
++		opts[0] |= skb_transport_offset(skb) << GTTCPHO_SHIFT;
+ 		opts[1] |= mss << TD1_MSS_SHIFT;
+ 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ 		u8 ip_protocol;
+@@ -4235,7 +4234,7 @@ static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp,
+ 		else
+ 			WARN_ON_ONCE(1);
+ 
+-		opts[1] |= transport_offset << TCPHO_SHIFT;
++		opts[1] |= skb_transport_offset(skb) << TCPHO_SHIFT;
+ 	} else {
+ 		unsigned int padto = rtl_quirk_packet_padto(tp, skb);
+ 
+@@ -4402,14 +4401,13 @@ static netdev_features_t rtl8169_features_check(struct sk_buff *skb,
+ 						struct net_device *dev,
+ 						netdev_features_t features)
+ {
+-	int transport_offset = skb_transport_offset(skb);
+ 	struct rtl8169_private *tp = netdev_priv(dev);
+ 
+ 	if (skb_is_gso(skb)) {
+ 		if (tp->mac_version == RTL_GIGA_MAC_VER_34)
+ 			features = rtl8168evl_fix_tso(skb, features);
+ 
+-		if (transport_offset > GTTCPHO_MAX &&
++		if (skb_transport_offset(skb) > GTTCPHO_MAX &&
+ 		    rtl_chip_supports_csum_v2(tp))
+ 			features &= ~NETIF_F_ALL_TSO;
+ 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+@@ -4420,7 +4418,7 @@ static netdev_features_t rtl8169_features_check(struct sk_buff *skb,
+ 		if (rtl_quirk_packet_padto(tp, skb))
+ 			features &= ~NETIF_F_CSUM_MASK;
+ 
+-		if (transport_offset > TCPHO_MAX &&
++		if (skb_transport_offset(skb) > TCPHO_MAX &&
+ 		    rtl_chip_supports_csum_v2(tp))
+ 			features &= ~NETIF_F_CSUM_MASK;
+ 	}
+diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
+index 2ea81931543c1..9b2bd09628a3b 100644
+--- a/drivers/net/usb/usbnet.c
++++ b/drivers/net/usb/usbnet.c
+@@ -2137,7 +2137,7 @@ static void usbnet_async_cmd_cb(struct urb *urb)
+ int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype,
+ 			   u16 value, u16 index, const void *data, u16 size)
+ {
+-	struct usb_ctrlrequest *req = NULL;
++	struct usb_ctrlrequest *req;
+ 	struct urb *urb;
+ 	int err = -ENOMEM;
+ 	void *buf = NULL;
+@@ -2155,7 +2155,7 @@ int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype,
+ 		if (!buf) {
+ 			netdev_err(dev->net, "Error allocating buffer"
+ 				   " in %s!\n", __func__);
+-			goto fail_free;
++			goto fail_free_urb;
+ 		}
+ 	}
+ 
+@@ -2179,14 +2179,21 @@ int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype,
+ 	if (err < 0) {
+ 		netdev_err(dev->net, "Error submitting the control"
+ 			   " message: status=%d\n", err);
+-		goto fail_free;
++		goto fail_free_all;
+ 	}
+ 	return 0;
+ 
++fail_free_all:
++	kfree(req);
+ fail_free_buf:
+ 	kfree(buf);
+-fail_free:
+-	kfree(req);
++	/*
++	 * avoid a double free
++	 * needed because the flag can be set only
++	 * after filling the URB
++	 */
++	urb->transfer_flags = 0;
++fail_free_urb:
+ 	usb_free_urb(urb);
+ fail:
+ 	return err;
+diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c
+index 4ada80317a3bd..b5c1a8f363f32 100644
+--- a/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c
++++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c
+@@ -158,26 +158,26 @@ static const struct sunxi_desc_pin sun8i_a83t_pins[] = {
+ 	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14),
+ 		  SUNXI_FUNCTION(0x0, "gpio_in"),
+ 		  SUNXI_FUNCTION(0x1, "gpio_out"),
+-		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ6 */
++		  SUNXI_FUNCTION(0x2, "nand0"),		/* DQ6 */
+ 		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D6 */
+ 	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15),
+ 		  SUNXI_FUNCTION(0x0, "gpio_in"),
+ 		  SUNXI_FUNCTION(0x1, "gpio_out"),
+-		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ7 */
++		  SUNXI_FUNCTION(0x2, "nand0"),		/* DQ7 */
+ 		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D7 */
+ 	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16),
+ 		  SUNXI_FUNCTION(0x0, "gpio_in"),
+ 		  SUNXI_FUNCTION(0x1, "gpio_out"),
+-		  SUNXI_FUNCTION(0x2, "nand"),		/* DQS */
++		  SUNXI_FUNCTION(0x2, "nand0"),		/* DQS */
+ 		  SUNXI_FUNCTION(0x3, "mmc2")),		/* RST */
+ 	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 17),
+ 		  SUNXI_FUNCTION(0x0, "gpio_in"),
+ 		  SUNXI_FUNCTION(0x1, "gpio_out"),
+-		  SUNXI_FUNCTION(0x2, "nand")),		/* CE2 */
++		  SUNXI_FUNCTION(0x2, "nand0")),	/* CE2 */
+ 	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 18),
+ 		  SUNXI_FUNCTION(0x0, "gpio_in"),
+ 		  SUNXI_FUNCTION(0x1, "gpio_out"),
+-		  SUNXI_FUNCTION(0x2, "nand")),		/* CE3 */
++		  SUNXI_FUNCTION(0x2, "nand0")),	/* CE3 */
+ 	/* Hole */
+ 	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2),
+ 		  SUNXI_FUNCTION(0x0, "gpio_in"),
+diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+index d9327d7d56eea..dd928402af997 100644
+--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
++++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+@@ -544,6 +544,8 @@ static int sunxi_pconf_set(struct pinctrl_dev *pctldev, unsigned pin,
+ 	struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ 	int i;
+ 
++	pin -= pctl->desc->pin_base;
++
+ 	for (i = 0; i < num_configs; i++) {
+ 		enum pin_config_param param;
+ 		unsigned long flags;
+diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c
+index b2d365ae02823..dae8a2e0f7455 100644
+--- a/drivers/soc/atmel/soc.c
++++ b/drivers/soc/atmel/soc.c
+@@ -91,14 +91,14 @@ static const struct at91_soc socs[] __initconst = {
+ 	AT91_SOC(SAM9X60_CIDR_MATCH, AT91_CIDR_MATCH_MASK,
+ 		 AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH,
+ 		 "sam9x60", "sam9x60"),
+-	AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_D5M_EXID_MATCH,
+-		 AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH,
++	AT91_SOC(SAM9X60_CIDR_MATCH, AT91_CIDR_MATCH_MASK,
++		 AT91_CIDR_VERSION_MASK, SAM9X60_D5M_EXID_MATCH,
+ 		 "sam9x60 64MiB DDR2 SiP", "sam9x60"),
+-	AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_D1G_EXID_MATCH,
+-		 AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH,
++	AT91_SOC(SAM9X60_CIDR_MATCH, AT91_CIDR_MATCH_MASK,
++		 AT91_CIDR_VERSION_MASK, SAM9X60_D1G_EXID_MATCH,
+ 		 "sam9x60 128MiB DDR2 SiP", "sam9x60"),
+-	AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_D6K_EXID_MATCH,
+-		 AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH,
++	AT91_SOC(SAM9X60_CIDR_MATCH, AT91_CIDR_MATCH_MASK,
++		 AT91_CIDR_VERSION_MASK, SAM9X60_D6K_EXID_MATCH,
+ 		 "sam9x60 8MiB SDRAM SiP", "sam9x60"),
+ #endif
+ #ifdef CONFIG_SOC_SAMA5
+diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
+index 9a8ae6fa6ecbb..526a7d2de4912 100644
+--- a/drivers/video/fbdev/core/fbcon.c
++++ b/drivers/video/fbdev/core/fbcon.c
+@@ -2480,6 +2480,11 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font,
+ 	if (charcount != 256 && charcount != 512)
+ 		return -EINVAL;
+ 
++	/* font bigger than screen resolution ? */
++	if (w > FBCON_SWAP(info->var.rotate, info->var.xres, info->var.yres) ||
++	    h > FBCON_SWAP(info->var.rotate, info->var.yres, info->var.xres))
++		return -EINVAL;
++
+ 	/* Make sure drawing engine can handle the font */
+ 	if (!(info->pixmap.blit_x & (1 << (font->width - 1))) ||
+ 	    !(info->pixmap.blit_y & (1 << (font->height - 1))))
+@@ -2742,6 +2747,34 @@ void fbcon_update_vcs(struct fb_info *info, bool all)
+ }
+ EXPORT_SYMBOL(fbcon_update_vcs);
+ 
++/* let fbcon check if it supports a new screen resolution */
++int fbcon_modechange_possible(struct fb_info *info, struct fb_var_screeninfo *var)
++{
++	struct fbcon_ops *ops = info->fbcon_par;
++	struct vc_data *vc;
++	unsigned int i;
++
++	WARN_CONSOLE_UNLOCKED();
++
++	if (!ops)
++		return 0;
++
++	/* prevent setting a screen size which is smaller than font size */
++	for (i = first_fb_vc; i <= last_fb_vc; i++) {
++		vc = vc_cons[i].d;
++		if (!vc || vc->vc_mode != KD_TEXT ||
++			   registered_fb[con2fb_map[i]] != info)
++			continue;
++
++		if (vc->vc_font.width  > FBCON_SWAP(var->rotate, var->xres, var->yres) ||
++		    vc->vc_font.height > FBCON_SWAP(var->rotate, var->yres, var->xres))
++			return -EINVAL;
++	}
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(fbcon_modechange_possible);
++
+ int fbcon_mode_deleted(struct fb_info *info,
+ 		       struct fb_videomode *mode)
+ {
+diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
+index a6bb0e4382167..85de02d0d3aaa 100644
+--- a/drivers/video/fbdev/core/fbmem.c
++++ b/drivers/video/fbdev/core/fbmem.c
+@@ -510,7 +510,7 @@ static int fb_show_logo_line(struct fb_info *info, int rotate,
+ 
+ 		while (n && (n * (logo->width + 8) - 8 > xres))
+ 			--n;
+-		image.dx = (xres - n * (logo->width + 8) - 8) / 2;
++		image.dx = (xres - (n * (logo->width + 8) - 8)) / 2;
+ 		image.dy = y ?: (yres - logo->height) / 2;
+ 	} else {
+ 		image.dx = 0;
+@@ -1016,6 +1016,16 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
+ 	if (ret)
+ 		return ret;
+ 
++	/* verify that virtual resolution >= physical resolution */
++	if (var->xres_virtual < var->xres ||
++	    var->yres_virtual < var->yres) {
++		pr_warn("WARNING: fbcon: Driver '%s' missed to adjust virtual screen size (%ux%u vs. %ux%u)\n",
++			info->fix.id,
++			var->xres_virtual, var->yres_virtual,
++			var->xres, var->yres);
++		return -EINVAL;
++	}
++
+ 	if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW)
+ 		return 0;
+ 
+@@ -1106,7 +1116,9 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
+ 			return -EFAULT;
+ 		console_lock();
+ 		lock_fb_info(info);
+-		ret = fb_set_var(info, &var);
++		ret = fbcon_modechange_possible(info, &var);
++		if (!ret)
++			ret = fb_set_var(info, &var);
+ 		if (!ret)
+ 			fbcon_update_vcs(info, var.activate & FB_ACTIVATE_ALL);
+ 		unlock_fb_info(info);
+diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c
+index 9d3cf01117093..7c3726aa9e149 100644
+--- a/fs/fscache/cookie.c
++++ b/fs/fscache/cookie.c
+@@ -517,7 +517,14 @@ static void fscache_perform_lookup(struct fscache_cookie *cookie)
+ 	}
+ 
+ 	fscache_see_cookie(cookie, fscache_cookie_see_active);
+-	fscache_set_cookie_state(cookie, FSCACHE_COOKIE_STATE_ACTIVE);
++	spin_lock(&cookie->lock);
++	if (test_and_clear_bit(FSCACHE_COOKIE_DO_INVALIDATE, &cookie->flags))
++		__fscache_set_cookie_state(cookie,
++					   FSCACHE_COOKIE_STATE_INVALIDATING);
++	else
++		__fscache_set_cookie_state(cookie, FSCACHE_COOKIE_STATE_ACTIVE);
++	spin_unlock(&cookie->lock);
++	wake_up_cookie_state(cookie);
+ 	trace = fscache_access_lookup_cookie_end;
+ 
+ out:
+@@ -752,6 +759,9 @@ again_locked:
+ 			spin_lock(&cookie->lock);
+ 		}
+ 
++		if (test_and_clear_bit(FSCACHE_COOKIE_DO_INVALIDATE, &cookie->flags))
++			fscache_end_cookie_access(cookie, fscache_access_invalidate_cookie_end);
++
+ 		switch (state) {
+ 		case FSCACHE_COOKIE_STATE_RELINQUISHING:
+ 			fscache_see_cookie(cookie, fscache_cookie_see_relinquish);
+@@ -1048,6 +1058,9 @@ void __fscache_invalidate(struct fscache_cookie *cookie,
+ 		return;
+ 
+ 	case FSCACHE_COOKIE_STATE_LOOKING_UP:
++		__fscache_begin_cookie_access(cookie, fscache_access_invalidate_cookie);
++		set_bit(FSCACHE_COOKIE_DO_INVALIDATE, &cookie->flags);
++		fallthrough;
+ 	case FSCACHE_COOKIE_STATE_CREATING:
+ 		spin_unlock(&cookie->lock);
+ 		_leave(" [look %x]", cookie->inval_counter);
+diff --git a/fs/fscache/volume.c b/fs/fscache/volume.c
+index f2aa7dbad7667..a058e0136bfeb 100644
+--- a/fs/fscache/volume.c
++++ b/fs/fscache/volume.c
+@@ -143,7 +143,7 @@ static void fscache_wait_on_volume_collision(struct fscache_volume *candidate,
+ {
+ 	wait_var_event_timeout(&candidate->flags,
+ 			       !fscache_is_acquire_pending(candidate), 20 * HZ);
+-	if (!fscache_is_acquire_pending(candidate)) {
++	if (fscache_is_acquire_pending(candidate)) {
+ 		pr_notice("Potential volume collision new=%08x old=%08x",
+ 			  candidate->debug_id, collidee_debug_id);
+ 		fscache_stat(&fscache_n_volumes_collision);
+@@ -182,7 +182,7 @@ static bool fscache_hash_volume(struct fscache_volume *candidate)
+ 	hlist_bl_add_head(&candidate->hash_link, h);
+ 	hlist_bl_unlock(h);
+ 
+-	if (test_bit(FSCACHE_VOLUME_ACQUIRE_PENDING, &candidate->flags))
++	if (fscache_is_acquire_pending(candidate))
+ 		fscache_wait_on_volume_collision(candidate, collidee_debug_id);
+ 	return true;
+ 
+diff --git a/fs/io_uring.c b/fs/io_uring.c
+index 7e8c715052c09..3d97372e811eb 100644
+--- a/fs/io_uring.c
++++ b/fs/io_uring.c
+@@ -3495,6 +3495,13 @@ static ssize_t io_iov_buffer_select(struct io_kiocb *req, struct iovec *iov,
+ 	return __io_iov_buffer_select(req, iov, issue_flags);
+ }
+ 
++static inline bool io_do_buffer_select(struct io_kiocb *req)
++{
++	if (!(req->flags & REQ_F_BUFFER_SELECT))
++		return false;
++	return !(req->flags & REQ_F_BUFFER_SELECTED);
++}
++
+ static struct iovec *__io_import_iovec(int rw, struct io_kiocb *req,
+ 				       struct io_rw_state *s,
+ 				       unsigned int issue_flags)
+@@ -3854,18 +3861,19 @@ static int io_read(struct io_kiocb *req, unsigned int issue_flags)
+ 		if (unlikely(ret < 0))
+ 			return ret;
+ 	} else {
++		rw = req->async_data;
++		s = &rw->s;
++
+ 		/*
+ 		 * Safe and required to re-import if we're using provided
+ 		 * buffers, as we dropped the selected one before retry.
+ 		 */
+-		if (req->flags & REQ_F_BUFFER_SELECT) {
++		if (io_do_buffer_select(req)) {
+ 			ret = io_import_iovec(READ, req, &iovec, s, issue_flags);
+ 			if (unlikely(ret < 0))
+ 				return ret;
+ 		}
+ 
+-		rw = req->async_data;
+-		s = &rw->s;
+ 		/*
+ 		 * We come here from an earlier attempt, restore our state to
+ 		 * match in case it doesn't. It's cheap enough that we don't
+diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
+index 92b7ea8d8f5e1..181907349b49b 100644
+--- a/include/acpi/cppc_acpi.h
++++ b/include/acpi/cppc_acpi.h
+@@ -144,6 +144,7 @@ extern bool acpi_cpc_valid(void);
+ extern int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data);
+ extern unsigned int cppc_get_transition_latency(int cpu);
+ extern bool cpc_ffh_supported(void);
++extern bool cpc_supported_by_cpu(void);
+ extern int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val);
+ extern int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val);
+ #else /* !CONFIG_ACPI_CPPC_LIB */
+diff --git a/include/linux/acpi.h b/include/linux/acpi.h
+index d7136d13aa442..cf1f770208da3 100644
+--- a/include/linux/acpi.h
++++ b/include/linux/acpi.h
+@@ -574,13 +574,15 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context);
+ #define OSC_SB_OSLPI_SUPPORT			0x00000100
+ #define OSC_SB_CPC_DIVERSE_HIGH_SUPPORT		0x00001000
+ #define OSC_SB_GENERIC_INITIATOR_SUPPORT	0x00002000
++#define OSC_SB_CPC_FLEXIBLE_ADR_SPACE		0x00004000
+ #define OSC_SB_NATIVE_USB4_SUPPORT		0x00040000
+ #define OSC_SB_PRM_SUPPORT			0x00200000
+ 
+ extern bool osc_sb_apei_support_acked;
+ extern bool osc_pc_lpi_support_confirmed;
+ extern bool osc_sb_native_usb4_support_confirmed;
+-extern bool osc_sb_cppc_not_supported;
++extern bool osc_sb_cppc2_support_acked;
++extern bool osc_cpc_flexible_adr_space_confirmed;
+ 
+ /* USB4 Capabilities */
+ #define OSC_USB_USB3_TUNNELING			0x00000001
+diff --git a/include/linux/fbcon.h b/include/linux/fbcon.h
+index ff5596dd30f85..2382dec6d6ab8 100644
+--- a/include/linux/fbcon.h
++++ b/include/linux/fbcon.h
+@@ -15,6 +15,8 @@ void fbcon_new_modelist(struct fb_info *info);
+ void fbcon_get_requirement(struct fb_info *info,
+ 			   struct fb_blit_caps *caps);
+ void fbcon_fb_blanked(struct fb_info *info, int blank);
++int  fbcon_modechange_possible(struct fb_info *info,
++			       struct fb_var_screeninfo *var);
+ void fbcon_update_vcs(struct fb_info *info, bool all);
+ void fbcon_remap_all(struct fb_info *info);
+ int fbcon_set_con2fb_map_ioctl(void __user *argp);
+@@ -33,6 +35,8 @@ static inline void fbcon_new_modelist(struct fb_info *info) {}
+ static inline void fbcon_get_requirement(struct fb_info *info,
+ 					 struct fb_blit_caps *caps) {}
+ static inline void fbcon_fb_blanked(struct fb_info *info, int blank) {}
++static inline int  fbcon_modechange_possible(struct fb_info *info,
++				struct fb_var_screeninfo *var) { return 0; }
+ static inline void fbcon_update_vcs(struct fb_info *info, bool all) {}
+ static inline void fbcon_remap_all(struct fb_info *info) {}
+ static inline int fbcon_set_con2fb_map_ioctl(void __user *argp) { return 0; }
+diff --git a/include/linux/fscache.h b/include/linux/fscache.h
+index e25539072463b..a25804f141d31 100644
+--- a/include/linux/fscache.h
++++ b/include/linux/fscache.h
+@@ -129,6 +129,7 @@ struct fscache_cookie {
+ #define FSCACHE_COOKIE_DO_PREP_TO_WRITE	12		/* T if cookie needs write preparation */
+ #define FSCACHE_COOKIE_HAVE_DATA	13		/* T if this cookie has data stored */
+ #define FSCACHE_COOKIE_IS_HASHED	14		/* T if this cookie is hashed */
++#define FSCACHE_COOKIE_DO_INVALIDATE	15		/* T if cookie needs invalidation */
+ 
+ 	enum fscache_cookie_state	state;
+ 	u8				advice;		/* FSCACHE_ADV_* */
+diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
+index 2f9891cb3d001..82543019ff012 100644
+--- a/include/linux/intel-iommu.h
++++ b/include/linux/intel-iommu.h
+@@ -611,7 +611,6 @@ struct intel_iommu {
+ struct device_domain_info {
+ 	struct list_head link;	/* link to domain siblings */
+ 	struct list_head global; /* link to global list */
+-	struct list_head table;	/* link to pasid table */
+ 	u32 segment;		/* PCI segment number */
+ 	u8 bus;			/* PCI bus number */
+ 	u8 devfn;		/* PCI devfn number */
+@@ -728,8 +727,6 @@ extern int dmar_ir_support(void);
+ void *alloc_pgtable_page(int node);
+ void free_pgtable_page(void *vaddr);
+ struct intel_iommu *domain_get_iommu(struct dmar_domain *domain);
+-int for_each_device_domain(int (*fn)(struct device_domain_info *info,
+-				     void *data), void *data);
+ void iommu_flush_write_buffer(struct intel_iommu *iommu);
+ int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct device *dev);
+ struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn);
+diff --git a/include/linux/memregion.h b/include/linux/memregion.h
+index e11595256cac0..c04c4fd2e2091 100644
+--- a/include/linux/memregion.h
++++ b/include/linux/memregion.h
+@@ -16,7 +16,7 @@ static inline int memregion_alloc(gfp_t gfp)
+ {
+ 	return -ENOMEM;
+ }
+-void memregion_free(int id)
++static inline void memregion_free(int id)
+ {
+ }
+ #endif
+diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
+index 2bff6a10095d1..73634b6653a1b 100644
+--- a/include/linux/pm_runtime.h
++++ b/include/linux/pm_runtime.h
+@@ -82,7 +82,7 @@ extern void pm_runtime_get_suppliers(struct device *dev);
+ extern void pm_runtime_put_suppliers(struct device *dev);
+ extern void pm_runtime_new_link(struct device *dev);
+ extern void pm_runtime_drop_link(struct device_link *link);
+-extern void pm_runtime_release_supplier(struct device_link *link, bool check_idle);
++extern void pm_runtime_release_supplier(struct device_link *link);
+ 
+ extern int devm_pm_runtime_enable(struct device *dev);
+ 
+@@ -308,8 +308,7 @@ static inline void pm_runtime_get_suppliers(struct device *dev) {}
+ static inline void pm_runtime_put_suppliers(struct device *dev) {}
+ static inline void pm_runtime_new_link(struct device *dev) {}
+ static inline void pm_runtime_drop_link(struct device_link *link) {}
+-static inline void pm_runtime_release_supplier(struct device_link *link,
+-					       bool check_idle) {}
++static inline void pm_runtime_release_supplier(struct device_link *link) {}
+ 
+ #endif /* !CONFIG_PM */
+ 
+diff --git a/include/linux/rtsx_usb.h b/include/linux/rtsx_usb.h
+index 159729cffd8e1..3247ed8e9ff0f 100644
+--- a/include/linux/rtsx_usb.h
++++ b/include/linux/rtsx_usb.h
+@@ -54,8 +54,6 @@ struct rtsx_ucr {
+ 	struct usb_device	*pusb_dev;
+ 	struct usb_interface	*pusb_intf;
+ 	struct usb_sg_request	current_sg;
+-	unsigned char		*iobuf;
+-	dma_addr_t		iobuf_dma;
+ 
+ 	struct timer_list	sg_timer;
+ 	struct mutex		dev_mutex;
+diff --git a/include/net/act_api.h b/include/net/act_api.h
+index 3049cb69c0252..9cf6870b526eb 100644
+--- a/include/net/act_api.h
++++ b/include/net/act_api.h
+@@ -134,7 +134,8 @@ struct tc_action_ops {
+ 	(*get_psample_group)(const struct tc_action *a,
+ 			     tc_action_priv_destructor *destructor);
+ 	int     (*offload_act_setup)(struct tc_action *act, void *entry_data,
+-				     u32 *index_inc, bool bind);
++				     u32 *index_inc, bool bind,
++				     struct netlink_ext_ack *extack);
+ };
+ 
+ struct tc_action_net {
+diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h
+index 6484095a8c011..7ac313858037a 100644
+--- a/include/net/flow_offload.h
++++ b/include/net/flow_offload.h
+@@ -152,6 +152,7 @@ enum flow_action_id {
+ 	FLOW_ACTION_PIPE,
+ 	FLOW_ACTION_VLAN_PUSH_ETH,
+ 	FLOW_ACTION_VLAN_POP_ETH,
++	FLOW_ACTION_CONTINUE,
+ 	NUM_FLOW_ACTIONS,
+ };
+ 
+diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
+index a3b57a93228a7..8cf001aed858d 100644
+--- a/include/net/pkt_cls.h
++++ b/include/net/pkt_cls.h
+@@ -547,10 +547,12 @@ tcf_match_indev(struct sk_buff *skb, int ifindex)
+ }
+ 
+ int tc_setup_offload_action(struct flow_action *flow_action,
+-			    const struct tcf_exts *exts);
++			    const struct tcf_exts *exts,
++			    struct netlink_ext_ack *extack);
+ void tc_cleanup_offload_action(struct flow_action *flow_action);
+ int tc_setup_action(struct flow_action *flow_action,
+-		    struct tc_action *actions[]);
++		    struct tc_action *actions[],
++		    struct netlink_ext_ack *extack);
+ 
+ int tc_setup_cb_call(struct tcf_block *block, enum tc_setup_type type,
+ 		     void *type_data, bool err_stop, bool rtnl_held);
+diff --git a/include/video/of_display_timing.h b/include/video/of_display_timing.h
+index e1126a74882a5..eff166fdd81b9 100644
+--- a/include/video/of_display_timing.h
++++ b/include/video/of_display_timing.h
+@@ -8,6 +8,8 @@
+ #ifndef __LINUX_OF_DISPLAY_TIMING_H
+ #define __LINUX_OF_DISPLAY_TIMING_H
+ 
++#include <linux/errno.h>
++
+ struct device_node;
+ struct display_timing;
+ struct display_timings;
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 9c1a02b82ecd0..d04147a5efa55 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -1417,6 +1417,21 @@ static void __reg_bound_offset(struct bpf_reg_state *reg)
+ 	reg->var_off = tnum_or(tnum_clear_subreg(var64_off), var32_off);
+ }
+ 
++static void reg_bounds_sync(struct bpf_reg_state *reg)
++{
++	/* We might have learned new bounds from the var_off. */
++	__update_reg_bounds(reg);
++	/* We might have learned something about the sign bit. */
++	__reg_deduce_bounds(reg);
++	/* We might have learned some bits from the bounds. */
++	__reg_bound_offset(reg);
++	/* Intersecting with the old var_off might have improved our bounds
++	 * slightly, e.g. if umax was 0x7f...f and var_off was (0; 0xf...fc),
++	 * then new var_off is (0; 0x7f...fc) which improves our umax.
++	 */
++	__update_reg_bounds(reg);
++}
++
+ static bool __reg32_bound_s64(s32 a)
+ {
+ 	return a >= 0 && a <= S32_MAX;
+@@ -1458,16 +1473,8 @@ static void __reg_combine_32_into_64(struct bpf_reg_state *reg)
+ 		 * so they do not impact tnum bounds calculation.
+ 		 */
+ 		__mark_reg64_unbounded(reg);
+-		__update_reg_bounds(reg);
+ 	}
+-
+-	/* Intersecting with the old var_off might have improved our bounds
+-	 * slightly.  e.g. if umax was 0x7f...f and var_off was (0; 0xf...fc),
+-	 * then new var_off is (0; 0x7f...fc) which improves our umax.
+-	 */
+-	__reg_deduce_bounds(reg);
+-	__reg_bound_offset(reg);
+-	__update_reg_bounds(reg);
++	reg_bounds_sync(reg);
+ }
+ 
+ static bool __reg64_bound_s32(s64 a)
+@@ -1483,7 +1490,6 @@ static bool __reg64_bound_u32(u64 a)
+ static void __reg_combine_64_into_32(struct bpf_reg_state *reg)
+ {
+ 	__mark_reg32_unbounded(reg);
+-
+ 	if (__reg64_bound_s32(reg->smin_value) && __reg64_bound_s32(reg->smax_value)) {
+ 		reg->s32_min_value = (s32)reg->smin_value;
+ 		reg->s32_max_value = (s32)reg->smax_value;
+@@ -1492,14 +1498,7 @@ static void __reg_combine_64_into_32(struct bpf_reg_state *reg)
+ 		reg->u32_min_value = (u32)reg->umin_value;
+ 		reg->u32_max_value = (u32)reg->umax_value;
+ 	}
+-
+-	/* Intersecting with the old var_off might have improved our bounds
+-	 * slightly.  e.g. if umax was 0x7f...f and var_off was (0; 0xf...fc),
+-	 * then new var_off is (0; 0x7f...fc) which improves our umax.
+-	 */
+-	__reg_deduce_bounds(reg);
+-	__reg_bound_offset(reg);
+-	__update_reg_bounds(reg);
++	reg_bounds_sync(reg);
+ }
+ 
+ /* Mark a register as having a completely unknown (scalar) value. */
+@@ -6485,9 +6484,7 @@ static void do_refine_retval_range(struct bpf_reg_state *regs, int ret_type,
+ 	ret_reg->s32_max_value = meta->msize_max_value;
+ 	ret_reg->smin_value = -MAX_ERRNO;
+ 	ret_reg->s32_min_value = -MAX_ERRNO;
+-	__reg_deduce_bounds(ret_reg);
+-	__reg_bound_offset(ret_reg);
+-	__update_reg_bounds(ret_reg);
++	reg_bounds_sync(ret_reg);
+ }
+ 
+ static int
+@@ -7693,11 +7690,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
+ 
+ 	if (!check_reg_sane_offset(env, dst_reg, ptr_reg->type))
+ 		return -EINVAL;
+-
+-	__update_reg_bounds(dst_reg);
+-	__reg_deduce_bounds(dst_reg);
+-	__reg_bound_offset(dst_reg);
+-
++	reg_bounds_sync(dst_reg);
+ 	if (sanitize_check_bounds(env, insn, dst_reg) < 0)
+ 		return -EACCES;
+ 	if (sanitize_needed(opcode)) {
+@@ -8435,10 +8428,7 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env,
+ 	/* ALU32 ops are zero extended into 64bit register */
+ 	if (alu32)
+ 		zext_32_to_64(dst_reg);
+-
+-	__update_reg_bounds(dst_reg);
+-	__reg_deduce_bounds(dst_reg);
+-	__reg_bound_offset(dst_reg);
++	reg_bounds_sync(dst_reg);
+ 	return 0;
+ }
+ 
+@@ -8627,10 +8617,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
+ 							 insn->dst_reg);
+ 				}
+ 				zext_32_to_64(dst_reg);
+-
+-				__update_reg_bounds(dst_reg);
+-				__reg_deduce_bounds(dst_reg);
+-				__reg_bound_offset(dst_reg);
++				reg_bounds_sync(dst_reg);
+ 			}
+ 		} else {
+ 			/* case: R = imm
+@@ -9068,26 +9055,33 @@ static void reg_set_min_max(struct bpf_reg_state *true_reg,
+ 		return;
+ 
+ 	switch (opcode) {
++	/* JEQ/JNE comparison doesn't change the register equivalence.
++	 *
++	 * r1 = r2;
++	 * if (r1 == 42) goto label;
++	 * ...
++	 * label: // here both r1 and r2 are known to be 42.
++	 *
++	 * Hence when marking register as known preserve it's ID.
++	 */
+ 	case BPF_JEQ:
++		if (is_jmp32) {
++			__mark_reg32_known(true_reg, val32);
++			true_32off = tnum_subreg(true_reg->var_off);
++		} else {
++			___mark_reg_known(true_reg, val);
++			true_64off = true_reg->var_off;
++		}
++		break;
+ 	case BPF_JNE:
+-	{
+-		struct bpf_reg_state *reg =
+-			opcode == BPF_JEQ ? true_reg : false_reg;
+-
+-		/* JEQ/JNE comparison doesn't change the register equivalence.
+-		 * r1 = r2;
+-		 * if (r1 == 42) goto label;
+-		 * ...
+-		 * label: // here both r1 and r2 are known to be 42.
+-		 *
+-		 * Hence when marking register as known preserve it's ID.
+-		 */
+-		if (is_jmp32)
+-			__mark_reg32_known(reg, val32);
+-		else
+-			___mark_reg_known(reg, val);
++		if (is_jmp32) {
++			__mark_reg32_known(false_reg, val32);
++			false_32off = tnum_subreg(false_reg->var_off);
++		} else {
++			___mark_reg_known(false_reg, val);
++			false_64off = false_reg->var_off;
++		}
+ 		break;
+-	}
+ 	case BPF_JSET:
+ 		if (is_jmp32) {
+ 			false_32off = tnum_and(false_32off, tnum_const(~val32));
+@@ -9226,21 +9220,8 @@ static void __reg_combine_min_max(struct bpf_reg_state *src_reg,
+ 							dst_reg->smax_value);
+ 	src_reg->var_off = dst_reg->var_off = tnum_intersect(src_reg->var_off,
+ 							     dst_reg->var_off);
+-	/* We might have learned new bounds from the var_off. */
+-	__update_reg_bounds(src_reg);
+-	__update_reg_bounds(dst_reg);
+-	/* We might have learned something about the sign bit. */
+-	__reg_deduce_bounds(src_reg);
+-	__reg_deduce_bounds(dst_reg);
+-	/* We might have learned some bits from the bounds. */
+-	__reg_bound_offset(src_reg);
+-	__reg_bound_offset(dst_reg);
+-	/* Intersecting with the old var_off might have improved our bounds
+-	 * slightly.  e.g. if umax was 0x7f...f and var_off was (0; 0xf...fc),
+-	 * then new var_off is (0; 0x7f...fc) which improves our umax.
+-	 */
+-	__update_reg_bounds(src_reg);
+-	__update_reg_bounds(dst_reg);
++	reg_bounds_sync(src_reg);
++	reg_bounds_sync(dst_reg);
+ }
+ 
+ static void reg_combine_min_max(struct bpf_reg_state *true_src,
+diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c
+index 6833d88871816..d30e4db04506a 100644
+--- a/kernel/rcu/srcutree.c
++++ b/kernel/rcu/srcutree.c
+@@ -382,9 +382,11 @@ void cleanup_srcu_struct(struct srcu_struct *ssp)
+ 			return; /* Forgot srcu_barrier(), so just leak it! */
+ 	}
+ 	if (WARN_ON(rcu_seq_state(READ_ONCE(ssp->srcu_gp_seq)) != SRCU_STATE_IDLE) ||
++	    WARN_ON(rcu_seq_current(&ssp->srcu_gp_seq) != ssp->srcu_gp_seq_needed) ||
+ 	    WARN_ON(srcu_readers_active(ssp))) {
+-		pr_info("%s: Active srcu_struct %p state: %d\n",
+-			__func__, ssp, rcu_seq_state(READ_ONCE(ssp->srcu_gp_seq)));
++		pr_info("%s: Active srcu_struct %p read state: %d gp state: %lu/%lu\n",
++			__func__, ssp, rcu_seq_state(READ_ONCE(ssp->srcu_gp_seq)),
++			rcu_seq_current(&ssp->srcu_gp_seq), ssp->srcu_gp_seq_needed);
+ 		return; /* Caller forgot to stop doing call_srcu()? */
+ 	}
+ 	free_percpu(ssp->sda);
+diff --git a/lib/idr.c b/lib/idr.c
+index f4ab4f4aa3c7f..7ecdfdb5309e7 100644
+--- a/lib/idr.c
++++ b/lib/idr.c
+@@ -491,7 +491,8 @@ void ida_free(struct ida *ida, unsigned int id)
+ 	struct ida_bitmap *bitmap;
+ 	unsigned long flags;
+ 
+-	BUG_ON((int)id < 0);
++	if ((int)id < 0)
++		return;
+ 
+ 	xas_lock_irqsave(&xas, flags);
+ 	bitmap = xas_load(&xas);
+diff --git a/net/can/bcm.c b/net/can/bcm.c
+index 64c07e650bb41..c3ad310c2109d 100644
+--- a/net/can/bcm.c
++++ b/net/can/bcm.c
+@@ -100,6 +100,7 @@ static inline u64 get_u64(const struct canfd_frame *cp, int offset)
+ 
+ struct bcm_op {
+ 	struct list_head list;
++	struct rcu_head rcu;
+ 	int ifindex;
+ 	canid_t can_id;
+ 	u32 flags;
+@@ -718,10 +719,9 @@ static struct bcm_op *bcm_find_op(struct list_head *ops,
+ 	return NULL;
+ }
+ 
+-static void bcm_remove_op(struct bcm_op *op)
++static void bcm_free_op_rcu(struct rcu_head *rcu_head)
+ {
+-	hrtimer_cancel(&op->timer);
+-	hrtimer_cancel(&op->thrtimer);
++	struct bcm_op *op = container_of(rcu_head, struct bcm_op, rcu);
+ 
+ 	if ((op->frames) && (op->frames != &op->sframe))
+ 		kfree(op->frames);
+@@ -732,6 +732,14 @@ static void bcm_remove_op(struct bcm_op *op)
+ 	kfree(op);
+ }
+ 
++static void bcm_remove_op(struct bcm_op *op)
++{
++	hrtimer_cancel(&op->timer);
++	hrtimer_cancel(&op->thrtimer);
++
++	call_rcu(&op->rcu, bcm_free_op_rcu);
++}
++
+ static void bcm_rx_unreg(struct net_device *dev, struct bcm_op *op)
+ {
+ 	if (op->rx_reg_dev == dev) {
+@@ -757,6 +765,9 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh,
+ 		if ((op->can_id == mh->can_id) && (op->ifindex == ifindex) &&
+ 		    (op->flags & CAN_FD_FRAME) == (mh->flags & CAN_FD_FRAME)) {
+ 
++			/* disable automatic timer on frame reception */
++			op->flags |= RX_NO_AUTOTIMER;
++
+ 			/*
+ 			 * Don't care if we're bound or not (due to netdev
+ 			 * problems) can_rx_unregister() is always a save
+@@ -785,7 +796,6 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh,
+ 						  bcm_rx_handler, op);
+ 
+ 			list_del(&op->list);
+-			synchronize_rcu();
+ 			bcm_remove_op(op);
+ 			return 1; /* done */
+ 		}
+diff --git a/net/mptcp/options.c b/net/mptcp/options.c
+index b548cec86c9d8..48e34b81fa1cc 100644
+--- a/net/mptcp/options.c
++++ b/net/mptcp/options.c
+@@ -1538,6 +1538,9 @@ mp_rst:
+ 		*ptr++ = mptcp_option(MPTCPOPT_MP_PRIO,
+ 				      TCPOLEN_MPTCP_PRIO,
+ 				      opts->backup, TCPOPT_NOP);
++
++		MPTCP_INC_STATS(sock_net((const struct sock *)tp),
++				MPTCP_MIB_MPPRIOTX);
+ 	}
+ 
+ mp_capable_done:
+diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
+index e3dcc5501579f..78345278e4a71 100644
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -720,24 +720,23 @@ static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
+ 
+ 	mptcp_for_each_subflow(msk, subflow) {
+ 		struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
+-		struct sock *sk = (struct sock *)msk;
+ 		struct mptcp_addr_info local;
++		bool slow;
+ 
+ 		local_address((struct sock_common *)ssk, &local);
+ 		if (!addresses_equal(&local, addr, addr->port))
+ 			continue;
+ 
++		slow = lock_sock_fast(ssk);
+ 		if (subflow->backup != bkup)
+ 			msk->last_snd = NULL;
+ 		subflow->backup = bkup;
+ 		subflow->send_mp_prio = 1;
+ 		subflow->request_bkup = bkup;
+-		__MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPPRIOTX);
+ 
+-		spin_unlock_bh(&msk->pm.lock);
+ 		pr_debug("send ack for mp_prio");
+-		mptcp_subflow_send_ack(ssk);
+-		spin_lock_bh(&msk->pm.lock);
++		__mptcp_subflow_send_ack(ssk);
++		unlock_sock_fast(ssk, slow);
+ 
+ 		return 0;
+ 	}
+@@ -794,7 +793,8 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
+ 			removed = true;
+ 			__MPTCP_INC_STATS(sock_net(sk), rm_type);
+ 		}
+-		__set_bit(rm_list->ids[i], msk->pm.id_avail_bitmap);
++		if (rm_type == MPTCP_MIB_RMSUBFLOW)
++			__set_bit(rm_list->ids[i], msk->pm.id_avail_bitmap);
+ 		if (!removed)
+ 			continue;
+ 
+@@ -1769,8 +1769,10 @@ static void mptcp_pm_nl_fullmesh(struct mptcp_sock *msk,
+ 
+ 	list.ids[list.nr++] = addr->id;
+ 
++	spin_lock_bh(&msk->pm.lock);
+ 	mptcp_pm_nl_rm_subflow_received(msk, &list);
+ 	mptcp_pm_create_subflow_or_signal_addr(msk);
++	spin_unlock_bh(&msk->pm.lock);
+ }
+ 
+ static int mptcp_nl_set_flags(struct net *net,
+@@ -1788,12 +1790,10 @@ static int mptcp_nl_set_flags(struct net *net,
+ 			goto next;
+ 
+ 		lock_sock(sk);
+-		spin_lock_bh(&msk->pm.lock);
+ 		if (changed & MPTCP_PM_ADDR_FLAG_BACKUP)
+ 			ret = mptcp_pm_nl_mp_prio_send_ack(msk, addr, bkup);
+ 		if (changed & MPTCP_PM_ADDR_FLAG_FULLMESH)
+ 			mptcp_pm_nl_fullmesh(msk, addr);
+-		spin_unlock_bh(&msk->pm.lock);
+ 		release_sock(sk);
+ 
+ next:
+diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
+index 713077eef04ac..b0fb1fc0bd4a9 100644
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -506,13 +506,18 @@ static bool tcp_can_send_ack(const struct sock *ssk)
+ 	       (TCPF_SYN_SENT | TCPF_SYN_RECV | TCPF_TIME_WAIT | TCPF_CLOSE | TCPF_LISTEN));
+ }
+ 
++void __mptcp_subflow_send_ack(struct sock *ssk)
++{
++	if (tcp_can_send_ack(ssk))
++		tcp_send_ack(ssk);
++}
++
+ void mptcp_subflow_send_ack(struct sock *ssk)
+ {
+ 	bool slow;
+ 
+ 	slow = lock_sock_fast(ssk);
+-	if (tcp_can_send_ack(ssk))
+-		tcp_send_ack(ssk);
++	__mptcp_subflow_send_ack(ssk);
+ 	unlock_sock_fast(ssk, slow);
+ }
+ 
+diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
+index 2aab5aff6bcdf..ad36a05aa67df 100644
+--- a/net/mptcp/protocol.h
++++ b/net/mptcp/protocol.h
+@@ -584,6 +584,7 @@ void __init mptcp_subflow_init(void);
+ void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how);
+ void mptcp_close_ssk(struct sock *sk, struct sock *ssk,
+ 		     struct mptcp_subflow_context *subflow);
++void __mptcp_subflow_send_ack(struct sock *ssk);
+ void mptcp_subflow_send_ack(struct sock *ssk);
+ void mptcp_subflow_reset(struct sock *ssk);
+ void mptcp_subflow_queue_clean(struct sock *ssk);
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 81243c834abbe..a136148627e70 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -5213,13 +5213,20 @@ static int nft_setelem_parse_data(struct nft_ctx *ctx, struct nft_set *set,
+ 				  struct nft_data *data,
+ 				  struct nlattr *attr)
+ {
++	u32 dtype;
+ 	int err;
+ 
+ 	err = nft_data_init(ctx, data, NFT_DATA_VALUE_MAXLEN, desc, attr);
+ 	if (err < 0)
+ 		return err;
+ 
+-	if (desc->type != NFT_DATA_VERDICT && desc->len != set->dlen) {
++	if (set->dtype == NFT_DATA_VERDICT)
++		dtype = NFT_DATA_VERDICT;
++	else
++		dtype = NFT_DATA_VALUE;
++
++	if (dtype != desc->type ||
++	    set->dlen != desc->len) {
+ 		nft_data_release(data, desc->type);
+ 		return -EINVAL;
+ 	}
+diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c
+index 2c8051d8cca69..4f9299b9dcddc 100644
+--- a/net/netfilter/nft_set_pipapo.c
++++ b/net/netfilter/nft_set_pipapo.c
+@@ -2124,6 +2124,32 @@ out_scratch:
+ 	return err;
+ }
+ 
++/**
++ * nft_set_pipapo_match_destroy() - Destroy elements from key mapping array
++ * @set:	nftables API set representation
++ * @m:		matching data pointing to key mapping array
++ */
++static void nft_set_pipapo_match_destroy(const struct nft_set *set,
++					 struct nft_pipapo_match *m)
++{
++	struct nft_pipapo_field *f;
++	int i, r;
++
++	for (i = 0, f = m->f; i < m->field_count - 1; i++, f++)
++		;
++
++	for (r = 0; r < f->rules; r++) {
++		struct nft_pipapo_elem *e;
++
++		if (r < f->rules - 1 && f->mt[r + 1].e == f->mt[r].e)
++			continue;
++
++		e = f->mt[r].e;
++
++		nft_set_elem_destroy(set, e, true);
++	}
++}
++
+ /**
+  * nft_pipapo_destroy() - Free private data for set and all committed elements
+  * @set:	nftables API set representation
+@@ -2132,26 +2158,13 @@ static void nft_pipapo_destroy(const struct nft_set *set)
+ {
+ 	struct nft_pipapo *priv = nft_set_priv(set);
+ 	struct nft_pipapo_match *m;
+-	struct nft_pipapo_field *f;
+-	int i, r, cpu;
++	int cpu;
+ 
+ 	m = rcu_dereference_protected(priv->match, true);
+ 	if (m) {
+ 		rcu_barrier();
+ 
+-		for (i = 0, f = m->f; i < m->field_count - 1; i++, f++)
+-			;
+-
+-		for (r = 0; r < f->rules; r++) {
+-			struct nft_pipapo_elem *e;
+-
+-			if (r < f->rules - 1 && f->mt[r + 1].e == f->mt[r].e)
+-				continue;
+-
+-			e = f->mt[r].e;
+-
+-			nft_set_elem_destroy(set, e, true);
+-		}
++		nft_set_pipapo_match_destroy(set, m);
+ 
+ #ifdef NFT_PIPAPO_ALIGN
+ 		free_percpu(m->scratch_aligned);
+@@ -2165,6 +2178,11 @@ static void nft_pipapo_destroy(const struct nft_set *set)
+ 	}
+ 
+ 	if (priv->clone) {
++		m = priv->clone;
++
++		if (priv->dirty)
++			nft_set_pipapo_match_destroy(set, m);
++
+ #ifdef NFT_PIPAPO_ALIGN
+ 		free_percpu(priv->clone->scratch_aligned);
+ #endif
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index e2e6b6b785789..5e93510fa3d24 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -227,8 +227,8 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh)
+ {
+ 	struct rose_neigh *s;
+ 
+-	rose_stop_ftimer(rose_neigh);
+-	rose_stop_t0timer(rose_neigh);
++	del_timer_sync(&rose_neigh->ftimer);
++	del_timer_sync(&rose_neigh->t0timer);
+ 
+ 	skb_queue_purge(&rose_neigh->queue);
+ 
+diff --git a/net/sched/act_api.c b/net/sched/act_api.c
+index 6fa9e7b1406a4..817065aa28331 100644
+--- a/net/sched/act_api.c
++++ b/net/sched/act_api.c
+@@ -195,7 +195,7 @@ static int offload_action_init(struct flow_offload_action *fl_action,
+ 	if (act->ops->offload_act_setup) {
+ 		spin_lock_bh(&act->tcfa_lock);
+ 		err = act->ops->offload_act_setup(act, fl_action, NULL,
+-						  false);
++						  false, extack);
+ 		spin_unlock_bh(&act->tcfa_lock);
+ 		return err;
+ 	}
+@@ -271,7 +271,7 @@ static int tcf_action_offload_add_ex(struct tc_action *action,
+ 	if (err)
+ 		goto fl_err;
+ 
+-	err = tc_setup_action(&fl_action->action, actions);
++	err = tc_setup_action(&fl_action->action, actions, extack);
+ 	if (err) {
+ 		NL_SET_ERR_MSG_MOD(extack,
+ 				   "Failed to setup tc actions for offload");
+diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c
+index e0f515b774cad..22847ee009efa 100644
+--- a/net/sched/act_csum.c
++++ b/net/sched/act_csum.c
+@@ -696,7 +696,8 @@ static size_t tcf_csum_get_fill_size(const struct tc_action *act)
+ }
+ 
+ static int tcf_csum_offload_act_setup(struct tc_action *act, void *entry_data,
+-				      u32 *index_inc, bool bind)
++				      u32 *index_inc, bool bind,
++				      struct netlink_ext_ack *extack)
+ {
+ 	if (bind) {
+ 		struct flow_action_entry *entry = entry_data;
+diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
+index b3ca837fd4e82..e013253b10d18 100644
+--- a/net/sched/act_ct.c
++++ b/net/sched/act_ct.c
+@@ -1584,7 +1584,8 @@ static void tcf_stats_update(struct tc_action *a, u64 bytes, u64 packets,
+ }
+ 
+ static int tcf_ct_offload_act_setup(struct tc_action *act, void *entry_data,
+-				    u32 *index_inc, bool bind)
++				    u32 *index_inc, bool bind,
++				    struct netlink_ext_ack *extack)
+ {
+ 	if (bind) {
+ 		struct flow_action_entry *entry = entry_data;
+diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c
+index bde6a6c01e64c..db84a0473cc13 100644
+--- a/net/sched/act_gact.c
++++ b/net/sched/act_gact.c
+@@ -253,7 +253,8 @@ static size_t tcf_gact_get_fill_size(const struct tc_action *act)
+ }
+ 
+ static int tcf_gact_offload_act_setup(struct tc_action *act, void *entry_data,
+-				      u32 *index_inc, bool bind)
++				      u32 *index_inc, bool bind,
++				      struct netlink_ext_ack *extack)
+ {
+ 	if (bind) {
+ 		struct flow_action_entry *entry = entry_data;
+diff --git a/net/sched/act_gate.c b/net/sched/act_gate.c
+index d56e73843a4b7..fd51552747332 100644
+--- a/net/sched/act_gate.c
++++ b/net/sched/act_gate.c
+@@ -619,7 +619,8 @@ static int tcf_gate_get_entries(struct flow_action_entry *entry,
+ }
+ 
+ static int tcf_gate_offload_act_setup(struct tc_action *act, void *entry_data,
+-				      u32 *index_inc, bool bind)
++				      u32 *index_inc, bool bind,
++				      struct netlink_ext_ack *extack)
+ {
+ 	int err;
+ 
+diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
+index 39acd1d186098..70a6a4447e6bd 100644
+--- a/net/sched/act_mirred.c
++++ b/net/sched/act_mirred.c
+@@ -460,7 +460,8 @@ static void tcf_offload_mirred_get_dev(struct flow_action_entry *entry,
+ }
+ 
+ static int tcf_mirred_offload_act_setup(struct tc_action *act, void *entry_data,
+-					u32 *index_inc, bool bind)
++					u32 *index_inc, bool bind,
++					struct netlink_ext_ack *extack)
+ {
+ 	if (bind) {
+ 		struct flow_action_entry *entry = entry_data;
+diff --git a/net/sched/act_mpls.c b/net/sched/act_mpls.c
+index b9ff3459fdab9..23fcfa5605dfa 100644
+--- a/net/sched/act_mpls.c
++++ b/net/sched/act_mpls.c
+@@ -385,7 +385,8 @@ static int tcf_mpls_search(struct net *net, struct tc_action **a, u32 index)
+ }
+ 
+ static int tcf_mpls_offload_act_setup(struct tc_action *act, void *entry_data,
+-				      u32 *index_inc, bool bind)
++				      u32 *index_inc, bool bind,
++				      struct netlink_ext_ack *extack)
+ {
+ 	if (bind) {
+ 		struct flow_action_entry *entry = entry_data;
+diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c
+index 211c757bfc3c4..8fccc914f4642 100644
+--- a/net/sched/act_pedit.c
++++ b/net/sched/act_pedit.c
+@@ -510,7 +510,8 @@ static int tcf_pedit_search(struct net *net, struct tc_action **a, u32 index)
+ }
+ 
+ static int tcf_pedit_offload_act_setup(struct tc_action *act, void *entry_data,
+-				       u32 *index_inc, bool bind)
++				       u32 *index_inc, bool bind,
++				       struct netlink_ext_ack *extack)
+ {
+ 	if (bind) {
+ 		struct flow_action_entry *entry = entry_data;
+diff --git a/net/sched/act_police.c b/net/sched/act_police.c
+index f4d9177052639..b759628a47c20 100644
+--- a/net/sched/act_police.c
++++ b/net/sched/act_police.c
+@@ -419,7 +419,8 @@ static int tcf_police_search(struct net *net, struct tc_action **a, u32 index)
+ 	return tcf_idr_search(tn, a, index);
+ }
+ 
+-static int tcf_police_act_to_flow_act(int tc_act, u32 *extval)
++static int tcf_police_act_to_flow_act(int tc_act, u32 *extval,
++				      struct netlink_ext_ack *extack)
+ {
+ 	int act_id = -EOPNOTSUPP;
+ 
+@@ -430,19 +431,28 @@ static int tcf_police_act_to_flow_act(int tc_act, u32 *extval)
+ 			act_id = FLOW_ACTION_DROP;
+ 		else if (tc_act == TC_ACT_PIPE)
+ 			act_id = FLOW_ACTION_PIPE;
++		else if (tc_act == TC_ACT_RECLASSIFY)
++			NL_SET_ERR_MSG_MOD(extack, "Offload not supported when conform/exceed action is \"reclassify\"");
++		else
++			NL_SET_ERR_MSG_MOD(extack, "Unsupported conform/exceed action offload");
+ 	} else if (TC_ACT_EXT_CMP(tc_act, TC_ACT_GOTO_CHAIN)) {
+ 		act_id = FLOW_ACTION_GOTO;
+ 		*extval = tc_act & TC_ACT_EXT_VAL_MASK;
+ 	} else if (TC_ACT_EXT_CMP(tc_act, TC_ACT_JUMP)) {
+ 		act_id = FLOW_ACTION_JUMP;
+ 		*extval = tc_act & TC_ACT_EXT_VAL_MASK;
++	} else if (tc_act == TC_ACT_UNSPEC) {
++		act_id = FLOW_ACTION_CONTINUE;
++	} else {
++		NL_SET_ERR_MSG_MOD(extack, "Unsupported conform/exceed action offload");
+ 	}
+ 
+ 	return act_id;
+ }
+ 
+ static int tcf_police_offload_act_setup(struct tc_action *act, void *entry_data,
+-					u32 *index_inc, bool bind)
++					u32 *index_inc, bool bind,
++					struct netlink_ext_ack *extack)
+ {
+ 	if (bind) {
+ 		struct flow_action_entry *entry = entry_data;
+@@ -466,14 +476,16 @@ static int tcf_police_offload_act_setup(struct tc_action *act, void *entry_data,
+ 		entry->police.mtu = tcf_police_tcfp_mtu(act);
+ 
+ 		act_id = tcf_police_act_to_flow_act(police->tcf_action,
+-						    &entry->police.exceed.extval);
++						    &entry->police.exceed.extval,
++						    extack);
+ 		if (act_id < 0)
+ 			return act_id;
+ 
+ 		entry->police.exceed.act_id = act_id;
+ 
+ 		act_id = tcf_police_act_to_flow_act(p->tcfp_result,
+-						    &entry->police.notexceed.extval);
++						    &entry->police.notexceed.extval,
++						    extack);
+ 		if (act_id < 0)
+ 			return act_id;
+ 
+diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c
+index 9a22cdda6bbdc..2f7f5e44d28c9 100644
+--- a/net/sched/act_sample.c
++++ b/net/sched/act_sample.c
+@@ -291,7 +291,8 @@ static void tcf_offload_sample_get_group(struct flow_action_entry *entry,
+ }
+ 
+ static int tcf_sample_offload_act_setup(struct tc_action *act, void *entry_data,
+-					u32 *index_inc, bool bind)
++					u32 *index_inc, bool bind,
++					struct netlink_ext_ack *extack)
+ {
+ 	if (bind) {
+ 		struct flow_action_entry *entry = entry_data;
+diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c
+index ceba11b198bba..8cd8e506c9c9b 100644
+--- a/net/sched/act_skbedit.c
++++ b/net/sched/act_skbedit.c
+@@ -328,7 +328,8 @@ static size_t tcf_skbedit_get_fill_size(const struct tc_action *act)
+ }
+ 
+ static int tcf_skbedit_offload_act_setup(struct tc_action *act, void *entry_data,
+-					 u32 *index_inc, bool bind)
++					 u32 *index_inc, bool bind,
++					 struct netlink_ext_ack *extack)
+ {
+ 	if (bind) {
+ 		struct flow_action_entry *entry = entry_data;
+diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
+index 23aba03d26a8d..3c6f40478c813 100644
+--- a/net/sched/act_tunnel_key.c
++++ b/net/sched/act_tunnel_key.c
+@@ -808,7 +808,8 @@ static int tcf_tunnel_encap_get_tunnel(struct flow_action_entry *entry,
+ static int tcf_tunnel_key_offload_act_setup(struct tc_action *act,
+ 					    void *entry_data,
+ 					    u32 *index_inc,
+-					    bool bind)
++					    bool bind,
++					    struct netlink_ext_ack *extack)
+ {
+ 	int err;
+ 
+diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c
+index 883454c4f9219..8c89bce99cbd1 100644
+--- a/net/sched/act_vlan.c
++++ b/net/sched/act_vlan.c
+@@ -369,7 +369,8 @@ static size_t tcf_vlan_get_fill_size(const struct tc_action *act)
+ }
+ 
+ static int tcf_vlan_offload_act_setup(struct tc_action *act, void *entry_data,
+-				      u32 *index_inc, bool bind)
++				      u32 *index_inc, bool bind,
++				      struct netlink_ext_ack *extack)
+ {
+ 	if (bind) {
+ 		struct flow_action_entry *entry = entry_data;
+diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
+index f0699f39afdb0..2d4dc1468a9a5 100644
+--- a/net/sched/cls_api.c
++++ b/net/sched/cls_api.c
+@@ -3513,11 +3513,13 @@ EXPORT_SYMBOL(tc_cleanup_offload_action);
+ 
+ static int tc_setup_offload_act(struct tc_action *act,
+ 				struct flow_action_entry *entry,
+-				u32 *index_inc)
++				u32 *index_inc,
++				struct netlink_ext_ack *extack)
+ {
+ #ifdef CONFIG_NET_CLS_ACT
+ 	if (act->ops->offload_act_setup)
+-		return act->ops->offload_act_setup(act, entry, index_inc, true);
++		return act->ops->offload_act_setup(act, entry, index_inc, true,
++						   extack);
+ 	else
+ 		return -EOPNOTSUPP;
+ #else
+@@ -3526,7 +3528,8 @@ static int tc_setup_offload_act(struct tc_action *act,
+ }
+ 
+ int tc_setup_action(struct flow_action *flow_action,
+-		    struct tc_action *actions[])
++		    struct tc_action *actions[],
++		    struct netlink_ext_ack *extack)
+ {
+ 	int i, j, index, err = 0;
+ 	struct tc_action *act;
+@@ -3551,7 +3554,7 @@ int tc_setup_action(struct flow_action *flow_action,
+ 		entry->hw_stats = tc_act_hw_stats(act->hw_stats);
+ 		entry->hw_index = act->tcfa_index;
+ 		index = 0;
+-		err = tc_setup_offload_act(act, entry, &index);
++		err = tc_setup_offload_act(act, entry, &index, extack);
+ 		if (!err)
+ 			j += index;
+ 		else
+@@ -3570,13 +3573,14 @@ err_out_locked:
+ }
+ 
+ int tc_setup_offload_action(struct flow_action *flow_action,
+-			    const struct tcf_exts *exts)
++			    const struct tcf_exts *exts,
++			    struct netlink_ext_ack *extack)
+ {
+ #ifdef CONFIG_NET_CLS_ACT
+ 	if (!exts)
+ 		return 0;
+ 
+-	return tc_setup_action(flow_action, exts->actions);
++	return tc_setup_action(flow_action, exts->actions, extack);
+ #else
+ 	return 0;
+ #endif
+diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
+index ed5e6f08e74a8..cddacf49f9e86 100644
+--- a/net/sched/cls_flower.c
++++ b/net/sched/cls_flower.c
+@@ -464,7 +464,8 @@ static int fl_hw_replace_filter(struct tcf_proto *tp,
+ 	cls_flower.rule->match.key = &f->mkey;
+ 	cls_flower.classid = f->res.classid;
+ 
+-	err = tc_setup_offload_action(&cls_flower.rule->action, &f->exts);
++	err = tc_setup_offload_action(&cls_flower.rule->action, &f->exts,
++				      cls_flower.common.extack);
+ 	if (err) {
+ 		kfree(cls_flower.rule);
+ 		if (skip_sw) {
+@@ -2362,7 +2363,8 @@ static int fl_reoffload(struct tcf_proto *tp, bool add, flow_setup_cb_t *cb,
+ 		cls_flower.rule->match.mask = &f->mask->key;
+ 		cls_flower.rule->match.key = &f->mkey;
+ 
+-		err = tc_setup_offload_action(&cls_flower.rule->action, &f->exts);
++		err = tc_setup_offload_action(&cls_flower.rule->action, &f->exts,
++					      cls_flower.common.extack);
+ 		if (err) {
+ 			kfree(cls_flower.rule);
+ 			if (tc_skip_sw(f->flags)) {
+diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c
+index ca5670fd5228e..df80c6b185a01 100644
+--- a/net/sched/cls_matchall.c
++++ b/net/sched/cls_matchall.c
+@@ -97,7 +97,8 @@ static int mall_replace_hw_filter(struct tcf_proto *tp,
+ 	cls_mall.command = TC_CLSMATCHALL_REPLACE;
+ 	cls_mall.cookie = cookie;
+ 
+-	err = tc_setup_offload_action(&cls_mall.rule->action, &head->exts);
++	err = tc_setup_offload_action(&cls_mall.rule->action, &head->exts,
++				      cls_mall.common.extack);
+ 	if (err) {
+ 		kfree(cls_mall.rule);
+ 		mall_destroy_hw_filter(tp, head, cookie, NULL);
+@@ -302,7 +303,8 @@ static int mall_reoffload(struct tcf_proto *tp, bool add, flow_setup_cb_t *cb,
+ 		TC_CLSMATCHALL_REPLACE : TC_CLSMATCHALL_DESTROY;
+ 	cls_mall.cookie = (unsigned long)head;
+ 
+-	err = tc_setup_offload_action(&cls_mall.rule->action, &head->exts);
++	err = tc_setup_offload_action(&cls_mall.rule->action, &head->exts,
++				      cls_mall.common.extack);
+ 	if (err) {
+ 		kfree(cls_mall.rule);
+ 		if (add && tc_skip_sw(head->flags)) {
+diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c
+index 87bdd71c7bb66..f70112176b7c1 100644
+--- a/net/xdp/xsk_buff_pool.c
++++ b/net/xdp/xsk_buff_pool.c
+@@ -332,6 +332,7 @@ static void __xp_dma_unmap(struct xsk_dma_map *dma_map, unsigned long attrs)
+ 	for (i = 0; i < dma_map->dma_pages_cnt; i++) {
+ 		dma = &dma_map->dma_pages[i];
+ 		if (*dma) {
++			*dma &= ~XSK_NEXT_PG_CONTIG_MASK;
+ 			dma_unmap_page_attrs(dma_map->dev, *dma, PAGE_SIZE,
+ 					     DMA_BIDIRECTIONAL, attrs);
+ 			*dma = 0;
+diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
+index bd60308769ff7..8634004a606b6 100644
+--- a/sound/pci/cs46xx/cs46xx.c
++++ b/sound/pci/cs46xx/cs46xx.c
+@@ -74,36 +74,36 @@ static int snd_card_cs46xx_probe(struct pci_dev *pci,
+ 	err = snd_cs46xx_create(card, pci,
+ 				external_amp[dev], thinkpad[dev]);
+ 	if (err < 0)
+-		return err;
++		goto error;
+ 	card->private_data = chip;
+ 	chip->accept_valid = mmap_valid[dev];
+ 	err = snd_cs46xx_pcm(chip, 0);
+ 	if (err < 0)
+-		return err;
++		goto error;
+ #ifdef CONFIG_SND_CS46XX_NEW_DSP
+ 	err = snd_cs46xx_pcm_rear(chip, 1);
+ 	if (err < 0)
+-		return err;
++		goto error;
+ 	err = snd_cs46xx_pcm_iec958(chip, 2);
+ 	if (err < 0)
+-		return err;
++		goto error;
+ #endif
+ 	err = snd_cs46xx_mixer(chip, 2);
+ 	if (err < 0)
+-		return err;
++		goto error;
+ #ifdef CONFIG_SND_CS46XX_NEW_DSP
+ 	if (chip->nr_ac97_codecs ==2) {
+ 		err = snd_cs46xx_pcm_center_lfe(chip, 3);
+ 		if (err < 0)
+-			return err;
++			goto error;
+ 	}
+ #endif
+ 	err = snd_cs46xx_midi(chip, 0);
+ 	if (err < 0)
+-		return err;
++		goto error;
+ 	err = snd_cs46xx_start_dsp(chip);
+ 	if (err < 0)
+-		return err;
++		goto error;
+ 
+ 	snd_cs46xx_gameport(chip);
+ 
+@@ -117,11 +117,15 @@ static int snd_card_cs46xx_probe(struct pci_dev *pci,
+ 
+ 	err = snd_card_register(card);
+ 	if (err < 0)
+-		return err;
++		goto error;
+ 
+ 	pci_set_drvdata(pci, card);
+ 	dev++;
+ 	return 0;
++
++ error:
++	snd_card_free(card);
++	return err;
+ }
+ 
+ static struct pci_driver cs46xx_driver = {
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index d3d786de8f4c4..45f5db25a77ed 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -9264,6 +9264,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x1558, 0x70f4, "Clevo NH77EPY", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+ 	SND_PCI_QUIRK(0x1558, 0x70f6, "Clevo NH77DPQ-Y", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+ 	SND_PCI_QUIRK(0x1558, 0x7716, "Clevo NS50PU", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
++	SND_PCI_QUIRK(0x1558, 0x7718, "Clevo L140PU", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+ 	SND_PCI_QUIRK(0x1558, 0x8228, "Clevo NR40BU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+ 	SND_PCI_QUIRK(0x1558, 0x8520, "Clevo NH50D[CD]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+ 	SND_PCI_QUIRK(0x1558, 0x8521, "Clevo NH77D[CD]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+diff --git a/sound/soc/codecs/rt700.c b/sound/soc/codecs/rt700.c
+index e61a8257bf647..360d61a36c354 100644
+--- a/sound/soc/codecs/rt700.c
++++ b/sound/soc/codecs/rt700.c
+@@ -315,17 +315,27 @@ static int rt700_set_jack_detect(struct snd_soc_component *component,
+ 	struct snd_soc_jack *hs_jack, void *data)
+ {
+ 	struct rt700_priv *rt700 = snd_soc_component_get_drvdata(component);
++	int ret;
+ 
+ 	rt700->hs_jack = hs_jack;
+ 
+-	if (!rt700->hw_init) {
+-		dev_dbg(&rt700->slave->dev,
+-			"%s hw_init not ready yet\n", __func__);
++	ret = pm_runtime_resume_and_get(component->dev);
++	if (ret < 0) {
++		if (ret != -EACCES) {
++			dev_err(component->dev, "%s: failed to resume %d\n", __func__, ret);
++			return ret;
++		}
++
++		/* pm_runtime not enabled yet */
++		dev_dbg(component->dev,	"%s: skipping jack init for now\n", __func__);
+ 		return 0;
+ 	}
+ 
+ 	rt700_jack_init(rt700);
+ 
++	pm_runtime_mark_last_busy(component->dev);
++	pm_runtime_put_autosuspend(component->dev);
++
+ 	return 0;
+ }
+ 
+diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c
+index bdb1375f03388..9d59e653b941b 100644
+--- a/sound/soc/codecs/rt711-sdca.c
++++ b/sound/soc/codecs/rt711-sdca.c
+@@ -487,16 +487,27 @@ static int rt711_sdca_set_jack_detect(struct snd_soc_component *component,
+ 	struct snd_soc_jack *hs_jack, void *data)
+ {
+ 	struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component);
++	int ret;
+ 
+ 	rt711->hs_jack = hs_jack;
+ 
+-	if (!rt711->hw_init) {
+-		dev_dbg(&rt711->slave->dev,
+-			"%s hw_init not ready yet\n", __func__);
++	ret = pm_runtime_resume_and_get(component->dev);
++	if (ret < 0) {
++		if (ret != -EACCES) {
++			dev_err(component->dev, "%s: failed to resume %d\n", __func__, ret);
++			return ret;
++		}
++
++		/* pm_runtime not enabled yet */
++		dev_dbg(component->dev,	"%s: skipping jack init for now\n", __func__);
+ 		return 0;
+ 	}
+ 
+ 	rt711_sdca_jack_init(rt711);
++
++	pm_runtime_mark_last_busy(component->dev);
++	pm_runtime_put_autosuspend(component->dev);
++
+ 	return 0;
+ }
+ 
+@@ -1190,14 +1201,6 @@ static int rt711_sdca_probe(struct snd_soc_component *component)
+ 	return 0;
+ }
+ 
+-static void rt711_sdca_remove(struct snd_soc_component *component)
+-{
+-	struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component);
+-
+-	regcache_cache_only(rt711->regmap, true);
+-	regcache_cache_only(rt711->mbq_regmap, true);
+-}
+-
+ static const struct snd_soc_component_driver soc_sdca_dev_rt711 = {
+ 	.probe = rt711_sdca_probe,
+ 	.controls = rt711_sdca_snd_controls,
+@@ -1207,7 +1210,7 @@ static const struct snd_soc_component_driver soc_sdca_dev_rt711 = {
+ 	.dapm_routes = rt711_sdca_audio_map,
+ 	.num_dapm_routes = ARRAY_SIZE(rt711_sdca_audio_map),
+ 	.set_jack = rt711_sdca_set_jack_detect,
+-	.remove = rt711_sdca_remove,
++	.endianness = 1,
+ };
+ 
+ static int rt711_sdca_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream,
+diff --git a/sound/soc/codecs/rt711.c b/sound/soc/codecs/rt711.c
+index ea25fd58d43a9..9958067e80f11 100644
+--- a/sound/soc/codecs/rt711.c
++++ b/sound/soc/codecs/rt711.c
+@@ -457,17 +457,27 @@ static int rt711_set_jack_detect(struct snd_soc_component *component,
+ 	struct snd_soc_jack *hs_jack, void *data)
+ {
+ 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
++	int ret;
+ 
+ 	rt711->hs_jack = hs_jack;
+ 
+-	if (!rt711->hw_init) {
+-		dev_dbg(&rt711->slave->dev,
+-			"%s hw_init not ready yet\n", __func__);
++	ret = pm_runtime_resume_and_get(component->dev);
++	if (ret < 0) {
++		if (ret != -EACCES) {
++			dev_err(component->dev, "%s: failed to resume %d\n", __func__, ret);
++			return ret;
++		}
++
++		/* pm_runtime not enabled yet */
++		dev_dbg(component->dev,	"%s: skipping jack init for now\n", __func__);
+ 		return 0;
+ 	}
+ 
+ 	rt711_jack_init(rt711);
+ 
++	pm_runtime_mark_last_busy(component->dev);
++	pm_runtime_put_autosuspend(component->dev);
++
+ 	return 0;
+ }
+ 
+@@ -932,13 +942,6 @@ static int rt711_probe(struct snd_soc_component *component)
+ 	return 0;
+ }
+ 
+-static void rt711_remove(struct snd_soc_component *component)
+-{
+-	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
+-
+-	regcache_cache_only(rt711->regmap, true);
+-}
+-
+ static const struct snd_soc_component_driver soc_codec_dev_rt711 = {
+ 	.probe = rt711_probe,
+ 	.set_bias_level = rt711_set_bias_level,
+@@ -949,7 +952,7 @@ static const struct snd_soc_component_driver soc_codec_dev_rt711 = {
+ 	.dapm_routes = rt711_audio_map,
+ 	.num_dapm_routes = ARRAY_SIZE(rt711_audio_map),
+ 	.set_jack = rt711_set_jack_detect,
+-	.remove = rt711_remove,
++	.endianness = 1,
+ };
+ 
+ static int rt711_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream,
+diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
+index 19c4a90ec1ea9..ee59ef36b85a6 100644
+--- a/sound/soc/qcom/qdsp6/q6apm-dai.c
++++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
+@@ -147,6 +147,12 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
+ 	cfg.num_channels = runtime->channels;
+ 	cfg.bit_width = prtd->bits_per_sample;
+ 
++	if (prtd->state) {
++		/* clear the previous setup if any  */
++		q6apm_graph_stop(prtd->graph);
++		q6apm_unmap_memory_regions(prtd->graph, substream->stream);
++	}
++
+ 	prtd->pcm_count = snd_pcm_lib_period_bytes(substream);
+ 	prtd->pos = 0;
+ 	/* rate and channels are sent to audio driver */
+diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c
+index dc1f743730c0d..6888e0a4665d2 100644
+--- a/sound/soc/sof/intel/hda-pcm.c
++++ b/sound/soc/sof/intel/hda-pcm.c
+@@ -192,79 +192,7 @@ snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev,
+ 		goto found;
+ 	}
+ 
+-	switch (sof_hda_position_quirk) {
+-	case SOF_HDA_POSITION_QUIRK_USE_SKYLAKE_LEGACY:
+-		/*
+-		 * This legacy code, inherited from the Skylake driver,
+-		 * mixes DPIB registers and DPIB DDR updates and
+-		 * does not seem to follow any known hardware recommendations.
+-		 * It's not clear e.g. why there is a different flow
+-		 * for capture and playback, the only information that matters is
+-		 * what traffic class is used, and on all SOF-enabled platforms
+-		 * only VC0 is supported so the work-around was likely not necessary
+-		 * and quite possibly wrong.
+-		 */
+-
+-		/* DPIB/posbuf position mode:
+-		 * For Playback, Use DPIB register from HDA space which
+-		 * reflects the actual data transferred.
+-		 * For Capture, Use the position buffer for pointer, as DPIB
+-		 * is not accurate enough, its update may be completed
+-		 * earlier than the data written to DDR.
+-		 */
+-		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+-			pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
+-					       AZX_REG_VS_SDXDPIB_XBASE +
+-					       (AZX_REG_VS_SDXDPIB_XINTERVAL *
+-						hstream->index));
+-		} else {
+-			/*
+-			 * For capture stream, we need more workaround to fix the
+-			 * position incorrect issue:
+-			 *
+-			 * 1. Wait at least 20us before reading position buffer after
+-			 * the interrupt generated(IOC), to make sure position update
+-			 * happens on frame boundary i.e. 20.833uSec for 48KHz.
+-			 * 2. Perform a dummy Read to DPIB register to flush DMA
+-			 * position value.
+-			 * 3. Read the DMA Position from posbuf. Now the readback
+-			 * value should be >= period boundary.
+-			 */
+-			usleep_range(20, 21);
+-			snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
+-					 AZX_REG_VS_SDXDPIB_XBASE +
+-					 (AZX_REG_VS_SDXDPIB_XINTERVAL *
+-					  hstream->index));
+-			pos = snd_hdac_stream_get_pos_posbuf(hstream);
+-		}
+-		break;
+-	case SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS:
+-		/*
+-		 * In case VC1 traffic is disabled this is the recommended option
+-		 */
+-		pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
+-				       AZX_REG_VS_SDXDPIB_XBASE +
+-				       (AZX_REG_VS_SDXDPIB_XINTERVAL *
+-					hstream->index));
+-		break;
+-	case SOF_HDA_POSITION_QUIRK_USE_DPIB_DDR_UPDATE:
+-		/*
+-		 * This is the recommended option when VC1 is enabled.
+-		 * While this isn't needed for SOF platforms it's added for
+-		 * consistency and debug.
+-		 */
+-		pos = snd_hdac_stream_get_pos_posbuf(hstream);
+-		break;
+-	default:
+-		dev_err_once(sdev->dev, "hda_position_quirk value %d not supported\n",
+-			     sof_hda_position_quirk);
+-		pos = 0;
+-		break;
+-	}
+-
+-	if (pos >= hstream->bufsize)
+-		pos = 0;
+-
++	pos = hda_dsp_stream_get_position(hstream, substream->stream, true);
+ found:
+ 	pos = bytes_to_frames(substream->runtime, pos);
+ 
+diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c
+index daeb64c495e40..d95ae17e81cc4 100644
+--- a/sound/soc/sof/intel/hda-stream.c
++++ b/sound/soc/sof/intel/hda-stream.c
+@@ -707,12 +707,13 @@ bool hda_dsp_check_stream_irq(struct snd_sof_dev *sdev)
+ }
+ 
+ static void
+-hda_dsp_set_bytes_transferred(struct hdac_stream *hstream, u64 buffer_size)
++hda_dsp_compr_bytes_transferred(struct hdac_stream *hstream, int direction)
+ {
++	u64 buffer_size = hstream->bufsize;
+ 	u64 prev_pos, pos, num_bytes;
+ 
+ 	div64_u64_rem(hstream->curr_pos, buffer_size, &prev_pos);
+-	pos = snd_hdac_stream_get_pos_posbuf(hstream);
++	pos = hda_dsp_stream_get_position(hstream, direction, false);
+ 
+ 	if (pos < prev_pos)
+ 		num_bytes = (buffer_size - prev_pos) +  pos;
+@@ -748,8 +749,7 @@ static bool hda_dsp_stream_check(struct hdac_bus *bus, u32 status)
+ 			if (s->substream && sof_hda->no_ipc_position) {
+ 				snd_sof_pcm_period_elapsed(s->substream);
+ 			} else if (s->cstream) {
+-				hda_dsp_set_bytes_transferred(s,
+-					s->cstream->runtime->buffer_size);
++				hda_dsp_compr_bytes_transferred(s, s->cstream->direction);
+ 				snd_compr_fragment_elapsed(s->cstream);
+ 			}
+ 		}
+@@ -1009,3 +1009,89 @@ void hda_dsp_stream_free(struct snd_sof_dev *sdev)
+ 		devm_kfree(sdev->dev, hda_stream);
+ 	}
+ }
++
++snd_pcm_uframes_t hda_dsp_stream_get_position(struct hdac_stream *hstream,
++					      int direction, bool can_sleep)
++{
++	struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream);
++	struct sof_intel_hda_stream *hda_stream = hstream_to_sof_hda_stream(hext_stream);
++	struct snd_sof_dev *sdev = hda_stream->sdev;
++	snd_pcm_uframes_t pos;
++
++	switch (sof_hda_position_quirk) {
++	case SOF_HDA_POSITION_QUIRK_USE_SKYLAKE_LEGACY:
++		/*
++		 * This legacy code, inherited from the Skylake driver,
++		 * mixes DPIB registers and DPIB DDR updates and
++		 * does not seem to follow any known hardware recommendations.
++		 * It's not clear e.g. why there is a different flow
++		 * for capture and playback, the only information that matters is
++		 * what traffic class is used, and on all SOF-enabled platforms
++		 * only VC0 is supported so the work-around was likely not necessary
++		 * and quite possibly wrong.
++		 */
++
++		/* DPIB/posbuf position mode:
++		 * For Playback, Use DPIB register from HDA space which
++		 * reflects the actual data transferred.
++		 * For Capture, Use the position buffer for pointer, as DPIB
++		 * is not accurate enough, its update may be completed
++		 * earlier than the data written to DDR.
++		 */
++		if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
++			pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
++					       AZX_REG_VS_SDXDPIB_XBASE +
++					       (AZX_REG_VS_SDXDPIB_XINTERVAL *
++						hstream->index));
++		} else {
++			/*
++			 * For capture stream, we need more workaround to fix the
++			 * position incorrect issue:
++			 *
++			 * 1. Wait at least 20us before reading position buffer after
++			 * the interrupt generated(IOC), to make sure position update
++			 * happens on frame boundary i.e. 20.833uSec for 48KHz.
++			 * 2. Perform a dummy Read to DPIB register to flush DMA
++			 * position value.
++			 * 3. Read the DMA Position from posbuf. Now the readback
++			 * value should be >= period boundary.
++			 */
++			if (can_sleep)
++				usleep_range(20, 21);
++
++			snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
++					 AZX_REG_VS_SDXDPIB_XBASE +
++					 (AZX_REG_VS_SDXDPIB_XINTERVAL *
++					  hstream->index));
++			pos = snd_hdac_stream_get_pos_posbuf(hstream);
++		}
++		break;
++	case SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS:
++		/*
++		 * In case VC1 traffic is disabled this is the recommended option
++		 */
++		pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
++				       AZX_REG_VS_SDXDPIB_XBASE +
++				       (AZX_REG_VS_SDXDPIB_XINTERVAL *
++					hstream->index));
++		break;
++	case SOF_HDA_POSITION_QUIRK_USE_DPIB_DDR_UPDATE:
++		/*
++		 * This is the recommended option when VC1 is enabled.
++		 * While this isn't needed for SOF platforms it's added for
++		 * consistency and debug.
++		 */
++		pos = snd_hdac_stream_get_pos_posbuf(hstream);
++		break;
++	default:
++		dev_err_once(sdev->dev, "hda_position_quirk value %d not supported\n",
++			     sof_hda_position_quirk);
++		pos = 0;
++		break;
++	}
++
++	if (pos >= hstream->bufsize)
++		pos = 0;
++
++	return pos;
++}
+diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
+index 05e5e158614a1..196494ba1245b 100644
+--- a/sound/soc/sof/intel/hda.h
++++ b/sound/soc/sof/intel/hda.h
+@@ -557,6 +557,9 @@ int hda_dsp_stream_setup_bdl(struct snd_sof_dev *sdev,
+ bool hda_dsp_check_ipc_irq(struct snd_sof_dev *sdev);
+ bool hda_dsp_check_stream_irq(struct snd_sof_dev *sdev);
+ 
++snd_pcm_uframes_t hda_dsp_stream_get_position(struct hdac_stream *hstream,
++					      int direction, bool can_sleep);
++
+ struct hdac_ext_stream *
+ 	hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags);
+ int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag);
+diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c
+index cdff48c4195f8..80fb82ece38d7 100644
+--- a/sound/soc/sof/ipc3-topology.c
++++ b/sound/soc/sof/ipc3-topology.c
+@@ -1578,24 +1578,23 @@ static int sof_ipc3_control_load_bytes(struct snd_sof_dev *sdev, struct snd_sof_
+ 	struct sof_ipc_ctrl_data *cdata;
+ 	int ret;
+ 
+-	scontrol->ipc_control_data = kzalloc(scontrol->max_size, GFP_KERNEL);
+-	if (!scontrol->ipc_control_data)
+-		return -ENOMEM;
+-
+-	if (scontrol->max_size < sizeof(*cdata) ||
+-	    scontrol->max_size < sizeof(struct sof_abi_hdr)) {
+-		ret = -EINVAL;
+-		goto err;
++	if (scontrol->max_size < (sizeof(*cdata) + sizeof(struct sof_abi_hdr))) {
++		dev_err(sdev->dev, "%s: insufficient size for a bytes control: %zu.\n",
++			__func__, scontrol->max_size);
++		return -EINVAL;
+ 	}
+ 
+-	/* init the get/put bytes data */
+ 	if (scontrol->priv_size > scontrol->max_size - sizeof(*cdata)) {
+-		dev_err(sdev->dev, "err: bytes data size %zu exceeds max %zu.\n",
++		dev_err(sdev->dev,
++			"%s: bytes data size %zu exceeds max %zu.\n", __func__,
+ 			scontrol->priv_size, scontrol->max_size - sizeof(*cdata));
+-		ret = -EINVAL;
+-		goto err;
++		return -EINVAL;
+ 	}
+ 
++	scontrol->ipc_control_data = kzalloc(scontrol->max_size, GFP_KERNEL);
++	if (!scontrol->ipc_control_data)
++		return -ENOMEM;
++
+ 	scontrol->size = sizeof(struct sof_ipc_ctrl_data) + scontrol->priv_size;
+ 
+ 	cdata = scontrol->ipc_control_data;
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index e8468f9b007d1..12ce69b04f634 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -1842,6 +1842,10 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
+ 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
+ 	DEVICE_FLG(0x1395, 0x740a, /* Sennheiser DECT */
+ 		   QUIRK_FLAG_GET_SAMPLE_RATE),
++	DEVICE_FLG(0x1397, 0x0508, /* Behringer UMC204HD */
++		   QUIRK_FLAG_PLAYBACK_FIRST | QUIRK_FLAG_GENERIC_IMPLICIT_FB),
++	DEVICE_FLG(0x1397, 0x0509, /* Behringer UMC404HD */
++		   QUIRK_FLAG_PLAYBACK_FIRST | QUIRK_FLAG_GENERIC_IMPLICIT_FB),
+ 	DEVICE_FLG(0x13e5, 0x0001, /* Serato Phono */
+ 		   QUIRK_FLAG_IGNORE_CTL_ERROR),
+ 	DEVICE_FLG(0x154e, 0x1002, /* Denon DCD-1500RE */
+diff --git a/tools/testing/selftests/net/forwarding/lib.sh b/tools/testing/selftests/net/forwarding/lib.sh
+index 664b9ecaf2282..063da0d534629 100644
+--- a/tools/testing/selftests/net/forwarding/lib.sh
++++ b/tools/testing/selftests/net/forwarding/lib.sh
+@@ -1176,6 +1176,7 @@ learning_test()
+ 	# FDB entry was installed.
+ 	bridge link set dev $br_port1 flood off
+ 
++	ip link set $host1_if promisc on
+ 	tc qdisc add dev $host1_if ingress
+ 	tc filter add dev $host1_if ingress protocol ip pref 1 handle 101 \
+ 		flower dst_mac $mac action drop
+@@ -1186,7 +1187,7 @@ learning_test()
+ 	tc -j -s filter show dev $host1_if ingress \
+ 		| jq -e ".[] | select(.options.handle == 101) \
+ 		| select(.options.actions[0].stats.packets == 1)" &> /dev/null
+-	check_fail $? "Packet reached second host when should not"
++	check_fail $? "Packet reached first host when should not"
+ 
+ 	$MZ $host1_if -c 1 -p 64 -a $mac -t ip -q
+ 	sleep 1
+@@ -1225,6 +1226,7 @@ learning_test()
+ 
+ 	tc filter del dev $host1_if ingress protocol ip pref 1 handle 101 flower
+ 	tc qdisc del dev $host1_if ingress
++	ip link set $host1_if promisc off
+ 
+ 	bridge link set dev $br_port1 flood on
+ 
+@@ -1242,6 +1244,7 @@ flood_test_do()
+ 
+ 	# Add an ACL on `host2_if` which will tell us whether the packet
+ 	# was flooded to it or not.
++	ip link set $host2_if promisc on
+ 	tc qdisc add dev $host2_if ingress
+ 	tc filter add dev $host2_if ingress protocol ip pref 1 handle 101 \
+ 		flower dst_mac $mac action drop
+@@ -1259,6 +1262,7 @@ flood_test_do()
+ 
+ 	tc filter del dev $host2_if ingress protocol ip pref 1 handle 101 flower
+ 	tc qdisc del dev $host2_if ingress
++	ip link set $host2_if promisc off
+ 
+ 	return $err
+ }
+diff --git a/tools/testing/selftests/net/udpgro.sh b/tools/testing/selftests/net/udpgro.sh
+index f8a19f548ae9d..ebbd0b2824327 100755
+--- a/tools/testing/selftests/net/udpgro.sh
++++ b/tools/testing/selftests/net/udpgro.sh
+@@ -34,7 +34,7 @@ cfg_veth() {
+ 	ip -netns "${PEER_NS}" addr add dev veth1 192.168.1.1/24
+ 	ip -netns "${PEER_NS}" addr add dev veth1 2001:db8::1/64 nodad
+ 	ip -netns "${PEER_NS}" link set dev veth1 up
+-	ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp_dummy
++	ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp
+ }
+ 
+ run_one() {
+diff --git a/tools/testing/selftests/net/udpgro_bench.sh b/tools/testing/selftests/net/udpgro_bench.sh
+index 820bc50f6b687..fad2d1a71cac3 100755
+--- a/tools/testing/selftests/net/udpgro_bench.sh
++++ b/tools/testing/selftests/net/udpgro_bench.sh
+@@ -34,7 +34,7 @@ run_one() {
+ 	ip -netns "${PEER_NS}" addr add dev veth1 2001:db8::1/64 nodad
+ 	ip -netns "${PEER_NS}" link set dev veth1 up
+ 
+-	ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp_dummy
++	ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp
+ 	ip netns exec "${PEER_NS}" ./udpgso_bench_rx ${rx_args} -r &
+ 	ip netns exec "${PEER_NS}" ./udpgso_bench_rx -t ${rx_args} -r &
+ 
+diff --git a/tools/testing/selftests/net/udpgro_frglist.sh b/tools/testing/selftests/net/udpgro_frglist.sh
+index 807b74c8fd80f..832c738cc3c29 100755
+--- a/tools/testing/selftests/net/udpgro_frglist.sh
++++ b/tools/testing/selftests/net/udpgro_frglist.sh
+@@ -36,7 +36,7 @@ run_one() {
+ 	ip netns exec "${PEER_NS}" ethtool -K veth1 rx-gro-list on
+ 
+ 
+-	ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp_dummy
++	ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp
+ 	tc -n "${PEER_NS}" qdisc add dev veth1 clsact
+ 	tc -n "${PEER_NS}" filter add dev veth1 ingress prio 4 protocol ipv6 bpf object-file ../bpf/nat6to4.o section schedcls/ingress6/nat_6  direct-action
+ 	tc -n "${PEER_NS}" filter add dev veth1 egress prio 4 protocol ip bpf object-file ../bpf/nat6to4.o section schedcls/egress4/snat4 direct-action
+diff --git a/tools/testing/selftests/net/udpgro_fwd.sh b/tools/testing/selftests/net/udpgro_fwd.sh
+index 6f05e06f67613..1bcd82e1f662e 100755
+--- a/tools/testing/selftests/net/udpgro_fwd.sh
++++ b/tools/testing/selftests/net/udpgro_fwd.sh
+@@ -46,7 +46,7 @@ create_ns() {
+ 		ip -n $BASE$ns addr add dev veth$ns $BM_NET_V4$ns/24
+ 		ip -n $BASE$ns addr add dev veth$ns $BM_NET_V6$ns/64 nodad
+ 	done
+-	ip -n $NS_DST link set veth$DST xdp object ../bpf/xdp_dummy.o section xdp_dummy 2>/dev/null
++	ip -n $NS_DST link set veth$DST xdp object ../bpf/xdp_dummy.o section xdp 2>/dev/null
+ }
+ 
+ create_vxlan_endpoint() {
+diff --git a/tools/testing/selftests/net/veth.sh b/tools/testing/selftests/net/veth.sh
+index 19eac3e44c065..430895d1a2b63 100755
+--- a/tools/testing/selftests/net/veth.sh
++++ b/tools/testing/selftests/net/veth.sh
+@@ -289,14 +289,14 @@ if [ $CPUS -gt 1 ]; then
+ 	ip netns exec $NS_SRC ethtool -L veth$SRC rx 1 tx 2 2>/dev/null
+ 	printf "%-60s" "bad setting: XDP with RX nr less than TX"
+ 	ip -n $NS_DST link set dev veth$DST xdp object ../bpf/xdp_dummy.o \
+-		section xdp_dummy 2>/dev/null &&\
++		section xdp 2>/dev/null &&\
+ 		echo "fail - set operation successful ?!?" || echo " ok "
+ 
+ 	# the following tests will run with multiple channels active
+ 	ip netns exec $NS_SRC ethtool -L veth$SRC rx 2
+ 	ip netns exec $NS_DST ethtool -L veth$DST rx 2
+ 	ip -n $NS_DST link set dev veth$DST xdp object ../bpf/xdp_dummy.o \
+-		section xdp_dummy 2>/dev/null
++		section xdp 2>/dev/null
+ 	printf "%-60s" "bad setting: reducing RX nr below peer TX with XDP set"
+ 	ip netns exec $NS_DST ethtool -L veth$DST rx 1 2>/dev/null &&\
+ 		echo "fail - set operation successful ?!?" || echo " ok "
+@@ -311,7 +311,7 @@ if [ $CPUS -gt 2 ]; then
+ 	chk_channels "setting invalid channels nr" $DST 2 2
+ fi
+ 
+-ip -n $NS_DST link set dev veth$DST xdp object ../bpf/xdp_dummy.o section xdp_dummy 2>/dev/null
++ip -n $NS_DST link set dev veth$DST xdp object ../bpf/xdp_dummy.o section xdp 2>/dev/null
+ chk_gro_flag "with xdp attached - gro flag" $DST on
+ chk_gro_flag "        - peer gro flag" $SRC off
+ chk_tso_flag "        - tso flag" $SRC off


             reply	other threads:[~2022-07-12 15:58 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-12 15:58 Mike Pagano [this message]
  -- strict thread matches above, loose matches on Subject: below --
2022-08-21 19:59 [gentoo-commits] proj/linux-patches:5.18 commit in: / Mike Pagano
2022-08-21 16:54 Mike Pagano
2022-08-17 14:31 Mike Pagano
2022-08-11 12:32 Mike Pagano
2022-08-03 14:22 Alice Ferrazzi
2022-07-29 16:39 Mike Pagano
2022-07-23 11:45 Alice Ferrazzi
2022-07-22 11:11 Mike Pagano
2022-07-22 11:06 Mike Pagano
2022-07-15 10:10 Alice Ferrazzi
2022-07-15  8:59 Alice Ferrazzi
2022-07-07 17:29 Mike Pagano
2022-07-07 16:26 Mike Pagano
2022-07-02 16:12 Mike Pagano
2022-06-29 11:07 Mike Pagano
2022-06-26 21:52 Mike Pagano
2022-06-25 19:42 Mike Pagano
2022-06-22 12:53 Mike Pagano
2022-06-16 12:07 Mike Pagano
2022-06-14 17:29 Mike Pagano
2022-06-09 18:40 Mike Pagano
2022-06-09 11:25 Mike Pagano
2022-06-06 11:01 Mike Pagano
2022-05-30 21:42 Mike Pagano
2022-05-30 13:57 Mike Pagano
2022-05-24 21:02 Mike Pagano
2022-05-24 18:14 Mike Pagano
2022-05-11 17:39 Mike Pagano
2022-04-25 16:23 Mike Pagano
2022-04-25 16:15 Mike Pagano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1657641434.eca2f342ada520977a8ae1535efc2e3944602e51.mpagano@gentoo \
    --to=mpagano@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox