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.13 commit in: /
Date: Mon, 19 Jul 2021 11:15:25 +0000 (UTC)	[thread overview]
Message-ID: <1626693229.251a2869d4d1cff8f96751d70c93211e5b7a34ab.mpagano@gentoo> (raw)

commit:     251a2869d4d1cff8f96751d70c93211e5b7a34ab
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Mon Jul 19 11:13:49 2021 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Mon Jul 19 11:13:49 2021 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=251a2869

Linux patch 5.13.3

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

 0000_README             |     4 +
 1002_linux-5.13.3.patch | 12204 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 12208 insertions(+)

diff --git a/0000_README b/0000_README
index e1ba986..13b88ab 100644
--- a/0000_README
+++ b/0000_README
@@ -51,6 +51,10 @@ Patch:  1001_linux-5.13.2.patch
 From:   http://www.kernel.org
 Desc:   Linux 5.13.2
 
+Patch:  1002_linux-5.13.3.patch
+From:   http://www.kernel.org
+Desc:   Linux 5.13.3
+
 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/1002_linux-5.13.3.patch b/1002_linux-5.13.3.patch
new file mode 100644
index 0000000..c335b1f
--- /dev/null
+++ b/1002_linux-5.13.3.patch
@@ -0,0 +1,12204 @@
+diff --git a/Documentation/Makefile b/Documentation/Makefile
+index 9c42dde97671f..c3feb657b6548 100644
+--- a/Documentation/Makefile
++++ b/Documentation/Makefile
+@@ -76,7 +76,7 @@ quiet_cmd_sphinx = SPHINX  $@ --> file://$(abspath $(BUILDDIR)/$3/$4)
+ 	PYTHONDONTWRITEBYTECODE=1 \
+ 	BUILDDIR=$(abspath $(BUILDDIR)) SPHINX_CONF=$(abspath $(srctree)/$(src)/$5/$(SPHINX_CONF)) \
+ 	$(PYTHON3) $(srctree)/scripts/jobserver-exec \
+-	$(SHELL) $(srctree)/Documentation/sphinx/parallel-wrapper.sh \
++	$(CONFIG_SHELL) $(srctree)/Documentation/sphinx/parallel-wrapper.sh \
+ 	$(SPHINXBUILD) \
+ 	-b $2 \
+ 	-c $(abspath $(srctree)/$(src)) \
+diff --git a/Makefile b/Makefile
+index 31bbcc5255357..83f4212e004f1 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 5
+ PATCHLEVEL = 13
+-SUBLEVEL = 2
++SUBLEVEL = 3
+ EXTRAVERSION =
+ NAME = Opossums on Parade
+ 
+diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h
+index 57420356ce4c1..6b3daba60987e 100644
+--- a/arch/alpha/include/uapi/asm/socket.h
++++ b/arch/alpha/include/uapi/asm/socket.h
+@@ -127,6 +127,8 @@
+ #define SO_PREFER_BUSY_POLL	69
+ #define SO_BUSY_POLL_BUDGET	70
+ 
++#define SO_NETNS_COOKIE		71
++
+ #if !defined(__KERNEL__)
+ 
+ #if __BITS_PER_LONG == 64
+diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
+index 61c97d3b58c70..c995d1f4594f6 100644
+--- a/arch/arm64/include/asm/tlb.h
++++ b/arch/arm64/include/asm/tlb.h
+@@ -28,6 +28,10 @@ static void tlb_flush(struct mmu_gather *tlb);
+  */
+ static inline int tlb_get_level(struct mmu_gather *tlb)
+ {
++	/* The TTL field is only valid for the leaf entry. */
++	if (tlb->freed_tables)
++		return 0;
++
+ 	if (tlb->cleared_ptes && !(tlb->cleared_pmds ||
+ 				   tlb->cleared_puds ||
+ 				   tlb->cleared_p4ds))
+diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
+index ed51970c08e75..344e6c622efdd 100644
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -428,6 +428,8 @@ config MACH_INGENIC_SOC
+ 	select MIPS_GENERIC
+ 	select MACH_INGENIC
+ 	select SYS_SUPPORTS_ZBOOT_UART16550
++	select CPU_SUPPORTS_CPUFREQ
++	select MIPS_EXTERNAL_TIMER
+ 
+ config LANTIQ
+ 	bool "Lantiq based platforms"
+diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts
+index 8877c62609de5..3a4eaf1f3f487 100644
+--- a/arch/mips/boot/dts/ingenic/ci20.dts
++++ b/arch/mips/boot/dts/ingenic/ci20.dts
+@@ -525,10 +525,10 @@
+ 
+ &tcu {
+ 	/*
+-	 * 750 kHz for the system timer and 3 MHz for the clocksource,
++	 * 750 kHz for the system timer and clocksource,
+ 	 * use channel #0 for the system timer, #1 for the clocksource.
+ 	 */
+ 	assigned-clocks = <&tcu TCU_CLK_TIMER0>, <&tcu TCU_CLK_TIMER1>,
+ 					  <&tcu TCU_CLK_OST>;
+-	assigned-clock-rates = <750000>, <3000000>, <3000000>;
++	assigned-clock-rates = <750000>, <750000>, <3000000>;
+ };
+diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
+index 336e02b3b3cea..3d71081afc55f 100644
+--- a/arch/mips/include/asm/cpu-features.h
++++ b/arch/mips/include/asm/cpu-features.h
+@@ -64,6 +64,8 @@
+ 	((MIPS_ISA_REV >= (ge)) && (MIPS_ISA_REV < (lt)))
+ #define __isa_range_or_flag(ge, lt, flag) \
+ 	(__isa_range(ge, lt) || ((MIPS_ISA_REV < (lt)) && __isa(flag)))
++#define __isa_range_and_ase(ge, lt, ase) \
++	(__isa_range(ge, lt) && __ase(ase))
+ 
+ /*
+  * SMP assumption: Options of CPU 0 are a superset of all processors.
+@@ -421,7 +423,7 @@
+ #endif
+ 
+ #ifndef cpu_has_mipsmt
+-#define cpu_has_mipsmt		__isa_lt_and_ase(6, MIPS_ASE_MIPSMT)
++#define cpu_has_mipsmt		__isa_range_and_ase(2, 6, MIPS_ASE_MIPSMT)
+ #endif
+ 
+ #ifndef cpu_has_vp
+diff --git a/arch/mips/include/asm/hugetlb.h b/arch/mips/include/asm/hugetlb.h
+index 10e3be870df78..c2144409c0c40 100644
+--- a/arch/mips/include/asm/hugetlb.h
++++ b/arch/mips/include/asm/hugetlb.h
+@@ -46,7 +46,13 @@ static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+ static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
+ 					 unsigned long addr, pte_t *ptep)
+ {
+-	flush_tlb_page(vma, addr & huge_page_mask(hstate_vma(vma)));
++	/*
++	 * clear the huge pte entry firstly, so that the other smp threads will
++	 * not get old pte entry after finishing flush_tlb_page and before
++	 * setting new huge pte entry
++	 */
++	huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
++	flush_tlb_page(vma, addr);
+ }
+ 
+ #define __HAVE_ARCH_HUGE_PTE_NONE
+diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
+index 9c8099a6ffed1..acdf8c69220b0 100644
+--- a/arch/mips/include/asm/mipsregs.h
++++ b/arch/mips/include/asm/mipsregs.h
+@@ -2077,7 +2077,7 @@ _ASM_MACRO_0(tlbginvf, _ASM_INSN_IF_MIPS(0x4200000c)
+ ({ int __res;								\
+ 	__asm__ __volatile__(						\
+ 		".set\tpush\n\t"					\
+-		".set\tmips32r2\n\t"					\
++		".set\tmips32r5\n\t"					\
+ 		_ASM_SET_VIRT						\
+ 		"mfgc0\t%0, " #source ", %1\n\t"			\
+ 		".set\tpop"						\
+@@ -2090,7 +2090,7 @@ _ASM_MACRO_0(tlbginvf, _ASM_INSN_IF_MIPS(0x4200000c)
+ ({ unsigned long long __res;						\
+ 	__asm__ __volatile__(						\
+ 		".set\tpush\n\t"					\
+-		".set\tmips64r2\n\t"					\
++		".set\tmips64r5\n\t"					\
+ 		_ASM_SET_VIRT						\
+ 		"dmfgc0\t%0, " #source ", %1\n\t"			\
+ 		".set\tpop"						\
+@@ -2103,7 +2103,7 @@ _ASM_MACRO_0(tlbginvf, _ASM_INSN_IF_MIPS(0x4200000c)
+ do {									\
+ 	__asm__ __volatile__(						\
+ 		".set\tpush\n\t"					\
+-		".set\tmips32r2\n\t"					\
++		".set\tmips32r5\n\t"					\
+ 		_ASM_SET_VIRT						\
+ 		"mtgc0\t%z0, " #register ", %1\n\t"			\
+ 		".set\tpop"						\
+@@ -2115,7 +2115,7 @@ do {									\
+ do {									\
+ 	__asm__ __volatile__(						\
+ 		".set\tpush\n\t"					\
+-		".set\tmips64r2\n\t"					\
++		".set\tmips64r5\n\t"					\
+ 		_ASM_SET_VIRT						\
+ 		"dmtgc0\t%z0, " #register ", %1\n\t"			\
+ 		".set\tpop"						\
+diff --git a/arch/mips/include/asm/pgalloc.h b/arch/mips/include/asm/pgalloc.h
+index 8b18424b31208..d0cf997b4ba84 100644
+--- a/arch/mips/include/asm/pgalloc.h
++++ b/arch/mips/include/asm/pgalloc.h
+@@ -59,11 +59,15 @@ do {							\
+ 
+ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
+ {
+-	pmd_t *pmd;
++	pmd_t *pmd = NULL;
++	struct page *pg;
+ 
+-	pmd = (pmd_t *) __get_free_pages(GFP_KERNEL, PMD_ORDER);
+-	if (pmd)
++	pg = alloc_pages(GFP_KERNEL | __GFP_ACCOUNT, PMD_ORDER);
++	if (pg) {
++		pgtable_pmd_page_ctor(pg);
++		pmd = (pmd_t *)page_address(pg);
+ 		pmd_init((unsigned long)pmd, (unsigned long)invalid_pte_table);
++	}
+ 	return pmd;
+ }
+ 
+diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h
+index 2d949969313b6..cdf404a831b25 100644
+--- a/arch/mips/include/uapi/asm/socket.h
++++ b/arch/mips/include/uapi/asm/socket.h
+@@ -138,6 +138,8 @@
+ #define SO_PREFER_BUSY_POLL	69
+ #define SO_BUSY_POLL_BUDGET	70
+ 
++#define SO_NETNS_COOKIE		71
++
+ #if !defined(__KERNEL__)
+ 
+ #if __BITS_PER_LONG == 64
+diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
+index 0ef240adefb59..630fcb4cb30e7 100644
+--- a/arch/mips/kernel/cpu-probe.c
++++ b/arch/mips/kernel/cpu-probe.c
+@@ -1840,6 +1840,11 @@ static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu)
+ 		 */
+ 		case PRID_COMP_INGENIC_D0:
+ 			c->isa_level &= ~MIPS_CPU_ISA_M32R2;
++
++			/* FPU is not properly detected on JZ4760(B). */
++			if (c->processor_id == 0x2ed0024f)
++				c->options |= MIPS_CPU_FPU;
++
+ 			fallthrough;
+ 
+ 		/*
+diff --git a/arch/mips/loongson64/numa.c b/arch/mips/loongson64/numa.c
+index fa9b4a487a479..e8e3e48c53330 100644
+--- a/arch/mips/loongson64/numa.c
++++ b/arch/mips/loongson64/numa.c
+@@ -129,6 +129,9 @@ static void __init node_mem_init(unsigned int node)
+ 		if (node_end_pfn(0) >= (0xffffffff >> PAGE_SHIFT))
+ 			memblock_reserve((node_addrspace_offset | 0xfe000000),
+ 					 32 << 20);
++
++		/* Reserve pfn range 0~node[0]->node_start_pfn */
++		memblock_reserve(0, PAGE_SIZE * start_pfn);
+ 	}
+ }
+ 
+diff --git a/arch/mips/loongson64/reset.c b/arch/mips/loongson64/reset.c
+index c97bfdc8c9226..758d5d26aaaa2 100644
+--- a/arch/mips/loongson64/reset.c
++++ b/arch/mips/loongson64/reset.c
+@@ -126,11 +126,12 @@ static void loongson_kexec_shutdown(void)
+ 	for_each_possible_cpu(cpu)
+ 		if (!cpu_online(cpu))
+ 			cpu_device_up(get_cpu_device(cpu));
++
++	secondary_kexec_args[0] = TO_UNCAC(0x3ff01000);
+ #endif
+ 	kexec_args[0] = kexec_argc;
+ 	kexec_args[1] = fw_arg1;
+ 	kexec_args[2] = fw_arg2;
+-	secondary_kexec_args[0] = TO_UNCAC(0x3ff01000);
+ 	memcpy((void *)fw_arg1, kexec_argv, KEXEC_ARGV_SIZE);
+ 	memcpy((void *)fw_arg2, kexec_envp, KEXEC_ENVP_SIZE);
+ }
+@@ -141,7 +142,9 @@ static void loongson_crash_shutdown(struct pt_regs *regs)
+ 	kexec_args[0] = kdump_argc;
+ 	kexec_args[1] = fw_arg1;
+ 	kexec_args[2] = fw_arg2;
++#ifdef CONFIG_SMP
+ 	secondary_kexec_args[0] = TO_UNCAC(0x3ff01000);
++#endif
+ 	memcpy((void *)fw_arg1, kdump_argv, KEXEC_ARGV_SIZE);
+ 	memcpy((void *)fw_arg2, kexec_envp, KEXEC_ENVP_SIZE);
+ }
+diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h
+index f60904329bbcc..5b5351cdcb338 100644
+--- a/arch/parisc/include/uapi/asm/socket.h
++++ b/arch/parisc/include/uapi/asm/socket.h
+@@ -119,6 +119,8 @@
+ #define SO_PREFER_BUSY_POLL	0x4043
+ #define SO_BUSY_POLL_BUDGET	0x4044
+ 
++#define SO_NETNS_COOKIE		0x4045
++
+ #if !defined(__KERNEL__)
+ 
+ #if __BITS_PER_LONG == 64
+diff --git a/arch/powerpc/include/asm/barrier.h b/arch/powerpc/include/asm/barrier.h
+index 7ae29cfb06c07..f0e6872364842 100644
+--- a/arch/powerpc/include/asm/barrier.h
++++ b/arch/powerpc/include/asm/barrier.h
+@@ -46,6 +46,8 @@
+ #    define SMPWMB      eieio
+ #endif
+ 
++/* clang defines this macro for a builtin, which will not work with runtime patching */
++#undef __lwsync
+ #define __lwsync()	__asm__ __volatile__ (stringify_in_c(LWSYNC) : : :"memory")
+ #define dma_rmb()	__lwsync()
+ #define dma_wmb()	__asm__ __volatile__ (stringify_in_c(SMPWMB) : : :"memory")
+diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
+index 34f641d4a2fe9..a8d0ce85d39ad 100644
+--- a/arch/powerpc/mm/fault.c
++++ b/arch/powerpc/mm/fault.c
+@@ -199,9 +199,7 @@ static bool bad_kernel_fault(struct pt_regs *regs, unsigned long error_code,
+ {
+ 	int is_exec = TRAP(regs) == INTERRUPT_INST_STORAGE;
+ 
+-	/* NX faults set DSISR_PROTFAULT on the 8xx, DSISR_NOEXEC_OR_G on others */
+-	if (is_exec && (error_code & (DSISR_NOEXEC_OR_G | DSISR_KEYFAULT |
+-				      DSISR_PROTFAULT))) {
++	if (is_exec) {
+ 		pr_crit_ratelimited("kernel tried to execute %s page (%lx) - exploit attempt? (uid: %d)\n",
+ 				    address >= TASK_SIZE ? "exec-protected" : "user",
+ 				    address,
+diff --git a/arch/powerpc/net/bpf_jit_comp32.c b/arch/powerpc/net/bpf_jit_comp32.c
+index bbb16099e8c7f..68476780047ac 100644
+--- a/arch/powerpc/net/bpf_jit_comp32.c
++++ b/arch/powerpc/net/bpf_jit_comp32.c
+@@ -773,9 +773,17 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
+ 			break;
+ 
+ 		/*
+-		 * BPF_STX XADD (atomic_add)
++		 * BPF_STX ATOMIC (atomic ops)
+ 		 */
+-		case BPF_STX | BPF_XADD | BPF_W: /* *(u32 *)(dst + off) += src */
++		case BPF_STX | BPF_ATOMIC | BPF_W:
++			if (imm != BPF_ADD) {
++				pr_err_ratelimited("eBPF filter atomic op code %02x (@%d) unsupported\n",
++						   code, i);
++				return -ENOTSUPP;
++			}
++
++			/* *(u32 *)(dst + off) += src */
++
+ 			bpf_set_seen_register(ctx, tmp_reg);
+ 			/* Get offset into TMP_REG */
+ 			EMIT(PPC_RAW_LI(tmp_reg, off));
+@@ -789,7 +797,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
+ 			PPC_BCC_SHORT(COND_NE, (ctx->idx - 3) * 4);
+ 			break;
+ 
+-		case BPF_STX | BPF_XADD | BPF_DW: /* *(u64 *)(dst + off) += src */
++		case BPF_STX | BPF_ATOMIC | BPF_DW: /* *(u64 *)(dst + off) += src */
+ 			return -EOPNOTSUPP;
+ 
+ 		/*
+diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c
+index 5f5fe63a3d1ce..7ba0840fc3b55 100644
+--- a/arch/powerpc/platforms/powernv/vas-window.c
++++ b/arch/powerpc/platforms/powernv/vas-window.c
+@@ -1093,9 +1093,9 @@ struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop,
+ 		/*
+ 		 * Process closes window during exit. In the case of
+ 		 * multithread application, the child thread can open
+-		 * window and can exit without closing it. Expects parent
+-		 * thread to use and close the window. So do not need
+-		 * to take pid reference for parent thread.
++		 * window and can exit without closing it. so takes tgid
++		 * reference until window closed to make sure tgid is not
++		 * reused.
+ 		 */
+ 		txwin->tgid = find_get_pid(task_tgid_vnr(current));
+ 		/*
+@@ -1339,8 +1339,9 @@ int vas_win_close(struct vas_window *window)
+ 	/* if send window, drop reference to matching receive window */
+ 	if (window->tx_win) {
+ 		if (window->user_win) {
+-			/* Drop references to pid and mm */
++			/* Drop references to pid. tgid and mm */
+ 			put_pid(window->pid);
++			put_pid(window->tgid);
+ 			if (window->mm) {
+ 				mm_context_remove_vas_window(window->mm);
+ 				mmdrop(window->mm);
+diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c
+index a8304327072d3..dbdbbc2f1dc51 100644
+--- a/arch/powerpc/sysdev/xive/common.c
++++ b/arch/powerpc/sysdev/xive/common.c
+@@ -1153,11 +1153,10 @@ static int __init xive_request_ipi(void)
+ 		 * Since the HW interrupt number doesn't have any meaning,
+ 		 * simply use the node number.
+ 		 */
+-		xid->irq = irq_domain_alloc_irqs(ipi_domain, 1, node, &info);
+-		if (xid->irq < 0) {
+-			ret = xid->irq;
++		ret = irq_domain_alloc_irqs(ipi_domain, 1, node, &info);
++		if (ret < 0)
+ 			goto out_free_xive_ipis;
+-		}
++		xid->irq = ret;
+ 
+ 		snprintf(xid->name, sizeof(xid->name), "IPI-%d", node);
+ 
+diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h
+index 848a22fbac20e..92675dc380fa2 100644
+--- a/arch/sparc/include/uapi/asm/socket.h
++++ b/arch/sparc/include/uapi/asm/socket.h
+@@ -120,6 +120,8 @@
+ #define SO_PREFER_BUSY_POLL	 0x0048
+ #define SO_BUSY_POLL_BUDGET	 0x0049
+ 
++#define SO_NETNS_COOKIE          0x0050
++
+ #if !defined(__KERNEL__)
+ 
+ 
+diff --git a/block/blk-rq-qos.c b/block/blk-rq-qos.c
+index 656460636ad34..e83af7bc75919 100644
+--- a/block/blk-rq-qos.c
++++ b/block/blk-rq-qos.c
+@@ -266,8 +266,8 @@ void rq_qos_wait(struct rq_wait *rqw, void *private_data,
+ 	if (!has_sleeper && acquire_inflight_cb(rqw, private_data))
+ 		return;
+ 
+-	prepare_to_wait_exclusive(&rqw->wait, &data.wq, TASK_UNINTERRUPTIBLE);
+-	has_sleeper = !wq_has_single_sleeper(&rqw->wait);
++	has_sleeper = !prepare_to_wait_exclusive(&rqw->wait, &data.wq,
++						 TASK_UNINTERRUPTIBLE);
+ 	do {
+ 		/* The memory barrier in set_task_state saves us here. */
+ 		if (data.got_token)
+diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c
+index cb69b737cb499..56b695136977a 100644
+--- a/drivers/ata/ahci_sunxi.c
++++ b/drivers/ata/ahci_sunxi.c
+@@ -200,7 +200,7 @@ static void ahci_sunxi_start_engine(struct ata_port *ap)
+ }
+ 
+ static const struct ata_port_info ahci_sunxi_port_info = {
+-	.flags		= AHCI_FLAG_COMMON | ATA_FLAG_NCQ,
++	.flags		= AHCI_FLAG_COMMON | ATA_FLAG_NCQ | ATA_FLAG_NO_DIPM,
+ 	.pio_mask	= ATA_PIO4,
+ 	.udma_mask	= ATA_UDMA6,
+ 	.port_ops	= &ahci_platform_ops,
+diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
+index 933e3ff2ee8d1..3f2ebfb06afdf 100644
+--- a/drivers/atm/iphase.c
++++ b/drivers/atm/iphase.c
+@@ -3279,7 +3279,7 @@ static void __exit ia_module_exit(void)
+ {
+ 	pci_unregister_driver(&ia_driver);
+ 
+-        del_timer(&ia_timer);
++	del_timer_sync(&ia_timer);
+ }
+ 
+ module_init(ia_module_init);
+diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
+index 5c7e4df159b91..bc5a6ab6fa4b4 100644
+--- a/drivers/atm/nicstar.c
++++ b/drivers/atm/nicstar.c
+@@ -299,7 +299,7 @@ static void __exit nicstar_cleanup(void)
+ {
+ 	XPRINTK("nicstar: nicstar_cleanup() called.\n");
+ 
+-	del_timer(&ns_timer);
++	del_timer_sync(&ns_timer);
+ 
+ 	pci_unregister_driver(&nicstar_driver);
+ 
+@@ -527,6 +527,15 @@ static int ns_init_card(int i, struct pci_dev *pcidev)
+ 	/* Set the VPI/VCI MSb mask to zero so we can receive OAM cells */
+ 	writel(0x00000000, card->membase + VPM);
+ 
++	card->intcnt = 0;
++	if (request_irq
++	    (pcidev->irq, &ns_irq_handler, IRQF_SHARED, "nicstar", card) != 0) {
++		pr_err("nicstar%d: can't allocate IRQ %d.\n", i, pcidev->irq);
++		error = 9;
++		ns_init_card_error(card, error);
++		return error;
++	}
++
+ 	/* Initialize TSQ */
+ 	card->tsq.org = dma_alloc_coherent(&card->pcidev->dev,
+ 					   NS_TSQSIZE + NS_TSQ_ALIGNMENT,
+@@ -753,15 +762,6 @@ static int ns_init_card(int i, struct pci_dev *pcidev)
+ 
+ 	card->efbie = 1;
+ 
+-	card->intcnt = 0;
+-	if (request_irq
+-	    (pcidev->irq, &ns_irq_handler, IRQF_SHARED, "nicstar", card) != 0) {
+-		printk("nicstar%d: can't allocate IRQ %d.\n", i, pcidev->irq);
+-		error = 9;
+-		ns_init_card_error(card, error);
+-		return error;
+-	}
+-
+ 	/* Register device */
+ 	card->atmdev = atm_dev_register("nicstar", &card->pcidev->dev, &atm_ops,
+ 					-1, NULL);
+@@ -839,10 +839,12 @@ static void ns_init_card_error(ns_dev *card, int error)
+ 			dev_kfree_skb_any(hb);
+ 	}
+ 	if (error >= 12) {
+-		kfree(card->rsq.org);
++		dma_free_coherent(&card->pcidev->dev, NS_RSQSIZE + NS_RSQ_ALIGNMENT,
++				card->rsq.org, card->rsq.dma);
+ 	}
+ 	if (error >= 11) {
+-		kfree(card->tsq.org);
++		dma_free_coherent(&card->pcidev->dev, NS_TSQSIZE + NS_TSQ_ALIGNMENT,
++				card->tsq.org, card->tsq.dma);
+ 	}
+ 	if (error >= 10) {
+ 		free_irq(card->pcidev->irq, card);
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 7f6ba2c975ed4..6d23308119d16 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -270,6 +270,8 @@ static const struct usb_device_id blacklist_table[] = {
+ 						     BTUSB_WIDEBAND_SPEECH },
+ 	{ USB_DEVICE(0x0cf3, 0xe360), .driver_info = BTUSB_QCA_ROME |
+ 						     BTUSB_WIDEBAND_SPEECH },
++	{ USB_DEVICE(0x0cf3, 0xe500), .driver_info = BTUSB_QCA_ROME |
++						     BTUSB_WIDEBAND_SPEECH },
+ 	{ USB_DEVICE(0x0489, 0xe092), .driver_info = BTUSB_QCA_ROME |
+ 						     BTUSB_WIDEBAND_SPEECH },
+ 	{ USB_DEVICE(0x0489, 0xe09f), .driver_info = BTUSB_QCA_ROME |
+@@ -1749,6 +1751,13 @@ static void btusb_work(struct work_struct *work)
+ 			 * which work with WBS at all.
+ 			 */
+ 			new_alts = btusb_find_altsetting(data, 6) ? 6 : 1;
++			/* Because mSBC frames do not need to be aligned to the
++			 * SCO packet boundary. If support the Alt 3, use the
++			 * Alt 3 for HCI payload >= 60 Bytes let air packet
++			 * data satisfy 60 bytes.
++			 */
++			if (new_alts == 1 && btusb_find_altsetting(data, 3))
++				new_alts = 3;
+ 		}
+ 
+ 		if (btusb_switch_alt_setting(hdev, new_alts) < 0)
+@@ -3312,11 +3321,6 @@ static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev,
+ 	struct btmtk_wmt_hdr *hdr;
+ 	int err;
+ 
+-	/* Submit control IN URB on demand to process the WMT event */
+-	err = btusb_mtk_submit_wmt_recv_urb(hdev);
+-	if (err < 0)
+-		return err;
+-
+ 	/* Send the WMT command and wait until the WMT event returns */
+ 	hlen = sizeof(*hdr) + wmt_params->dlen;
+ 	if (hlen > 255)
+@@ -3342,6 +3346,11 @@ static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev,
+ 		goto err_free_wc;
+ 	}
+ 
++	/* Submit control IN URB on demand to process the WMT event */
++	err = btusb_mtk_submit_wmt_recv_urb(hdev);
++	if (err < 0)
++		return err;
++
+ 	/* The vendor specific WMT commands are all answered by a vendor
+ 	 * specific event and will have the Command Status or Command
+ 	 * Complete as with usual HCI command flow control.
+@@ -4062,6 +4071,11 @@ static int btusb_setup_qca_download_fw(struct hci_dev *hdev,
+ 	sent += size;
+ 	count -= size;
+ 
++	/* ep2 need time to switch from function acl to function dfu,
++	 * so we add 20ms delay here.
++	 */
++	msleep(20);
++
+ 	while (count) {
+ 		size = min_t(size_t, count, QCA_DFU_PACKET_LEN);
+ 
+@@ -4154,9 +4168,15 @@ static int btusb_setup_qca_load_nvm(struct hci_dev *hdev,
+ 	int err;
+ 
+ 	if (((ver->flag >> 8) & 0xff) == QCA_FLAG_MULTI_NVM) {
+-		snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x_%04x.bin",
+-			 le32_to_cpu(ver->rom_version),
+-			 le16_to_cpu(ver->board_id));
++		/* if boardid equal 0, use default nvm without surfix */
++		if (le16_to_cpu(ver->board_id) == 0x0) {
++			snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x.bin",
++				 le32_to_cpu(ver->rom_version));
++		} else {
++			snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x_%04x.bin",
++				le32_to_cpu(ver->rom_version),
++				le16_to_cpu(ver->board_id));
++		}
+ 	} else {
+ 		snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x.bin",
+ 			 le32_to_cpu(ver->rom_version));
+diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
+index 32c334e34d553..e4ff3b50de7f3 100644
+--- a/drivers/char/ipmi/ipmi_watchdog.c
++++ b/drivers/char/ipmi/ipmi_watchdog.c
+@@ -371,16 +371,18 @@ static int __ipmi_set_timeout(struct ipmi_smi_msg  *smi_msg,
+ 	data[0] = 0;
+ 	WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS);
+ 
+-	if ((ipmi_version_major > 1)
+-	    || ((ipmi_version_major == 1) && (ipmi_version_minor >= 5))) {
+-		/* This is an IPMI 1.5-only feature. */
+-		data[0] |= WDOG_DONT_STOP_ON_SET;
+-	} else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) {
+-		/*
+-		 * In ipmi 1.0, setting the timer stops the watchdog, we
+-		 * need to start it back up again.
+-		 */
+-		hbnow = 1;
++	if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) {
++		if ((ipmi_version_major > 1) ||
++		    ((ipmi_version_major == 1) && (ipmi_version_minor >= 5))) {
++			/* This is an IPMI 1.5-only feature. */
++			data[0] |= WDOG_DONT_STOP_ON_SET;
++		} else {
++			/*
++			 * In ipmi 1.0, setting the timer stops the watchdog, we
++			 * need to start it back up again.
++			 */
++			hbnow = 1;
++		}
+ 	}
+ 
+ 	data[1] = 0;
+diff --git a/drivers/clk/renesas/r8a77995-cpg-mssr.c b/drivers/clk/renesas/r8a77995-cpg-mssr.c
+index 9cfd00cf4e69a..81c0bc1e78af8 100644
+--- a/drivers/clk/renesas/r8a77995-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77995-cpg-mssr.c
+@@ -75,6 +75,7 @@ static const struct cpg_core_clk r8a77995_core_clks[] __initconst = {
+ 	DEF_RATE(".oco",       CLK_OCO,            8 * 1000 * 1000),
+ 
+ 	/* Core Clock Outputs */
++	DEF_FIXED("za2",       R8A77995_CLK_ZA2,   CLK_PLL0D3,     2, 1),
+ 	DEF_FIXED("z2",        R8A77995_CLK_Z2,    CLK_PLL0D3,     1, 1),
+ 	DEF_FIXED("ztr",       R8A77995_CLK_ZTR,   CLK_PLL1,       6, 1),
+ 	DEF_FIXED("zt",        R8A77995_CLK_ZT,    CLK_PLL1,       4, 1),
+diff --git a/drivers/clk/renesas/rcar-usb2-clock-sel.c b/drivers/clk/renesas/rcar-usb2-clock-sel.c
+index 34a85dc95beb8..9fb79bd794350 100644
+--- a/drivers/clk/renesas/rcar-usb2-clock-sel.c
++++ b/drivers/clk/renesas/rcar-usb2-clock-sel.c
+@@ -128,10 +128,8 @@ static int rcar_usb2_clock_sel_resume(struct device *dev)
+ static int rcar_usb2_clock_sel_remove(struct platform_device *pdev)
+ {
+ 	struct device *dev = &pdev->dev;
+-	struct usb2_clock_sel_priv *priv = platform_get_drvdata(pdev);
+ 
+ 	of_clk_del_provider(dev->of_node);
+-	clk_hw_unregister(&priv->hw);
+ 	pm_runtime_put(dev);
+ 	pm_runtime_disable(dev);
+ 
+@@ -164,9 +162,6 @@ static int rcar_usb2_clock_sel_probe(struct platform_device *pdev)
+ 	if (IS_ERR(priv->rsts))
+ 		return PTR_ERR(priv->rsts);
+ 
+-	pm_runtime_enable(dev);
+-	pm_runtime_get_sync(dev);
+-
+ 	clk = devm_clk_get(dev, "usb_extal");
+ 	if (!IS_ERR(clk) && !clk_prepare_enable(clk)) {
+ 		priv->extal = !!clk_get_rate(clk);
+@@ -183,6 +178,8 @@ static int rcar_usb2_clock_sel_probe(struct platform_device *pdev)
+ 		return -ENOENT;
+ 	}
+ 
++	pm_runtime_enable(dev);
++	pm_runtime_get_sync(dev);
+ 	platform_set_drvdata(pdev, priv);
+ 	dev_set_drvdata(dev, priv);
+ 
+@@ -190,11 +187,20 @@ static int rcar_usb2_clock_sel_probe(struct platform_device *pdev)
+ 	init.ops = &usb2_clock_sel_clock_ops;
+ 	priv->hw.init = &init;
+ 
+-	clk = clk_register(NULL, &priv->hw);
+-	if (IS_ERR(clk))
+-		return PTR_ERR(clk);
++	ret = devm_clk_hw_register(NULL, &priv->hw);
++	if (ret)
++		goto pm_put;
++
++	ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &priv->hw);
++	if (ret)
++		goto pm_put;
++
++	return 0;
+ 
+-	return of_clk_add_hw_provider(np, of_clk_hw_simple_get, &priv->hw);
++pm_put:
++	pm_runtime_put(dev);
++	pm_runtime_disable(dev);
++	return ret;
+ }
+ 
+ static const struct dev_pm_ops rcar_usb2_clock_sel_pm_ops = {
+diff --git a/drivers/clk/tegra/clk-periph-gate.c b/drivers/clk/tegra/clk-periph-gate.c
+index 4b31beefc9fc2..dc3f92678407b 100644
+--- a/drivers/clk/tegra/clk-periph-gate.c
++++ b/drivers/clk/tegra/clk-periph-gate.c
+@@ -48,18 +48,9 @@ static int clk_periph_is_enabled(struct clk_hw *hw)
+ 	return state;
+ }
+ 
+-static int clk_periph_enable(struct clk_hw *hw)
++static void clk_periph_enable_locked(struct clk_hw *hw)
+ {
+ 	struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw);
+-	unsigned long flags = 0;
+-
+-	spin_lock_irqsave(&periph_ref_lock, flags);
+-
+-	gate->enable_refcnt[gate->clk_num]++;
+-	if (gate->enable_refcnt[gate->clk_num] > 1) {
+-		spin_unlock_irqrestore(&periph_ref_lock, flags);
+-		return 0;
+-	}
+ 
+ 	write_enb_set(periph_clk_to_bit(gate), gate);
+ 	udelay(2);
+@@ -78,6 +69,32 @@ static int clk_periph_enable(struct clk_hw *hw)
+ 		udelay(1);
+ 		writel_relaxed(0, gate->clk_base + LVL2_CLK_GATE_OVRE);
+ 	}
++}
++
++static void clk_periph_disable_locked(struct clk_hw *hw)
++{
++	struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw);
++
++	/*
++	 * If peripheral is in the APB bus then read the APB bus to
++	 * flush the write operation in apb bus. This will avoid the
++	 * peripheral access after disabling clock
++	 */
++	if (gate->flags & TEGRA_PERIPH_ON_APB)
++		tegra_read_chipid();
++
++	write_enb_clr(periph_clk_to_bit(gate), gate);
++}
++
++static int clk_periph_enable(struct clk_hw *hw)
++{
++	struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw);
++	unsigned long flags = 0;
++
++	spin_lock_irqsave(&periph_ref_lock, flags);
++
++	if (!gate->enable_refcnt[gate->clk_num]++)
++		clk_periph_enable_locked(hw);
+ 
+ 	spin_unlock_irqrestore(&periph_ref_lock, flags);
+ 
+@@ -91,21 +108,28 @@ static void clk_periph_disable(struct clk_hw *hw)
+ 
+ 	spin_lock_irqsave(&periph_ref_lock, flags);
+ 
+-	gate->enable_refcnt[gate->clk_num]--;
+-	if (gate->enable_refcnt[gate->clk_num] > 0) {
+-		spin_unlock_irqrestore(&periph_ref_lock, flags);
+-		return;
+-	}
++	WARN_ON(!gate->enable_refcnt[gate->clk_num]);
++
++	if (--gate->enable_refcnt[gate->clk_num] == 0)
++		clk_periph_disable_locked(hw);
++
++	spin_unlock_irqrestore(&periph_ref_lock, flags);
++}
++
++static void clk_periph_disable_unused(struct clk_hw *hw)
++{
++	struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw);
++	unsigned long flags = 0;
++
++	spin_lock_irqsave(&periph_ref_lock, flags);
+ 
+ 	/*
+-	 * If peripheral is in the APB bus then read the APB bus to
+-	 * flush the write operation in apb bus. This will avoid the
+-	 * peripheral access after disabling clock
++	 * Some clocks are duplicated and some of them are marked as critical,
++	 * like fuse and fuse_burn for example, thus the enable_refcnt will
++	 * be non-zero here if the "unused" duplicate is disabled by CCF.
+ 	 */
+-	if (gate->flags & TEGRA_PERIPH_ON_APB)
+-		tegra_read_chipid();
+-
+-	write_enb_clr(periph_clk_to_bit(gate), gate);
++	if (!gate->enable_refcnt[gate->clk_num])
++		clk_periph_disable_locked(hw);
+ 
+ 	spin_unlock_irqrestore(&periph_ref_lock, flags);
+ }
+@@ -114,6 +138,7 @@ const struct clk_ops tegra_clk_periph_gate_ops = {
+ 	.is_enabled = clk_periph_is_enabled,
+ 	.enable = clk_periph_enable,
+ 	.disable = clk_periph_disable,
++	.disable_unused = clk_periph_disable_unused,
+ };
+ 
+ struct clk *tegra_clk_register_periph_gate(const char *name,
+@@ -148,9 +173,6 @@ struct clk *tegra_clk_register_periph_gate(const char *name,
+ 	gate->enable_refcnt = enable_refcnt;
+ 	gate->regs = pregs;
+ 
+-	if (read_enb(gate) & periph_clk_to_bit(gate))
+-		enable_refcnt[clk_num]++;
+-
+ 	/* Data in .init is copied by clk_register(), so stack variable OK */
+ 	gate->hw.init = &init;
+ 
+diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c
+index 67620c7ecd9ee..79ca3aa072b70 100644
+--- a/drivers/clk/tegra/clk-periph.c
++++ b/drivers/clk/tegra/clk-periph.c
+@@ -100,6 +100,15 @@ static void clk_periph_disable(struct clk_hw *hw)
+ 	gate_ops->disable(gate_hw);
+ }
+ 
++static void clk_periph_disable_unused(struct clk_hw *hw)
++{
++	struct tegra_clk_periph *periph = to_clk_periph(hw);
++	const struct clk_ops *gate_ops = periph->gate_ops;
++	struct clk_hw *gate_hw = &periph->gate.hw;
++
++	gate_ops->disable_unused(gate_hw);
++}
++
+ static void clk_periph_restore_context(struct clk_hw *hw)
+ {
+ 	struct tegra_clk_periph *periph = to_clk_periph(hw);
+@@ -126,6 +135,7 @@ const struct clk_ops tegra_clk_periph_ops = {
+ 	.is_enabled = clk_periph_is_enabled,
+ 	.enable = clk_periph_enable,
+ 	.disable = clk_periph_disable,
++	.disable_unused = clk_periph_disable_unused,
+ 	.restore_context = clk_periph_restore_context,
+ };
+ 
+@@ -135,6 +145,7 @@ static const struct clk_ops tegra_clk_periph_nodiv_ops = {
+ 	.is_enabled = clk_periph_is_enabled,
+ 	.enable = clk_periph_enable,
+ 	.disable = clk_periph_disable,
++	.disable_unused = clk_periph_disable_unused,
+ 	.restore_context = clk_periph_restore_context,
+ };
+ 
+diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
+index 0193cebe8c5a3..823a567f2adc2 100644
+--- a/drivers/clk/tegra/clk-pll.c
++++ b/drivers/clk/tegra/clk-pll.c
+@@ -1131,7 +1131,8 @@ static int clk_pllu_enable(struct clk_hw *hw)
+ 	if (pll->lock)
+ 		spin_lock_irqsave(pll->lock, flags);
+ 
+-	_clk_pll_enable(hw);
++	if (!clk_pll_is_enabled(hw))
++		_clk_pll_enable(hw);
+ 
+ 	ret = clk_pll_wait_for_lock(pll);
+ 	if (ret < 0)
+@@ -1748,15 +1749,13 @@ static int clk_pllu_tegra114_enable(struct clk_hw *hw)
+ 		return -EINVAL;
+ 	}
+ 
+-	if (clk_pll_is_enabled(hw))
+-		return 0;
+-
+ 	input_rate = clk_hw_get_rate(__clk_get_hw(osc));
+ 
+ 	if (pll->lock)
+ 		spin_lock_irqsave(pll->lock, flags);
+ 
+-	_clk_pll_enable(hw);
++	if (!clk_pll_is_enabled(hw))
++		_clk_pll_enable(hw);
+ 
+ 	ret = clk_pll_wait_for_lock(pll);
+ 	if (ret < 0)
+diff --git a/drivers/clk/tegra/clk-tegra124-emc.c b/drivers/clk/tegra/clk-tegra124-emc.c
+index bdf6f4a516176..74c1d894cca86 100644
+--- a/drivers/clk/tegra/clk-tegra124-emc.c
++++ b/drivers/clk/tegra/clk-tegra124-emc.c
+@@ -249,8 +249,10 @@ static int emc_set_timing(struct tegra_clk_emc *tegra,
+ 	div = timing->parent_rate / (timing->rate / 2) - 2;
+ 
+ 	err = tegra->prepare_timing_change(emc, timing->rate);
+-	if (err)
++	if (err) {
++		clk_disable_unprepare(timing->parent);
+ 		return err;
++	}
+ 
+ 	spin_lock_irqsave(tegra->lock, flags);
+ 
+diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
+index fe1a82627d570..5b412b51c21bf 100644
+--- a/drivers/clocksource/arm_arch_timer.c
++++ b/drivers/clocksource/arm_arch_timer.c
+@@ -365,7 +365,7 @@ static u64 notrace arm64_858921_read_cntvct_el0(void)
+ 	do {								\
+ 		_val = read_sysreg(reg);				\
+ 		_retries--;						\
+-	} while (((_val + 1) & GENMASK(9, 0)) <= 1 && _retries);	\
++	} while (((_val + 1) & GENMASK(8, 0)) <= 1 && _retries);	\
+ 									\
+ 	WARN_ON_ONCE(!_retries);					\
+ 	_val;								\
+diff --git a/drivers/extcon/extcon-intel-mrfld.c b/drivers/extcon/extcon-intel-mrfld.c
+index f47016fb28a84..cd1a5f230077c 100644
+--- a/drivers/extcon/extcon-intel-mrfld.c
++++ b/drivers/extcon/extcon-intel-mrfld.c
+@@ -197,6 +197,7 @@ static int mrfld_extcon_probe(struct platform_device *pdev)
+ 	struct intel_soc_pmic *pmic = dev_get_drvdata(dev->parent);
+ 	struct regmap *regmap = pmic->regmap;
+ 	struct mrfld_extcon_data *data;
++	unsigned int status;
+ 	unsigned int id;
+ 	int irq, ret;
+ 
+@@ -244,6 +245,14 @@ static int mrfld_extcon_probe(struct platform_device *pdev)
+ 	/* Get initial state */
+ 	mrfld_extcon_role_detect(data);
+ 
++	/*
++	 * Cached status value is used for cable detection, see comments
++	 * in mrfld_extcon_cable_detect(), we need to sync cached value
++	 * with a real state of the hardware.
++	 */
++	regmap_read(regmap, BCOVE_SCHGRIRQ1, &status);
++	data->status = status;
++
+ 	mrfld_extcon_clear(data, BCOVE_MIRQLVL1, BCOVE_LVL1_CHGR);
+ 	mrfld_extcon_clear(data, BCOVE_MCHGRIRQ1, BCOVE_CHGRIRQ_ALL);
+ 
+diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
+index 0078260fbabea..172c751a4f6c2 100644
+--- a/drivers/firmware/qemu_fw_cfg.c
++++ b/drivers/firmware/qemu_fw_cfg.c
+@@ -299,15 +299,13 @@ static int fw_cfg_do_platform_probe(struct platform_device *pdev)
+ 	return 0;
+ }
+ 
+-static ssize_t fw_cfg_showrev(struct kobject *k, struct attribute *a, char *buf)
++static ssize_t fw_cfg_showrev(struct kobject *k, struct kobj_attribute *a,
++			      char *buf)
+ {
+ 	return sprintf(buf, "%u\n", fw_cfg_rev);
+ }
+ 
+-static const struct {
+-	struct attribute attr;
+-	ssize_t (*show)(struct kobject *k, struct attribute *a, char *buf);
+-} fw_cfg_rev_attr = {
++static const struct kobj_attribute fw_cfg_rev_attr = {
+ 	.attr = { .name = "rev", .mode = S_IRUSR },
+ 	.show = fw_cfg_showrev,
+ };
+diff --git a/drivers/fpga/stratix10-soc.c b/drivers/fpga/stratix10-soc.c
+index 657a70c5fc996..9e34bbbce26e2 100644
+--- a/drivers/fpga/stratix10-soc.c
++++ b/drivers/fpga/stratix10-soc.c
+@@ -454,6 +454,7 @@ static int s10_remove(struct platform_device *pdev)
+ 	struct s10_priv *priv = mgr->priv;
+ 
+ 	fpga_mgr_unregister(mgr);
++	fpga_mgr_free(mgr);
+ 	stratix10_svc_free_channel(priv->chan);
+ 
+ 	return 0;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+index 7d4118c8128a5..5e69b5b50a196 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+@@ -50,12 +50,6 @@ static struct {
+ 	spinlock_t mem_limit_lock;
+ } kfd_mem_limit;
+ 
+-/* Struct used for amdgpu_amdkfd_bo_validate */
+-struct amdgpu_vm_parser {
+-	uint32_t        domain;
+-	bool            wait;
+-};
+-
+ static const char * const domain_bit_to_string[] = {
+ 		"CPU",
+ 		"GTT",
+@@ -346,11 +340,9 @@ validate_fail:
+ 	return ret;
+ }
+ 
+-static int amdgpu_amdkfd_validate(void *param, struct amdgpu_bo *bo)
++static int amdgpu_amdkfd_validate_vm_bo(void *_unused, struct amdgpu_bo *bo)
+ {
+-	struct amdgpu_vm_parser *p = param;
+-
+-	return amdgpu_amdkfd_bo_validate(bo, p->domain, p->wait);
++	return amdgpu_amdkfd_bo_validate(bo, bo->allowed_domains, false);
+ }
+ 
+ /* vm_validate_pt_pd_bos - Validate page table and directory BOs
+@@ -364,20 +356,15 @@ static int vm_validate_pt_pd_bos(struct amdgpu_vm *vm)
+ {
+ 	struct amdgpu_bo *pd = vm->root.base.bo;
+ 	struct amdgpu_device *adev = amdgpu_ttm_adev(pd->tbo.bdev);
+-	struct amdgpu_vm_parser param;
+ 	int ret;
+ 
+-	param.domain = AMDGPU_GEM_DOMAIN_VRAM;
+-	param.wait = false;
+-
+-	ret = amdgpu_vm_validate_pt_bos(adev, vm, amdgpu_amdkfd_validate,
+-					&param);
++	ret = amdgpu_vm_validate_pt_bos(adev, vm, amdgpu_amdkfd_validate_vm_bo, NULL);
+ 	if (ret) {
+ 		pr_err("failed to validate PT BOs\n");
+ 		return ret;
+ 	}
+ 
+-	ret = amdgpu_amdkfd_validate(&param, pd);
++	ret = amdgpu_amdkfd_validate_vm_bo(NULL, pd);
+ 	if (ret) {
+ 		pr_err("failed to validate PD\n");
+ 		return ret;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index 57ec108b59720..d83f2ee150b86 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -2856,7 +2856,7 @@ static int amdgpu_device_ip_reinit_early_sriov(struct amdgpu_device *adev)
+ 		AMD_IP_BLOCK_TYPE_IH,
+ 	};
+ 
+-	for (i = 0; i < ARRAY_SIZE(ip_order); i++) {
++	for (i = 0; i < adev->num_ip_blocks; i++) {
+ 		int j;
+ 		struct amdgpu_ip_block *block;
+ 
+@@ -3181,8 +3181,8 @@ static int amdgpu_device_get_job_timeout_settings(struct amdgpu_device *adev)
+ 	int ret = 0;
+ 
+ 	/*
+-	 * By default timeout for non compute jobs is 10000.
+-	 * And there is no timeout enforced on compute jobs.
++	 * By default timeout for non compute jobs is 10000
++	 * and 60000 for compute jobs.
+ 	 * In SR-IOV or passthrough mode, timeout for compute
+ 	 * jobs are 60000 by default.
+ 	 */
+@@ -3191,10 +3191,8 @@ static int amdgpu_device_get_job_timeout_settings(struct amdgpu_device *adev)
+ 	if (amdgpu_sriov_vf(adev))
+ 		adev->compute_timeout = amdgpu_sriov_is_pp_one_vf(adev) ?
+ 					msecs_to_jiffies(60000) : msecs_to_jiffies(10000);
+-	else if (amdgpu_passthrough(adev))
+-		adev->compute_timeout =  msecs_to_jiffies(60000);
+ 	else
+-		adev->compute_timeout = MAX_SCHEDULE_TIMEOUT;
++		adev->compute_timeout =  msecs_to_jiffies(60000);
+ 
+ 	if (strnlen(input, AMDGPU_MAX_TIMEOUT_PARAM_LENGTH)) {
+ 		while ((timeout_setting = strsep(&input, ",")) &&
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+index f93883db2b467..c576902ccf8e6 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+@@ -287,9 +287,9 @@ module_param_named(msi, amdgpu_msi, int, 0444);
+  *   for SDMA and Video.
+  *
+  * By default(with no lockup_timeout settings), the timeout for all non-compute(GFX, SDMA and Video)
+- * jobs is 10000. And there is no timeout enforced on compute jobs.
++ * jobs is 10000. The timeout for compute is 60000.
+  */
+-MODULE_PARM_DESC(lockup_timeout, "GPU lockup timeout in ms (default: for bare metal 10000 for non-compute jobs and infinity timeout for compute jobs; "
++MODULE_PARM_DESC(lockup_timeout, "GPU lockup timeout in ms (default: for bare metal 10000 for non-compute jobs and 60000 for compute jobs; "
+ 		"for passthrough or sriov, 10000 for all jobs."
+ 		" 0: keep default value. negative: infinity timeout), "
+ 		"format: for bare metal [Non-Compute] or [GFX,Compute,SDMA,Video]; "
+@@ -1179,6 +1179,7 @@ static const struct pci_device_id pciidlist[] = {
+ 	{0x1002, 0x73E0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_DIMGREY_CAVEFISH},
+ 	{0x1002, 0x73E1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_DIMGREY_CAVEFISH},
+ 	{0x1002, 0x73E2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_DIMGREY_CAVEFISH},
++	{0x1002, 0x73E3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_DIMGREY_CAVEFISH},
+ 	{0x1002, 0x73FF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_DIMGREY_CAVEFISH},
+ 
+ 	/* Aldebaran */
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+index a2fe2dac32c16..98906a43fda3d 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+@@ -130,7 +130,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
+ 	struct amdgpu_device *adev = ring->adev;
+ 	struct amdgpu_ib *ib = &ibs[0];
+ 	struct dma_fence *tmp = NULL;
+-	bool skip_preamble, need_ctx_switch;
++	bool need_ctx_switch;
+ 	unsigned patch_offset = ~0;
+ 	struct amdgpu_vm *vm;
+ 	uint64_t fence_ctx;
+@@ -227,7 +227,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
+ 	if (need_ctx_switch)
+ 		status |= AMDGPU_HAVE_CTX_SWITCH;
+ 
+-	skip_preamble = ring->current_ctx == fence_ctx;
+ 	if (job && ring->funcs->emit_cntxcntl) {
+ 		status |= job->preamble_status;
+ 		status |= job->preemption_status;
+@@ -245,14 +244,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
+ 	for (i = 0; i < num_ibs; ++i) {
+ 		ib = &ibs[i];
+ 
+-		/* drop preamble IBs if we don't have a context switch */
+-		if ((ib->flags & AMDGPU_IB_FLAG_PREAMBLE) &&
+-		    skip_preamble &&
+-		    !(status & AMDGPU_PREAMBLE_IB_PRESENT_FIRST) &&
+-		    !amdgpu_mcbp &&
+-		    !amdgpu_sriov_vf(adev)) /* for SRIOV preemption, Preamble CE ib must be inserted anyway */
+-			continue;
+-
+ 		if (job && ring->funcs->emit_frame_cntl) {
+ 			if (secure != !!(ib->flags & AMDGPU_IB_FLAGS_SECURE)) {
+ 				amdgpu_ring_emit_frame_cntl(ring, false, secure);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
+index 25ee53545837d..45295dce5c3ec 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
+@@ -93,6 +93,8 @@ struct amdgpu_nbio_funcs {
+ 	void (*enable_aspm)(struct amdgpu_device *adev,
+ 			    bool enable);
+ 	void (*program_aspm)(struct amdgpu_device *adev);
++	void (*apply_lc_spc_mode_wa)(struct amdgpu_device *adev);
++	void (*apply_l1_link_width_reconfig_wa)(struct amdgpu_device *adev);
+ };
+ 
+ struct amdgpu_nbio {
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+index f9434bc2f9b21..db00de33caa32 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+@@ -1246,6 +1246,9 @@ int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer,
+ 
+ 	BUG_ON(bo->tbo.type == ttm_bo_type_kernel);
+ 	ubo = to_amdgpu_bo_user(bo);
++	if (metadata_size)
++		*metadata_size = ubo->metadata_size;
++
+ 	if (buffer) {
+ 		if (buffer_size < ubo->metadata_size)
+ 			return -EINVAL;
+@@ -1254,8 +1257,6 @@ int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer,
+ 			memcpy(buffer, ubo->metadata, ubo->metadata_size);
+ 	}
+ 
+-	if (metadata_size)
+-		*metadata_size = ubo->metadata_size;
+ 	if (flags)
+ 		*flags = ubo->metadata_flags;
+ 
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h
+index bbcccf53080dd..e5a75fb788ddb 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h
+@@ -21,6 +21,11 @@
+ #ifndef __AMDGPU_UMC_H__
+ #define __AMDGPU_UMC_H__
+ 
++/*
++ * (addr / 256) * 4096, the higher 26 bits in ErrorAddr
++ * is the index of 4KB block
++ */
++#define ADDR_OF_4KB_BLOCK(addr)			(((addr) & ~0xffULL) << 4)
+ /*
+  * (addr / 256) * 8192, the higher 26 bits in ErrorAddr
+  * is the index of 8KB block
+diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
+index 05ddec7ba7e2e..754b11dea6f04 100644
+--- a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
++++ b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
+@@ -51,6 +51,8 @@
+ #define mmBIF_MMSCH1_DOORBELL_RANGE		0x01d8
+ #define mmBIF_MMSCH1_DOORBELL_RANGE_BASE_IDX	2
+ 
++#define smnPCIE_LC_LINK_WIDTH_CNTL		0x11140288
++
+ static void nbio_v2_3_remap_hdp_registers(struct amdgpu_device *adev)
+ {
+ 	WREG32_SOC15(NBIO, 0, mmREMAP_HDP_MEM_FLUSH_CNTL,
+@@ -463,6 +465,43 @@ static void nbio_v2_3_program_aspm(struct amdgpu_device *adev)
+ 		WREG32_PCIE(smnPCIE_LC_CNTL3, data);
+ }
+ 
++static void nbio_v2_3_apply_lc_spc_mode_wa(struct amdgpu_device *adev)
++{
++	uint32_t reg_data = 0;
++	uint32_t link_width = 0;
++
++	if (!((adev->asic_type >= CHIP_NAVI10) &&
++	     (adev->asic_type <= CHIP_NAVI12)))
++		return;
++
++	reg_data = RREG32_PCIE(smnPCIE_LC_LINK_WIDTH_CNTL);
++	link_width = (reg_data & PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK)
++		>> PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT;
++
++	/*
++	 * Program PCIE_LC_CNTL6.LC_SPC_MODE_8GT to 0x2 (4 symbols per clock data)
++	 * if link_width is 0x3 (x4)
++	 */
++	if (0x3 == link_width) {
++		reg_data = RREG32_PCIE(smnPCIE_LC_CNTL6);
++		reg_data &= ~PCIE_LC_CNTL6__LC_SPC_MODE_8GT_MASK;
++		reg_data |= (0x2 << PCIE_LC_CNTL6__LC_SPC_MODE_8GT__SHIFT);
++		WREG32_PCIE(smnPCIE_LC_CNTL6, reg_data);
++	}
++}
++
++static void nbio_v2_3_apply_l1_link_width_reconfig_wa(struct amdgpu_device *adev)
++{
++	uint32_t reg_data = 0;
++
++	if (adev->asic_type != CHIP_NAVI10)
++		return;
++
++	reg_data = RREG32_PCIE(smnPCIE_LC_LINK_WIDTH_CNTL);
++	reg_data |= PCIE_LC_LINK_WIDTH_CNTL__LC_L1_RECONFIG_EN_MASK;
++	WREG32_PCIE(smnPCIE_LC_LINK_WIDTH_CNTL, reg_data);
++}
++
+ const struct amdgpu_nbio_funcs nbio_v2_3_funcs = {
+ 	.get_hdp_flush_req_offset = nbio_v2_3_get_hdp_flush_req_offset,
+ 	.get_hdp_flush_done_offset = nbio_v2_3_get_hdp_flush_done_offset,
+@@ -484,4 +523,6 @@ const struct amdgpu_nbio_funcs nbio_v2_3_funcs = {
+ 	.remap_hdp_registers = nbio_v2_3_remap_hdp_registers,
+ 	.enable_aspm = nbio_v2_3_enable_aspm,
+ 	.program_aspm =  nbio_v2_3_program_aspm,
++	.apply_lc_spc_mode_wa = nbio_v2_3_apply_lc_spc_mode_wa,
++	.apply_l1_link_width_reconfig_wa = nbio_v2_3_apply_l1_link_width_reconfig_wa,
+ };
+diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c
+index d290ca0b06da8..d73a4e9842d2e 100644
+--- a/drivers/gpu/drm/amd/amdgpu/nv.c
++++ b/drivers/gpu/drm/amd/amdgpu/nv.c
+@@ -1194,6 +1194,12 @@ static int nv_common_hw_init(void *handle)
+ {
+ 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ 
++	if (adev->nbio.funcs->apply_lc_spc_mode_wa)
++		adev->nbio.funcs->apply_lc_spc_mode_wa(adev);
++
++	if (adev->nbio.funcs->apply_l1_link_width_reconfig_wa)
++		adev->nbio.funcs->apply_l1_link_width_reconfig_wa(adev);
++
+ 	/* enable pcie gen2/3 link */
+ 	nv_pcie_gen3_enable(adev);
+ 	/* enable aspm */
+diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+index 5715be6770ecc..3bb996ac8d26a 100644
+--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+@@ -144,7 +144,7 @@ static const struct soc15_reg_golden golden_settings_sdma_4_1[] = {
+ 	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC0_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+ 	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_IB_CNTL, 0x800f0111, 0x00000100),
+ 	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+-	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0),
++	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003e0),
+ 	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_WATERMK, 0xfc000000, 0x00000000)
+ };
+ 
+@@ -288,7 +288,7 @@ static const struct soc15_reg_golden golden_settings_sdma_4_3[] = {
+ 	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_POWER_CNTL, 0x003fff07, 0x40000051),
+ 	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC0_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+ 	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+-	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0),
++	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003e0),
+ 	SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_WATERMK, 0xfc000000, 0x03fbe1fe)
+ };
+ 
+diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
+index 240596b25fe4e..9ab23947a1515 100644
+--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
+@@ -145,9 +145,6 @@ static int sdma_v5_2_init_microcode(struct amdgpu_device *adev)
+ 	struct amdgpu_firmware_info *info = NULL;
+ 	const struct common_firmware_header *header = NULL;
+ 
+-	if (amdgpu_sriov_vf(adev) && (adev->asic_type == CHIP_SIENNA_CICHLID))
+-		return 0;
+-
+ 	DRM_DEBUG("\n");
+ 
+ 	switch (adev->asic_type) {
+@@ -182,6 +179,9 @@ static int sdma_v5_2_init_microcode(struct amdgpu_device *adev)
+ 		       (void *)&adev->sdma.instance[0],
+ 		       sizeof(struct amdgpu_sdma_instance));
+ 
++	if (amdgpu_sriov_vf(adev) && (adev->asic_type == CHIP_SIENNA_CICHLID))
++		return 0;
++
+ 	DRM_DEBUG("psp_load == '%s'\n",
+ 		  adev->firmware.load_type == AMDGPU_FW_LOAD_PSP ? "true" : "false");
+ 
+diff --git a/drivers/gpu/drm/amd/amdgpu/umc_v8_7.c b/drivers/gpu/drm/amd/amdgpu/umc_v8_7.c
+index 89d20adfa001a..af59a35788e3e 100644
+--- a/drivers/gpu/drm/amd/amdgpu/umc_v8_7.c
++++ b/drivers/gpu/drm/amd/amdgpu/umc_v8_7.c
+@@ -234,7 +234,7 @@ static void umc_v8_7_query_error_address(struct amdgpu_device *adev,
+ 		err_addr &= ~((0x1ULL << lsb) - 1);
+ 
+ 		/* translate umc channel address to soc pa, 3 parts are included */
+-		retired_page = ADDR_OF_8KB_BLOCK(err_addr) |
++		retired_page = ADDR_OF_4KB_BLOCK(err_addr) |
+ 				ADDR_OF_256B_BLOCK(channel_index) |
+ 				OFFSET_IN_256B_BLOCK(err_addr);
+ 
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+index d3eaa1549bd78..f0bad74af2305 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+@@ -486,9 +486,6 @@ static int destroy_queue_nocpsch_locked(struct device_queue_manager *dqm,
+ 	if (retval == -ETIME)
+ 		qpd->reset_wavefronts = true;
+ 
+-
+-	mqd_mgr->free_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);
+-
+ 	list_del(&q->list);
+ 	if (list_empty(&qpd->queues_list)) {
+ 		if (qpd->reset_wavefronts) {
+@@ -523,6 +520,8 @@ static int destroy_queue_nocpsch(struct device_queue_manager *dqm,
+ 	int retval;
+ 	uint64_t sdma_val = 0;
+ 	struct kfd_process_device *pdd = qpd_to_pdd(qpd);
++	struct mqd_manager *mqd_mgr =
++		dqm->mqd_mgrs[get_mqd_type_from_queue_type(q->properties.type)];
+ 
+ 	/* Get the SDMA queue stats */
+ 	if ((q->properties.type == KFD_QUEUE_TYPE_SDMA) ||
+@@ -540,6 +539,8 @@ static int destroy_queue_nocpsch(struct device_queue_manager *dqm,
+ 		pdd->sdma_past_activity_counter += sdma_val;
+ 	dqm_unlock(dqm);
+ 
++	mqd_mgr->free_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);
++
+ 	return retval;
+ }
+ 
+@@ -1629,7 +1630,7 @@ out:
+ static int process_termination_nocpsch(struct device_queue_manager *dqm,
+ 		struct qcm_process_device *qpd)
+ {
+-	struct queue *q, *next;
++	struct queue *q;
+ 	struct device_process_node *cur, *next_dpn;
+ 	int retval = 0;
+ 	bool found = false;
+@@ -1637,12 +1638,19 @@ static int process_termination_nocpsch(struct device_queue_manager *dqm,
+ 	dqm_lock(dqm);
+ 
+ 	/* Clear all user mode queues */
+-	list_for_each_entry_safe(q, next, &qpd->queues_list, list) {
++	while (!list_empty(&qpd->queues_list)) {
++		struct mqd_manager *mqd_mgr;
+ 		int ret;
+ 
++		q = list_first_entry(&qpd->queues_list, struct queue, list);
++		mqd_mgr = dqm->mqd_mgrs[get_mqd_type_from_queue_type(
++				q->properties.type)];
+ 		ret = destroy_queue_nocpsch_locked(dqm, qpd, q);
+ 		if (ret)
+ 			retval = ret;
++		dqm_unlock(dqm);
++		mqd_mgr->free_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);
++		dqm_lock(dqm);
+ 	}
+ 
+ 	/* Unregister process */
+@@ -1674,36 +1682,34 @@ static int get_wave_state(struct device_queue_manager *dqm,
+ 			  u32 *save_area_used_size)
+ {
+ 	struct mqd_manager *mqd_mgr;
+-	int r;
+ 
+ 	dqm_lock(dqm);
+ 
+-	if (q->properties.type != KFD_QUEUE_TYPE_COMPUTE ||
+-	    q->properties.is_active || !q->device->cwsr_enabled) {
+-		r = -EINVAL;
+-		goto dqm_unlock;
+-	}
+-
+ 	mqd_mgr = dqm->mqd_mgrs[KFD_MQD_TYPE_CP];
+ 
+-	if (!mqd_mgr->get_wave_state) {
+-		r = -EINVAL;
+-		goto dqm_unlock;
++	if (q->properties.type != KFD_QUEUE_TYPE_COMPUTE ||
++	    q->properties.is_active || !q->device->cwsr_enabled ||
++	    !mqd_mgr->get_wave_state) {
++		dqm_unlock(dqm);
++		return -EINVAL;
+ 	}
+ 
+-	r = mqd_mgr->get_wave_state(mqd_mgr, q->mqd, ctl_stack,
+-			ctl_stack_used_size, save_area_used_size);
+-
+-dqm_unlock:
+ 	dqm_unlock(dqm);
+-	return r;
++
++	/*
++	 * get_wave_state is outside the dqm lock to prevent circular locking
++	 * and the queue should be protected against destruction by the process
++	 * lock.
++	 */
++	return mqd_mgr->get_wave_state(mqd_mgr, q->mqd, ctl_stack,
++			ctl_stack_used_size, save_area_used_size);
+ }
+ 
+ static int process_termination_cpsch(struct device_queue_manager *dqm,
+ 		struct qcm_process_device *qpd)
+ {
+ 	int retval;
+-	struct queue *q, *next;
++	struct queue *q;
+ 	struct kernel_queue *kq, *kq_next;
+ 	struct mqd_manager *mqd_mgr;
+ 	struct device_process_node *cur, *next_dpn;
+@@ -1760,24 +1766,26 @@ static int process_termination_cpsch(struct device_queue_manager *dqm,
+ 		qpd->reset_wavefronts = false;
+ 	}
+ 
+-	dqm_unlock(dqm);
+-
+-	/* Outside the DQM lock because under the DQM lock we can't do
+-	 * reclaim or take other locks that others hold while reclaiming.
+-	 */
+-	if (found)
+-		kfd_dec_compute_active(dqm->dev);
+-
+ 	/* Lastly, free mqd resources.
+ 	 * Do free_mqd() after dqm_unlock to avoid circular locking.
+ 	 */
+-	list_for_each_entry_safe(q, next, &qpd->queues_list, list) {
++	while (!list_empty(&qpd->queues_list)) {
++		q = list_first_entry(&qpd->queues_list, struct queue, list);
+ 		mqd_mgr = dqm->mqd_mgrs[get_mqd_type_from_queue_type(
+ 				q->properties.type)];
+ 		list_del(&q->list);
+ 		qpd->queue_count--;
++		dqm_unlock(dqm);
+ 		mqd_mgr->free_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);
++		dqm_lock(dqm);
+ 	}
++	dqm_unlock(dqm);
++
++	/* Outside the DQM lock because under the DQM lock we can't do
++	 * reclaim or take other locks that others hold while reclaiming.
++	 */
++	if (found)
++		kfd_dec_compute_active(dqm->dev);
+ 
+ 	return retval;
+ }
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 2b2d7b9f26f16..eeaae1cf2bc2b 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -4032,6 +4032,23 @@ static int fill_dc_scaling_info(const struct drm_plane_state *state,
+ 	scaling_info->src_rect.x = state->src_x >> 16;
+ 	scaling_info->src_rect.y = state->src_y >> 16;
+ 
++	/*
++	 * For reasons we don't (yet) fully understand a non-zero
++	 * src_y coordinate into an NV12 buffer can cause a
++	 * system hang. To avoid hangs (and maybe be overly cautious)
++	 * let's reject both non-zero src_x and src_y.
++	 *
++	 * We currently know of only one use-case to reproduce a
++	 * scenario with non-zero src_x and src_y for NV12, which
++	 * is to gesture the YouTube Android app into full screen
++	 * on ChromeOS.
++	 */
++	if (state->fb &&
++	    state->fb->format->format == DRM_FORMAT_NV12 &&
++	    (scaling_info->src_rect.x != 0 ||
++	     scaling_info->src_rect.y != 0))
++		return -EINVAL;
++
+ 	/*
+ 	 * For reasons we don't (yet) fully understand a non-zero
+ 	 * src_y coordinate into an NV12 buffer can cause a
+@@ -9481,7 +9498,8 @@ skip_modeset:
+ 	BUG_ON(dm_new_crtc_state->stream == NULL);
+ 
+ 	/* Scaling or underscan settings */
+-	if (is_scaling_state_different(dm_old_conn_state, dm_new_conn_state))
++	if (is_scaling_state_different(dm_old_conn_state, dm_new_conn_state) ||
++				drm_atomic_crtc_needs_modeset(new_crtc_state))
+ 		update_stream_scaling_settings(
+ 			&new_crtc_state->mode, dm_new_conn_state, dm_new_crtc_state->stream);
+ 
+@@ -10048,6 +10066,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
+ 			dm_old_crtc_state->dsc_force_changed == false)
+ 			continue;
+ 
++		ret = amdgpu_dm_verify_lut_sizes(new_crtc_state);
++		if (ret)
++			goto fail;
++
+ 		if (!new_crtc_state->enable)
+ 			continue;
+ 
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+index b2f2ccfc20bbe..c8e5bbbb8bceb 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+@@ -591,6 +591,7 @@ void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);
+ #define MAX_COLOR_LEGACY_LUT_ENTRIES 256
+ 
+ void amdgpu_dm_init_color_mod(void);
++int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state);
+ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc);
+ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
+ 				      struct dc_plane_state *dc_plane_state);
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+index 157fe4efbb599..a022e5bb30a5c 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+@@ -284,6 +284,37 @@ static int __set_input_tf(struct dc_transfer_func *func,
+ 	return res ? 0 : -ENOMEM;
+ }
+ 
++/**
++ * Verifies that the Degamma and Gamma LUTs attached to the |crtc_state| are of
++ * the expected size.
++ * Returns 0 on success.
++ */
++int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state)
++{
++	const struct drm_color_lut *lut = NULL;
++	uint32_t size = 0;
++
++	lut = __extract_blob_lut(crtc_state->degamma_lut, &size);
++	if (lut && size != MAX_COLOR_LUT_ENTRIES) {
++		DRM_DEBUG_DRIVER(
++			"Invalid Degamma LUT size. Should be %u but got %u.\n",
++			MAX_COLOR_LUT_ENTRIES, size);
++		return -EINVAL;
++	}
++
++	lut = __extract_blob_lut(crtc_state->gamma_lut, &size);
++	if (lut && size != MAX_COLOR_LUT_ENTRIES &&
++	    size != MAX_COLOR_LEGACY_LUT_ENTRIES) {
++		DRM_DEBUG_DRIVER(
++			"Invalid Gamma LUT size. Should be %u (or %u for legacy) but got %u.\n",
++			MAX_COLOR_LUT_ENTRIES, MAX_COLOR_LEGACY_LUT_ENTRIES,
++			size);
++		return -EINVAL;
++	}
++
++	return 0;
++}
++
+ /**
+  * amdgpu_dm_update_crtc_color_mgmt: Maps DRM color management to DC stream.
+  * @crtc: amdgpu_dm crtc state
+@@ -317,14 +348,12 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
+ 	bool is_legacy;
+ 	int r;
+ 
+-	degamma_lut = __extract_blob_lut(crtc->base.degamma_lut, &degamma_size);
+-	if (degamma_lut && degamma_size != MAX_COLOR_LUT_ENTRIES)
+-		return -EINVAL;
++	r = amdgpu_dm_verify_lut_sizes(&crtc->base);
++	if (r)
++		return r;
+ 
++	degamma_lut = __extract_blob_lut(crtc->base.degamma_lut, &degamma_size);
+ 	regamma_lut = __extract_blob_lut(crtc->base.gamma_lut, &regamma_size);
+-	if (regamma_lut && regamma_size != MAX_COLOR_LUT_ENTRIES &&
+-	    regamma_size != MAX_COLOR_LEGACY_LUT_ENTRIES)
+-		return -EINVAL;
+ 
+ 	has_degamma =
+ 		degamma_lut && !__is_lut_linear(degamma_lut, degamma_size);
+diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+index d79f4fe06c47e..4812a72f8aadc 100644
+--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+@@ -2131,7 +2131,7 @@ static enum bp_result get_integrated_info_v2_1(
+ 		info_v2_1->edp1_info.edp_pwr_down_bloff_to_vary_bloff;
+ 	info->edp1_info.edp_panel_bpc =
+ 		info_v2_1->edp1_info.edp_panel_bpc;
+-	info->edp1_info.edp_bootup_bl_level =
++	info->edp1_info.edp_bootup_bl_level = info_v2_1->edp1_info.edp_bootup_bl_level;
+ 
+ 	info->edp2_info.edp_backlight_pwm_hz =
+ 	le16_to_cpu(info_v2_1->edp2_info.edp_backlight_pwm_hz);
+diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
+index a06e86853bb96..75ba86f951f84 100644
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
+@@ -128,7 +128,7 @@ void rn_update_clocks(struct clk_mgr *clk_mgr_base,
+ 	struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
+ 	struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk;
+ 	struct dc *dc = clk_mgr_base->ctx->dc;
+-	int display_count, i;
++	int display_count;
+ 	bool update_dppclk = false;
+ 	bool update_dispclk = false;
+ 	bool dpp_clock_lowered = false;
+@@ -210,14 +210,6 @@ void rn_update_clocks(struct clk_mgr *clk_mgr_base,
+ 				clk_mgr_base->clks.dppclk_khz,
+ 				safe_to_lower);
+ 
+-		for (i = 0; i < context->stream_count; i++) {
+-			if (context->streams[i]->signal == SIGNAL_TYPE_EDP &&
+-				context->streams[i]->apply_seamless_boot_optimization) {
+-				dc_wait_for_vblank(dc, context->streams[i]);
+-				break;
+-			}
+-		}
+-
+ 		clk_mgr_base->clks.actual_dppclk_khz =
+ 				rn_vbios_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
+ 
+@@ -842,6 +834,7 @@ static struct wm_table lpddr4_wm_table_rn = {
+ 		},
+ 	}
+ };
++
+ static unsigned int find_socclk_for_voltage(struct dpm_clocks *clock_table, unsigned int voltage)
+ {
+ 	int i;
+@@ -854,6 +847,7 @@ static unsigned int find_socclk_for_voltage(struct dpm_clocks *clock_table, unsi
+ 	ASSERT(0);
+ 	return 0;
+ }
++
+ static unsigned int find_dcfclk_for_voltage(struct dpm_clocks *clock_table, unsigned int voltage)
+ {
+ 	int i;
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index 4713f09bcbf18..a869702d77af5 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -3219,19 +3219,6 @@ void dc_link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink)
+ 	}
+ }
+ 
+-void dc_wait_for_vblank(struct dc *dc, struct dc_stream_state *stream)
+-{
+-	int i;
+-
+-	for (i = 0; i < dc->res_pool->pipe_count; i++)
+-		if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream) {
+-			struct timing_generator *tg =
+-				dc->current_state->res_ctx.pipe_ctx[i].stream_res.tg;
+-			tg->funcs->wait_for_state(tg, CRTC_STATE_VBLANK);
+-			break;
+-		}
+-}
+-
+ void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info)
+ {
+ 	info->displayClock				= (unsigned int)state->bw_ctx.bw.dcn.clk.dispclk_khz;
+@@ -3287,7 +3274,7 @@ void dc_allow_idle_optimizations(struct dc *dc, bool allow)
+ 	if (dc->debug.disable_idle_power_optimizations)
+ 		return;
+ 
+-	if (dc->clk_mgr->funcs->is_smu_present)
++	if (dc->clk_mgr != NULL && dc->clk_mgr->funcs->is_smu_present)
+ 		if (!dc->clk_mgr->funcs->is_smu_present(dc->clk_mgr))
+ 			return;
+ 
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+index 72bd7bc681a81..ae6830ff1cf7d 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+@@ -1784,6 +1784,8 @@ static void set_dp_mst_mode(struct dc_link *link, bool mst_enable)
+ 		link->type = dc_connection_single;
+ 		link->local_sink = link->remote_sinks[0];
+ 		link->local_sink->sink_signal = SIGNAL_TYPE_DISPLAY_PORT;
++		dc_sink_retain(link->local_sink);
++		dm_helpers_dp_mst_stop_top_mgr(link->ctx, link);
+ 	} else if (mst_enable == true &&
+ 			link->type == dc_connection_single &&
+ 			link->remote_sinks[0] != NULL) {
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+index 8cb937c046aa0..3b1068a090951 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+@@ -695,124 +695,23 @@ static void calculate_split_count_and_index(struct pipe_ctx *pipe_ctx, int *spli
+ 	}
+ }
+ 
+-static void calculate_viewport(struct pipe_ctx *pipe_ctx)
++/*
++ * This is a preliminary vp size calculation to allow us to check taps support.
++ * The result is completely overridden afterwards.
++ */
++static void calculate_viewport_size(struct pipe_ctx *pipe_ctx)
+ {
+-	const struct dc_plane_state *plane_state = pipe_ctx->plane_state;
+-	const struct dc_stream_state *stream = pipe_ctx->stream;
+ 	struct scaler_data *data = &pipe_ctx->plane_res.scl_data;
+-	struct rect surf_src = plane_state->src_rect;
+-	struct rect clip, dest;
+-	int vpc_div = (data->format == PIXEL_FORMAT_420BPP8
+-			|| data->format == PIXEL_FORMAT_420BPP10) ? 2 : 1;
+-	int split_count = 0;
+-	int split_idx = 0;
+-	bool orthogonal_rotation, flip_y_start, flip_x_start;
+-
+-	calculate_split_count_and_index(pipe_ctx, &split_count, &split_idx);
+ 
+-	if (stream->view_format == VIEW_3D_FORMAT_SIDE_BY_SIDE ||
+-		stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM) {
+-		split_count = 0;
+-		split_idx = 0;
+-	}
+-
+-	/* The actual clip is an intersection between stream
+-	 * source and surface clip
+-	 */
+-	dest = plane_state->dst_rect;
+-	clip.x = stream->src.x > plane_state->clip_rect.x ?
+-			stream->src.x : plane_state->clip_rect.x;
+-
+-	clip.width = stream->src.x + stream->src.width <
+-			plane_state->clip_rect.x + plane_state->clip_rect.width ?
+-			stream->src.x + stream->src.width - clip.x :
+-			plane_state->clip_rect.x + plane_state->clip_rect.width - clip.x ;
+-
+-	clip.y = stream->src.y > plane_state->clip_rect.y ?
+-			stream->src.y : plane_state->clip_rect.y;
+-
+-	clip.height = stream->src.y + stream->src.height <
+-			plane_state->clip_rect.y + plane_state->clip_rect.height ?
+-			stream->src.y + stream->src.height - clip.y :
+-			plane_state->clip_rect.y + plane_state->clip_rect.height - clip.y ;
+-
+-	/*
+-	 * Need to calculate how scan origin is shifted in vp space
+-	 * to correctly rotate clip and dst
+-	 */
+-	get_vp_scan_direction(
+-			plane_state->rotation,
+-			plane_state->horizontal_mirror,
+-			&orthogonal_rotation,
+-			&flip_y_start,
+-			&flip_x_start);
+-
+-	if (orthogonal_rotation) {
+-		swap(clip.x, clip.y);
+-		swap(clip.width, clip.height);
+-		swap(dest.x, dest.y);
+-		swap(dest.width, dest.height);
+-	}
+-	if (flip_x_start) {
+-		clip.x = dest.x + dest.width - clip.x - clip.width;
+-		dest.x = 0;
+-	}
+-	if (flip_y_start) {
+-		clip.y = dest.y + dest.height - clip.y - clip.height;
+-		dest.y = 0;
+-	}
+-
+-	/* offset = surf_src.ofs + (clip.ofs - surface->dst_rect.ofs) * scl_ratio
+-	 * num_pixels = clip.num_pix * scl_ratio
+-	 */
+-	data->viewport.x = surf_src.x + (clip.x - dest.x) * surf_src.width / dest.width;
+-	data->viewport.width = clip.width * surf_src.width / dest.width;
+-
+-	data->viewport.y = surf_src.y + (clip.y - dest.y) * surf_src.height / dest.height;
+-	data->viewport.height = clip.height * surf_src.height / dest.height;
+-
+-	/* Handle split */
+-	if (split_count) {
+-		/* extra pixels in the division remainder need to go to pipes after
+-		 * the extra pixel index minus one(epimo) defined here as:
+-		 */
+-		int epimo = 0;
+-
+-		if (orthogonal_rotation) {
+-			if (flip_y_start)
+-				split_idx = split_count - split_idx;
+-
+-			epimo = split_count - data->viewport.height % (split_count + 1);
+-
+-			data->viewport.y += (data->viewport.height / (split_count + 1)) * split_idx;
+-			if (split_idx > epimo)
+-				data->viewport.y += split_idx - epimo - 1;
+-			data->viewport.height = data->viewport.height / (split_count + 1) + (split_idx > epimo ? 1 : 0);
+-		} else {
+-			if (flip_x_start)
+-				split_idx = split_count - split_idx;
+-
+-			epimo = split_count - data->viewport.width % (split_count + 1);
+-
+-			data->viewport.x += (data->viewport.width / (split_count + 1)) * split_idx;
+-			if (split_idx > epimo)
+-				data->viewport.x += split_idx - epimo - 1;
+-			data->viewport.width = data->viewport.width / (split_count + 1) + (split_idx > epimo ? 1 : 0);
+-		}
++	data->viewport.width = dc_fixpt_ceil(dc_fixpt_mul_int(data->ratios.horz, data->recout.width));
++	data->viewport.height = dc_fixpt_ceil(dc_fixpt_mul_int(data->ratios.vert, data->recout.height));
++	data->viewport_c.width = dc_fixpt_ceil(dc_fixpt_mul_int(data->ratios.horz_c, data->recout.width));
++	data->viewport_c.height = dc_fixpt_ceil(dc_fixpt_mul_int(data->ratios.vert_c, data->recout.height));
++	if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_90 ||
++			pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270) {
++		swap(data->viewport.width, data->viewport.height);
++		swap(data->viewport_c.width, data->viewport_c.height);
+ 	}
+-
+-	/* Round down, compensate in init */
+-	data->viewport_c.x = data->viewport.x / vpc_div;
+-	data->viewport_c.y = data->viewport.y / vpc_div;
+-	data->inits.h_c = (data->viewport.x % vpc_div) != 0 ? dc_fixpt_half : dc_fixpt_zero;
+-	data->inits.v_c = (data->viewport.y % vpc_div) != 0 ? dc_fixpt_half : dc_fixpt_zero;
+-
+-	/* Round up, assume original video size always even dimensions */
+-	data->viewport_c.width = (data->viewport.width + vpc_div - 1) / vpc_div;
+-	data->viewport_c.height = (data->viewport.height + vpc_div - 1) / vpc_div;
+-
+-	data->viewport_unadjusted = data->viewport;
+-	data->viewport_c_unadjusted = data->viewport_c;
+ }
+ 
+ static void calculate_recout(struct pipe_ctx *pipe_ctx)
+@@ -821,26 +720,21 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx)
+ 	const struct dc_stream_state *stream = pipe_ctx->stream;
+ 	struct scaler_data *data = &pipe_ctx->plane_res.scl_data;
+ 	struct rect surf_clip = plane_state->clip_rect;
+-	bool pri_split_tb = pipe_ctx->bottom_pipe &&
+-			pipe_ctx->bottom_pipe->plane_state == pipe_ctx->plane_state &&
+-			stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM;
+-	bool sec_split_tb = pipe_ctx->top_pipe &&
+-			pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state &&
+-			stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM;
+-	int split_count = 0;
+-	int split_idx = 0;
++	bool split_tb = stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM;
++	int split_count, split_idx;
+ 
+ 	calculate_split_count_and_index(pipe_ctx, &split_count, &split_idx);
++	if (stream->view_format == VIEW_3D_FORMAT_SIDE_BY_SIDE)
++		split_idx = 0;
+ 
+ 	/*
+ 	 * Only the leftmost ODM pipe should be offset by a nonzero distance
+ 	 */
+-	if (!pipe_ctx->prev_odm_pipe) {
++	if (!pipe_ctx->prev_odm_pipe || split_idx == split_count) {
+ 		data->recout.x = stream->dst.x;
+ 		if (stream->src.x < surf_clip.x)
+ 			data->recout.x += (surf_clip.x - stream->src.x) * stream->dst.width
+ 						/ stream->src.width;
+-
+ 	} else
+ 		data->recout.x = 0;
+ 
+@@ -861,26 +755,36 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx)
+ 	if (data->recout.height + data->recout.y > stream->dst.y + stream->dst.height)
+ 		data->recout.height = stream->dst.y + stream->dst.height - data->recout.y;
+ 
+-	/* Handle h & v split, handle rotation using viewport */
+-	if (sec_split_tb) {
+-		data->recout.y += data->recout.height / 2;
+-		/* Floor primary pipe, ceil 2ndary pipe */
+-		data->recout.height = (data->recout.height + 1) / 2;
+-	} else if (pri_split_tb)
++	/* Handle h & v split */
++	if (split_tb) {
++		ASSERT(data->recout.height % 2 == 0);
+ 		data->recout.height /= 2;
+-	else if (split_count) {
+-		/* extra pixels in the division remainder need to go to pipes after
+-		 * the extra pixel index minus one(epimo) defined here as:
+-		 */
+-		int epimo = split_count - data->recout.width % (split_count + 1);
+-
+-		/*no recout offset due to odm */
++	} else if (split_count) {
+ 		if (!pipe_ctx->next_odm_pipe && !pipe_ctx->prev_odm_pipe) {
++			/* extra pixels in the division remainder need to go to pipes after
++			 * the extra pixel index minus one(epimo) defined here as:
++			 */
++			int epimo = split_count - data->recout.width % (split_count + 1);
++
+ 			data->recout.x += (data->recout.width / (split_count + 1)) * split_idx;
+ 			if (split_idx > epimo)
+ 				data->recout.x += split_idx - epimo - 1;
++			ASSERT(stream->view_format != VIEW_3D_FORMAT_SIDE_BY_SIDE || data->recout.width % 2 == 0);
++			data->recout.width = data->recout.width / (split_count + 1) + (split_idx > epimo ? 1 : 0);
++		} else {
++			/* odm */
++			if (split_idx == split_count) {
++				/* rightmost pipe is the remainder recout */
++				data->recout.width -= data->h_active * split_count - data->recout.x;
++
++				/* ODM combine cases with MPO we can get negative widths */
++				if (data->recout.width < 0)
++					data->recout.width = 0;
++
++				data->recout.x = 0;
++			} else
++				data->recout.width = data->h_active - data->recout.x;
+ 		}
+-		data->recout.width = data->recout.width / (split_count + 1) + (split_idx > epimo ? 1 : 0);
+ 	}
+ }
+ 
+@@ -934,9 +838,15 @@ static void calculate_scaling_ratios(struct pipe_ctx *pipe_ctx)
+ 			pipe_ctx->plane_res.scl_data.ratios.vert_c, 19);
+ }
+ 
+-static inline void adjust_vp_and_init_for_seamless_clip(
++
++/*
++ * We completely calculate vp offset, size and inits here based entirely on scaling
++ * ratios and recout for pixel perfect pipe combine.
++ */
++static void calculate_init_and_vp(
+ 		bool flip_scan_dir,
+-		int recout_skip,
++		int recout_offset_within_recout_full,
++		int recout_size,
+ 		int src_size,
+ 		int taps,
+ 		struct fixed31_32 ratio,
+@@ -944,91 +854,87 @@ static inline void adjust_vp_and_init_for_seamless_clip(
+ 		int *vp_offset,
+ 		int *vp_size)
+ {
+-	if (!flip_scan_dir) {
+-		/* Adjust for viewport end clip-off */
+-		if ((*vp_offset + *vp_size) < src_size) {
+-			int vp_clip = src_size - *vp_size - *vp_offset;
+-			int int_part = dc_fixpt_floor(dc_fixpt_sub(*init, ratio));
+-
+-			int_part = int_part > 0 ? int_part : 0;
+-			*vp_size += int_part < vp_clip ? int_part : vp_clip;
+-		}
+-
+-		/* Adjust for non-0 viewport offset */
+-		if (*vp_offset) {
+-			int int_part;
+-
+-			*init = dc_fixpt_add(*init, dc_fixpt_mul_int(ratio, recout_skip));
+-			int_part = dc_fixpt_floor(*init) - *vp_offset;
+-			if (int_part < taps) {
+-				int int_adj = *vp_offset >= (taps - int_part) ?
+-							(taps - int_part) : *vp_offset;
+-				*vp_offset -= int_adj;
+-				*vp_size += int_adj;
+-				int_part += int_adj;
+-			} else if (int_part > taps) {
+-				*vp_offset += int_part - taps;
+-				*vp_size -= int_part - taps;
+-				int_part = taps;
+-			}
+-			init->value &= 0xffffffff;
+-			*init = dc_fixpt_add_int(*init, int_part);
+-		}
+-	} else {
+-		/* Adjust for non-0 viewport offset */
+-		if (*vp_offset) {
+-			int int_part = dc_fixpt_floor(dc_fixpt_sub(*init, ratio));
+-
+-			int_part = int_part > 0 ? int_part : 0;
+-			*vp_size += int_part < *vp_offset ? int_part : *vp_offset;
+-			*vp_offset -= int_part < *vp_offset ? int_part : *vp_offset;
+-		}
++	struct fixed31_32 temp;
++	int int_part;
+ 
+-		/* Adjust for viewport end clip-off */
+-		if ((*vp_offset + *vp_size) < src_size) {
+-			int int_part;
+-			int end_offset = src_size - *vp_offset - *vp_size;
+-
+-			/*
+-			 * this is init if vp had no offset, keep in mind this is from the
+-			 * right side of vp due to scan direction
+-			 */
+-			*init = dc_fixpt_add(*init, dc_fixpt_mul_int(ratio, recout_skip));
+-			/*
+-			 * this is the difference between first pixel of viewport available to read
+-			 * and init position, takning into account scan direction
+-			 */
+-			int_part = dc_fixpt_floor(*init) - end_offset;
+-			if (int_part < taps) {
+-				int int_adj = end_offset >= (taps - int_part) ?
+-							(taps - int_part) : end_offset;
+-				*vp_size += int_adj;
+-				int_part += int_adj;
+-			} else if (int_part > taps) {
+-				*vp_size += int_part - taps;
+-				int_part = taps;
+-			}
+-			init->value &= 0xffffffff;
+-			*init = dc_fixpt_add_int(*init, int_part);
+-		}
++	/*
++	 * First of the taps starts sampling pixel number <init_int_part> corresponding to recout
++	 * pixel 1. Next recout pixel samples int part of <init + scaling ratio> and so on.
++	 * All following calculations are based on this logic.
++	 *
++	 * Init calculated according to formula:
++	 * 	init = (scaling_ratio + number_of_taps + 1) / 2
++	 * 	init_bot = init + scaling_ratio
++	 * 	to get pixel perfect combine add the fraction from calculating vp offset
++	 */
++	temp = dc_fixpt_mul_int(ratio, recout_offset_within_recout_full);
++	*vp_offset = dc_fixpt_floor(temp);
++	temp.value &= 0xffffffff;
++	*init = dc_fixpt_truncate(dc_fixpt_add(dc_fixpt_div_int(
++			dc_fixpt_add_int(ratio, taps + 1), 2), temp), 19);
++	/*
++	 * If viewport has non 0 offset and there are more taps than covered by init then
++	 * we should decrease the offset and increase init so we are never sampling
++	 * outside of viewport.
++	 */
++	int_part = dc_fixpt_floor(*init);
++	if (int_part < taps) {
++		int_part = taps - int_part;
++		if (int_part > *vp_offset)
++			int_part = *vp_offset;
++		*vp_offset -= int_part;
++		*init = dc_fixpt_add_int(*init, int_part);
+ 	}
++	/*
++	 * If taps are sampling outside of viewport at end of recout and there are more pixels
++	 * available in the surface we should increase the viewport size, regardless set vp to
++	 * only what is used.
++	 */
++	temp = dc_fixpt_add(*init, dc_fixpt_mul_int(ratio, recout_size - 1));
++	*vp_size = dc_fixpt_floor(temp);
++	if (*vp_size + *vp_offset > src_size)
++		*vp_size = src_size - *vp_offset;
++
++	/* We did all the math assuming we are scanning same direction as display does,
++	 * however mirror/rotation changes how vp scans vs how it is offset. If scan direction
++	 * is flipped we simply need to calculate offset from the other side of plane.
++	 * Note that outside of viewport all scaling hardware works in recout space.
++	 */
++	if (flip_scan_dir)
++		*vp_offset = src_size - *vp_offset - *vp_size;
+ }
+ 
+-static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx)
++static void calculate_inits_and_viewports(struct pipe_ctx *pipe_ctx)
+ {
+ 	const struct dc_plane_state *plane_state = pipe_ctx->plane_state;
+ 	const struct dc_stream_state *stream = pipe_ctx->stream;
+-	struct pipe_ctx *odm_pipe = pipe_ctx;
+ 	struct scaler_data *data = &pipe_ctx->plane_res.scl_data;
+-	struct rect src = pipe_ctx->plane_state->src_rect;
+-	int recout_skip_h, recout_skip_v, surf_size_h, surf_size_v;
++	struct rect src = plane_state->src_rect;
+ 	int vpc_div = (data->format == PIXEL_FORMAT_420BPP8
+-			|| data->format == PIXEL_FORMAT_420BPP10) ? 2 : 1;
++				|| data->format == PIXEL_FORMAT_420BPP10) ? 2 : 1;
++	int split_count, split_idx, ro_lb, ro_tb, recout_full_x, recout_full_y;
+ 	bool orthogonal_rotation, flip_vert_scan_dir, flip_horz_scan_dir;
+-	int odm_idx = 0;
+ 
++	calculate_split_count_and_index(pipe_ctx, &split_count, &split_idx);
+ 	/*
+-	 * Need to calculate the scan direction for viewport to make adjustments
++	 * recout full is what the recout would have been if we didnt clip
++	 * the source plane at all. We only care about left(ro_lb) and top(ro_tb)
++	 * offsets of recout within recout full because those are the directions
++	 * we scan from and therefore the only ones that affect inits.
++	 */
++	recout_full_x = stream->dst.x + (plane_state->dst_rect.x - stream->src.x)
++			* stream->dst.width / stream->src.width;
++	recout_full_y = stream->dst.y + (plane_state->dst_rect.y - stream->src.y)
++			* stream->dst.height / stream->src.height;
++	if (pipe_ctx->prev_odm_pipe && split_idx)
++		ro_lb = data->h_active * split_idx - recout_full_x;
++	else
++		ro_lb = data->recout.x - recout_full_x;
++	ro_tb = data->recout.y - recout_full_y;
++	ASSERT(ro_lb >= 0 && ro_tb >= 0);
++
++	/*
++	 * Work in recout rotation since that requires less transformations
+ 	 */
+ 	get_vp_scan_direction(
+ 			plane_state->rotation,
+@@ -1037,145 +943,62 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx)
+ 			&flip_vert_scan_dir,
+ 			&flip_horz_scan_dir);
+ 
+-	/* Calculate src rect rotation adjusted to recout space */
+-	surf_size_h = src.x + src.width;
+-	surf_size_v = src.y + src.height;
+-	if (flip_horz_scan_dir)
+-		src.x = 0;
+-	if (flip_vert_scan_dir)
+-		src.y = 0;
+ 	if (orthogonal_rotation) {
+-		swap(src.x, src.y);
+ 		swap(src.width, src.height);
++		swap(flip_vert_scan_dir, flip_horz_scan_dir);
+ 	}
+ 
+-	/*modified recout_skip_h calculation due to odm having no recout offset*/
+-	while (odm_pipe->prev_odm_pipe) {
+-		odm_idx++;
+-		odm_pipe = odm_pipe->prev_odm_pipe;
+-	}
+-	/*odm_pipe is the leftmost pipe in the ODM group*/
+-	recout_skip_h = odm_idx * data->recout.width;
+-
+-	/* Recout matching initial vp offset = recout_offset - (stream dst offset +
+-	 *			((surf dst offset - stream src offset) * 1/ stream scaling ratio)
+-	 *			- (surf surf_src offset * 1/ full scl ratio))
+-	 */
+-	recout_skip_h += odm_pipe->plane_res.scl_data.recout.x
+-				- (stream->dst.x + (plane_state->dst_rect.x - stream->src.x)
+-					* stream->dst.width / stream->src.width -
+-					src.x * plane_state->dst_rect.width / src.width
+-					* stream->dst.width / stream->src.width);
+-
+-
+-	recout_skip_v = data->recout.y - (stream->dst.y + (plane_state->dst_rect.y - stream->src.y)
+-					* stream->dst.height / stream->src.height -
+-					src.y * plane_state->dst_rect.height / src.height
+-					* stream->dst.height / stream->src.height);
+-	if (orthogonal_rotation)
+-		swap(recout_skip_h, recout_skip_v);
+-	/*
+-	 * Init calculated according to formula:
+-	 * 	init = (scaling_ratio + number_of_taps + 1) / 2
+-	 * 	init_bot = init + scaling_ratio
+-	 * 	init_c = init + truncated_vp_c_offset(from calculate viewport)
+-	 */
+-	data->inits.h = dc_fixpt_truncate(dc_fixpt_div_int(
+-			dc_fixpt_add_int(data->ratios.horz, data->taps.h_taps + 1), 2), 19);
+-
+-	data->inits.h_c = dc_fixpt_truncate(dc_fixpt_add(data->inits.h_c, dc_fixpt_div_int(
+-			dc_fixpt_add_int(data->ratios.horz_c, data->taps.h_taps_c + 1), 2)), 19);
+-
+-	data->inits.v = dc_fixpt_truncate(dc_fixpt_div_int(
+-			dc_fixpt_add_int(data->ratios.vert, data->taps.v_taps + 1), 2), 19);
+-
+-	data->inits.v_c = dc_fixpt_truncate(dc_fixpt_add(data->inits.v_c, dc_fixpt_div_int(
+-			dc_fixpt_add_int(data->ratios.vert_c, data->taps.v_taps_c + 1), 2)), 19);
+-
+-	/*
+-	 * Taps, inits and scaling ratios are in recout space need to rotate
+-	 * to viewport rotation before adjustment
+-	 */
+-	adjust_vp_and_init_for_seamless_clip(
++	calculate_init_and_vp(
+ 			flip_horz_scan_dir,
+-			recout_skip_h,
+-			surf_size_h,
+-			orthogonal_rotation ? data->taps.v_taps : data->taps.h_taps,
+-			orthogonal_rotation ? data->ratios.vert : data->ratios.horz,
+-			orthogonal_rotation ? &data->inits.v : &data->inits.h,
++			ro_lb,
++			data->recout.width,
++			src.width,
++			data->taps.h_taps,
++			data->ratios.horz,
++			&data->inits.h,
+ 			&data->viewport.x,
+ 			&data->viewport.width);
+-	adjust_vp_and_init_for_seamless_clip(
++	calculate_init_and_vp(
+ 			flip_horz_scan_dir,
+-			recout_skip_h,
+-			surf_size_h / vpc_div,
+-			orthogonal_rotation ? data->taps.v_taps_c : data->taps.h_taps_c,
+-			orthogonal_rotation ? data->ratios.vert_c : data->ratios.horz_c,
+-			orthogonal_rotation ? &data->inits.v_c : &data->inits.h_c,
++			ro_lb,
++			data->recout.width,
++			src.width / vpc_div,
++			data->taps.h_taps_c,
++			data->ratios.horz_c,
++			&data->inits.h_c,
+ 			&data->viewport_c.x,
+ 			&data->viewport_c.width);
+-	adjust_vp_and_init_for_seamless_clip(
++	calculate_init_and_vp(
+ 			flip_vert_scan_dir,
+-			recout_skip_v,
+-			surf_size_v,
+-			orthogonal_rotation ? data->taps.h_taps : data->taps.v_taps,
+-			orthogonal_rotation ? data->ratios.horz : data->ratios.vert,
+-			orthogonal_rotation ? &data->inits.h : &data->inits.v,
++			ro_tb,
++			data->recout.height,
++			src.height,
++			data->taps.v_taps,
++			data->ratios.vert,
++			&data->inits.v,
+ 			&data->viewport.y,
+ 			&data->viewport.height);
+-	adjust_vp_and_init_for_seamless_clip(
++	calculate_init_and_vp(
+ 			flip_vert_scan_dir,
+-			recout_skip_v,
+-			surf_size_v / vpc_div,
+-			orthogonal_rotation ? data->taps.h_taps_c : data->taps.v_taps_c,
+-			orthogonal_rotation ? data->ratios.horz_c : data->ratios.vert_c,
+-			orthogonal_rotation ? &data->inits.h_c : &data->inits.v_c,
++			ro_tb,
++			data->recout.height,
++			src.height / vpc_div,
++			data->taps.v_taps_c,
++			data->ratios.vert_c,
++			&data->inits.v_c,
+ 			&data->viewport_c.y,
+ 			&data->viewport_c.height);
+-
+-	/* Interlaced inits based on final vert inits */
+-	data->inits.v_bot = dc_fixpt_add(data->inits.v, data->ratios.vert);
+-	data->inits.v_c_bot = dc_fixpt_add(data->inits.v_c, data->ratios.vert_c);
+-
+-}
+-
+-/*
+- * When handling 270 rotation in mixed SLS mode, we have
+- * stream->timing.h_border_left that is non zero.  If we are doing
+- * pipe-splitting, this h_border_left value gets added to recout.x and when it
+- * calls calculate_inits_and_adj_vp() and
+- * adjust_vp_and_init_for_seamless_clip(), it can cause viewport.height for a
+- * pipe to be incorrect.
+- *
+- * To fix this, instead of using stream->timing.h_border_left, we can use
+- * stream->dst.x to represent the border instead.  So we will set h_border_left
+- * to 0 and shift the appropriate amount in stream->dst.x.  We will then
+- * perform all calculations in resource_build_scaling_params() based on this
+- * and then restore the h_border_left and stream->dst.x to their original
+- * values.
+- *
+- * shift_border_left_to_dst() will shift the amount of h_border_left to
+- * stream->dst.x and set h_border_left to 0.  restore_border_left_from_dst()
+- * will restore h_border_left and stream->dst.x back to their original values
+- * We also need to make sure pipe_ctx->plane_res.scl_data.h_active uses the
+- * original h_border_left value in its calculation.
+- */
+-static int shift_border_left_to_dst(struct pipe_ctx *pipe_ctx)
+-{
+-	int store_h_border_left = pipe_ctx->stream->timing.h_border_left;
+-
+-	if (store_h_border_left) {
+-		pipe_ctx->stream->timing.h_border_left = 0;
+-		pipe_ctx->stream->dst.x += store_h_border_left;
++	if (orthogonal_rotation) {
++		swap(data->viewport.x, data->viewport.y);
++		swap(data->viewport.width, data->viewport.height);
++		swap(data->viewport_c.x, data->viewport_c.y);
++		swap(data->viewport_c.width, data->viewport_c.height);
+ 	}
+-	return store_h_border_left;
+-}
+-
+-static void restore_border_left_from_dst(struct pipe_ctx *pipe_ctx,
+-					 int store_h_border_left)
+-{
+-	pipe_ctx->stream->dst.x -= store_h_border_left;
+-	pipe_ctx->stream->timing.h_border_left = store_h_border_left;
++	data->viewport.x += src.x;
++	data->viewport.y += src.y;
++	ASSERT(src.x % vpc_div == 0 && src.y % vpc_div == 0);
++	data->viewport_c.x += src.x / vpc_div;
++	data->viewport_c.y += src.y / vpc_div;
+ }
+ 
+ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
+@@ -1183,48 +1006,42 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
+ 	const struct dc_plane_state *plane_state = pipe_ctx->plane_state;
+ 	struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
+ 	bool res = false;
+-	int store_h_border_left = shift_border_left_to_dst(pipe_ctx);
+ 	DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
+-	/* Important: scaling ratio calculation requires pixel format,
+-	 * lb depth calculation requires recout and taps require scaling ratios.
+-	 * Inits require viewport, taps, ratios and recout of split pipe
+-	 */
++
+ 	pipe_ctx->plane_res.scl_data.format = convert_pixel_format_to_dalsurface(
+ 			pipe_ctx->plane_state->format);
+ 
+-	calculate_scaling_ratios(pipe_ctx);
+-
+-	calculate_viewport(pipe_ctx);
++	/* Timing borders are part of vactive that we are also supposed to skip in addition
++	 * to any stream dst offset. Since dm logic assumes dst is in addressable
++	 * space we need to add the the left and top borders to dst offsets temporarily.
++	 * TODO: fix in DM, stream dst is supposed to be in vactive
++	 */
++	pipe_ctx->stream->dst.x += timing->h_border_left;
++	pipe_ctx->stream->dst.y += timing->v_border_top;
+ 
+-	if (pipe_ctx->plane_res.scl_data.viewport.height < MIN_VIEWPORT_SIZE ||
+-		pipe_ctx->plane_res.scl_data.viewport.width < MIN_VIEWPORT_SIZE) {
+-		if (store_h_border_left) {
+-			restore_border_left_from_dst(pipe_ctx,
+-				store_h_border_left);
+-		}
+-		return false;
+-	}
++	/* Calculate H and V active size */
++	pipe_ctx->plane_res.scl_data.h_active = timing->h_addressable +
++			timing->h_border_left + timing->h_border_right;
++	pipe_ctx->plane_res.scl_data.v_active = timing->v_addressable +
++		timing->v_border_top + timing->v_border_bottom;
++	if (pipe_ctx->next_odm_pipe || pipe_ctx->prev_odm_pipe)
++		pipe_ctx->plane_res.scl_data.h_active /= get_num_odm_splits(pipe_ctx) + 1;
+ 
++	/* depends on h_active */
+ 	calculate_recout(pipe_ctx);
++	/* depends on pixel format */
++	calculate_scaling_ratios(pipe_ctx);
++	/* depends on scaling ratios and recout, does not calculate offset yet */
++	calculate_viewport_size(pipe_ctx);
+ 
+-	/**
++	/*
++	 * LB calculations depend on vp size, h/v_active and scaling ratios
+ 	 * Setting line buffer pixel depth to 24bpp yields banding
+ 	 * on certain displays, such as the Sharp 4k
+ 	 */
+ 	pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP;
+ 	pipe_ctx->plane_res.scl_data.lb_params.alpha_en = plane_state->per_pixel_alpha;
+ 
+-	pipe_ctx->plane_res.scl_data.recout.x += timing->h_border_left;
+-	pipe_ctx->plane_res.scl_data.recout.y += timing->v_border_top;
+-
+-	pipe_ctx->plane_res.scl_data.h_active = timing->h_addressable +
+-		store_h_border_left + timing->h_border_right;
+-	pipe_ctx->plane_res.scl_data.v_active = timing->v_addressable +
+-		timing->v_border_top + timing->v_border_bottom;
+-	if (pipe_ctx->next_odm_pipe || pipe_ctx->prev_odm_pipe)
+-		pipe_ctx->plane_res.scl_data.h_active /= get_num_odm_splits(pipe_ctx) + 1;
+-
+-	/* Taps calculations */
+ 	if (pipe_ctx->plane_res.xfm != NULL)
+ 		res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps(
+ 				pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
+@@ -1251,9 +1068,31 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
+ 					&plane_state->scaling_quality);
+ 	}
+ 
++	/*
++	 * Depends on recout, scaling ratios, h_active and taps
++	 * May need to re-check lb size after this in some obscure scenario
++	 */
+ 	if (res)
+-		/* May need to re-check lb size after this in some obscure scenario */
+-		calculate_inits_and_adj_vp(pipe_ctx);
++		calculate_inits_and_viewports(pipe_ctx);
++
++	/*
++	 * Handle side by side and top bottom 3d recout offsets after vp calculation
++	 * since 3d is special and needs to calculate vp as if there is no recout offset
++	 * This may break with rotation, good thing we aren't mixing hw rotation and 3d
++	 */
++	if (pipe_ctx->top_pipe && pipe_ctx->top_pipe->plane_state == plane_state) {
++		ASSERT(plane_state->rotation == ROTATION_ANGLE_0 ||
++			(pipe_ctx->stream->view_format != VIEW_3D_FORMAT_TOP_AND_BOTTOM &&
++				pipe_ctx->stream->view_format != VIEW_3D_FORMAT_SIDE_BY_SIDE));
++		if (pipe_ctx->stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM)
++			pipe_ctx->plane_res.scl_data.recout.y += pipe_ctx->plane_res.scl_data.recout.height;
++		else if (pipe_ctx->stream->view_format == VIEW_3D_FORMAT_SIDE_BY_SIDE)
++			pipe_ctx->plane_res.scl_data.recout.x += pipe_ctx->plane_res.scl_data.recout.width;
++	}
++
++	if (pipe_ctx->plane_res.scl_data.viewport.height < MIN_VIEWPORT_SIZE ||
++			pipe_ctx->plane_res.scl_data.viewport.width < MIN_VIEWPORT_SIZE)
++		res = false;
+ 
+ 	DC_LOG_SCALER("%s pipe %d:\nViewport: height:%d width:%d x:%d y:%d  Recout: height:%d width:%d x:%d y:%d  HACTIVE:%d VACTIVE:%d\n"
+ 			"src_rect: height:%d width:%d x:%d y:%d  dst_rect: height:%d width:%d x:%d y:%d  clip_rect: height:%d width:%d x:%d y:%d\n",
+@@ -1282,8 +1121,8 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
+ 			plane_state->clip_rect.x,
+ 			plane_state->clip_rect.y);
+ 
+-	if (store_h_border_left)
+-		restore_border_left_from_dst(pipe_ctx, store_h_border_left);
++	pipe_ctx->stream->dst.x -= timing->h_border_left;
++	pipe_ctx->stream->dst.y -= timing->v_border_top;
+ 
+ 	return res;
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
+index 100d434f7a038..65f801b506863 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc.h
++++ b/drivers/gpu/drm/amd/display/dc/dc.h
+@@ -719,7 +719,6 @@ void dc_init_callbacks(struct dc *dc,
+ void dc_deinit_callbacks(struct dc *dc);
+ void dc_destroy(struct dc **dc);
+ 
+-void dc_wait_for_vblank(struct dc *dc, struct dc_stream_state *stream);
+ /*******************************************************************************
+  * Surface Interfaces
+  ******************************************************************************/
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
+index 432754eaf10b8..a6f21f9de6e4e 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
++++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
+@@ -271,11 +271,6 @@ struct dc_edid_caps {
+ 	struct dc_panel_patch panel_patch;
+ };
+ 
+-struct view {
+-	uint32_t width;
+-	uint32_t height;
+-};
+-
+ struct dc_mode_flags {
+ 	/* note: part of refresh rate flag*/
+ 	uint32_t INTERLACE :1;
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c
+index efa86d5c68470..a33f522a2648a 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c
+@@ -496,10 +496,13 @@ static enum lb_memory_config dpp1_dscl_find_lb_memory_config(struct dcn10_dpp *d
+ 	int vtaps_c = scl_data->taps.v_taps_c;
+ 	int ceil_vratio = dc_fixpt_ceil(scl_data->ratios.vert);
+ 	int ceil_vratio_c = dc_fixpt_ceil(scl_data->ratios.vert_c);
+-	enum lb_memory_config mem_cfg = LB_MEMORY_CONFIG_0;
+ 
+-	if (dpp->base.ctx->dc->debug.use_max_lb)
+-		return mem_cfg;
++	if (dpp->base.ctx->dc->debug.use_max_lb) {
++		if (scl_data->format == PIXEL_FORMAT_420BPP8
++				|| scl_data->format == PIXEL_FORMAT_420BPP10)
++			return LB_MEMORY_CONFIG_3;
++		return LB_MEMORY_CONFIG_0;
++	}
+ 
+ 	dpp->base.caps->dscl_calc_lb_num_partitions(
+ 			scl_data, LB_MEMORY_CONFIG_1, &num_part_y, &num_part_c);
+@@ -628,8 +631,10 @@ static void dpp1_dscl_set_manual_ratio_init(
+ 		SCL_V_INIT_INT, init_int);
+ 
+ 	if (REG(SCL_VERT_FILTER_INIT_BOT)) {
+-		init_frac = dc_fixpt_u0d19(data->inits.v_bot) << 5;
+-		init_int = dc_fixpt_floor(data->inits.v_bot);
++		struct fixed31_32 bot = dc_fixpt_add(data->inits.v, data->ratios.vert);
++
++		init_frac = dc_fixpt_u0d19(bot) << 5;
++		init_int = dc_fixpt_floor(bot);
+ 		REG_SET_2(SCL_VERT_FILTER_INIT_BOT, 0,
+ 			SCL_V_INIT_FRAC_BOT, init_frac,
+ 			SCL_V_INIT_INT_BOT, init_int);
+@@ -642,8 +647,10 @@ static void dpp1_dscl_set_manual_ratio_init(
+ 		SCL_V_INIT_INT_C, init_int);
+ 
+ 	if (REG(SCL_VERT_FILTER_INIT_BOT_C)) {
+-		init_frac = dc_fixpt_u0d19(data->inits.v_c_bot) << 5;
+-		init_int = dc_fixpt_floor(data->inits.v_c_bot);
++		struct fixed31_32 bot = dc_fixpt_add(data->inits.v_c, data->ratios.vert_c);
++
++		init_frac = dc_fixpt_u0d19(bot) << 5;
++		init_int = dc_fixpt_floor(bot);
+ 		REG_SET_2(SCL_VERT_FILTER_INIT_BOT_C, 0,
+ 			SCL_V_INIT_FRAC_BOT_C, init_frac,
+ 			SCL_V_INIT_INT_BOT_C, init_int);
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+index 6a10daec15ccd..793554e61c520 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+@@ -243,7 +243,7 @@ void dcn20_dccg_init(struct dce_hwseq *hws)
+ 	REG_WRITE(MILLISECOND_TIME_BASE_DIV, 0x1186a0);
+ 
+ 	/* This value is dependent on the hardware pipeline delay so set once per SOC */
+-	REG_WRITE(DISPCLK_FREQ_CHANGE_CNTL, 0x801003c);
++	REG_WRITE(DISPCLK_FREQ_CHANGE_CNTL, 0xe01003c);
+ }
+ 
+ void dcn20_disable_vga(
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+index 8357aa3c41d5a..d7d70b9bb3874 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+@@ -2289,12 +2289,14 @@ int dcn20_populate_dml_pipes_from_context(
+ 
+ 			pipes[pipe_cnt].pipe.src.source_scan = pln->rotation == ROTATION_ANGLE_90
+ 					|| pln->rotation == ROTATION_ANGLE_270 ? dm_vert : dm_horz;
+-			pipes[pipe_cnt].pipe.src.viewport_y_y = scl->viewport_unadjusted.y;
+-			pipes[pipe_cnt].pipe.src.viewport_y_c = scl->viewport_c_unadjusted.y;
+-			pipes[pipe_cnt].pipe.src.viewport_width = scl->viewport_unadjusted.width;
+-			pipes[pipe_cnt].pipe.src.viewport_width_c = scl->viewport_c_unadjusted.width;
+-			pipes[pipe_cnt].pipe.src.viewport_height = scl->viewport_unadjusted.height;
+-			pipes[pipe_cnt].pipe.src.viewport_height_c = scl->viewport_c_unadjusted.height;
++			pipes[pipe_cnt].pipe.src.viewport_y_y = scl->viewport.y;
++			pipes[pipe_cnt].pipe.src.viewport_y_c = scl->viewport_c.y;
++			pipes[pipe_cnt].pipe.src.viewport_width = scl->viewport.width;
++			pipes[pipe_cnt].pipe.src.viewport_width_c = scl->viewport_c.width;
++			pipes[pipe_cnt].pipe.src.viewport_height = scl->viewport.height;
++			pipes[pipe_cnt].pipe.src.viewport_height_c = scl->viewport_c.height;
++			pipes[pipe_cnt].pipe.src.viewport_width_max = pln->src_rect.width;
++			pipes[pipe_cnt].pipe.src.viewport_height_max = pln->src_rect.height;
+ 			pipes[pipe_cnt].pipe.src.surface_width_y = pln->plane_size.surface_size.width;
+ 			pipes[pipe_cnt].pipe.src.surface_height_y = pln->plane_size.surface_size.height;
+ 			pipes[pipe_cnt].pipe.src.surface_width_c = pln->plane_size.chroma_size.width;
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c
+index cb3f70a71b512..db6bb7ea53169 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c
+@@ -64,6 +64,7 @@ typedef struct {
+ #define BPP_INVALID 0
+ #define BPP_BLENDED_PIPE 0xffffffff
+ #define DCN30_MAX_DSC_IMAGE_WIDTH 5184
++#define DCN30_MAX_FMT_420_BUFFER_WIDTH 4096
+ 
+ static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib);
+ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
+@@ -2052,7 +2053,7 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
+ 			v->DISPCLKWithoutRamping,
+ 			v->DISPCLKDPPCLKVCOSpeed);
+ 	v->MaxDispclkRoundedToDFSGranularity = RoundToDFSGranularityDown(
+-			v->soc.clock_limits[mode_lib->soc.num_states].dispclk_mhz,
++			v->soc.clock_limits[mode_lib->soc.num_states - 1].dispclk_mhz,
+ 			v->DISPCLKDPPCLKVCOSpeed);
+ 	if (v->DISPCLKWithoutRampingRoundedToDFSGranularity
+ 			> v->MaxDispclkRoundedToDFSGranularity) {
+@@ -3957,20 +3958,20 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
+ 			for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
+ 				v->PlaneRequiredDISPCLKWithoutODMCombine = v->PixelClock[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
+ 						* (1.0 + v->DISPCLKRampingMargin / 100.0);
+-				if ((v->PlaneRequiredDISPCLKWithoutODMCombine >= v->MaxDispclk[i] && v->MaxDispclk[i] == v->MaxDispclk[mode_lib->soc.num_states]
+-						&& v->MaxDppclk[i] == v->MaxDppclk[mode_lib->soc.num_states])) {
++				if ((v->PlaneRequiredDISPCLKWithoutODMCombine >= v->MaxDispclk[i] && v->MaxDispclk[i] == v->MaxDispclk[mode_lib->soc.num_states - 1]
++						&& v->MaxDppclk[i] == v->MaxDppclk[mode_lib->soc.num_states - 1])) {
+ 					v->PlaneRequiredDISPCLKWithoutODMCombine = v->PixelClock[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
+ 				}
+ 				v->PlaneRequiredDISPCLKWithODMCombine2To1 = v->PixelClock[k] / 2 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
+ 						* (1 + v->DISPCLKRampingMargin / 100.0);
+-				if ((v->PlaneRequiredDISPCLKWithODMCombine2To1 >= v->MaxDispclk[i] && v->MaxDispclk[i] == v->MaxDispclk[mode_lib->soc.num_states]
+-						&& v->MaxDppclk[i] == v->MaxDppclk[mode_lib->soc.num_states])) {
++				if ((v->PlaneRequiredDISPCLKWithODMCombine2To1 >= v->MaxDispclk[i] && v->MaxDispclk[i] == v->MaxDispclk[mode_lib->soc.num_states - 1]
++						&& v->MaxDppclk[i] == v->MaxDppclk[mode_lib->soc.num_states - 1])) {
+ 					v->PlaneRequiredDISPCLKWithODMCombine2To1 = v->PixelClock[k] / 2 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
+ 				}
+ 				v->PlaneRequiredDISPCLKWithODMCombine4To1 = v->PixelClock[k] / 4 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
+ 						* (1 + v->DISPCLKRampingMargin / 100.0);
+-				if ((v->PlaneRequiredDISPCLKWithODMCombine4To1 >= v->MaxDispclk[i] && v->MaxDispclk[i] == v->MaxDispclk[mode_lib->soc.num_states]
+-						&& v->MaxDppclk[i] == v->MaxDppclk[mode_lib->soc.num_states])) {
++				if ((v->PlaneRequiredDISPCLKWithODMCombine4To1 >= v->MaxDispclk[i] && v->MaxDispclk[i] == v->MaxDispclk[mode_lib->soc.num_states - 1]
++						&& v->MaxDppclk[i] == v->MaxDppclk[mode_lib->soc.num_states - 1])) {
+ 					v->PlaneRequiredDISPCLKWithODMCombine4To1 = v->PixelClock[k] / 4 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
+ 				}
+ 
+@@ -3987,19 +3988,30 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
+ 				} else if (v->PlaneRequiredDISPCLKWithoutODMCombine > v->MaxDispclkRoundedDownToDFSGranularity) {
+ 					v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
+ 					v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1;
+-				} else if (v->DSCEnabled[k] && (v->HActive[k] > DCN30_MAX_DSC_IMAGE_WIDTH)) {
+-					v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
+-					v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1;
+ 				} else {
+ 					v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
+ 					v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithoutODMCombine;
+-					/*420 format workaround*/
+-					if (v->HActive[k] > 4096 && v->OutputFormat[k] == dm_420) {
++				}
++				if (v->DSCEnabled[k] && v->HActive[k] > DCN30_MAX_DSC_IMAGE_WIDTH
++						&& v->ODMCombineEnablePerState[i][k] != dm_odm_combine_mode_4to1) {
++					if (v->HActive[k] / 2 > DCN30_MAX_DSC_IMAGE_WIDTH) {
++						v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_4to1;
++						v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine4To1;
++					} else {
++						v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
++						v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1;
++					}
++				}
++				if (v->OutputFormat[k] == dm_420 && v->HActive[k] > DCN30_MAX_FMT_420_BUFFER_WIDTH
++						&& v->ODMCombineEnablePerState[i][k] != dm_odm_combine_mode_4to1) {
++					if (v->HActive[k] / 2 > DCN30_MAX_FMT_420_BUFFER_WIDTH) {
++						v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_4to1;
++						v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine4To1;
++					} else {
+ 						v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
+ 						v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1;
+ 					}
+ 				}
+-
+ 				if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_4to1) {
+ 					v->MPCCombine[i][j][k] = false;
+ 					v->NoOfDPP[i][j][k] = 4;
+@@ -4281,42 +4293,8 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
+ 		}
+ 	}
+ 
+-	for (i = 0; i < v->soc.num_states; i++) {
+-		v->DSCCLKRequiredMoreThanSupported[i] = false;
+-		for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
+-			if (v->BlendingAndTiming[k] == k) {
+-				if (v->Output[k] == dm_dp || v->Output[k] == dm_edp) {
+-					if (v->OutputFormat[k] == dm_420) {
+-						v->DSCFormatFactor = 2;
+-					} else if (v->OutputFormat[k] == dm_444) {
+-						v->DSCFormatFactor = 1;
+-					} else if (v->OutputFormat[k] == dm_n422) {
+-						v->DSCFormatFactor = 2;
+-					} else {
+-						v->DSCFormatFactor = 1;
+-					}
+-					if (v->RequiresDSC[i][k] == true) {
+-						if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_4to1) {
+-							if (v->PixelClockBackEnd[k] / 12.0 / v->DSCFormatFactor
+-									> (1.0 - v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * v->MaxDSCCLK[i]) {
+-								v->DSCCLKRequiredMoreThanSupported[i] = true;
+-							}
+-						} else if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
+-							if (v->PixelClockBackEnd[k] / 6.0 / v->DSCFormatFactor
+-									> (1.0 - v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * v->MaxDSCCLK[i]) {
+-								v->DSCCLKRequiredMoreThanSupported[i] = true;
+-							}
+-						} else {
+-							if (v->PixelClockBackEnd[k] / 3.0 / v->DSCFormatFactor
+-									> (1.0 - v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * v->MaxDSCCLK[i]) {
+-								v->DSCCLKRequiredMoreThanSupported[i] = true;
+-							}
+-						}
+-					}
+-				}
+-			}
+-		}
+-	}
++	/* Skip dscclk validation: as long as dispclk is supported, dscclk is also implicitly supported */
++
+ 	for (i = 0; i < v->soc.num_states; i++) {
+ 		v->NotEnoughDSCUnits[i] = false;
+ 		v->TotalDSCUnitsRequired = 0.0;
+@@ -5319,7 +5297,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
+ 		for (j = 0; j < 2; j++) {
+ 			if (v->ScaleRatioAndTapsSupport == 1 && v->SourceFormatPixelAndScanSupport == 1 && v->ViewportSizeSupport[i][j] == 1
+ 					&& v->DIOSupport[i] == 1 && v->ODMCombine4To1SupportCheckOK[i] == 1
+-					&& v->NotEnoughDSCUnits[i] == 0 && v->DSCCLKRequiredMoreThanSupported[i] == 0
++					&& v->NotEnoughDSCUnits[i] == 0
+ 					&& v->DTBCLKRequiredMoreThanSupported[i] == 0
+ 					&& v->ROBSupport[i][j] == 1 && v->DISPCLK_DPPCLK_Support[i][j] == 1 && v->TotalAvailablePipesSupport[i][j] == 1
+ 					&& EnoughWritebackUnits == 1 && WritebackModeSupport == 1
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
+index 2ece3690bfa31..a0f0c54c863bc 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
++++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
+@@ -253,6 +253,8 @@ struct _vcs_dpi_display_pipe_source_params_st {
+ 	unsigned int viewport_y_c;
+ 	unsigned int viewport_width_c;
+ 	unsigned int viewport_height_c;
++	unsigned int viewport_width_max;
++	unsigned int viewport_height_max;
+ 	unsigned int data_pitch;
+ 	unsigned int data_pitch_c;
+ 	unsigned int meta_pitch;
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
+index 2a967458065be..8e5c9d22b3648 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
+@@ -630,6 +630,19 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib)
+ 				}
+ 			}
+ 		}
++		if (src->viewport_width_max) {
++			int hdiv_c = src->source_format >= dm_420_8 && src->source_format <= dm_422_10 ? 2 : 1;
++			int vdiv_c = src->source_format >= dm_420_8 && src->source_format <= dm_420_12 ? 2 : 1;
++
++			if (mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] > src->viewport_width_max)
++				mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] = src->viewport_width_max;
++			if (mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] > src->viewport_height_max)
++				mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] = src->viewport_height_max;
++			if (mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] > src->viewport_width_max / hdiv_c)
++				mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] = src->viewport_width_max / hdiv_c;
++			if (mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] > src->viewport_height_max / vdiv_c)
++				mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] = src->viewport_height_max / vdiv_c;
++		}
+ 
+ 		if (pipes[k].pipe.src.immediate_flip) {
+ 			mode_lib->vba.ImmediateFlipSupport = true;
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h b/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h
+index 2947d1b155129..2a0db2b03047e 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h
+@@ -162,9 +162,7 @@ struct scl_inits {
+ 	struct fixed31_32 h;
+ 	struct fixed31_32 h_c;
+ 	struct fixed31_32 v;
+-	struct fixed31_32 v_bot;
+ 	struct fixed31_32 v_c;
+-	struct fixed31_32 v_c_bot;
+ };
+ 
+ struct scaler_data {
+@@ -173,8 +171,6 @@ struct scaler_data {
+ 	struct scaling_taps taps;
+ 	struct rect viewport;
+ 	struct rect viewport_c;
+-	struct rect viewport_unadjusted;
+-	struct rect viewport_c_unadjusted;
+ 	struct rect recout;
+ 	struct scaling_ratios ratios;
+ 	struct scl_inits inits;
+diff --git a/drivers/gpu/drm/amd/display/dc/irq_types.h b/drivers/gpu/drm/amd/display/dc/irq_types.h
+index ae8f47ec0f8c3..1e4602bffb08d 100644
+--- a/drivers/gpu/drm/amd/display/dc/irq_types.h
++++ b/drivers/gpu/drm/amd/display/dc/irq_types.h
+@@ -165,7 +165,7 @@ enum irq_type
+ };
+ 
+ #define DAL_VALID_IRQ_SRC_NUM(src) \
+-	((src) <= DAL_IRQ_SOURCES_NUMBER && (src) > DC_IRQ_SOURCE_INVALID)
++	((src) < DAL_IRQ_SOURCES_NUMBER && (src) > DC_IRQ_SOURCE_INVALID)
+ 
+ /* Number of Page Flip IRQ Sources. */
+ #define DAL_PFLIP_IRQ_SRC_NUM \
+diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c
+index 68a6481d7f8f3..b963226e8af43 100644
+--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c
++++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c
+@@ -260,7 +260,6 @@ enum mod_hdcp_status mod_hdcp_setup(struct mod_hdcp *hdcp,
+ 	struct mod_hdcp_output output;
+ 	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
+ 
+-	memset(hdcp, 0, sizeof(struct mod_hdcp));
+ 	memset(&output, 0, sizeof(output));
+ 	hdcp->config = *config;
+ 	HDCP_TOP_INTERFACE_TRACE(hdcp);
+diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
+index 2cbd931363bdd..6d26d9c63ab2f 100644
+--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
++++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
+@@ -29,8 +29,10 @@ static inline enum mod_hdcp_status validate_bksv(struct mod_hdcp *hdcp)
+ {
+ 	uint64_t n = 0;
+ 	uint8_t count = 0;
++	u8 bksv[sizeof(n)] = { };
+ 
+-	memcpy(&n, hdcp->auth.msg.hdcp1.bksv, sizeof(uint64_t));
++	memcpy(bksv, hdcp->auth.msg.hdcp1.bksv, sizeof(hdcp->auth.msg.hdcp1.bksv));
++	n = *(uint64_t *)bksv;
+ 
+ 	while (n) {
+ 		count++;
+diff --git a/drivers/gpu/drm/amd/include/navi10_enum.h b/drivers/gpu/drm/amd/include/navi10_enum.h
+index d5ead9680c6ed..84bcb96f76ea4 100644
+--- a/drivers/gpu/drm/amd/include/navi10_enum.h
++++ b/drivers/gpu/drm/amd/include/navi10_enum.h
+@@ -430,7 +430,7 @@ ARRAY_2D_DEPTH                           = 0x00000001,
+  */
+ 
+ typedef enum ENUM_NUM_SIMD_PER_CU {
+-NUM_SIMD_PER_CU                          = 0x00000004,
++NUM_SIMD_PER_CU                          = 0x00000002,
+ } ENUM_NUM_SIMD_PER_CU;
+ 
+ /*
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
+index dcbe3a72da093..0d2f61f56f45c 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
+@@ -1290,10 +1290,13 @@ static int aldebaran_usr_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_
+ 
+ static bool aldebaran_is_dpm_running(struct smu_context *smu)
+ {
+-	int ret = 0;
++	int ret;
+ 	uint32_t feature_mask[2];
+ 	unsigned long feature_enabled;
++
+ 	ret = smu_cmn_get_enabled_mask(smu, feature_mask, 2);
++	if (ret)
++		return false;
+ 	feature_enabled = (unsigned long)((uint64_t)feature_mask[0] |
+ 					  ((uint64_t)feature_mask[1] << 32));
+ 	return !!(feature_enabled & SMC_DPM_FEATURE);
+@@ -1779,10 +1782,8 @@ static int aldebaran_set_mp1_state(struct smu_context *smu,
+ 	case PP_MP1_STATE_UNLOAD:
+ 		return smu_cmn_set_mp1_state(smu, mp1_state);
+ 	default:
+-		return -EINVAL;
++		return 0;
+ 	}
+-
+-	return 0;
+ }
+ 
+ static const struct pptable_funcs aldebaran_ppt_funcs = {
+diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c
+index ddbba67f0283a..8c2ab3d653b70 100644
+--- a/drivers/gpu/drm/arm/malidp_planes.c
++++ b/drivers/gpu/drm/arm/malidp_planes.c
+@@ -927,6 +927,11 @@ static const struct drm_plane_helper_funcs malidp_de_plane_helper_funcs = {
+ 	.atomic_disable = malidp_de_plane_disable,
+ };
+ 
++static const uint64_t linear_only_modifiers[] = {
++	DRM_FORMAT_MOD_LINEAR,
++	DRM_FORMAT_MOD_INVALID
++};
++
+ int malidp_de_planes_init(struct drm_device *drm)
+ {
+ 	struct malidp_drm *malidp = drm->dev_private;
+@@ -990,8 +995,8 @@ int malidp_de_planes_init(struct drm_device *drm)
+ 		 */
+ 		ret = drm_universal_plane_init(drm, &plane->base, crtcs,
+ 				&malidp_de_plane_funcs, formats, n,
+-				(id == DE_SMART) ? NULL : modifiers, plane_type,
+-				NULL);
++				(id == DE_SMART) ? linear_only_modifiers : modifiers,
++				plane_type, NULL);
+ 
+ 		if (ret < 0)
+ 			goto cleanup;
+diff --git a/drivers/gpu/drm/ast/ast_dp501.c b/drivers/gpu/drm/ast/ast_dp501.c
+index 88121c0e0d05c..cd93c44f26627 100644
+--- a/drivers/gpu/drm/ast/ast_dp501.c
++++ b/drivers/gpu/drm/ast/ast_dp501.c
+@@ -189,6 +189,9 @@ bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size)
+ 	u32 i, data;
+ 	u32 boot_address;
+ 
++	if (ast->config_mode != ast_use_p2a)
++		return false;
++
+ 	data = ast_mindwm(ast, 0x1e6e2100) & 0x01;
+ 	if (data) {
+ 		boot_address = get_fw_base(ast);
+@@ -207,6 +210,9 @@ static bool ast_launch_m68k(struct drm_device *dev)
+ 	u8 *fw_addr = NULL;
+ 	u8 jreg;
+ 
++	if (ast->config_mode != ast_use_p2a)
++		return false;
++
+ 	data = ast_mindwm(ast, 0x1e6e2100) & 0x01;
+ 	if (!data) {
+ 
+@@ -271,25 +277,55 @@ u8 ast_get_dp501_max_clk(struct drm_device *dev)
+ 	struct ast_private *ast = to_ast_private(dev);
+ 	u32 boot_address, offset, data;
+ 	u8 linkcap[4], linkrate, linklanes, maxclk = 0xff;
++	u32 *plinkcap;
+ 
+-	boot_address = get_fw_base(ast);
+-
+-	/* validate FW version */
+-	offset = 0xf000;
+-	data = ast_mindwm(ast, boot_address + offset);
+-	if ((data & 0xf0) != 0x10) /* version: 1x */
+-		return maxclk;
+-
+-	/* Read Link Capability */
+-	offset  = 0xf014;
+-	*(u32 *)linkcap = ast_mindwm(ast, boot_address + offset);
+-	if (linkcap[2] == 0) {
+-		linkrate = linkcap[0];
+-		linklanes = linkcap[1];
+-		data = (linkrate == 0x0a) ? (90 * linklanes) : (54 * linklanes);
+-		if (data > 0xff)
+-			data = 0xff;
+-		maxclk = (u8)data;
++	if (ast->config_mode == ast_use_p2a) {
++		boot_address = get_fw_base(ast);
++
++		/* validate FW version */
++		offset = AST_DP501_GBL_VERSION;
++		data = ast_mindwm(ast, boot_address + offset);
++		if ((data & AST_DP501_FW_VERSION_MASK) != AST_DP501_FW_VERSION_1) /* version: 1x */
++			return maxclk;
++
++		/* Read Link Capability */
++		offset  = AST_DP501_LINKRATE;
++		plinkcap = (u32 *)linkcap;
++		*plinkcap  = ast_mindwm(ast, boot_address + offset);
++		if (linkcap[2] == 0) {
++			linkrate = linkcap[0];
++			linklanes = linkcap[1];
++			data = (linkrate == 0x0a) ? (90 * linklanes) : (54 * linklanes);
++			if (data > 0xff)
++				data = 0xff;
++			maxclk = (u8)data;
++		}
++	} else {
++		if (!ast->dp501_fw_buf)
++			return AST_DP501_DEFAULT_DCLK;	/* 1024x768 as default */
++
++		/* dummy read */
++		offset = 0x0000;
++		data = readl(ast->dp501_fw_buf + offset);
++
++		/* validate FW version */
++		offset = AST_DP501_GBL_VERSION;
++		data = readl(ast->dp501_fw_buf + offset);
++		if ((data & AST_DP501_FW_VERSION_MASK) != AST_DP501_FW_VERSION_1) /* version: 1x */
++			return maxclk;
++
++		/* Read Link Capability */
++		offset = AST_DP501_LINKRATE;
++		plinkcap = (u32 *)linkcap;
++		*plinkcap = readl(ast->dp501_fw_buf + offset);
++		if (linkcap[2] == 0) {
++			linkrate = linkcap[0];
++			linklanes = linkcap[1];
++			data = (linkrate == 0x0a) ? (90 * linklanes) : (54 * linklanes);
++			if (data > 0xff)
++				data = 0xff;
++			maxclk = (u8)data;
++		}
+ 	}
+ 	return maxclk;
+ }
+@@ -298,26 +334,57 @@ bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata)
+ {
+ 	struct ast_private *ast = to_ast_private(dev);
+ 	u32 i, boot_address, offset, data;
++	u32 *pEDIDidx;
+ 
+-	boot_address = get_fw_base(ast);
+-
+-	/* validate FW version */
+-	offset = 0xf000;
+-	data = ast_mindwm(ast, boot_address + offset);
+-	if ((data & 0xf0) != 0x10)
+-		return false;
+-
+-	/* validate PnP Monitor */
+-	offset = 0xf010;
+-	data = ast_mindwm(ast, boot_address + offset);
+-	if (!(data & 0x01))
+-		return false;
++	if (ast->config_mode == ast_use_p2a) {
++		boot_address = get_fw_base(ast);
+ 
+-	/* Read EDID */
+-	offset = 0xf020;
+-	for (i = 0; i < 128; i += 4) {
+-		data = ast_mindwm(ast, boot_address + offset + i);
+-		*(u32 *)(ediddata + i) = data;
++		/* validate FW version */
++		offset = AST_DP501_GBL_VERSION;
++		data = ast_mindwm(ast, boot_address + offset);
++		if ((data & AST_DP501_FW_VERSION_MASK) != AST_DP501_FW_VERSION_1)
++			return false;
++
++		/* validate PnP Monitor */
++		offset = AST_DP501_PNPMONITOR;
++		data = ast_mindwm(ast, boot_address + offset);
++		if (!(data & AST_DP501_PNP_CONNECTED))
++			return false;
++
++		/* Read EDID */
++		offset = AST_DP501_EDID_DATA;
++		for (i = 0; i < 128; i += 4) {
++			data = ast_mindwm(ast, boot_address + offset + i);
++			pEDIDidx = (u32 *)(ediddata + i);
++			*pEDIDidx = data;
++		}
++	} else {
++		if (!ast->dp501_fw_buf)
++			return false;
++
++		/* dummy read */
++		offset = 0x0000;
++		data = readl(ast->dp501_fw_buf + offset);
++
++		/* validate FW version */
++		offset = AST_DP501_GBL_VERSION;
++		data = readl(ast->dp501_fw_buf + offset);
++		if ((data & AST_DP501_FW_VERSION_MASK) != AST_DP501_FW_VERSION_1)
++			return false;
++
++		/* validate PnP Monitor */
++		offset = AST_DP501_PNPMONITOR;
++		data = readl(ast->dp501_fw_buf + offset);
++		if (!(data & AST_DP501_PNP_CONNECTED))
++			return false;
++
++		/* Read EDID */
++		offset = AST_DP501_EDID_DATA;
++		for (i = 0; i < 128; i += 4) {
++			data = readl(ast->dp501_fw_buf + offset + i);
++			pEDIDidx = (u32 *)(ediddata + i);
++			*pEDIDidx = data;
++		}
+ 	}
+ 
+ 	return true;
+diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
+index e82ab86287703..911f9f4147741 100644
+--- a/drivers/gpu/drm/ast/ast_drv.h
++++ b/drivers/gpu/drm/ast/ast_drv.h
+@@ -150,6 +150,7 @@ struct ast_private {
+ 
+ 	void __iomem *regs;
+ 	void __iomem *ioregs;
++	void __iomem *dp501_fw_buf;
+ 
+ 	enum ast_chip chip;
+ 	bool vga2_clone;
+@@ -325,6 +326,17 @@ int ast_mode_config_init(struct ast_private *ast);
+ #define AST_MM_ALIGN_SHIFT 4
+ #define AST_MM_ALIGN_MASK ((1 << AST_MM_ALIGN_SHIFT) - 1)
+ 
++#define AST_DP501_FW_VERSION_MASK	GENMASK(7, 4)
++#define AST_DP501_FW_VERSION_1		BIT(4)
++#define AST_DP501_PNP_CONNECTED		BIT(1)
++
++#define AST_DP501_DEFAULT_DCLK	65
++
++#define AST_DP501_GBL_VERSION	0xf000
++#define AST_DP501_PNPMONITOR	0xf010
++#define AST_DP501_LINKRATE	0xf014
++#define AST_DP501_EDID_DATA	0xf020
++
+ int ast_mm_init(struct ast_private *ast);
+ 
+ /* ast post */
+diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
+index c29cc7f19863a..2aff2e6cf450c 100644
+--- a/drivers/gpu/drm/ast/ast_main.c
++++ b/drivers/gpu/drm/ast/ast_main.c
+@@ -99,7 +99,7 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)
+ 	if (!(jregd0 & 0x80) || !(jregd1 & 0x10)) {
+ 		/* Double check it's actually working */
+ 		data = ast_read32(ast, 0xf004);
+-		if (data != 0xFFFFFFFF) {
++		if ((data != 0xFFFFFFFF) && (data != 0x00)) {
+ 			/* P2A works, grab silicon revision */
+ 			ast->config_mode = ast_use_p2a;
+ 
+@@ -450,6 +450,14 @@ struct ast_private *ast_device_create(const struct drm_driver *drv,
+ 	if (ret)
+ 		return ERR_PTR(ret);
+ 
++	/* map reserved buffer */
++	ast->dp501_fw_buf = NULL;
++	if (dev->vram_mm->vram_size < pci_resource_len(pdev, 0)) {
++		ast->dp501_fw_buf = pci_iomap_range(pdev, 0, dev->vram_mm->vram_size, 0);
++		if (!ast->dp501_fw_buf)
++			drm_info(dev, "failed to map reserved buffer!\n");
++	}
++
+ 	ret = ast_mode_config_init(ast);
+ 	if (ret)
+ 		return ERR_PTR(ret);
+diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
+index 989a05bc81979..ddcd5b6ad37aa 100644
+--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
++++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
+@@ -2369,9 +2369,9 @@ static int cdns_mhdp_probe(struct platform_device *pdev)
+ 	clk_prepare_enable(clk);
+ 
+ 	pm_runtime_enable(dev);
+-	ret = pm_runtime_get_sync(dev);
++	ret = pm_runtime_resume_and_get(dev);
+ 	if (ret < 0) {
+-		dev_err(dev, "pm_runtime_get_sync failed\n");
++		dev_err(dev, "pm_runtime_resume_and_get failed\n");
+ 		pm_runtime_disable(dev);
+ 		goto clk_disable;
+ 	}
+diff --git a/drivers/gpu/drm/bridge/cdns-dsi.c b/drivers/gpu/drm/bridge/cdns-dsi.c
+index 76373e31df92d..b31281f76117c 100644
+--- a/drivers/gpu/drm/bridge/cdns-dsi.c
++++ b/drivers/gpu/drm/bridge/cdns-dsi.c
+@@ -1028,7 +1028,7 @@ static ssize_t cdns_dsi_transfer(struct mipi_dsi_host *host,
+ 	struct mipi_dsi_packet packet;
+ 	int ret, i, tx_len, rx_len;
+ 
+-	ret = pm_runtime_get_sync(host->dev);
++	ret = pm_runtime_resume_and_get(host->dev);
+ 	if (ret < 0)
+ 		return ret;
+ 
+diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
+index e8eb8deb444bb..29b1ce2140abc 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
++++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
+@@ -1215,6 +1215,7 @@ static struct i2c_device_id lt9611_id[] = {
+ 	{ "lontium,lt9611", 0 },
+ 	{}
+ };
++MODULE_DEVICE_TABLE(i2c, lt9611_id);
+ 
+ static const struct of_device_id lt9611_match_table[] = {
+ 	{ .compatible = "lontium,lt9611" },
+diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
+index 66b67402f1acd..c65ca860712d2 100644
+--- a/drivers/gpu/drm/bridge/nwl-dsi.c
++++ b/drivers/gpu/drm/bridge/nwl-dsi.c
+@@ -21,6 +21,7 @@
+ #include <linux/sys_soc.h>
+ #include <linux/time64.h>
+ 
++#include <drm/drm_atomic_state_helper.h>
+ #include <drm/drm_bridge.h>
+ #include <drm/drm_mipi_dsi.h>
+ #include <drm/drm_of.h>
+@@ -742,7 +743,9 @@ static int nwl_dsi_disable(struct nwl_dsi *dsi)
+ 	return 0;
+ }
+ 
+-static void nwl_dsi_bridge_disable(struct drm_bridge *bridge)
++static void
++nwl_dsi_bridge_atomic_disable(struct drm_bridge *bridge,
++			      struct drm_bridge_state *old_bridge_state)
+ {
+ 	struct nwl_dsi *dsi = bridge_to_dsi(bridge);
+ 	int ret;
+@@ -803,17 +806,6 @@ static int nwl_dsi_get_dphy_params(struct nwl_dsi *dsi,
+ 	return 0;
+ }
+ 
+-static bool nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge,
+-				      const struct drm_display_mode *mode,
+-				      struct drm_display_mode *adjusted_mode)
+-{
+-	/* At least LCDIF + NWL needs active high sync */
+-	adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
+-	adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
+-
+-	return true;
+-}
+-
+ static enum drm_mode_status
+ nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge,
+ 			  const struct drm_display_info *info,
+@@ -831,6 +823,24 @@ nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge,
+ 	return MODE_OK;
+ }
+ 
++static int nwl_dsi_bridge_atomic_check(struct drm_bridge *bridge,
++				       struct drm_bridge_state *bridge_state,
++				       struct drm_crtc_state *crtc_state,
++				       struct drm_connector_state *conn_state)
++{
++	struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
++
++	/* At least LCDIF + NWL needs active high sync */
++	adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
++	adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
++
++	/* Do a full modeset if crtc_state->active is changed to be true. */
++	if (crtc_state->active_changed && crtc_state->active)
++		crtc_state->mode_changed = true;
++
++	return 0;
++}
++
+ static void
+ nwl_dsi_bridge_mode_set(struct drm_bridge *bridge,
+ 			const struct drm_display_mode *mode,
+@@ -862,7 +872,9 @@ nwl_dsi_bridge_mode_set(struct drm_bridge *bridge,
+ 	drm_mode_debug_printmodeline(adjusted_mode);
+ }
+ 
+-static void nwl_dsi_bridge_pre_enable(struct drm_bridge *bridge)
++static void
++nwl_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge,
++				 struct drm_bridge_state *old_bridge_state)
+ {
+ 	struct nwl_dsi *dsi = bridge_to_dsi(bridge);
+ 	int ret;
+@@ -897,7 +909,9 @@ static void nwl_dsi_bridge_pre_enable(struct drm_bridge *bridge)
+ 	}
+ }
+ 
+-static void nwl_dsi_bridge_enable(struct drm_bridge *bridge)
++static void
++nwl_dsi_bridge_atomic_enable(struct drm_bridge *bridge,
++			     struct drm_bridge_state *old_bridge_state)
+ {
+ 	struct nwl_dsi *dsi = bridge_to_dsi(bridge);
+ 	int ret;
+@@ -942,14 +956,17 @@ static void nwl_dsi_bridge_detach(struct drm_bridge *bridge)
+ }
+ 
+ static const struct drm_bridge_funcs nwl_dsi_bridge_funcs = {
+-	.pre_enable = nwl_dsi_bridge_pre_enable,
+-	.enable     = nwl_dsi_bridge_enable,
+-	.disable    = nwl_dsi_bridge_disable,
+-	.mode_fixup = nwl_dsi_bridge_mode_fixup,
+-	.mode_set   = nwl_dsi_bridge_mode_set,
+-	.mode_valid = nwl_dsi_bridge_mode_valid,
+-	.attach	    = nwl_dsi_bridge_attach,
+-	.detach	    = nwl_dsi_bridge_detach,
++	.atomic_duplicate_state	= drm_atomic_helper_bridge_duplicate_state,
++	.atomic_destroy_state	= drm_atomic_helper_bridge_destroy_state,
++	.atomic_reset		= drm_atomic_helper_bridge_reset,
++	.atomic_check		= nwl_dsi_bridge_atomic_check,
++	.atomic_pre_enable	= nwl_dsi_bridge_atomic_pre_enable,
++	.atomic_enable		= nwl_dsi_bridge_atomic_enable,
++	.atomic_disable		= nwl_dsi_bridge_atomic_disable,
++	.mode_set		= nwl_dsi_bridge_mode_set,
++	.mode_valid		= nwl_dsi_bridge_mode_valid,
++	.attach			= nwl_dsi_bridge_attach,
++	.detach			= nwl_dsi_bridge_detach,
+ };
+ 
+ static int nwl_dsi_parse_dt(struct nwl_dsi *dsi)
+diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
+index cb2f53e566858..cd9ece0680bf1 100644
+--- a/drivers/gpu/drm/drm_dp_helper.c
++++ b/drivers/gpu/drm/drm_dp_helper.c
+@@ -679,7 +679,14 @@ int drm_dp_read_downstream_info(struct drm_dp_aux *aux,
+ 	    !(dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT))
+ 		return 0;
+ 
++	/* Some branches advertise having 0 downstream ports, despite also advertising they have a
++	 * downstream port present. The DP spec isn't clear on if this is allowed or not, but since
++	 * some branches do it we need to handle it regardless.
++	 */
+ 	len = drm_dp_downstream_port_count(dpcd);
++	if (!len)
++		return 0;
++
+ 	if (dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE)
+ 		len *= 4;
+ 
+diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
+index 642c60f3d9b18..005510f309cf7 100644
+--- a/drivers/gpu/drm/i915/display/intel_dp.c
++++ b/drivers/gpu/drm/i915/display/intel_dp.c
+@@ -2850,7 +2850,7 @@ static int intel_dp_vsc_sdp_unpack(struct drm_dp_vsc_sdp *vsc,
+ 	if (size < sizeof(struct dp_sdp))
+ 		return -EINVAL;
+ 
+-	memset(vsc, 0, size);
++	memset(vsc, 0, sizeof(*vsc));
+ 
+ 	if (sdp->sdp_header.HB0 != 0)
+ 		return -EINVAL;
+diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
+index e6a88c8cbd691..8457b9788cdab 100644
+--- a/drivers/gpu/drm/imx/imx-drm-core.c
++++ b/drivers/gpu/drm/imx/imx-drm-core.c
+@@ -145,9 +145,26 @@ static const struct drm_ioctl_desc imx_drm_ioctls[] = {
+ 	/* none so far */
+ };
+ 
++static int imx_drm_dumb_create(struct drm_file *file_priv,
++			       struct drm_device *drm,
++			       struct drm_mode_create_dumb *args)
++{
++	u32 width = args->width;
++	int ret;
++
++	args->width = ALIGN(width, 8);
++
++	ret = drm_gem_cma_dumb_create(file_priv, drm, args);
++	if (ret)
++		return ret;
++
++	args->width = width;
++	return ret;
++}
++
+ static const struct drm_driver imx_drm_driver = {
+ 	.driver_features	= DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
+-	DRM_GEM_CMA_DRIVER_OPS,
++	DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE(imx_drm_dumb_create),
+ 	.ioctls			= imx_drm_ioctls,
+ 	.num_ioctls		= ARRAY_SIZE(imx_drm_ioctls),
+ 	.fops			= &imx_drm_driver_fops,
+diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
+index ffdc492c5bc51..53132ddf9587b 100644
+--- a/drivers/gpu/drm/imx/imx-ldb.c
++++ b/drivers/gpu/drm/imx/imx-ldb.c
+@@ -274,6 +274,11 @@ imx_ldb_encoder_atomic_mode_set(struct drm_encoder *encoder,
+ 			 "%s: mode exceeds 85 MHz pixel clock\n", __func__);
+ 	}
+ 
++	if (!IS_ALIGNED(mode->hdisplay, 8)) {
++		dev_warn(ldb->dev,
++			 "%s: hdisplay does not align to 8 byte\n", __func__);
++	}
++
+ 	if (dual) {
+ 		serial_clk = 3500UL * mode->clock;
+ 		imx_ldb_set_clock(ldb, mux, 0, serial_clk, di_clk);
+diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
+index e6431a227feb1..9c8829f945b23 100644
+--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
++++ b/drivers/gpu/drm/imx/ipuv3-crtc.c
+@@ -305,10 +305,19 @@ static void ipu_crtc_mode_set_nofb(struct drm_crtc *crtc)
+ 	sig_cfg.vsync_pin = imx_crtc_state->di_vsync_pin;
+ 
+ 	drm_display_mode_to_videomode(mode, &sig_cfg.mode);
++	if (!IS_ALIGNED(sig_cfg.mode.hactive, 8)) {
++		unsigned int new_hactive = ALIGN(sig_cfg.mode.hactive, 8);
++
++		dev_warn(ipu_crtc->dev, "8-pixel align hactive %d -> %d\n",
++			 sig_cfg.mode.hactive, new_hactive);
++
++		sig_cfg.mode.hfront_porch = new_hactive - sig_cfg.mode.hactive;
++		sig_cfg.mode.hactive = new_hactive;
++	}
+ 
+ 	ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di,
+ 			 mode->flags & DRM_MODE_FLAG_INTERLACE,
+-			 imx_crtc_state->bus_format, mode->hdisplay);
++			 imx_crtc_state->bus_format, sig_cfg.mode.hactive);
+ 	ipu_di_init_sync_panel(ipu_crtc->di, &sig_cfg);
+ }
+ 
+diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
+index 233310712deb0..886de0f80b4ed 100644
+--- a/drivers/gpu/drm/imx/ipuv3-plane.c
++++ b/drivers/gpu/drm/imx/ipuv3-plane.c
+@@ -30,6 +30,11 @@ to_ipu_plane_state(struct drm_plane_state *p)
+ 	return container_of(p, struct ipu_plane_state, base);
+ }
+ 
++static unsigned int ipu_src_rect_width(const struct drm_plane_state *state)
++{
++	return ALIGN(drm_rect_width(&state->src) >> 16, 8);
++}
++
+ static inline struct ipu_plane *to_ipu_plane(struct drm_plane *p)
+ {
+ 	return container_of(p, struct ipu_plane, base);
+@@ -441,6 +446,12 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
+ 	if (old_fb && fb->pitches[0] != old_fb->pitches[0])
+ 		crtc_state->mode_changed = true;
+ 
++	if (ALIGN(fb->width, 8) * fb->format->cpp[0] >
++	    fb->pitches[0] + fb->offsets[0]) {
++		dev_warn(dev, "pitch is not big enough for 8 pixels alignment");
++		return -EINVAL;
++	}
++
+ 	switch (fb->format->format) {
+ 	case DRM_FORMAT_YUV420:
+ 	case DRM_FORMAT_YVU420:
+@@ -616,7 +627,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
+ 	if (ipu_state->use_pre) {
+ 		axi_id = ipu_chan_assign_axi_id(ipu_plane->dma);
+ 		ipu_prg_channel_configure(ipu_plane->ipu_ch, axi_id,
+-					  drm_rect_width(&new_state->src) >> 16,
++					  ipu_src_rect_width(new_state),
+ 					  drm_rect_height(&new_state->src) >> 16,
+ 					  fb->pitches[0], fb->format->format,
+ 					  fb->modifier, &eba);
+@@ -649,9 +660,9 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
+ 		break;
+ 	}
+ 
+-	ipu_dmfc_config_wait4eot(ipu_plane->dmfc, drm_rect_width(dst));
++	ipu_dmfc_config_wait4eot(ipu_plane->dmfc, ALIGN(drm_rect_width(dst), 8));
+ 
+-	width = drm_rect_width(&new_state->src) >> 16;
++	width = ipu_src_rect_width(new_state);
+ 	height = drm_rect_height(&new_state->src) >> 16;
+ 	info = drm_format_info(fb->format->format);
+ 	ipu_calculate_bursts(width, info->cpp[0], fb->pitches[0],
+@@ -716,7 +727,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
+ 
+ 		ipu_cpmem_zero(ipu_plane->alpha_ch);
+ 		ipu_cpmem_set_resolution(ipu_plane->alpha_ch,
+-					 drm_rect_width(&new_state->src) >> 16,
++					 ipu_src_rect_width(new_state),
+ 					 drm_rect_height(&new_state->src) >> 16);
+ 		ipu_cpmem_set_format_passthrough(ipu_plane->alpha_ch, 8);
+ 		ipu_cpmem_set_high_priority(ipu_plane->alpha_ch);
+diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
+index 29742ec5ab952..389cad59e0909 100644
+--- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
++++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
+@@ -342,7 +342,7 @@ static void ingenic_drm_crtc_atomic_flush(struct drm_crtc *crtc,
+ 	if (priv->update_clk_rate) {
+ 		mutex_lock(&priv->clk_mutex);
+ 		clk_set_rate(priv->pix_clk,
+-			     crtc_state->adjusted_mode.clock * 1000);
++			     crtc_state->adjusted_mode.crtc_clock * 1000);
+ 		priv->update_clk_rate = false;
+ 		mutex_unlock(&priv->clk_mutex);
+ 	}
+@@ -419,7 +419,7 @@ static void ingenic_drm_plane_enable(struct ingenic_drm *priv,
+ 	unsigned int en_bit;
+ 
+ 	if (priv->soc_info->has_osd) {
+-		if (plane->type == DRM_PLANE_TYPE_PRIMARY)
++		if (plane != &priv->f0)
+ 			en_bit = JZ_LCD_OSDC_F1EN;
+ 		else
+ 			en_bit = JZ_LCD_OSDC_F0EN;
+@@ -434,7 +434,7 @@ void ingenic_drm_plane_disable(struct device *dev, struct drm_plane *plane)
+ 	unsigned int en_bit;
+ 
+ 	if (priv->soc_info->has_osd) {
+-		if (plane->type == DRM_PLANE_TYPE_PRIMARY)
++		if (plane != &priv->f0)
+ 			en_bit = JZ_LCD_OSDC_F1EN;
+ 		else
+ 			en_bit = JZ_LCD_OSDC_F0EN;
+@@ -461,8 +461,7 @@ void ingenic_drm_plane_config(struct device *dev,
+ 
+ 	ingenic_drm_plane_enable(priv, plane);
+ 
+-	if (priv->soc_info->has_osd &&
+-	    plane->type == DRM_PLANE_TYPE_PRIMARY) {
++	if (priv->soc_info->has_osd && plane != &priv->f0) {
+ 		switch (fourcc) {
+ 		case DRM_FORMAT_XRGB1555:
+ 			ctrl |= JZ_LCD_OSDCTRL_RGB555;
+@@ -510,7 +509,7 @@ void ingenic_drm_plane_config(struct device *dev,
+ 	}
+ 
+ 	if (priv->soc_info->has_osd) {
+-		if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
++		if (plane != &priv->f0) {
+ 			xy_reg = JZ_REG_LCD_XYP1;
+ 			size_reg = JZ_REG_LCD_SIZE1;
+ 		} else {
+@@ -561,7 +560,7 @@ static void ingenic_drm_plane_atomic_update(struct drm_plane *plane,
+ 		height = newstate->src_h >> 16;
+ 		cpp = newstate->fb->format->cpp[0];
+ 
+-		if (!priv->soc_info->has_osd || plane->type == DRM_PLANE_TYPE_OVERLAY)
++		if (!priv->soc_info->has_osd || plane == &priv->f0)
+ 			hwdesc = &priv->dma_hwdescs->hwdesc_f0;
+ 		else
+ 			hwdesc = &priv->dma_hwdescs->hwdesc_f1;
+diff --git a/drivers/gpu/drm/ingenic/ingenic-ipu.c b/drivers/gpu/drm/ingenic/ingenic-ipu.c
+index 5ae6adab8306c..3b1091e7c0cde 100644
+--- a/drivers/gpu/drm/ingenic/ingenic-ipu.c
++++ b/drivers/gpu/drm/ingenic/ingenic-ipu.c
+@@ -767,7 +767,7 @@ static int ingenic_ipu_bind(struct device *dev, struct device *master, void *d)
+ 
+ 	err = drm_universal_plane_init(drm, plane, 1, &ingenic_ipu_plane_funcs,
+ 				       soc_info->formats, soc_info->num_formats,
+-				       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
++				       NULL, DRM_PLANE_TYPE_OVERLAY, NULL);
+ 	if (err) {
+ 		dev_err(dev, "Failed to init plane: %i\n", err);
+ 		return err;
+diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+index 40df2c8231877..474efb8442493 100644
+--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
++++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+@@ -260,7 +260,7 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
+ 		drm_connector_list_iter_end(&conn_iter);
+ 	}
+ 
+-	ret = pm_runtime_get_sync(crtc->dev->dev);
++	ret = pm_runtime_resume_and_get(crtc->dev->dev);
+ 	if (ret < 0) {
+ 		DRM_ERROR("Failed to enable power domain: %d\n", ret);
+ 		return ret;
+diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
+index 3d729270bde15..4a5b518288b06 100644
+--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
++++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
+@@ -88,8 +88,6 @@ static int mdp4_hw_init(struct msm_kms *kms)
+ 	if (mdp4_kms->rev > 1)
+ 		mdp4_write(mdp4_kms, REG_MDP4_RESET_STATUS, 1);
+ 
+-	dev->mode_config.allow_fb_modifiers = true;
+-
+ out:
+ 	pm_runtime_put_sync(dev->dev);
+ 
+diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c
+index 9aecca919f24b..49bdabea8ed59 100644
+--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c
++++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c
+@@ -349,6 +349,12 @@ enum mdp4_pipe mdp4_plane_pipe(struct drm_plane *plane)
+ 	return mdp4_plane->pipe;
+ }
+ 
++static const uint64_t supported_format_modifiers[] = {
++	DRM_FORMAT_MOD_SAMSUNG_64_32_TILE,
++	DRM_FORMAT_MOD_LINEAR,
++	DRM_FORMAT_MOD_INVALID
++};
++
+ /* initialize plane */
+ struct drm_plane *mdp4_plane_init(struct drm_device *dev,
+ 		enum mdp4_pipe pipe_id, bool private_plane)
+@@ -377,7 +383,7 @@ struct drm_plane *mdp4_plane_init(struct drm_device *dev,
+ 	type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
+ 	ret = drm_universal_plane_init(dev, plane, 0xff, &mdp4_plane_funcs,
+ 				 mdp4_plane->formats, mdp4_plane->nformats,
+-				 NULL, type, NULL);
++				 supported_format_modifiers, type, NULL);
+ 	if (ret)
+ 		goto fail;
+ 
+diff --git a/drivers/gpu/drm/mxsfb/Kconfig b/drivers/gpu/drm/mxsfb/Kconfig
+index 0143d539f8f82..ee22cd25d3e3d 100644
+--- a/drivers/gpu/drm/mxsfb/Kconfig
++++ b/drivers/gpu/drm/mxsfb/Kconfig
+@@ -10,7 +10,6 @@ config DRM_MXSFB
+ 	depends on COMMON_CLK
+ 	select DRM_MXS
+ 	select DRM_KMS_HELPER
+-	select DRM_KMS_FB_HELPER
+ 	select DRM_KMS_CMA_HELPER
+ 	select DRM_PANEL
+ 	select DRM_PANEL_BRIDGE
+diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
+index dac02c7be54dc..ac6cb8c6fc1a1 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_display.c
++++ b/drivers/gpu/drm/nouveau/nouveau_display.c
+@@ -697,7 +697,6 @@ nouveau_display_create(struct drm_device *dev)
+ 
+ 	dev->mode_config.preferred_depth = 24;
+ 	dev->mode_config.prefer_shadow = 1;
+-	dev->mode_config.allow_fb_modifiers = true;
+ 
+ 	if (drm->client.device.info.chipset < 0x11)
+ 		dev->mode_config.async_page_flip = false;
+diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
+index 47d27e54a34f2..3644652f726f7 100644
+--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
++++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
+@@ -92,6 +92,15 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
+ 	struct thermal_cooling_device *cooling;
+ 	struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
+ 
++	if (pfdev->comp->num_supplies > 1) {
++		/*
++		 * GPUs with more than 1 supply require platform-specific handling:
++		 * continue without devfreq
++		 */
++		DRM_DEV_INFO(dev, "More than 1 supply is not supported yet\n");
++		return 0;
++	}
++
+ 	ret = devm_pm_opp_set_regulators(dev, pfdev->comp->supply_names,
+ 					 pfdev->comp->num_supplies);
+ 	if (ret) {
+diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
+index 652af7a134bd0..1d03ec7636047 100644
+--- a/drivers/gpu/drm/radeon/radeon_display.c
++++ b/drivers/gpu/drm/radeon/radeon_display.c
+@@ -1325,6 +1325,7 @@ radeon_user_framebuffer_create(struct drm_device *dev,
+ 	/* Handle is imported dma-buf, so cannot be migrated to VRAM for scanout */
+ 	if (obj->import_attach) {
+ 		DRM_DEBUG_KMS("Cannot create framebuffer from imported dma_buf\n");
++		drm_gem_object_put(obj);
+ 		return ERR_PTR(-EINVAL);
+ 	}
+ 
+diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
+index efeb115ae70ec..40aece37e0b4e 100644
+--- a/drivers/gpu/drm/radeon/radeon_drv.c
++++ b/drivers/gpu/drm/radeon/radeon_drv.c
+@@ -386,13 +386,13 @@ radeon_pci_shutdown(struct pci_dev *pdev)
+ 	if (radeon_device_is_virtual())
+ 		radeon_pci_remove(pdev);
+ 
+-#ifdef CONFIG_PPC64
++#if defined(CONFIG_PPC64) || defined(CONFIG_MACH_LOONGSON64)
+ 	/*
+ 	 * Some adapters need to be suspended before a
+ 	 * shutdown occurs in order to prevent an error
+-	 * during kexec.
+-	 * Make this power specific becauase it breaks
+-	 * some non-power boards.
++	 * during kexec, shutdown or reboot.
++	 * Make this power and Loongson specific because
++	 * it breaks some other boards.
+ 	 */
+ 	radeon_suspend_kms(pci_get_drvdata(pdev), true, true, false);
+ #endif
+diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+index d8c47ee3cad37..520a0a0cd2b56 100644
+--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
++++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+@@ -243,7 +243,6 @@ struct dw_mipi_dsi_rockchip {
+ 	struct dw_mipi_dsi *dmd;
+ 	const struct rockchip_dw_dsi_chip_data *cdata;
+ 	struct dw_mipi_dsi_plat_data pdata;
+-	int devcnt;
+ };
+ 
+ struct dphy_pll_parameter_map {
+@@ -1141,9 +1140,6 @@ static int dw_mipi_dsi_rockchip_remove(struct platform_device *pdev)
+ {
+ 	struct dw_mipi_dsi_rockchip *dsi = platform_get_drvdata(pdev);
+ 
+-	if (dsi->devcnt == 0)
+-		component_del(dsi->dev, &dw_mipi_dsi_rockchip_ops);
+-
+ 	dw_mipi_dsi_remove(dsi->dmd);
+ 
+ 	return 0;
+diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+index 80053d91a301f..a6fe03c3748aa 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
++++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+@@ -349,8 +349,8 @@ static const struct vop_win_phy rk3066_win0_data = {
+ 	.nformats = ARRAY_SIZE(formats_win_full),
+ 	.format_modifiers = format_modifiers_win_full,
+ 	.enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 0),
+-	.format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 4),
+-	.rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 19),
++	.format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 4),
++	.rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 19),
+ 	.act_info = VOP_REG(RK3066_WIN0_ACT_INFO, 0x1fff1fff, 0),
+ 	.dsp_info = VOP_REG(RK3066_WIN0_DSP_INFO, 0x0fff0fff, 0),
+ 	.dsp_st = VOP_REG(RK3066_WIN0_DSP_ST, 0x1fff1fff, 0),
+@@ -361,13 +361,12 @@ static const struct vop_win_phy rk3066_win0_data = {
+ };
+ 
+ static const struct vop_win_phy rk3066_win1_data = {
+-	.scl = &rk3066_win_scl,
+ 	.data_formats = formats_win_full,
+ 	.nformats = ARRAY_SIZE(formats_win_full),
+ 	.format_modifiers = format_modifiers_win_full,
+ 	.enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 1),
+-	.format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 7),
+-	.rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 23),
++	.format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 7),
++	.rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 23),
+ 	.act_info = VOP_REG(RK3066_WIN1_ACT_INFO, 0x1fff1fff, 0),
+ 	.dsp_info = VOP_REG(RK3066_WIN1_DSP_INFO, 0x0fff0fff, 0),
+ 	.dsp_st = VOP_REG(RK3066_WIN1_DSP_ST, 0x1fff1fff, 0),
+@@ -382,8 +381,8 @@ static const struct vop_win_phy rk3066_win2_data = {
+ 	.nformats = ARRAY_SIZE(formats_win_lite),
+ 	.format_modifiers = format_modifiers_win_lite,
+ 	.enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 2),
+-	.format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 10),
+-	.rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 27),
++	.format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 10),
++	.rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 27),
+ 	.dsp_info = VOP_REG(RK3066_WIN2_DSP_INFO, 0x0fff0fff, 0),
+ 	.dsp_st = VOP_REG(RK3066_WIN2_DSP_ST, 0x1fff1fff, 0),
+ 	.yrgb_mst = VOP_REG(RK3066_WIN2_MST, 0xffffffff, 0),
+@@ -408,6 +407,9 @@ static const struct vop_common rk3066_common = {
+ 	.dither_down_en = VOP_REG(RK3066_DSP_CTRL0, 0x1, 11),
+ 	.dither_down_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 10),
+ 	.dsp_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 24),
++	.dither_up = VOP_REG(RK3066_DSP_CTRL0, 0x1, 9),
++	.dsp_lut_en = VOP_REG(RK3066_SYS_CTRL1, 0x1, 31),
++	.data_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 25),
+ };
+ 
+ static const struct vop_win_data rk3066_vop_win_data[] = {
+@@ -505,7 +507,10 @@ static const struct vop_common rk3188_common = {
+ 	.dither_down_sel = VOP_REG(RK3188_DSP_CTRL0, 0x1, 27),
+ 	.dither_down_en = VOP_REG(RK3188_DSP_CTRL0, 0x1, 11),
+ 	.dither_down_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 10),
+-	.dsp_blank = VOP_REG(RK3188_DSP_CTRL1, 0x3, 24),
++	.dsp_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 24),
++	.dither_up = VOP_REG(RK3188_DSP_CTRL0, 0x1, 9),
++	.dsp_lut_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 28),
++	.data_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 25),
+ };
+ 
+ static const struct vop_win_data rk3188_vop_win_data[] = {
+diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c
+index f0790e9471d1a..86a4209d8c770 100644
+--- a/drivers/gpu/drm/scheduler/sched_entity.c
++++ b/drivers/gpu/drm/scheduler/sched_entity.c
+@@ -116,7 +116,8 @@ static bool drm_sched_entity_is_idle(struct drm_sched_entity *entity)
+ 	rmb(); /* for list_empty to work without lock */
+ 
+ 	if (list_empty(&entity->list) ||
+-	    spsc_queue_count(&entity->job_queue) == 0)
++	    spsc_queue_count(&entity->job_queue) == 0 ||
++	    entity->stopped)
+ 		return true;
+ 
+ 	return false;
+@@ -221,11 +222,16 @@ static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,
+ static void drm_sched_entity_kill_jobs(struct drm_sched_entity *entity)
+ {
+ 	struct drm_sched_job *job;
++	struct dma_fence *f;
+ 	int r;
+ 
+ 	while ((job = to_drm_sched_job(spsc_queue_pop(&entity->job_queue)))) {
+ 		struct drm_sched_fence *s_fence = job->s_fence;
+ 
++		/* Wait for all dependencies to avoid data corruptions */
++		while ((f = job->sched->ops->dependency(job, entity)))
++			dma_fence_wait(f, false);
++
+ 		drm_sched_fence_scheduled(s_fence);
+ 		dma_fence_set_error(&s_fence->finished, -ESRCH);
+ 
+diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c
+index 92d8de24d0a17..c105c807d7e53 100644
+--- a/drivers/gpu/drm/scheduler/sched_main.c
++++ b/drivers/gpu/drm/scheduler/sched_main.c
+@@ -888,9 +888,33 @@ EXPORT_SYMBOL(drm_sched_init);
+  */
+ void drm_sched_fini(struct drm_gpu_scheduler *sched)
+ {
++	struct drm_sched_entity *s_entity;
++	int i;
++
+ 	if (sched->thread)
+ 		kthread_stop(sched->thread);
+ 
++	for (i = DRM_SCHED_PRIORITY_COUNT - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) {
++		struct drm_sched_rq *rq = &sched->sched_rq[i];
++
++		if (!rq)
++			continue;
++
++		spin_lock(&rq->lock);
++		list_for_each_entry(s_entity, &rq->entities, list)
++			/*
++			 * Prevents reinsertion and marks job_queue as idle,
++			 * it will removed from rq in drm_sched_entity_fini
++			 * eventually
++			 */
++			s_entity->stopped = true;
++		spin_unlock(&rq->lock);
++
++	}
++
++	/* Wakeup everyone stuck in drm_sched_entity_flush for this scheduler */
++	wake_up_all(&sched->job_scheduled);
++
+ 	/* Confirm no work left behind accessing device structures */
+ 	cancel_delayed_work_sync(&sched->work_tdr);
+ 
+diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
+index f9120dc246828..51bbbc42a144f 100644
+--- a/drivers/gpu/drm/tegra/dc.c
++++ b/drivers/gpu/drm/tegra/dc.c
+@@ -348,7 +348,7 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
+ 	 * For YUV planar modes, the number of bytes per pixel takes into
+ 	 * account only the luma component and therefore is 1.
+ 	 */
+-	yuv = tegra_plane_format_is_yuv(window->format, &planar);
++	yuv = tegra_plane_format_is_yuv(window->format, &planar, NULL);
+ 	if (!yuv)
+ 		bpp = window->bits_per_pixel / 8;
+ 	else
+@@ -999,6 +999,11 @@ static const struct drm_plane_helper_funcs tegra_cursor_plane_helper_funcs = {
+ 	.atomic_disable = tegra_cursor_atomic_disable,
+ };
+ 
++static const uint64_t linear_modifiers[] = {
++	DRM_FORMAT_MOD_LINEAR,
++	DRM_FORMAT_MOD_INVALID
++};
++
+ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm,
+ 						      struct tegra_dc *dc)
+ {
+@@ -1032,7 +1037,7 @@ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm,
+ 
+ 	err = drm_universal_plane_init(drm, &plane->base, possible_crtcs,
+ 				       &tegra_plane_funcs, formats,
+-				       num_formats, NULL,
++				       num_formats, linear_modifiers,
+ 				       DRM_PLANE_TYPE_CURSOR, NULL);
+ 	if (err < 0) {
+ 		kfree(plane);
+@@ -1151,7 +1156,8 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
+ 
+ 	err = drm_universal_plane_init(drm, &plane->base, possible_crtcs,
+ 				       &tegra_plane_funcs, formats,
+-				       num_formats, NULL, type, NULL);
++				       num_formats, linear_modifiers,
++				       type, NULL);
+ 	if (err < 0) {
+ 		kfree(plane);
+ 		return ERR_PTR(err);
+diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
+index 29f19c3c61493..455c3fdef8dc9 100644
+--- a/drivers/gpu/drm/tegra/dc.h
++++ b/drivers/gpu/drm/tegra/dc.h
+@@ -696,6 +696,9 @@ int tegra_dc_rgb_exit(struct tegra_dc *dc);
+ 
+ #define DC_WINBUF_START_ADDR_HI			0x80d
+ 
++#define DC_WINBUF_START_ADDR_HI_U		0x80f
++#define DC_WINBUF_START_ADDR_HI_V		0x811
++
+ #define DC_WINBUF_CDE_CONTROL			0x82f
+ #define  ENABLE_SURFACE (1 << 0)
+ 
+@@ -720,6 +723,10 @@ int tegra_dc_rgb_exit(struct tegra_dc *dc);
+ #define DC_WIN_PLANAR_STORAGE			0x709
+ #define PITCH(x) (((x) >> 6) & 0x1fff)
+ 
++#define DC_WIN_PLANAR_STORAGE_UV		0x70a
++#define  PITCH_U(x) ((((x) >> 6) & 0x1fff) <<  0)
++#define  PITCH_V(x) ((((x) >> 6) & 0x1fff) << 16)
++
+ #define DC_WIN_SET_PARAMS			0x70d
+ #define  CLAMP_BEFORE_BLEND (1 << 15)
+ #define  DEGAMMA_NONE (0 << 13)
+diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
+index 0c350b0daab47..fbd00fbfe862e 100644
+--- a/drivers/gpu/drm/tegra/drm.c
++++ b/drivers/gpu/drm/tegra/drm.c
+@@ -1124,8 +1124,6 @@ static int host1x_drm_probe(struct host1x_device *dev)
+ 	drm->mode_config.max_width = 0;
+ 	drm->mode_config.max_height = 0;
+ 
+-	drm->mode_config.allow_fb_modifiers = true;
+-
+ 	drm->mode_config.normalize_zpos = true;
+ 
+ 	drm->mode_config.funcs = &tegra_drm_mode_config_funcs;
+diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c
+index bfae8a02f55b8..94e1ccfb6235a 100644
+--- a/drivers/gpu/drm/tegra/hub.c
++++ b/drivers/gpu/drm/tegra/hub.c
+@@ -454,7 +454,9 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane,
+ 	unsigned int zpos = new_state->normalized_zpos;
+ 	struct drm_framebuffer *fb = new_state->fb;
+ 	struct tegra_plane *p = to_tegra_plane(plane);
+-	dma_addr_t base;
++	dma_addr_t base, addr_flag = 0;
++	unsigned int bpc;
++	bool yuv, planar;
+ 	u32 value;
+ 	int err;
+ 
+@@ -473,6 +475,8 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane,
+ 		return;
+ 	}
+ 
++	yuv = tegra_plane_format_is_yuv(tegra_plane_state->format, &planar, &bpc);
++
+ 	tegra_dc_assign_shared_plane(dc, p);
+ 
+ 	tegra_plane_writel(p, VCOUNTER, DC_WIN_CORE_ACT_CONTROL);
+@@ -501,8 +505,6 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane,
+ 	/* disable compression */
+ 	tegra_plane_writel(p, 0, DC_WINBUF_CDE_CONTROL);
+ 
+-	base = tegra_plane_state->iova[0] + fb->offsets[0];
+-
+ #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+ 	/*
+ 	 * Physical address bit 39 in Tegra194 is used as a switch for special
+@@ -510,9 +512,12 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane,
+ 	 * dGPU sector layout.
+ 	 */
+ 	if (tegra_plane_state->tiling.sector_layout == TEGRA_BO_SECTOR_LAYOUT_GPU)
+-		base |= BIT_ULL(39);
++		addr_flag = BIT_ULL(39);
+ #endif
+ 
++	base = tegra_plane_state->iova[0] + fb->offsets[0];
++	base |= addr_flag;
++
+ 	tegra_plane_writel(p, tegra_plane_state->format, DC_WIN_COLOR_DEPTH);
+ 	tegra_plane_writel(p, 0, DC_WIN_PRECOMP_WGRP_PARAMS);
+ 
+@@ -535,7 +540,44 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane,
+ 	value = PITCH(fb->pitches[0]);
+ 	tegra_plane_writel(p, value, DC_WIN_PLANAR_STORAGE);
+ 
+-	value = CLAMP_BEFORE_BLEND | DEGAMMA_SRGB | INPUT_RANGE_FULL;
++	if (yuv && planar) {
++		base = tegra_plane_state->iova[1] + fb->offsets[1];
++		base |= addr_flag;
++
++		tegra_plane_writel(p, upper_32_bits(base), DC_WINBUF_START_ADDR_HI_U);
++		tegra_plane_writel(p, lower_32_bits(base), DC_WINBUF_START_ADDR_U);
++
++		base = tegra_plane_state->iova[2] + fb->offsets[2];
++		base |= addr_flag;
++
++		tegra_plane_writel(p, upper_32_bits(base), DC_WINBUF_START_ADDR_HI_V);
++		tegra_plane_writel(p, lower_32_bits(base), DC_WINBUF_START_ADDR_V);
++
++		value = PITCH_U(fb->pitches[2]) | PITCH_V(fb->pitches[2]);
++		tegra_plane_writel(p, value, DC_WIN_PLANAR_STORAGE_UV);
++	} else {
++		tegra_plane_writel(p, 0, DC_WINBUF_START_ADDR_U);
++		tegra_plane_writel(p, 0, DC_WINBUF_START_ADDR_HI_U);
++		tegra_plane_writel(p, 0, DC_WINBUF_START_ADDR_V);
++		tegra_plane_writel(p, 0, DC_WINBUF_START_ADDR_HI_V);
++		tegra_plane_writel(p, 0, DC_WIN_PLANAR_STORAGE_UV);
++	}
++
++	value = CLAMP_BEFORE_BLEND | INPUT_RANGE_FULL;
++
++	if (yuv) {
++		if (bpc < 12)
++			value |= DEGAMMA_YUV8_10;
++		else
++			value |= DEGAMMA_YUV12;
++
++		/* XXX parameterize */
++		value |= COLOR_SPACE_YUV_2020;
++	} else {
++		if (!tegra_plane_format_is_indexed(tegra_plane_state->format))
++			value |= DEGAMMA_SRGB;
++	}
++
+ 	tegra_plane_writel(p, value, DC_WIN_SET_PARAMS);
+ 
+ 	value = OFFSET_X(new_state->src_y >> 16) |
+diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
+index 2e11b4b1f7025..2e65b4075ce6c 100644
+--- a/drivers/gpu/drm/tegra/plane.c
++++ b/drivers/gpu/drm/tegra/plane.c
+@@ -375,7 +375,20 @@ int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap)
+ 	return 0;
+ }
+ 
+-bool tegra_plane_format_is_yuv(unsigned int format, bool *planar)
++bool tegra_plane_format_is_indexed(unsigned int format)
++{
++	switch (format) {
++	case WIN_COLOR_DEPTH_P1:
++	case WIN_COLOR_DEPTH_P2:
++	case WIN_COLOR_DEPTH_P4:
++	case WIN_COLOR_DEPTH_P8:
++		return true;
++	}
++
++	return false;
++}
++
++bool tegra_plane_format_is_yuv(unsigned int format, bool *planar, unsigned int *bpc)
+ {
+ 	switch (format) {
+ 	case WIN_COLOR_DEPTH_YCbCr422:
+@@ -383,6 +396,9 @@ bool tegra_plane_format_is_yuv(unsigned int format, bool *planar)
+ 		if (planar)
+ 			*planar = false;
+ 
++		if (bpc)
++			*bpc = 8;
++
+ 		return true;
+ 
+ 	case WIN_COLOR_DEPTH_YCbCr420P:
+@@ -396,6 +412,9 @@ bool tegra_plane_format_is_yuv(unsigned int format, bool *planar)
+ 		if (planar)
+ 			*planar = true;
+ 
++		if (bpc)
++			*bpc = 8;
++
+ 		return true;
+ 	}
+ 
+@@ -421,7 +440,7 @@ static bool __drm_format_has_alpha(u32 format)
+ static int tegra_plane_format_get_alpha(unsigned int opaque,
+ 					unsigned int *alpha)
+ {
+-	if (tegra_plane_format_is_yuv(opaque, NULL)) {
++	if (tegra_plane_format_is_yuv(opaque, NULL, NULL)) {
+ 		*alpha = opaque;
+ 		return 0;
+ 	}
+diff --git a/drivers/gpu/drm/tegra/plane.h b/drivers/gpu/drm/tegra/plane.h
+index c691dd79b27b1..1785c1559c0ce 100644
+--- a/drivers/gpu/drm/tegra/plane.h
++++ b/drivers/gpu/drm/tegra/plane.h
+@@ -74,7 +74,8 @@ int tegra_plane_state_add(struct tegra_plane *plane,
+ 			  struct drm_plane_state *state);
+ 
+ int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap);
+-bool tegra_plane_format_is_yuv(unsigned int format, bool *planar);
++bool tegra_plane_format_is_indexed(unsigned int format);
++bool tegra_plane_format_is_yuv(unsigned int format, bool *planar, unsigned int *bpc);
+ int tegra_plane_setup_legacy_state(struct tegra_plane *tegra,
+ 				   struct tegra_plane_state *state);
+ 
+diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
+index 1f36b67cd6ce9..18f5009ce90e3 100644
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c
+@@ -1035,7 +1035,7 @@ static const struct vc4_pv_data bcm2711_pv3_data = {
+ 	.fifo_depth = 64,
+ 	.pixels_per_clock = 1,
+ 	.encoder_types = {
+-		[0] = VC4_ENCODER_TYPE_VEC,
++		[PV_CONTROL_CLK_SELECT_VEC] = VC4_ENCODER_TYPE_VEC,
+ 	},
+ };
+ 
+@@ -1076,6 +1076,9 @@ static void vc4_set_crtc_possible_masks(struct drm_device *drm,
+ 		struct vc4_encoder *vc4_encoder;
+ 		int i;
+ 
++		if (encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL)
++			continue;
++
+ 		vc4_encoder = to_vc4_encoder(encoder);
+ 		for (i = 0; i < ARRAY_SIZE(pv_data->encoder_types); i++) {
+ 			if (vc4_encoder->type == encoder_types[i]) {
+diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
+index a7500716cf3f1..5dceadc61600e 100644
+--- a/drivers/gpu/drm/vc4/vc4_drv.h
++++ b/drivers/gpu/drm/vc4/vc4_drv.h
+@@ -825,7 +825,7 @@ void vc4_crtc_destroy_state(struct drm_crtc *crtc,
+ void vc4_crtc_reset(struct drm_crtc *crtc);
+ void vc4_crtc_handle_vblank(struct vc4_crtc *crtc);
+ void vc4_crtc_get_margins(struct drm_crtc_state *state,
+-			  unsigned int *right, unsigned int *left,
++			  unsigned int *left, unsigned int *right,
+ 			  unsigned int *top, unsigned int *bottom);
+ 
+ /* vc4_debugfs.c */
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index e94730beb15b7..188b74c9e9fff 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -745,7 +745,7 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder,
+ 	unsigned long pixel_rate, hsm_rate;
+ 	int ret;
+ 
+-	ret = pm_runtime_get_sync(&vc4_hdmi->pdev->dev);
++	ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev);
+ 	if (ret < 0) {
+ 		DRM_ERROR("Failed to retain power domain: %d\n", ret);
+ 		return;
+@@ -2012,6 +2012,14 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
+ 	if (vc4_hdmi->variant->reset)
+ 		vc4_hdmi->variant->reset(vc4_hdmi);
+ 
++	if ((of_device_is_compatible(dev->of_node, "brcm,bcm2711-hdmi0") ||
++	     of_device_is_compatible(dev->of_node, "brcm,bcm2711-hdmi1")) &&
++	    HDMI_READ(HDMI_VID_CTL) & VC4_HD_VID_CTL_ENABLE) {
++		clk_prepare_enable(vc4_hdmi->pixel_clock);
++		clk_prepare_enable(vc4_hdmi->hsm_clock);
++		clk_prepare_enable(vc4_hdmi->pixel_bvb_clock);
++	}
++
+ 	pm_runtime_enable(dev);
+ 
+ 	drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
+diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c
+index c0122d83b6511..2fc7f4b5fa098 100644
+--- a/drivers/gpu/drm/vc4/vc4_txp.c
++++ b/drivers/gpu/drm/vc4/vc4_txp.c
+@@ -507,7 +507,7 @@ static int vc4_txp_bind(struct device *dev, struct device *master, void *data)
+ 		return ret;
+ 
+ 	encoder = &txp->connector.encoder;
+-	encoder->possible_crtcs |= drm_crtc_mask(crtc);
++	encoder->possible_crtcs = drm_crtc_mask(crtc);
+ 
+ 	ret = devm_request_irq(dev, irq, vc4_txp_interrupt, 0,
+ 			       dev_name(dev), txp);
+diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c
+index b375394193be8..37a21a88d674c 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_kms.c
++++ b/drivers/gpu/drm/virtio/virtgpu_kms.c
+@@ -234,6 +234,7 @@ err_scanouts:
+ err_vbufs:
+ 	vgdev->vdev->config->del_vqs(vgdev->vdev);
+ err_vqs:
++	dev->dev_private = NULL;
+ 	kfree(vgdev);
+ 	return ret;
+ }
+diff --git a/drivers/gpu/drm/zte/Kconfig b/drivers/gpu/drm/zte/Kconfig
+index 90ebaedc11fdf..aa8594190b509 100644
+--- a/drivers/gpu/drm/zte/Kconfig
++++ b/drivers/gpu/drm/zte/Kconfig
+@@ -3,7 +3,6 @@ config DRM_ZTE
+ 	tristate "DRM Support for ZTE SoCs"
+ 	depends on DRM && ARCH_ZX
+ 	select DRM_KMS_CMA_HELPER
+-	select DRM_KMS_FB_HELPER
+ 	select DRM_KMS_HELPER
+ 	select SND_SOC_HDMI_CODEC if SND_SOC
+ 	select VIDEOMODE_HELPERS
+diff --git a/drivers/gpu/ipu-v3/ipu-dc.c b/drivers/gpu/ipu-v3/ipu-dc.c
+index 34b4075a6a8e5..ca96b235491a9 100644
+--- a/drivers/gpu/ipu-v3/ipu-dc.c
++++ b/drivers/gpu/ipu-v3/ipu-dc.c
+@@ -167,6 +167,11 @@ int ipu_dc_init_sync(struct ipu_dc *dc, struct ipu_di *di, bool interlaced,
+ 
+ 	dc->di = ipu_di_get_num(di);
+ 
++	if (!IS_ALIGNED(width, 8)) {
++		dev_warn(priv->dev,
++			 "%s: hactive does not align to 8 byte\n", __func__);
++	}
++
+ 	map = ipu_bus_format_to_map(bus_format);
+ 
+ 	/*
+diff --git a/drivers/gpu/ipu-v3/ipu-di.c b/drivers/gpu/ipu-v3/ipu-di.c
+index e617f60afeea3..666223c6bec4d 100644
+--- a/drivers/gpu/ipu-v3/ipu-di.c
++++ b/drivers/gpu/ipu-v3/ipu-di.c
+@@ -506,6 +506,13 @@ int ipu_di_adjust_videomode(struct ipu_di *di, struct videomode *mode)
+ {
+ 	u32 diff;
+ 
++	if (!IS_ALIGNED(mode->hactive, 8) &&
++	    mode->hfront_porch < ALIGN(mode->hactive, 8) - mode->hactive) {
++		dev_err(di->ipu->dev, "hactive %d is not aligned to 8 and front porch is too small to compensate\n",
++			mode->hactive);
++		return -EINVAL;
++	}
++
+ 	if (mode->vfront_porch >= 2)
+ 		return 0;
+ 
+diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
+index 4ddf3d2338443..3cfefcdb0dfd1 100644
+--- a/drivers/hwtracing/coresight/coresight-core.c
++++ b/drivers/hwtracing/coresight/coresight-core.c
+@@ -1392,7 +1392,7 @@ static int coresight_fixup_device_conns(struct coresight_device *csdev)
+ 		}
+ 	}
+ 
+-	return 0;
++	return ret;
+ }
+ 
+ static int coresight_remove_match(struct device *dev, void *data)
+diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
+index 45b85edfc6900..cd0fb7bfba684 100644
+--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
++++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
+@@ -530,7 +530,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
+ 		buf_ptr = buf->data_pages[cur] + offset;
+ 		*buf_ptr = readl_relaxed(drvdata->base + TMC_RRD);
+ 
+-		if (lost && *barrier) {
++		if (lost && i < CORESIGHT_BARRIER_PKT_SIZE) {
+ 			*buf_ptr = *barrier;
+ 			barrier++;
+ 		}
+diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
+index ad9a9ba5f00d1..5d3b8b8d163d6 100644
+--- a/drivers/infiniband/core/cma.c
++++ b/drivers/infiniband/core/cma.c
+@@ -2829,7 +2829,8 @@ static int cma_resolve_ib_route(struct rdma_id_private *id_priv,
+ 
+ 	cma_init_resolve_route_work(work, id_priv);
+ 
+-	route->path_rec = kmalloc(sizeof *route->path_rec, GFP_KERNEL);
++	if (!route->path_rec)
++		route->path_rec = kmalloc(sizeof *route->path_rec, GFP_KERNEL);
+ 	if (!route->path_rec) {
+ 		ret = -ENOMEM;
+ 		goto err1;
+diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c
+index d109bb3822a5f..c9403743346e1 100644
+--- a/drivers/infiniband/hw/cxgb4/qp.c
++++ b/drivers/infiniband/hw/cxgb4/qp.c
+@@ -295,6 +295,7 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq,
+ 	if (user && (!wq->sq.bar2_pa || (need_rq && !wq->rq.bar2_pa))) {
+ 		pr_warn("%s: sqid %u or rqid %u not in BAR2 range\n",
+ 			pci_name(rdev->lldi.pdev), wq->sq.qid, wq->rq.qid);
++		ret = -EINVAL;
+ 		goto free_dma;
+ 	}
+ 
+diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c
+index 9f63947bab123..fe2b7d223183f 100644
+--- a/drivers/infiniband/sw/rxe/rxe_mr.c
++++ b/drivers/infiniband/sw/rxe/rxe_mr.c
+@@ -135,7 +135,7 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,
+ 	if (IS_ERR(umem)) {
+ 		pr_warn("err %d from rxe_umem_get\n",
+ 			(int)PTR_ERR(umem));
+-		err = -EINVAL;
++		err = PTR_ERR(umem);
+ 		goto err1;
+ 	}
+ 
+diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
+index 18266f07c58d9..de3fc05fd2e8a 100644
+--- a/drivers/infiniband/ulp/isert/ib_isert.c
++++ b/drivers/infiniband/ulp/isert/ib_isert.c
+@@ -35,10 +35,10 @@ static const struct kernel_param_ops sg_tablesize_ops = {
+ 	.get = param_get_int,
+ };
+ 
+-static int isert_sg_tablesize = ISCSI_ISER_DEF_SG_TABLESIZE;
++static int isert_sg_tablesize = ISCSI_ISER_MIN_SG_TABLESIZE;
+ module_param_cb(sg_tablesize, &sg_tablesize_ops, &isert_sg_tablesize, 0644);
+ MODULE_PARM_DESC(sg_tablesize,
+-		 "Number of gather/scatter entries in a single scsi command, should >= 128 (default: 256, max: 4096)");
++		 "Number of gather/scatter entries in a single scsi command, should >= 128 (default: 128, max: 4096)");
+ 
+ static DEFINE_MUTEX(device_list_mutex);
+ static LIST_HEAD(device_list);
+diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h
+index 6c5af13db4e0d..ca8cfebe26ca7 100644
+--- a/drivers/infiniband/ulp/isert/ib_isert.h
++++ b/drivers/infiniband/ulp/isert/ib_isert.h
+@@ -65,9 +65,6 @@
+  */
+ #define ISER_RX_SIZE		(ISCSI_DEF_MAX_RECV_SEG_LEN + 1024)
+ 
+-/* Default I/O size is 1MB */
+-#define ISCSI_ISER_DEF_SG_TABLESIZE 256
+-
+ /* Minimum I/O size is 512KB */
+ #define ISCSI_ISER_MIN_SG_TABLESIZE 128
+ 
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-pri.h b/drivers/infiniband/ulp/rtrs/rtrs-pri.h
+index 86e65cf30cab0..d957bbf1ddd36 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-pri.h
++++ b/drivers/infiniband/ulp/rtrs/rtrs-pri.h
+@@ -47,12 +47,15 @@ enum {
+ 	MAX_PATHS_NUM = 128,
+ 
+ 	/*
+-	 * With the size of struct rtrs_permit allocated on the client, 4K
+-	 * is the maximum number of rtrs_permits we can allocate. This number is
+-	 * also used on the client to allocate the IU for the user connection
+-	 * to receive the RDMA addresses from the server.
++	 * Max IB immediate data size is 2^28 (MAX_IMM_PAYL_BITS)
++	 * and the minimum chunk size is 4096 (2^12).
++	 * So the maximum sess_queue_depth is 65536 (2^16) in theory.
++	 * But mempool_create, create_qp and ib_post_send fail with
++	 * "cannot allocate memory" error if sess_queue_depth is too big.
++	 * Therefore the pratical max value of sess_queue_depth is
++	 * somewhere between 1 and 65536 and it depends on the system.
+ 	 */
+-	MAX_SESS_QUEUE_DEPTH = 4096,
++	MAX_SESS_QUEUE_DEPTH = 65536,
+ 
+ 	RTRS_HB_INTERVAL_MS = 5000,
+ 	RTRS_HB_MISSED_MAX = 5,
+diff --git a/drivers/ipack/carriers/tpci200.c b/drivers/ipack/carriers/tpci200.c
+index ec71063fff76a..e1822e87ec3d2 100644
+--- a/drivers/ipack/carriers/tpci200.c
++++ b/drivers/ipack/carriers/tpci200.c
+@@ -596,8 +596,11 @@ static int tpci200_pci_probe(struct pci_dev *pdev,
+ 
+ out_err_bus_register:
+ 	tpci200_uninstall(tpci200);
++	/* tpci200->info->cfg_regs is unmapped in tpci200_uninstall */
++	tpci200->info->cfg_regs = NULL;
+ out_err_install:
+-	iounmap(tpci200->info->cfg_regs);
++	if (tpci200->info->cfg_regs)
++		iounmap(tpci200->info->cfg_regs);
+ out_err_ioremap:
+ 	pci_release_region(pdev, TPCI200_CFG_MEM_BAR);
+ out_err_pci_request:
+diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
+index 56bd2e9db6ed6..e501cb03f211d 100644
+--- a/drivers/isdn/hardware/mISDN/hfcpci.c
++++ b/drivers/isdn/hardware/mISDN/hfcpci.c
+@@ -2342,7 +2342,7 @@ static void __exit
+ HFC_cleanup(void)
+ {
+ 	if (timer_pending(&hfc_tl))
+-		del_timer(&hfc_tl);
++		del_timer_sync(&hfc_tl);
+ 
+ 	pci_unregister_driver(&hfc_driver);
+ }
+diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c
+index aecc246ade263..8f891d838cc68 100644
+--- a/drivers/md/dm-writecache.c
++++ b/drivers/md/dm-writecache.c
+@@ -532,7 +532,7 @@ static void ssd_commit_superblock(struct dm_writecache *wc)
+ 
+ 	region.bdev = wc->ssd_dev->bdev;
+ 	region.sector = 0;
+-	region.count = PAGE_SIZE >> SECTOR_SHIFT;
++	region.count = max(4096U, wc->block_size) >> SECTOR_SHIFT;
+ 
+ 	if (unlikely(region.sector + region.count > wc->metadata_sectors))
+ 		region.count = wc->metadata_sectors - region.sector;
+@@ -1301,8 +1301,12 @@ static int writecache_map(struct dm_target *ti, struct bio *bio)
+ 			writecache_flush(wc);
+ 			if (writecache_has_error(wc))
+ 				goto unlock_error;
++			if (unlikely(wc->cleaner))
++				goto unlock_remap_origin;
+ 			goto unlock_submit;
+ 		} else {
++			if (dm_bio_get_target_bio_nr(bio))
++				goto unlock_remap_origin;
+ 			writecache_offload_bio(wc, bio);
+ 			goto unlock_return;
+ 		}
+@@ -1360,14 +1364,18 @@ read_next_block:
+ 	} else {
+ 		do {
+ 			bool found_entry = false;
++			bool search_used = false;
+ 			if (writecache_has_error(wc))
+ 				goto unlock_error;
+ 			e = writecache_find_entry(wc, bio->bi_iter.bi_sector, 0);
+ 			if (e) {
+-				if (!writecache_entry_is_committed(wc, e))
++				if (!writecache_entry_is_committed(wc, e)) {
++					search_used = true;
+ 					goto bio_copy;
++				}
+ 				if (!WC_MODE_PMEM(wc) && !e->write_in_progress) {
+ 					wc->overwrote_committed = true;
++					search_used = true;
+ 					goto bio_copy;
+ 				}
+ 				found_entry = true;
+@@ -1377,7 +1385,7 @@ read_next_block:
+ 			}
+ 			e = writecache_pop_from_freelist(wc, (sector_t)-1);
+ 			if (unlikely(!e)) {
+-				if (!found_entry) {
++				if (!WC_MODE_PMEM(wc) && !found_entry) {
+ direct_write:
+ 					e = writecache_find_entry(wc, bio->bi_iter.bi_sector, WFE_RETURN_FOLLOWING);
+ 					if (e) {
+@@ -1404,13 +1412,31 @@ bio_copy:
+ 				sector_t current_cache_sec = start_cache_sec + (bio_size >> SECTOR_SHIFT);
+ 
+ 				while (bio_size < bio->bi_iter.bi_size) {
+-					struct wc_entry *f = writecache_pop_from_freelist(wc, current_cache_sec);
+-					if (!f)
+-						break;
+-					write_original_sector_seq_count(wc, f, bio->bi_iter.bi_sector +
+-									(bio_size >> SECTOR_SHIFT), wc->seq_count);
+-					writecache_insert_entry(wc, f);
+-					wc->uncommitted_blocks++;
++					if (!search_used) {
++						struct wc_entry *f = writecache_pop_from_freelist(wc, current_cache_sec);
++						if (!f)
++							break;
++						write_original_sector_seq_count(wc, f, bio->bi_iter.bi_sector +
++										(bio_size >> SECTOR_SHIFT), wc->seq_count);
++						writecache_insert_entry(wc, f);
++						wc->uncommitted_blocks++;
++					} else {
++						struct wc_entry *f;
++						struct rb_node *next = rb_next(&e->rb_node);
++						if (!next)
++							break;
++						f = container_of(next, struct wc_entry, rb_node);
++						if (f != e + 1)
++							break;
++						if (read_original_sector(wc, f) !=
++						    read_original_sector(wc, e) + (wc->block_size >> SECTOR_SHIFT))
++							break;
++						if (unlikely(f->write_in_progress))
++							break;
++						if (writecache_entry_is_committed(wc, f))
++							wc->overwrote_committed = true;
++						e = f;
++					}
+ 					bio_size += wc->block_size;
+ 					current_cache_sec += wc->block_size >> SECTOR_SHIFT;
+ 				}
+@@ -2463,7 +2489,7 @@ overflow:
+ 		goto bad;
+ 	}
+ 
+-	ti->num_flush_bios = 1;
++	ti->num_flush_bios = WC_MODE_PMEM(wc) ? 1 : 2;
+ 	ti->flush_supported = true;
+ 	ti->num_discard_bios = 1;
+ 
+diff --git a/drivers/md/dm-zoned-metadata.c b/drivers/md/dm-zoned-metadata.c
+index 039d17b289384..ee4626d085574 100644
+--- a/drivers/md/dm-zoned-metadata.c
++++ b/drivers/md/dm-zoned-metadata.c
+@@ -1390,6 +1390,13 @@ static int dmz_init_zone(struct blk_zone *blkz, unsigned int num, void *data)
+ 		return -ENXIO;
+ 	}
+ 
++	/*
++	 * Devices that have zones with a capacity smaller than the zone size
++	 * (e.g. NVMe zoned namespaces) are not supported.
++	 */
++	if (blkz->capacity != blkz->len)
++		return -ENXIO;
++
+ 	switch (blkz->type) {
+ 	case BLK_ZONE_TYPE_CONVENTIONAL:
+ 		set_bit(DMZ_RND, &zone->flags);
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index ca2aedd8ee7d1..11af200806391 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -1237,8 +1237,8 @@ static int dm_dax_zero_page_range(struct dax_device *dax_dev, pgoff_t pgoff,
+ 
+ /*
+  * A target may call dm_accept_partial_bio only from the map routine.  It is
+- * allowed for all bio types except REQ_PREFLUSH, REQ_OP_ZONE_RESET,
+- * REQ_OP_ZONE_OPEN, REQ_OP_ZONE_CLOSE and REQ_OP_ZONE_FINISH.
++ * allowed for all bio types except REQ_PREFLUSH, REQ_OP_ZONE_* zone management
++ * operations and REQ_OP_ZONE_APPEND (zone append writes).
+  *
+  * dm_accept_partial_bio informs the dm that the target only wants to process
+  * additional n_sectors sectors of the bio and the rest of the data should be
+@@ -1268,9 +1268,13 @@ void dm_accept_partial_bio(struct bio *bio, unsigned n_sectors)
+ {
+ 	struct dm_target_io *tio = container_of(bio, struct dm_target_io, clone);
+ 	unsigned bi_size = bio->bi_iter.bi_size >> SECTOR_SHIFT;
++
+ 	BUG_ON(bio->bi_opf & REQ_PREFLUSH);
++	BUG_ON(op_is_zone_mgmt(bio_op(bio)));
++	BUG_ON(bio_op(bio) == REQ_OP_ZONE_APPEND);
+ 	BUG_ON(bi_size > *tio->len_ptr);
+ 	BUG_ON(n_sectors > bi_size);
++
+ 	*tio->len_ptr -= bi_size - n_sectors;
+ 	bio->bi_iter.bi_size = n_sectors << SECTOR_SHIFT;
+ }
+diff --git a/drivers/md/persistent-data/dm-btree-remove.c b/drivers/md/persistent-data/dm-btree-remove.c
+index eff04fa23dfad..9e4d1212f4c16 100644
+--- a/drivers/md/persistent-data/dm-btree-remove.c
++++ b/drivers/md/persistent-data/dm-btree-remove.c
+@@ -549,7 +549,8 @@ int dm_btree_remove(struct dm_btree_info *info, dm_block_t root,
+ 		delete_at(n, index);
+ 	}
+ 
+-	*new_root = shadow_root(&spine);
++	if (!r)
++		*new_root = shadow_root(&spine);
+ 	exit_shadow_spine(&spine);
+ 
+ 	return r;
+diff --git a/drivers/md/persistent-data/dm-space-map-disk.c b/drivers/md/persistent-data/dm-space-map-disk.c
+index 61f56909e00be..4f8069bb04816 100644
+--- a/drivers/md/persistent-data/dm-space-map-disk.c
++++ b/drivers/md/persistent-data/dm-space-map-disk.c
+@@ -171,6 +171,14 @@ static int sm_disk_new_block(struct dm_space_map *sm, dm_block_t *b)
+ 	 * Any block we allocate has to be free in both the old and current ll.
+ 	 */
+ 	r = sm_ll_find_common_free_block(&smd->old_ll, &smd->ll, smd->begin, smd->ll.nr_blocks, b);
++	if (r == -ENOSPC) {
++		/*
++		 * There's no free block between smd->begin and the end of the metadata device.
++		 * We search before smd->begin in case something has been freed.
++		 */
++		r = sm_ll_find_common_free_block(&smd->old_ll, &smd->ll, 0, smd->begin, b);
++	}
++
+ 	if (r)
+ 		return r;
+ 
+@@ -194,7 +202,6 @@ static int sm_disk_commit(struct dm_space_map *sm)
+ 		return r;
+ 
+ 	memcpy(&smd->old_ll, &smd->ll, sizeof(smd->old_ll));
+-	smd->begin = 0;
+ 	smd->nr_allocated_this_transaction = 0;
+ 
+ 	return 0;
+diff --git a/drivers/md/persistent-data/dm-space-map-metadata.c b/drivers/md/persistent-data/dm-space-map-metadata.c
+index 9e3c64ec2026f..da439ac857963 100644
+--- a/drivers/md/persistent-data/dm-space-map-metadata.c
++++ b/drivers/md/persistent-data/dm-space-map-metadata.c
+@@ -452,6 +452,14 @@ static int sm_metadata_new_block_(struct dm_space_map *sm, dm_block_t *b)
+ 	 * Any block we allocate has to be free in both the old and current ll.
+ 	 */
+ 	r = sm_ll_find_common_free_block(&smm->old_ll, &smm->ll, smm->begin, smm->ll.nr_blocks, b);
++	if (r == -ENOSPC) {
++		/*
++		 * There's no free block between smm->begin and the end of the metadata device.
++		 * We search before smm->begin in case something has been freed.
++		 */
++		r = sm_ll_find_common_free_block(&smm->old_ll, &smm->ll, 0, smm->begin, b);
++	}
++
+ 	if (r)
+ 		return r;
+ 
+@@ -503,7 +511,6 @@ static int sm_metadata_commit(struct dm_space_map *sm)
+ 		return r;
+ 
+ 	memcpy(&smm->old_ll, &smm->ll, sizeof(smm->old_ll));
+-	smm->begin = 0;
+ 	smm->allocated_this_transaction = 0;
+ 
+ 	return 0;
+diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c
+index b05f409014b2f..4a848ac2d2cd2 100644
+--- a/drivers/media/i2c/ccs/ccs-core.c
++++ b/drivers/media/i2c/ccs/ccs-core.c
+@@ -1880,21 +1880,33 @@ static int ccs_pm_get_init(struct ccs_sensor *sensor)
+ 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
+ 	int rval;
+ 
++	/*
++	 * It can't use pm_runtime_resume_and_get() here, as the driver
++	 * relies at the returned value to detect if the device was already
++	 * active or not.
++	 */
+ 	rval = pm_runtime_get_sync(&client->dev);
+-	if (rval < 0) {
+-		pm_runtime_put_noidle(&client->dev);
++	if (rval < 0)
++		goto error;
+ 
+-		return rval;
+-	} else if (!rval) {
+-		rval = v4l2_ctrl_handler_setup(&sensor->pixel_array->
+-					       ctrl_handler);
+-		if (rval)
+-			return rval;
++	/* Device was already active, so don't set controls */
++	if (rval == 1)
++		return 0;
+ 
+-		return v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler);
+-	}
++	/* Restore V4L2 controls to the previously suspended device */
++	rval = v4l2_ctrl_handler_setup(&sensor->pixel_array->ctrl_handler);
++	if (rval)
++		goto error;
+ 
++	rval = v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler);
++	if (rval)
++		goto error;
++
++	/* Keep PM runtime usage_count incremented on success */
+ 	return 0;
++error:
++	pm_runtime_put(&client->dev);
++	return rval;
+ }
+ 
+ static int ccs_set_stream(struct v4l2_subdev *subdev, int enable)
+diff --git a/drivers/media/i2c/ccs/ccs-limits.c b/drivers/media/i2c/ccs/ccs-limits.c
+index f5511789ac837..4969fa425317d 100644
+--- a/drivers/media/i2c/ccs/ccs-limits.c
++++ b/drivers/media/i2c/ccs/ccs-limits.c
+@@ -1,5 +1,9 @@
+ // SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause
+ /* Copyright (C) 2019--2020 Intel Corporation */
++/*
++ * Generated by Documentation/driver-api/media/drivers/ccs/mk-ccs-regs;
++ * do not modify.
++ */
+ 
+ #include "ccs-limits.h"
+ #include "ccs-regs.h"
+diff --git a/drivers/media/i2c/ccs/ccs-limits.h b/drivers/media/i2c/ccs/ccs-limits.h
+index 1efa43c23a2eb..551d3ee9d04e1 100644
+--- a/drivers/media/i2c/ccs/ccs-limits.h
++++ b/drivers/media/i2c/ccs/ccs-limits.h
+@@ -1,5 +1,9 @@
+ /* SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause */
+ /* Copyright (C) 2019--2020 Intel Corporation */
++/*
++ * Generated by Documentation/driver-api/media/drivers/ccs/mk-ccs-regs;
++ * do not modify.
++ */
+ 
+ #ifndef __CCS_LIMITS_H__
+ #define __CCS_LIMITS_H__
+diff --git a/drivers/media/i2c/ccs/ccs-regs.h b/drivers/media/i2c/ccs/ccs-regs.h
+index 4b3e5df2121f8..6ce84c5ecf207 100644
+--- a/drivers/media/i2c/ccs/ccs-regs.h
++++ b/drivers/media/i2c/ccs/ccs-regs.h
+@@ -1,5 +1,9 @@
+ /* SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause */
+ /* Copyright (C) 2019--2020 Intel Corporation */
++/*
++ * Generated by Documentation/driver-api/media/drivers/ccs/mk-ccs-regs;
++ * do not modify.
++ */
+ 
+ #ifndef __CCS_REGS_H__
+ #define __CCS_REGS_H__
+@@ -202,7 +206,7 @@
+ #define CCS_R_OP_PIX_CLK_DIV					(0x0308 | CCS_FL_16BIT)
+ #define CCS_R_OP_SYS_CLK_DIV					(0x030a | CCS_FL_16BIT)
+ #define CCS_R_OP_PRE_PLL_CLK_DIV				(0x030c | CCS_FL_16BIT)
+-#define CCS_R_OP_PLL_MULTIPLIER					(0x031e | CCS_FL_16BIT)
++#define CCS_R_OP_PLL_MULTIPLIER					(0x030e | CCS_FL_16BIT)
+ #define CCS_R_PLL_MODE						0x0310
+ #define CCS_PLL_MODE_SHIFT					0U
+ #define CCS_PLL_MODE_MASK					0x1
+diff --git a/drivers/media/i2c/saa6588.c b/drivers/media/i2c/saa6588.c
+index ecb491d5f2ab8..d1e0716bdfffd 100644
+--- a/drivers/media/i2c/saa6588.c
++++ b/drivers/media/i2c/saa6588.c
+@@ -380,7 +380,7 @@ static void saa6588_configure(struct saa6588 *s)
+ 
+ /* ---------------------------------------------------------------------- */
+ 
+-static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
++static long saa6588_command(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+ {
+ 	struct saa6588 *s = to_saa6588(sd);
+ 	struct saa6588_command *a = arg;
+@@ -433,7 +433,7 @@ static int saa6588_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *vt)
+ /* ----------------------------------------------------------------------- */
+ 
+ static const struct v4l2_subdev_core_ops saa6588_core_ops = {
+-	.ioctl = saa6588_ioctl,
++	.command = saa6588_command,
+ };
+ 
+ static const struct v4l2_subdev_tuner_ops saa6588_tuner_ops = {
+diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c
+index 1f62a9d8ea1d3..0e9df8b35ac66 100644
+--- a/drivers/media/pci/bt8xx/bttv-driver.c
++++ b/drivers/media/pci/bt8xx/bttv-driver.c
+@@ -3179,7 +3179,7 @@ static int radio_release(struct file *file)
+ 
+ 	btv->radio_user--;
+ 
+-	bttv_call_all(btv, core, ioctl, SAA6588_CMD_CLOSE, &cmd);
++	bttv_call_all(btv, core, command, SAA6588_CMD_CLOSE, &cmd);
+ 
+ 	if (btv->radio_user == 0)
+ 		btv->has_radio_tuner = 0;
+@@ -3260,7 +3260,7 @@ static ssize_t radio_read(struct file *file, char __user *data,
+ 	cmd.result = -ENODEV;
+ 	radio_enable(btv);
+ 
+-	bttv_call_all(btv, core, ioctl, SAA6588_CMD_READ, &cmd);
++	bttv_call_all(btv, core, command, SAA6588_CMD_READ, &cmd);
+ 
+ 	return cmd.result;
+ }
+@@ -3281,7 +3281,7 @@ static __poll_t radio_poll(struct file *file, poll_table *wait)
+ 	cmd.instance = file;
+ 	cmd.event_list = wait;
+ 	cmd.poll_mask = res;
+-	bttv_call_all(btv, core, ioctl, SAA6588_CMD_POLL, &cmd);
++	bttv_call_all(btv, core, command, SAA6588_CMD_POLL, &cmd);
+ 
+ 	return cmd.poll_mask;
+ }
+diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c
+index 0f9d6b9edb90a..374c8e1087de1 100644
+--- a/drivers/media/pci/saa7134/saa7134-video.c
++++ b/drivers/media/pci/saa7134/saa7134-video.c
+@@ -1181,7 +1181,7 @@ static int video_release(struct file *file)
+ 
+ 	saa_call_all(dev, tuner, standby);
+ 	if (vdev->vfl_type == VFL_TYPE_RADIO)
+-		saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, &cmd);
++		saa_call_all(dev, core, command, SAA6588_CMD_CLOSE, &cmd);
+ 	mutex_unlock(&dev->lock);
+ 
+ 	return 0;
+@@ -1200,7 +1200,7 @@ static ssize_t radio_read(struct file *file, char __user *data,
+ 	cmd.result = -ENODEV;
+ 
+ 	mutex_lock(&dev->lock);
+-	saa_call_all(dev, core, ioctl, SAA6588_CMD_READ, &cmd);
++	saa_call_all(dev, core, command, SAA6588_CMD_READ, &cmd);
+ 	mutex_unlock(&dev->lock);
+ 
+ 	return cmd.result;
+@@ -1216,7 +1216,7 @@ static __poll_t radio_poll(struct file *file, poll_table *wait)
+ 	cmd.event_list = wait;
+ 	cmd.poll_mask = 0;
+ 	mutex_lock(&dev->lock);
+-	saa_call_all(dev, core, ioctl, SAA6588_CMD_POLL, &cmd);
++	saa_call_all(dev, core, command, SAA6588_CMD_POLL, &cmd);
+ 	mutex_unlock(&dev->lock);
+ 
+ 	return rc | cmd.poll_mask;
+diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
+index d19bad997f30c..bf3c3e76b9213 100644
+--- a/drivers/media/platform/davinci/vpbe_display.c
++++ b/drivers/media/platform/davinci/vpbe_display.c
+@@ -47,7 +47,7 @@ static int venc_is_second_field(struct vpbe_display *disp_dev)
+ 
+ 	ret = v4l2_subdev_call(vpbe_dev->venc,
+ 			       core,
+-			       ioctl,
++			       command,
+ 			       VENC_GET_FLD,
+ 			       &val);
+ 	if (ret < 0) {
+diff --git a/drivers/media/platform/davinci/vpbe_venc.c b/drivers/media/platform/davinci/vpbe_venc.c
+index 8caa084e57046..bde241c26d795 100644
+--- a/drivers/media/platform/davinci/vpbe_venc.c
++++ b/drivers/media/platform/davinci/vpbe_venc.c
+@@ -521,9 +521,7 @@ static int venc_s_routing(struct v4l2_subdev *sd, u32 input, u32 output,
+ 	return ret;
+ }
+ 
+-static long venc_ioctl(struct v4l2_subdev *sd,
+-			unsigned int cmd,
+-			void *arg)
++static long venc_command(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+ {
+ 	u32 val;
+ 
+@@ -542,7 +540,7 @@ static long venc_ioctl(struct v4l2_subdev *sd,
+ }
+ 
+ static const struct v4l2_subdev_core_ops venc_core_ops = {
+-	.ioctl      = venc_ioctl,
++	.command      = venc_command,
+ };
+ 
+ static const struct v4l2_subdev_video_ops venc_video_ops = {
+diff --git a/drivers/media/rc/bpf-lirc.c b/drivers/media/rc/bpf-lirc.c
+index 3fe3edd808765..afae0afe3f810 100644
+--- a/drivers/media/rc/bpf-lirc.c
++++ b/drivers/media/rc/bpf-lirc.c
+@@ -326,7 +326,8 @@ int lirc_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr)
+ 	}
+ 
+ 	if (attr->query.prog_cnt != 0 && prog_ids && cnt)
+-		ret = bpf_prog_array_copy_to_user(progs, prog_ids, cnt);
++		ret = bpf_prog_array_copy_to_user(progs, prog_ids,
++						  attr->query.prog_cnt);
+ 
+ unlock:
+ 	mutex_unlock(&ir_raw_handler_lock);
+diff --git a/drivers/media/usb/dvb-usb/dtv5100.c b/drivers/media/usb/dvb-usb/dtv5100.c
+index fba06932a9e0e..1c13e493322cc 100644
+--- a/drivers/media/usb/dvb-usb/dtv5100.c
++++ b/drivers/media/usb/dvb-usb/dtv5100.c
+@@ -26,6 +26,7 @@ static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr,
+ 			   u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
+ {
+ 	struct dtv5100_state *st = d->priv;
++	unsigned int pipe;
+ 	u8 request;
+ 	u8 type;
+ 	u16 value;
+@@ -34,6 +35,7 @@ static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr,
+ 	switch (wlen) {
+ 	case 1:
+ 		/* write { reg }, read { value } */
++		pipe = usb_rcvctrlpipe(d->udev, 0);
+ 		request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_READ :
+ 							DTV5100_TUNER_READ);
+ 		type = USB_TYPE_VENDOR | USB_DIR_IN;
+@@ -41,6 +43,7 @@ static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr,
+ 		break;
+ 	case 2:
+ 		/* write { reg, value } */
++		pipe = usb_sndctrlpipe(d->udev, 0);
+ 		request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_WRITE :
+ 							DTV5100_TUNER_WRITE);
+ 		type = USB_TYPE_VENDOR | USB_DIR_OUT;
+@@ -54,7 +57,7 @@ static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr,
+ 
+ 	memcpy(st->data, rbuf, rlen);
+ 	msleep(1); /* avoid I2C errors */
+-	return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), request,
++	return usb_control_msg(d->udev, pipe, request,
+ 			       type, value, index, st->data, rlen,
+ 			       DTV5100_USB_TIMEOUT);
+ }
+@@ -141,7 +144,7 @@ static int dtv5100_probe(struct usb_interface *intf,
+ 
+ 	/* initialize non qt1010/zl10353 part? */
+ 	for (i = 0; dtv5100_init[i].request; i++) {
+-		ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
++		ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ 				      dtv5100_init[i].request,
+ 				      USB_TYPE_VENDOR | USB_DIR_OUT,
+ 				      dtv5100_init[i].value,
+diff --git a/drivers/media/usb/gspca/sq905.c b/drivers/media/usb/gspca/sq905.c
+index 9491110709718..32504ebcfd4de 100644
+--- a/drivers/media/usb/gspca/sq905.c
++++ b/drivers/media/usb/gspca/sq905.c
+@@ -116,7 +116,7 @@ static int sq905_command(struct gspca_dev *gspca_dev, u16 index)
+ 	}
+ 
+ 	ret = usb_control_msg(gspca_dev->dev,
+-			      usb_sndctrlpipe(gspca_dev->dev, 0),
++			      usb_rcvctrlpipe(gspca_dev->dev, 0),
+ 			      USB_REQ_SYNCH_FRAME,                /* request */
+ 			      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 			      SQ905_PING, 0, gspca_dev->usb_buf, 1,
+diff --git a/drivers/media/usb/gspca/sunplus.c b/drivers/media/usb/gspca/sunplus.c
+index ace3da40006e7..971dee0a56dae 100644
+--- a/drivers/media/usb/gspca/sunplus.c
++++ b/drivers/media/usb/gspca/sunplus.c
+@@ -242,6 +242,10 @@ static void reg_r(struct gspca_dev *gspca_dev,
+ 		gspca_err(gspca_dev, "reg_r: buffer overflow\n");
+ 		return;
+ 	}
++	if (len == 0) {
++		gspca_err(gspca_dev, "reg_r: zero-length read\n");
++		return;
++	}
+ 	if (gspca_dev->usb_err < 0)
+ 		return;
+ 	ret = usb_control_msg(gspca_dev->dev,
+@@ -250,7 +254,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
+ 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 			0,		/* value */
+ 			index,
+-			len ? gspca_dev->usb_buf : NULL, len,
++			gspca_dev->usb_buf, len,
+ 			500);
+ 	if (ret < 0) {
+ 		pr_err("reg_r err %d\n", ret);
+@@ -727,7 +731,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
+ 		case MegaImageVI:
+ 			reg_w_riv(gspca_dev, 0xf0, 0, 0);
+ 			spca504B_WaitCmdStatus(gspca_dev);
+-			reg_r(gspca_dev, 0xf0, 4, 0);
++			reg_w_riv(gspca_dev, 0xf0, 4, 0);
+ 			spca504B_WaitCmdStatus(gspca_dev);
+ 			break;
+ 		default:
+diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
+index a777b389a66ec..e16464606b140 100644
+--- a/drivers/media/usb/uvc/uvc_video.c
++++ b/drivers/media/usb/uvc/uvc_video.c
+@@ -127,10 +127,37 @@ int uvc_query_ctrl(struct uvc_device *dev, u8 query, u8 unit,
+ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,
+ 	struct uvc_streaming_control *ctrl)
+ {
++	static const struct usb_device_id elgato_cam_link_4k = {
++		USB_DEVICE(0x0fd9, 0x0066)
++	};
+ 	struct uvc_format *format = NULL;
+ 	struct uvc_frame *frame = NULL;
+ 	unsigned int i;
+ 
++	/*
++	 * The response of the Elgato Cam Link 4K is incorrect: The second byte
++	 * contains bFormatIndex (instead of being the second byte of bmHint).
++	 * The first byte is always zero. The third byte is always 1.
++	 *
++	 * The UVC 1.5 class specification defines the first five bits in the
++	 * bmHint bitfield. The remaining bits are reserved and should be zero.
++	 * Therefore a valid bmHint will be less than 32.
++	 *
++	 * Latest Elgato Cam Link 4K firmware as of 2021-03-23 needs this fix.
++	 * MCU: 20.02.19, FPGA: 67
++	 */
++	if (usb_match_one_id(stream->dev->intf, &elgato_cam_link_4k) &&
++	    ctrl->bmHint > 255) {
++		u8 corrected_format_index = ctrl->bmHint >> 8;
++
++		uvc_dbg(stream->dev, VIDEO,
++			"Correct USB video probe response from {bmHint: 0x%04x, bFormatIndex: %u} to {bmHint: 0x%04x, bFormatIndex: %u}\n",
++			ctrl->bmHint, ctrl->bFormatIndex,
++			1, corrected_format_index);
++		ctrl->bmHint = 1;
++		ctrl->bFormatIndex = corrected_format_index;
++	}
++
+ 	for (i = 0; i < stream->nformats; ++i) {
+ 		if (stream->format[i].index == ctrl->bFormatIndex) {
+ 			format = &stream->format[i];
+diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c
+index 1ef611e083237..538a330046ec9 100644
+--- a/drivers/media/usb/zr364xx/zr364xx.c
++++ b/drivers/media/usb/zr364xx/zr364xx.c
+@@ -1032,6 +1032,7 @@ static int zr364xx_start_readpipe(struct zr364xx_camera *cam)
+ 	DBG("submitting URB %p\n", pipe_info->stream_urb);
+ 	retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
+ 	if (retval) {
++		usb_free_urb(pipe_info->stream_urb);
+ 		printk(KERN_ERR KBUILD_MODNAME ": start read pipe failed\n");
+ 		return retval;
+ 	}
+diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
+index 07d823656ee65..cf50c60bbb5d3 100644
+--- a/drivers/media/v4l2-core/v4l2-ioctl.c
++++ b/drivers/media/v4l2-core/v4l2-ioctl.c
+@@ -3124,8 +3124,10 @@ static int video_get_user(void __user *arg, void *parg,
+ 		if (copy_from_user(parg, (void __user *)arg, n))
+ 			err = -EFAULT;
+ 	} else if (in_compat_syscall()) {
++		memset(parg, 0, n);
+ 		err = v4l2_compat_get_user(arg, parg, cmd);
+ 	} else {
++		memset(parg, 0, n);
+ #if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME)
+ 		switch (cmd) {
+ 		case VIDIOC_QUERYBUF_TIME32:
+diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
+index c6f139b2e0c09..765c0210cb528 100644
+--- a/drivers/mfd/syscon.c
++++ b/drivers/mfd/syscon.c
+@@ -108,6 +108,7 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_clk)
+ 	syscon_config.max_register = resource_size(&res) - reg_io_width;
+ 
+ 	regmap = regmap_init_mmio(NULL, base, &syscon_config);
++	kfree(syscon_config.name);
+ 	if (IS_ERR(regmap)) {
+ 		pr_err("regmap init failed\n");
+ 		ret = PTR_ERR(regmap);
+@@ -144,7 +145,6 @@ err_clk:
+ 	regmap_exit(regmap);
+ err_regmap:
+ 	iounmap(base);
+-	kfree(syscon_config.name);
+ err_map:
+ 	kfree(syscon);
+ 	return ERR_PTR(ret);
+diff --git a/drivers/misc/lkdtm/bugs.c b/drivers/misc/lkdtm/bugs.c
+index 0e8254d0cf0ba..9ff02bdf31530 100644
+--- a/drivers/misc/lkdtm/bugs.c
++++ b/drivers/misc/lkdtm/bugs.c
+@@ -161,6 +161,9 @@ void lkdtm_UNALIGNED_LOAD_STORE_WRITE(void)
+ 	if (*p == 0)
+ 		val = 0x87654321;
+ 	*p = val;
++
++	if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS))
++		pr_err("XFAIL: arch has CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS\n");
+ }
+ 
+ void lkdtm_SOFTLOCKUP(void)
+diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c
+index 8024b6a5cc7fc..cd833011f2850 100644
+--- a/drivers/misc/lkdtm/core.c
++++ b/drivers/misc/lkdtm/core.c
+@@ -177,9 +177,7 @@ static const struct crashtype crashtypes[] = {
+ 	CRASHTYPE(STACKLEAK_ERASING),
+ 	CRASHTYPE(CFI_FORWARD_PROTO),
+ 	CRASHTYPE(FORTIFIED_STRSCPY),
+-#ifdef CONFIG_X86_32
+ 	CRASHTYPE(DOUBLE_FAULT),
+-#endif
+ #ifdef CONFIG_PPC_BOOK3S_64
+ 	CRASHTYPE(PPC_SLB_MULTIHIT),
+ #endif
+diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
+index f194940c59746..cc403da868708 100644
+--- a/drivers/mmc/core/core.c
++++ b/drivers/mmc/core/core.c
+@@ -937,11 +937,14 @@ int mmc_execute_tuning(struct mmc_card *card)
+ 
+ 	err = host->ops->execute_tuning(host, opcode);
+ 
+-	if (err)
++	if (err) {
+ 		pr_err("%s: tuning execution failed: %d\n",
+ 			mmc_hostname(host), err);
+-	else
++	} else {
++		host->retune_now = 0;
++		host->need_retune = 0;
+ 		mmc_retune_enable(host);
++	}
+ 
+ 	return err;
+ }
+diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
+index 2c48d65041013..e277ef4fa0995 100644
+--- a/drivers/mmc/core/sd.c
++++ b/drivers/mmc/core/sd.c
+@@ -847,11 +847,13 @@ try_again:
+ 		return err;
+ 
+ 	/*
+-	 * In case CCS and S18A in the response is set, start Signal Voltage
+-	 * Switch procedure. SPI mode doesn't support CMD11.
++	 * In case the S18A bit is set in the response, let's start the signal
++	 * voltage switch procedure. SPI mode doesn't support CMD11.
++	 * Note that, according to the spec, the S18A bit is not valid unless
++	 * the CCS bit is set as well. We deliberately deviate from the spec in
++	 * regards to this, which allows UHS-I to be supported for SDSC cards.
+ 	 */
+-	if (!mmc_host_is_spi(host) && rocr &&
+-	   ((*rocr & 0x41000000) == 0x41000000)) {
++	if (!mmc_host_is_spi(host) && rocr && (*rocr & 0x01000000)) {
+ 		err = mmc_set_uhs_voltage(host, pocr);
+ 		if (err == -EAGAIN) {
+ 			retries--;
+diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
+index c3fbf8c825c4f..8fe65f172a611 100644
+--- a/drivers/mmc/host/sdhci-acpi.c
++++ b/drivers/mmc/host/sdhci-acpi.c
+@@ -822,6 +822,17 @@ static const struct dmi_system_id sdhci_acpi_quirks[] = {
+ 		},
+ 		.driver_data = (void *)DMI_QUIRK_SD_NO_WRITE_PROTECT,
+ 	},
++	{
++		/*
++		 * The Toshiba WT8-B's microSD slot always reports the card being
++		 * write-protected.
++		 */
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "TOSHIBA ENCORE 2 WT8-B"),
++		},
++		.driver_data = (void *)DMI_QUIRK_SD_NO_WRITE_PROTECT,
++	},
+ 	{} /* Terminating entry */
+ };
+ 
+diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
+index bf238ade16021..6b39126fbf06c 100644
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -1812,6 +1812,10 @@ static u16 sdhci_get_preset_value(struct sdhci_host *host)
+ 	u16 preset = 0;
+ 
+ 	switch (host->timing) {
++	case MMC_TIMING_MMC_HS:
++	case MMC_TIMING_SD_HS:
++		preset = sdhci_readw(host, SDHCI_PRESET_FOR_HIGH_SPEED);
++		break;
+ 	case MMC_TIMING_UHS_SDR12:
+ 		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12);
+ 		break;
+diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
+index 0770c036e2ff5..960fed78529e1 100644
+--- a/drivers/mmc/host/sdhci.h
++++ b/drivers/mmc/host/sdhci.h
+@@ -253,6 +253,7 @@
+ 
+ /* 60-FB reserved */
+ 
++#define SDHCI_PRESET_FOR_HIGH_SPEED	0x64
+ #define SDHCI_PRESET_FOR_SDR12 0x66
+ #define SDHCI_PRESET_FOR_SDR25 0x68
+ #define SDHCI_PRESET_FOR_SDR50 0x6A
+diff --git a/drivers/net/dsa/ocelot/seville_vsc9953.c b/drivers/net/dsa/ocelot/seville_vsc9953.c
+index 84f93a874d502..deae923c8b7a8 100644
+--- a/drivers/net/dsa/ocelot/seville_vsc9953.c
++++ b/drivers/net/dsa/ocelot/seville_vsc9953.c
+@@ -1206,6 +1206,11 @@ static int seville_probe(struct platform_device *pdev)
+ 	felix->info = &seville_info_vsc9953;
+ 
+ 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!res) {
++		err = -EINVAL;
++		dev_err(&pdev->dev, "Invalid resource\n");
++		goto err_alloc_felix;
++	}
+ 	felix->switch_base = res->start;
+ 
+ 	ds = kzalloc(sizeof(struct dsa_switch), GFP_KERNEL);
+diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c
+index 5335244e4577a..89d16c587bb7d 100644
+--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
++++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
+@@ -423,6 +423,10 @@ static int bcmgenet_mii_register(struct bcmgenet_priv *priv)
+ 	int id, ret;
+ 
+ 	pres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!pres) {
++		dev_err(&pdev->dev, "Invalid resource\n");
++		return -EINVAL;
++	}
+ 	memset(&res, 0, sizeof(res));
+ 	memset(&ppd, 0, sizeof(ppd));
+ 
+diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
+index 0602d5d5d2eee..2e002e4b4b4aa 100644
+--- a/drivers/net/ethernet/freescale/fec.h
++++ b/drivers/net/ethernet/freescale/fec.h
+@@ -467,6 +467,11 @@ struct bufdesc_ex {
+  */
+ #define FEC_QUIRK_NO_HARD_RESET		(1 << 18)
+ 
++/* i.MX6SX ENET IP supports multiple queues (3 queues), use this quirk to
++ * represents this ENET IP.
++ */
++#define FEC_QUIRK_HAS_MULTI_QUEUES	(1 << 19)
++
+ struct bufdesc_prop {
+ 	int qid;
+ 	/* Address of Rx and Tx buffers */
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index ad82cffc6f3f5..8aea707a65a77 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -76,6 +76,8 @@ static void fec_enet_itr_coal_init(struct net_device *ndev);
+ 
+ #define DRIVER_NAME	"fec"
+ 
++static const u16 fec_enet_vlan_pri_to_queue[8] = {0, 0, 1, 1, 1, 2, 2, 2};
++
+ /* Pause frame feild and FIFO threshold */
+ #define FEC_ENET_FCE	(1 << 5)
+ #define FEC_ENET_RSEM_V	0x84
+@@ -122,7 +124,7 @@ static const struct fec_devinfo fec_imx6x_info = {
+ 		  FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
+ 		  FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
+ 		  FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE |
+-		  FEC_QUIRK_CLEAR_SETUP_MII,
++		  FEC_QUIRK_CLEAR_SETUP_MII | FEC_QUIRK_HAS_MULTI_QUEUES,
+ };
+ 
+ static const struct fec_devinfo fec_imx6ul_info = {
+@@ -421,6 +423,7 @@ fec_enet_txq_submit_frag_skb(struct fec_enet_priv_tx_q *txq,
+ 				estatus |= FEC_TX_BD_FTYPE(txq->bd.qid);
+ 			if (skb->ip_summed == CHECKSUM_PARTIAL)
+ 				estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS;
++
+ 			ebdp->cbd_bdu = 0;
+ 			ebdp->cbd_esc = cpu_to_fec32(estatus);
+ 		}
+@@ -954,7 +957,7 @@ fec_restart(struct net_device *ndev)
+ 	 * For i.MX6SX SOC, enet use AXI bus, we use disable MAC
+ 	 * instead of reset MAC itself.
+ 	 */
+-	if (fep->quirks & FEC_QUIRK_HAS_AVB ||
++	if (fep->quirks & FEC_QUIRK_HAS_MULTI_QUEUES ||
+ 	    ((fep->quirks & FEC_QUIRK_NO_HARD_RESET) && fep->link)) {
+ 		writel(0, fep->hwp + FEC_ECNTRL);
+ 	} else {
+@@ -1165,7 +1168,7 @@ fec_stop(struct net_device *ndev)
+ 	 * instead of reset MAC itself.
+ 	 */
+ 	if (!(fep->wol_flag & FEC_WOL_FLAG_SLEEP_ON)) {
+-		if (fep->quirks & FEC_QUIRK_HAS_AVB) {
++		if (fep->quirks & FEC_QUIRK_HAS_MULTI_QUEUES) {
+ 			writel(0, fep->hwp + FEC_ECNTRL);
+ 		} else {
+ 			writel(1, fep->hwp + FEC_ECNTRL);
+@@ -2570,7 +2573,7 @@ static void fec_enet_itr_coal_set(struct net_device *ndev)
+ 
+ 	writel(tx_itr, fep->hwp + FEC_TXIC0);
+ 	writel(rx_itr, fep->hwp + FEC_RXIC0);
+-	if (fep->quirks & FEC_QUIRK_HAS_AVB) {
++	if (fep->quirks & FEC_QUIRK_HAS_MULTI_QUEUES) {
+ 		writel(tx_itr, fep->hwp + FEC_TXIC1);
+ 		writel(rx_itr, fep->hwp + FEC_RXIC1);
+ 		writel(tx_itr, fep->hwp + FEC_TXIC2);
+@@ -3239,10 +3242,40 @@ static int fec_set_features(struct net_device *netdev,
+ 	return 0;
+ }
+ 
++static u16 fec_enet_get_raw_vlan_tci(struct sk_buff *skb)
++{
++	struct vlan_ethhdr *vhdr;
++	unsigned short vlan_TCI = 0;
++
++	if (skb->protocol == htons(ETH_P_ALL)) {
++		vhdr = (struct vlan_ethhdr *)(skb->data);
++		vlan_TCI = ntohs(vhdr->h_vlan_TCI);
++	}
++
++	return vlan_TCI;
++}
++
++static u16 fec_enet_select_queue(struct net_device *ndev, struct sk_buff *skb,
++				 struct net_device *sb_dev)
++{
++	struct fec_enet_private *fep = netdev_priv(ndev);
++	u16 vlan_tag;
++
++	if (!(fep->quirks & FEC_QUIRK_HAS_AVB))
++		return netdev_pick_tx(ndev, skb, NULL);
++
++	vlan_tag = fec_enet_get_raw_vlan_tci(skb);
++	if (!vlan_tag)
++		return vlan_tag;
++
++	return fec_enet_vlan_pri_to_queue[vlan_tag >> 13];
++}
++
+ static const struct net_device_ops fec_netdev_ops = {
+ 	.ndo_open		= fec_enet_open,
+ 	.ndo_stop		= fec_enet_close,
+ 	.ndo_start_xmit		= fec_enet_start_xmit,
++	.ndo_select_queue       = fec_enet_select_queue,
+ 	.ndo_set_rx_mode	= set_multicast_list,
+ 	.ndo_validate_addr	= eth_validate_addr,
+ 	.ndo_tx_timeout		= fec_timeout,
+@@ -3371,7 +3404,7 @@ static int fec_enet_init(struct net_device *ndev)
+ 		fep->csum_flags |= FLAG_RX_CSUM_ENABLED;
+ 	}
+ 
+-	if (fep->quirks & FEC_QUIRK_HAS_AVB) {
++	if (fep->quirks & FEC_QUIRK_HAS_MULTI_QUEUES) {
+ 		fep->tx_align = 0;
+ 		fep->rx_align = 0x3f;
+ 	}
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index ede65b32f8212..efc98903c0b72 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -1554,7 +1554,8 @@ static int create_hdr_descs(u8 hdr_field, u8 *hdr_data, int len, int *hdr_len,
+ 
+ /**
+  * build_hdr_descs_arr - build a header descriptor array
+- * @txbuff: tx buffer
++ * @skb: tx socket buffer
++ * @indir_arr: indirect array
+  * @num_entries: number of descriptors to be sent
+  * @hdr_field: bit field determining which headers will be sent
+  *
+diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c
+index f8d78af76d7de..1b0958bd24f6c 100644
+--- a/drivers/net/ethernet/intel/e100.c
++++ b/drivers/net/ethernet/intel/e100.c
+@@ -1395,7 +1395,7 @@ static int e100_phy_check_without_mii(struct nic *nic)
+ 	u8 phy_type;
+ 	int without_mii;
+ 
+-	phy_type = (nic->eeprom[eeprom_phy_iface] >> 8) & 0x0f;
++	phy_type = (le16_to_cpu(nic->eeprom[eeprom_phy_iface]) >> 8) & 0x0f;
+ 
+ 	switch (phy_type) {
+ 	case NoSuchPhy: /* Non-MII PHY; UNTESTED! */
+@@ -1515,7 +1515,7 @@ static int e100_phy_init(struct nic *nic)
+ 		mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr);
+ 	} else if ((nic->mac >= mac_82550_D102) || ((nic->flags & ich) &&
+ 	   (mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000) &&
+-		(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))) {
++	   (le16_to_cpu(nic->eeprom[eeprom_cnfg_mdix]) & eeprom_mdix_enabled))) {
+ 		/* enable/disable MDI/MDI-X auto-switching. */
+ 		mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG,
+ 				nic->mii.force_media ? 0 : NCONFIG_AUTO_SWITCH);
+@@ -2269,9 +2269,9 @@ static int e100_asf(struct nic *nic)
+ {
+ 	/* ASF can be enabled from eeprom */
+ 	return (nic->pdev->device >= 0x1050) && (nic->pdev->device <= 0x1057) &&
+-	   (nic->eeprom[eeprom_config_asf] & eeprom_asf) &&
+-	   !(nic->eeprom[eeprom_config_asf] & eeprom_gcl) &&
+-	   ((nic->eeprom[eeprom_smbus_addr] & 0xFF) != 0xFE);
++	   (le16_to_cpu(nic->eeprom[eeprom_config_asf]) & eeprom_asf) &&
++	   !(le16_to_cpu(nic->eeprom[eeprom_config_asf]) & eeprom_gcl) &&
++	   ((le16_to_cpu(nic->eeprom[eeprom_smbus_addr]) & 0xFF) != 0xFE);
+ }
+ 
+ static int e100_up(struct nic *nic)
+@@ -2926,7 +2926,7 @@ static int e100_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 
+ 	/* Wol magic packet can be enabled from eeprom */
+ 	if ((nic->mac >= mac_82558_D101_A4) &&
+-	   (nic->eeprom[eeprom_id] & eeprom_id_wol)) {
++	   (le16_to_cpu(nic->eeprom[eeprom_id]) & eeprom_id_wol)) {
+ 		nic->flags |= wol_magic;
+ 		device_set_wakeup_enable(&pdev->dev, true);
+ 	}
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_ptp.c b/drivers/net/ethernet/intel/i40e/i40e_ptp.c
+index f1f6fc3744e9c..7b971b205d36a 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_ptp.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_ptp.c
+@@ -11,13 +11,14 @@
+  * operate with the nanosecond field directly without fear of overflow.
+  *
+  * Much like the 82599, the update period is dependent upon the link speed:
+- * At 40Gb link or no link, the period is 1.6ns.
+- * At 10Gb link, the period is multiplied by 2. (3.2ns)
++ * At 40Gb, 25Gb, or no link, the period is 1.6ns.
++ * At 10Gb or 5Gb link, the period is multiplied by 2. (3.2ns)
+  * At 1Gb link, the period is multiplied by 20. (32ns)
+  * 1588 functionality is not supported at 100Mbps.
+  */
+ #define I40E_PTP_40GB_INCVAL		0x0199999999ULL
+ #define I40E_PTP_10GB_INCVAL_MULT	2
++#define I40E_PTP_5GB_INCVAL_MULT	2
+ #define I40E_PTP_1GB_INCVAL_MULT	20
+ 
+ #define I40E_PRTTSYN_CTL1_TSYNTYPE_V1  BIT(I40E_PRTTSYN_CTL1_TSYNTYPE_SHIFT)
+@@ -465,6 +466,9 @@ void i40e_ptp_set_increment(struct i40e_pf *pf)
+ 	case I40E_LINK_SPEED_10GB:
+ 		mult = I40E_PTP_10GB_INCVAL_MULT;
+ 		break;
++	case I40E_LINK_SPEED_5GB:
++		mult = I40E_PTP_5GB_INCVAL_MULT;
++		break;
+ 	case I40E_LINK_SPEED_1GB:
+ 		mult = I40E_PTP_1GB_INCVAL_MULT;
+ 		break;
+diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c
+index 99301ad95290d..1f30f24648d8e 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
++++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
+@@ -3462,13 +3462,9 @@ static int
+ ice_get_rc_coalesce(struct ethtool_coalesce *ec, enum ice_container_type c_type,
+ 		    struct ice_ring_container *rc)
+ {
+-	struct ice_pf *pf;
+-
+ 	if (!rc->ring)
+ 		return -EINVAL;
+ 
+-	pf = rc->ring->vsi->back;
+-
+ 	switch (c_type) {
+ 	case ICE_RX_CONTAINER:
+ 		ec->use_adaptive_rx_coalesce = ITR_IS_DYNAMIC(rc);
+@@ -3480,7 +3476,7 @@ ice_get_rc_coalesce(struct ethtool_coalesce *ec, enum ice_container_type c_type,
+ 		ec->tx_coalesce_usecs = rc->itr_setting;
+ 		break;
+ 	default:
+-		dev_dbg(ice_pf_to_dev(pf), "Invalid c_type %d\n", c_type);
++		dev_dbg(ice_pf_to_dev(rc->ring->vsi->back), "Invalid c_type %d\n", c_type);
+ 		return -EINVAL;
+ 	}
+ 
+diff --git a/drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h b/drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h
+index 21329ed3087e1..4238ab0433eef 100644
+--- a/drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h
++++ b/drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h
+@@ -630,7 +630,7 @@ static const struct ice_rx_ptype_decoded ice_ptype_lkup[] = {
+ 	/* L2 Packet types */
+ 	ICE_PTT_UNUSED_ENTRY(0),
+ 	ICE_PTT(1, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
+-	ICE_PTT(2, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE),
++	ICE_PTT_UNUSED_ENTRY(2),
+ 	ICE_PTT_UNUSED_ENTRY(3),
+ 	ICE_PTT_UNUSED_ENTRY(4),
+ 	ICE_PTT_UNUSED_ENTRY(5),
+@@ -744,7 +744,7 @@ static const struct ice_rx_ptype_decoded ice_ptype_lkup[] = {
+ 	/* Non Tunneled IPv6 */
+ 	ICE_PTT(88, IP, IPV6, FRG, NONE, NONE, NOF, NONE, PAY3),
+ 	ICE_PTT(89, IP, IPV6, NOF, NONE, NONE, NOF, NONE, PAY3),
+-	ICE_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP,  PAY3),
++	ICE_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP,  PAY4),
+ 	ICE_PTT_UNUSED_ENTRY(91),
+ 	ICE_PTT(92, IP, IPV6, NOF, NONE, NONE, NOF, TCP,  PAY4),
+ 	ICE_PTT(93, IP, IPV6, NOF, NONE, NONE, NOF, SCTP, PAY4),
+diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
+index 4474dd6a7ba14..a925273c2cca6 100644
+--- a/drivers/net/ethernet/intel/ice/ice_type.h
++++ b/drivers/net/ethernet/intel/ice/ice_type.h
+@@ -63,7 +63,7 @@ enum ice_aq_res_ids {
+ /* FW update timeout definitions are in milliseconds */
+ #define ICE_NVM_TIMEOUT			180000
+ #define ICE_CHANGE_LOCK_TIMEOUT		1000
+-#define ICE_GLOBAL_CFG_LOCK_TIMEOUT	3000
++#define ICE_GLOBAL_CFG_LOCK_TIMEOUT	5000
+ 
+ enum ice_aq_res_access_type {
+ 	ICE_RES_READ = 1,
+diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
+index b2a042f825ff5..7b1885f9ce039 100644
+--- a/drivers/net/ethernet/intel/igb/igb_main.c
++++ b/drivers/net/ethernet/intel/igb/igb_main.c
+@@ -2643,7 +2643,8 @@ static int igb_parse_cls_flower(struct igb_adapter *adapter,
+ 			}
+ 
+ 			input->filter.match_flags |= IGB_FILTER_FLAG_VLAN_TCI;
+-			input->filter.vlan_tci = match.key->vlan_priority;
++			input->filter.vlan_tci =
++				(__force __be16)match.key->vlan_priority;
+ 		}
+ 	}
+ 
+@@ -6275,12 +6276,12 @@ int igb_xmit_xdp_ring(struct igb_adapter *adapter,
+ 	cmd_type |= len | IGB_TXD_DCMD;
+ 	tx_desc->read.cmd_type_len = cpu_to_le32(cmd_type);
+ 
+-	olinfo_status = cpu_to_le32(len << E1000_ADVTXD_PAYLEN_SHIFT);
++	olinfo_status = len << E1000_ADVTXD_PAYLEN_SHIFT;
+ 	/* 82575 requires a unique index per ring */
+ 	if (test_bit(IGB_RING_FLAG_TX_CTX_IDX, &tx_ring->flags))
+ 		olinfo_status |= tx_ring->reg_idx << 4;
+ 
+-	tx_desc->read.olinfo_status = olinfo_status;
++	tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status);
+ 
+ 	netdev_tx_sent_queue(txring_txq(tx_ring), tx_buffer->bytecount);
+ 
+@@ -8592,7 +8593,7 @@ static void igb_process_skb_fields(struct igb_ring *rx_ring,
+ 
+ 		if (igb_test_staterr(rx_desc, E1000_RXDEXT_STATERR_LB) &&
+ 		    test_bit(IGB_RING_FLAG_RX_LB_VLAN_BSWAP, &rx_ring->flags))
+-			vid = be16_to_cpu(rx_desc->wb.upper.vlan);
++			vid = be16_to_cpu((__force __be16)rx_desc->wb.upper.vlan);
+ 		else
+ 			vid = le16_to_cpu(rx_desc->wb.upper.vlan);
+ 
+diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c
+index fb3fbcb133310..630c1155f1965 100644
+--- a/drivers/net/ethernet/intel/igbvf/netdev.c
++++ b/drivers/net/ethernet/intel/igbvf/netdev.c
+@@ -83,14 +83,14 @@ static int igbvf_desc_unused(struct igbvf_ring *ring)
+ static void igbvf_receive_skb(struct igbvf_adapter *adapter,
+ 			      struct net_device *netdev,
+ 			      struct sk_buff *skb,
+-			      u32 status, u16 vlan)
++			      u32 status, __le16 vlan)
+ {
+ 	u16 vid;
+ 
+ 	if (status & E1000_RXD_STAT_VP) {
+ 		if ((adapter->flags & IGBVF_FLAG_RX_LB_VLAN_BSWAP) &&
+ 		    (status & E1000_RXDEXT_STATERR_LB))
+-			vid = be16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK;
++			vid = be16_to_cpu((__force __be16)vlan) & E1000_RXD_SPC_VLAN_MASK;
+ 		else
+ 			vid = le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK;
+ 		if (test_bit(vid, adapter->active_vlans))
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index b3041fe6c0aed..42cc27ef73785 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -7387,6 +7387,10 @@ static int mvpp2_probe(struct platform_device *pdev)
+ 			return PTR_ERR(priv->lms_base);
+ 	} else {
+ 		res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++		if (!res) {
++			dev_err(&pdev->dev, "Invalid resource\n");
++			return -EINVAL;
++		}
+ 		if (has_acpi_companion(&pdev->dev)) {
+ 			/* In case the MDIO memory region is declared in
+ 			 * the ACPI, it can already appear as 'in-use'
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+index f90894eea9e04..5346271974f55 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+@@ -1310,7 +1310,8 @@ static void mlx5e_handle_rx_cqe_rep(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
+ 	if (rep->vlan && skb_vlan_tag_present(skb))
+ 		skb_vlan_pop(skb);
+ 
+-	if (!mlx5e_rep_tc_update_skb(cqe, skb, &tc_priv)) {
++	if (unlikely(!mlx5_ipsec_is_rx_flow(cqe) &&
++		     !mlx5e_rep_tc_update_skb(cqe, skb, &tc_priv))) {
+ 		dev_kfree_skb_any(skb);
+ 		goto free_wqe;
+ 	}
+@@ -1367,7 +1368,8 @@ static void mlx5e_handle_rx_cqe_mpwrq_rep(struct mlx5e_rq *rq, struct mlx5_cqe64
+ 
+ 	mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb);
+ 
+-	if (!mlx5e_rep_tc_update_skb(cqe, skb, &tc_priv)) {
++	if (unlikely(!mlx5_ipsec_is_rx_flow(cqe) &&
++		     !mlx5e_rep_tc_update_skb(cqe, skb, &tc_priv))) {
+ 		dev_kfree_skb_any(skb);
+ 		goto mpwrq_cqe_out;
+ 	}
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag.c
+index b8748390335fd..9ce144ef83261 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lag.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag.c
+@@ -118,17 +118,24 @@ static bool __mlx5_lag_is_sriov(struct mlx5_lag *ldev)
+ static void mlx5_infer_tx_affinity_mapping(struct lag_tracker *tracker,
+ 					   u8 *port1, u8 *port2)
+ {
++	bool p1en;
++	bool p2en;
++
++	p1en = tracker->netdev_state[MLX5_LAG_P1].tx_enabled &&
++	       tracker->netdev_state[MLX5_LAG_P1].link_up;
++
++	p2en = tracker->netdev_state[MLX5_LAG_P2].tx_enabled &&
++	       tracker->netdev_state[MLX5_LAG_P2].link_up;
++
+ 	*port1 = 1;
+ 	*port2 = 2;
+-	if (!tracker->netdev_state[MLX5_LAG_P1].tx_enabled ||
+-	    !tracker->netdev_state[MLX5_LAG_P1].link_up) {
+-		*port1 = 2;
++	if ((!p1en && !p2en) || (p1en && p2en))
+ 		return;
+-	}
+ 
+-	if (!tracker->netdev_state[MLX5_LAG_P2].tx_enabled ||
+-	    !tracker->netdev_state[MLX5_LAG_P2].link_up)
++	if (p1en)
+ 		*port2 = 1;
++	else
++		*port1 = 2;
+ }
+ 
+ void mlx5_modify_lag(struct mlx5_lag *ldev,
+diff --git a/drivers/net/ethernet/micrel/ks8842.c b/drivers/net/ethernet/micrel/ks8842.c
+index caa251d0e3815..b27713906d3a6 100644
+--- a/drivers/net/ethernet/micrel/ks8842.c
++++ b/drivers/net/ethernet/micrel/ks8842.c
+@@ -1135,6 +1135,10 @@ static int ks8842_probe(struct platform_device *pdev)
+ 	unsigned i;
+ 
+ 	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!iomem) {
++		dev_err(&pdev->dev, "Invalid resource\n");
++		return -EINVAL;
++	}
+ 	if (!request_mem_region(iomem->start, resource_size(iomem), DRV_NAME))
+ 		goto err_mem_region;
+ 
+diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
+index b85733942053f..5249b64f4fc54 100644
+--- a/drivers/net/ethernet/moxa/moxart_ether.c
++++ b/drivers/net/ethernet/moxa/moxart_ether.c
+@@ -481,13 +481,12 @@ static int moxart_mac_probe(struct platform_device *pdev)
+ 	priv->ndev = ndev;
+ 	priv->pdev = pdev;
+ 
+-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-	ndev->base_addr = res->start;
+-	priv->base = devm_ioremap_resource(p_dev, res);
++	priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+ 	if (IS_ERR(priv->base)) {
+ 		ret = PTR_ERR(priv->base);
+ 		goto init_fail;
+ 	}
++	ndev->base_addr = res->start;
+ 
+ 	spin_lock_init(&priv->txlock);
+ 
+diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+index 3dc29b282a884..45b9ba1ec7607 100644
+--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
++++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+@@ -108,7 +108,7 @@ static int pch_ptp_match(struct sk_buff *skb, u16 uid_hi, u32 uid_lo, u16 seqid)
+ {
+ 	u8 *data = skb->data;
+ 	unsigned int offset;
+-	u16 *hi, *id;
++	u16 hi, id;
+ 	u32 lo;
+ 
+ 	if (ptp_classify_raw(skb) == PTP_CLASS_NONE)
+@@ -119,14 +119,11 @@ static int pch_ptp_match(struct sk_buff *skb, u16 uid_hi, u32 uid_lo, u16 seqid)
+ 	if (skb->len < offset + OFF_PTP_SEQUENCE_ID + sizeof(seqid))
+ 		return 0;
+ 
+-	hi = (u16 *)(data + offset + OFF_PTP_SOURCE_UUID);
+-	id = (u16 *)(data + offset + OFF_PTP_SEQUENCE_ID);
++	hi = get_unaligned_be16(data + offset + OFF_PTP_SOURCE_UUID + 0);
++	lo = get_unaligned_be32(data + offset + OFF_PTP_SOURCE_UUID + 2);
++	id = get_unaligned_be16(data + offset + OFF_PTP_SEQUENCE_ID);
+ 
+-	memcpy(&lo, &hi[1], sizeof(lo));
+-
+-	return (uid_hi == *hi &&
+-		uid_lo == lo &&
+-		seqid  == *id);
++	return (uid_hi == hi && uid_lo == lo && seqid == id);
+ }
+ 
+ static void
+@@ -136,7 +133,6 @@ pch_rx_timestamp(struct pch_gbe_adapter *adapter, struct sk_buff *skb)
+ 	struct pci_dev *pdev;
+ 	u64 ns;
+ 	u32 hi, lo, val;
+-	u16 uid, seq;
+ 
+ 	if (!adapter->hwts_rx_en)
+ 		return;
+@@ -152,10 +148,7 @@ pch_rx_timestamp(struct pch_gbe_adapter *adapter, struct sk_buff *skb)
+ 	lo = pch_src_uuid_lo_read(pdev);
+ 	hi = pch_src_uuid_hi_read(pdev);
+ 
+-	uid = hi & 0xffff;
+-	seq = (hi >> 16) & 0xffff;
+-
+-	if (!pch_ptp_match(skb, htons(uid), htonl(lo), htons(seq)))
++	if (!pch_ptp_match(skb, hi, lo, hi >> 16))
+ 		goto out;
+ 
+ 	ns = pch_rx_snap_read(pdev);
+diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
+index 2ee72dc431cd5..a0d4e052a79ed 100644
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -3510,7 +3510,6 @@ static void rtl_hw_start_8106(struct rtl8169_private *tp)
+ 	rtl_eri_write(tp, 0x1b0, ERIAR_MASK_0011, 0x0000);
+ 
+ 	rtl_pcie_state_l2l3_disable(tp);
+-	rtl_hw_aspm_clkreq_enable(tp, true);
+ }
+ 
+ DECLARE_RTL_COND(rtl_mac_ocp_e00e_cond)
+diff --git a/drivers/net/ethernet/sfc/ef10_sriov.c b/drivers/net/ethernet/sfc/ef10_sriov.c
+index 21fa6c0e88734..84041cd587d78 100644
+--- a/drivers/net/ethernet/sfc/ef10_sriov.c
++++ b/drivers/net/ethernet/sfc/ef10_sriov.c
+@@ -402,12 +402,17 @@ fail1:
+ 	return rc;
+ }
+ 
++/* Disable SRIOV and remove VFs
++ * If some VFs are attached to a guest (using Xen, only) nothing is
++ * done if force=false, and vports are freed if force=true (for the non
++ * attachedc ones, only) but SRIOV is not disabled and VFs are not
++ * removed in either case.
++ */
+ static int efx_ef10_pci_sriov_disable(struct efx_nic *efx, bool force)
+ {
+ 	struct pci_dev *dev = efx->pci_dev;
+-	unsigned int vfs_assigned = 0;
+-
+-	vfs_assigned = pci_vfs_assigned(dev);
++	unsigned int vfs_assigned = pci_vfs_assigned(dev);
++	int rc = 0;
+ 
+ 	if (vfs_assigned && !force) {
+ 		netif_info(efx, drv, efx->net_dev, "VFs are assigned to guests; "
+@@ -417,10 +422,12 @@ static int efx_ef10_pci_sriov_disable(struct efx_nic *efx, bool force)
+ 
+ 	if (!vfs_assigned)
+ 		pci_disable_sriov(dev);
++	else
++		rc = -EBUSY;
+ 
+ 	efx_ef10_sriov_free_vf_vswitching(efx);
+ 	efx->vf_count = 0;
+-	return 0;
++	return rc;
+ }
+ 
+ int efx_ef10_sriov_configure(struct efx_nic *efx, int num_vfs)
+@@ -439,7 +446,6 @@ int efx_ef10_sriov_init(struct efx_nic *efx)
+ void efx_ef10_sriov_fini(struct efx_nic *efx)
+ {
+ 	struct efx_ef10_nic_data *nic_data = efx->nic_data;
+-	unsigned int i;
+ 	int rc;
+ 
+ 	if (!nic_data->vf) {
+@@ -449,14 +455,7 @@ void efx_ef10_sriov_fini(struct efx_nic *efx)
+ 		return;
+ 	}
+ 
+-	/* Remove any VFs in the host */
+-	for (i = 0; i < efx->vf_count; ++i) {
+-		struct efx_nic *vf_efx = nic_data->vf[i].efx;
+-
+-		if (vf_efx)
+-			vf_efx->pci_dev->driver->remove(vf_efx->pci_dev);
+-	}
+-
++	/* Disable SRIOV and remove any VFs in the host */
+ 	rc = efx_ef10_pci_sriov_disable(efx, true);
+ 	if (rc)
+ 		netif_dbg(efx, drv, efx->net_dev,
+diff --git a/drivers/net/ethernet/sgi/ioc3-eth.c b/drivers/net/ethernet/sgi/ioc3-eth.c
+index 6eef0f45b133b..2b29fd4cbdf44 100644
+--- a/drivers/net/ethernet/sgi/ioc3-eth.c
++++ b/drivers/net/ethernet/sgi/ioc3-eth.c
+@@ -835,6 +835,10 @@ static int ioc3eth_probe(struct platform_device *pdev)
+ 	int err;
+ 
+ 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!regs) {
++		dev_err(&pdev->dev, "Invalid resource\n");
++		return -EINVAL;
++	}
+ 	/* get mac addr from one wire prom */
+ 	if (ioc3eth_get_mac_addr(regs, mac_addr))
+ 		return -EPROBE_DEFER; /* not available yet */
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+index b750074f8f9cf..e293bf1ce9f37 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+@@ -503,6 +503,12 @@ int stmmac_mdio_register(struct net_device *ndev)
+ 		found = 1;
+ 	}
+ 
++	if (!found && !mdio_node) {
++		dev_warn(dev, "No PHY found\n");
++		err = -ENODEV;
++		goto no_phy_found;
++	}
++
+ 	/* Try to probe the XPCS by scanning all addresses. */
+ 	if (priv->hw->xpcs) {
+ 		struct mdio_xpcs_args *xpcs = &priv->hw->xpcs_args;
+@@ -511,6 +517,7 @@ int stmmac_mdio_register(struct net_device *ndev)
+ 
+ 		xpcs->bus = new_bus;
+ 
++		found = 0;
+ 		for (addr = 0; addr < max_addr; addr++) {
+ 			xpcs->addr = addr;
+ 
+@@ -520,13 +527,12 @@ int stmmac_mdio_register(struct net_device *ndev)
+ 				break;
+ 			}
+ 		}
+-	}
+ 
+-	if (!found && !mdio_node) {
+-		dev_warn(dev, "No PHY found\n");
+-		mdiobus_unregister(new_bus);
+-		mdiobus_free(new_bus);
+-		return -ENODEV;
++		if (!found && !mdio_node) {
++			dev_warn(dev, "No XPCS found\n");
++			err = -ENODEV;
++			goto no_xpcs_found;
++		}
+ 	}
+ 
+ bus_register_done:
+@@ -534,6 +540,9 @@ bus_register_done:
+ 
+ 	return 0;
+ 
++no_xpcs_found:
++no_phy_found:
++	mdiobus_unregister(new_bus);
+ bus_register_fail:
+ 	mdiobus_free(new_bus);
+ 	return err;
+diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+index d9d58a7dabee8..b06377fe72938 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+@@ -1189,9 +1189,8 @@ static int xemaclite_of_probe(struct platform_device *ofdev)
+ 	}
+ 
+ 	dev_info(dev,
+-		 "Xilinx EmacLite at 0x%08lX mapped to 0x%08lX, irq=%d\n",
+-		 (unsigned long __force)ndev->mem_start,
+-		 (unsigned long __force)lp->base_addr, ndev->irq);
++		 "Xilinx EmacLite at 0x%08lX mapped to 0x%p, irq=%d\n",
++		 (unsigned long __force)ndev->mem_start, lp->base_addr, ndev->irq);
+ 	return 0;
+ 
+ error:
+diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c
+index cb89323855d84..1ecceeb9700db 100644
+--- a/drivers/net/ethernet/xscale/ixp4xx_eth.c
++++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c
+@@ -1531,8 +1531,8 @@ static int ixp4xx_eth_probe(struct platform_device *pdev)
+ 		phydev = of_phy_get_and_connect(ndev, np, ixp4xx_adjust_link);
+ 	} else {
+ 		phydev = mdiobus_get_phy(mdio_bus, plat->phy);
+-		if (IS_ERR(phydev)) {
+-			err = PTR_ERR(phydev);
++		if (!phydev) {
++			err = -ENODEV;
+ 			dev_err(dev, "could not connect phydev (%d)\n", err);
+ 			goto err_free_mem;
+ 		}
+diff --git a/drivers/net/fjes/fjes_main.c b/drivers/net/fjes/fjes_main.c
+index 466622664424d..e449d94661225 100644
+--- a/drivers/net/fjes/fjes_main.c
++++ b/drivers/net/fjes/fjes_main.c
+@@ -1262,6 +1262,10 @@ static int fjes_probe(struct platform_device *plat_dev)
+ 	adapter->interrupt_watch_enable = false;
+ 
+ 	res = platform_get_resource(plat_dev, IORESOURCE_MEM, 0);
++	if (!res) {
++		err = -EINVAL;
++		goto err_free_control_wq;
++	}
+ 	hw->hw_res.start = res->start;
+ 	hw->hw_res.size = resource_size(res);
+ 	hw->hw_res.irq = platform_get_irq(plat_dev, 0);
+diff --git a/drivers/net/ipa/ipa_main.c b/drivers/net/ipa/ipa_main.c
+index 9915603ed10ba..c4ad5f20496ed 100644
+--- a/drivers/net/ipa/ipa_main.c
++++ b/drivers/net/ipa/ipa_main.c
+@@ -529,6 +529,7 @@ static int ipa_firmware_load(struct device *dev)
+ 	}
+ 
+ 	ret = of_address_to_resource(node, 0, &res);
++	of_node_put(node);
+ 	if (ret) {
+ 		dev_err(dev, "error %d getting \"memory-region\" resource\n",
+ 			ret);
+diff --git a/drivers/net/mdio/mdio-ipq8064.c b/drivers/net/mdio/mdio-ipq8064.c
+index 8fe8f0119fc19..8de11f35ac1e3 100644
+--- a/drivers/net/mdio/mdio-ipq8064.c
++++ b/drivers/net/mdio/mdio-ipq8064.c
+@@ -7,10 +7,9 @@
+ 
+ #include <linux/delay.h>
+ #include <linux/kernel.h>
+-#include <linux/mfd/syscon.h>
+ #include <linux/module.h>
+ #include <linux/of_mdio.h>
+-#include <linux/phy.h>
++#include <linux/of_address.h>
+ #include <linux/platform_device.h>
+ #include <linux/regmap.h>
+ 
+@@ -96,14 +95,34 @@ ipq8064_mdio_write(struct mii_bus *bus, int phy_addr, int reg_offset, u16 data)
+ 	return ipq8064_mdio_wait_busy(priv);
+ }
+ 
++static const struct regmap_config ipq8064_mdio_regmap_config = {
++	.reg_bits = 32,
++	.reg_stride = 4,
++	.val_bits = 32,
++	.can_multi_write = false,
++	/* the mdio lock is used by any user of this mdio driver */
++	.disable_locking = true,
++
++	.cache_type = REGCACHE_NONE,
++};
++
+ static int
+ ipq8064_mdio_probe(struct platform_device *pdev)
+ {
+ 	struct device_node *np = pdev->dev.of_node;
+ 	struct ipq8064_mdio *priv;
++	struct resource res;
+ 	struct mii_bus *bus;
++	void __iomem *base;
+ 	int ret;
+ 
++	if (of_address_to_resource(np, 0, &res))
++		return -ENOMEM;
++
++	base = ioremap(res.start, resource_size(&res));
++	if (!base)
++		return -ENOMEM;
++
+ 	bus = devm_mdiobus_alloc_size(&pdev->dev, sizeof(*priv));
+ 	if (!bus)
+ 		return -ENOMEM;
+@@ -115,15 +134,10 @@ ipq8064_mdio_probe(struct platform_device *pdev)
+ 	bus->parent = &pdev->dev;
+ 
+ 	priv = bus->priv;
+-	priv->base = device_node_to_regmap(np);
+-	if (IS_ERR(priv->base)) {
+-		if (priv->base == ERR_PTR(-EPROBE_DEFER))
+-			return -EPROBE_DEFER;
+-
+-		dev_err(&pdev->dev, "error getting device regmap, error=%pe\n",
+-			priv->base);
++	priv->base = devm_regmap_init_mmio(&pdev->dev, base,
++					   &ipq8064_mdio_regmap_config);
++	if (IS_ERR(priv->base))
+ 		return PTR_ERR(priv->base);
+-	}
+ 
+ 	ret = of_mdiobus_register(bus, np);
+ 	if (ret)
+diff --git a/drivers/net/mdio/mdio-mux-bcm-iproc.c b/drivers/net/mdio/mdio-mux-bcm-iproc.c
+index 03261e6b9ceb5..aa29d6bdbdf25 100644
+--- a/drivers/net/mdio/mdio-mux-bcm-iproc.c
++++ b/drivers/net/mdio/mdio-mux-bcm-iproc.c
+@@ -187,7 +187,9 @@ static int mdio_mux_iproc_probe(struct platform_device *pdev)
+ 		return -ENOMEM;
+ 	md->dev = &pdev->dev;
+ 
+-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	md->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
++	if (IS_ERR(md->base))
++		return PTR_ERR(md->base);
+ 	if (res->start & 0xfff) {
+ 		/* For backward compatibility in case the
+ 		 * base address is specified with an offset.
+@@ -196,9 +198,6 @@ static int mdio_mux_iproc_probe(struct platform_device *pdev)
+ 		res->start &= ~0xfff;
+ 		res->end = res->start + MDIO_REG_ADDR_SPACE_SIZE - 1;
+ 	}
+-	md->base = devm_ioremap_resource(&pdev->dev, res);
+-	if (IS_ERR(md->base))
+-		return PTR_ERR(md->base);
+ 
+ 	md->mii_bus = devm_mdiobus_alloc(&pdev->dev);
+ 	if (!md->mii_bus) {
+diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c
+index 26b9c0d7cb9d5..b7ce0e737333c 100644
+--- a/drivers/net/phy/nxp-c45-tja11xx.c
++++ b/drivers/net/phy/nxp-c45-tja11xx.c
+@@ -546,6 +546,12 @@ static int nxp_c45_config_init(struct phy_device *phydev)
+ 		return ret;
+ 	}
+ 
++	/* Bug workaround for SJA1110 rev B: enable write access
++	 * to MDIO_MMD_PMAPMD
++	 */
++	phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x01F8, 1);
++	phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x01F9, 2);
++
+ 	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_PHY_CONFIG,
+ 			 PHY_CONFIG_AUTO);
+ 
+diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
+index 821e85a973679..7b99a3234c652 100644
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -357,6 +357,19 @@ static int rtl8211f_config_init(struct phy_device *phydev)
+ 	return 0;
+ }
+ 
++static int rtl821x_resume(struct phy_device *phydev)
++{
++	int ret;
++
++	ret = genphy_resume(phydev);
++	if (ret < 0)
++		return ret;
++
++	msleep(20);
++
++	return 0;
++}
++
+ static int rtl8211e_config_init(struct phy_device *phydev)
+ {
+ 	int ret = 0, oldpage;
+@@ -852,7 +865,7 @@ static struct phy_driver realtek_drvs[] = {
+ 		.config_intr	= &rtl8211f_config_intr,
+ 		.handle_interrupt = rtl8211f_handle_interrupt,
+ 		.suspend	= genphy_suspend,
+-		.resume		= genphy_resume,
++		.resume		= rtl821x_resume,
+ 		.read_page	= rtl821x_read_page,
+ 		.write_page	= rtl821x_write_page,
+ 	}, {
+diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
+index 78a01c71a17cf..2debb32a1813a 100644
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -721,6 +721,12 @@ static struct sk_buff *receive_small(struct net_device *dev,
+ 	len -= vi->hdr_len;
+ 	stats->bytes += len;
+ 
++	if (unlikely(len > GOOD_PACKET_LEN)) {
++		pr_debug("%s: rx error: len %u exceeds max size %d\n",
++			 dev->name, len, GOOD_PACKET_LEN);
++		dev->stats.rx_length_errors++;
++		goto err_len;
++	}
+ 	rcu_read_lock();
+ 	xdp_prog = rcu_dereference(rq->xdp_prog);
+ 	if (xdp_prog) {
+@@ -824,6 +830,7 @@ err:
+ err_xdp:
+ 	rcu_read_unlock();
+ 	stats->xdp_drops++;
++err_len:
+ 	stats->drops++;
+ 	put_page(page);
+ xdp_xmit:
+@@ -877,6 +884,12 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
+ 	head_skb = NULL;
+ 	stats->bytes += len - vi->hdr_len;
+ 
++	if (unlikely(len > truesize)) {
++		pr_debug("%s: rx error: len %u exceeds truesize %lu\n",
++			 dev->name, len, (unsigned long)ctx);
++		dev->stats.rx_length_errors++;
++		goto err_skb;
++	}
+ 	rcu_read_lock();
+ 	xdp_prog = rcu_dereference(rq->xdp_prog);
+ 	if (xdp_prog) {
+@@ -1004,13 +1017,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
+ 	}
+ 	rcu_read_unlock();
+ 
+-	if (unlikely(len > truesize)) {
+-		pr_debug("%s: rx error: len %u exceeds truesize %lu\n",
+-			 dev->name, len, (unsigned long)ctx);
+-		dev->stats.rx_length_errors++;
+-		goto err_skb;
+-	}
+-
+ 	head_skb = page_to_skb(vi, rq, page, offset, len, truesize, !xdp_prog,
+ 			       metasize, headroom);
+ 	curr_skb = head_skb;
+@@ -1619,7 +1625,7 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb)
+ 	if (virtio_net_hdr_from_skb(skb, &hdr->hdr,
+ 				    virtio_is_little_endian(vi->vdev), false,
+ 				    0))
+-		BUG();
++		return -EPROTO;
+ 
+ 	if (vi->mergeable_rx_bufs)
+ 		hdr->num_buffers = 0;
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+index 607d5d564928d..141d9fc299b01 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+@@ -3800,6 +3800,7 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
+ 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ 	struct cfg80211_chan_def chandef;
+ 	struct iwl_mvm_phy_ctxt *phy_ctxt;
++	bool band_change_removal;
+ 	int ret, i;
+ 
+ 	IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
+@@ -3880,19 +3881,30 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
+ 	cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT);
+ 
+ 	/*
+-	 * Change the PHY context configuration as it is currently referenced
+-	 * only by the P2P Device MAC
++	 * Check if the remain-on-channel is on a different band and that
++	 * requires context removal, see iwl_mvm_phy_ctxt_changed(). If
++	 * so, we'll need to release and then re-configure here, since we
++	 * must not remove a PHY context that's part of a binding.
+ 	 */
+-	if (mvmvif->phy_ctxt->ref == 1) {
++	band_change_removal =
++		fw_has_capa(&mvm->fw->ucode_capa,
++			    IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT) &&
++		mvmvif->phy_ctxt->channel->band != chandef.chan->band;
++
++	if (mvmvif->phy_ctxt->ref == 1 && !band_change_removal) {
++		/*
++		 * Change the PHY context configuration as it is currently
++		 * referenced only by the P2P Device MAC (and we can modify it)
++		 */
+ 		ret = iwl_mvm_phy_ctxt_changed(mvm, mvmvif->phy_ctxt,
+ 					       &chandef, 1, 1);
+ 		if (ret)
+ 			goto out_unlock;
+ 	} else {
+ 		/*
+-		 * The PHY context is shared with other MACs. Need to remove the
+-		 * P2P Device from the binding, allocate an new PHY context and
+-		 * create a new binding
++		 * The PHY context is shared with other MACs (or we're trying to
++		 * switch bands), so remove the P2P Device from the binding,
++		 * allocate an new PHY context and create a new binding.
+ 		 */
+ 		phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
+ 		if (!phy_ctxt) {
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+index 4d9d4d6892fc7..02cf521338578 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+@@ -1827,7 +1827,8 @@ int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
+ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+ 				enum iwl_mvm_smps_type_request req_type,
+ 				enum ieee80211_smps_mode smps_request);
+-bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm *mvm);
++bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm *mvm,
++				  struct iwl_mvm_phy_ctxt *ctxt);
+ 
+ /* Low latency */
+ int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
+index 0fd51f6aa2061..4ed2338027d13 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+ /*
+- * Copyright (C) 2012-2014, 2018-2020 Intel Corporation
++ * Copyright (C) 2012-2014, 2018-2021 Intel Corporation
+  * Copyright (C) 2013-2014 Intel Mobile Communications GmbH
+  * Copyright (C) 2017 Intel Deutschland GmbH
+  */
+@@ -76,6 +76,7 @@ static void iwl_mvm_phy_ctxt_cmd_hdr(struct iwl_mvm_phy_ctxt *ctxt,
+ }
+ 
+ static void iwl_mvm_phy_ctxt_set_rxchain(struct iwl_mvm *mvm,
++					 struct iwl_mvm_phy_ctxt *ctxt,
+ 					 __le32 *rxchain_info,
+ 					 u8 chains_static,
+ 					 u8 chains_dynamic)
+@@ -93,7 +94,7 @@ static void iwl_mvm_phy_ctxt_set_rxchain(struct iwl_mvm *mvm,
+ 	 * between the two antennas is sufficiently different to impact
+ 	 * performance.
+ 	 */
+-	if (active_cnt == 1 && iwl_mvm_rx_diversity_allowed(mvm)) {
++	if (active_cnt == 1 && iwl_mvm_rx_diversity_allowed(mvm, ctxt)) {
+ 		idle_cnt = 2;
+ 		active_cnt = 2;
+ 	}
+@@ -113,6 +114,7 @@ static void iwl_mvm_phy_ctxt_set_rxchain(struct iwl_mvm *mvm,
+  * Add the phy configuration to the PHY context command
+  */
+ static void iwl_mvm_phy_ctxt_cmd_data_v1(struct iwl_mvm *mvm,
++					 struct iwl_mvm_phy_ctxt *ctxt,
+ 					 struct iwl_phy_context_cmd_v1 *cmd,
+ 					 struct cfg80211_chan_def *chandef,
+ 					 u8 chains_static, u8 chains_dynamic)
+@@ -123,7 +125,7 @@ static void iwl_mvm_phy_ctxt_cmd_data_v1(struct iwl_mvm *mvm,
+ 	/* Set the channel info data */
+ 	iwl_mvm_set_chan_info_chandef(mvm, &cmd->ci, chandef);
+ 
+-	iwl_mvm_phy_ctxt_set_rxchain(mvm, &tail->rxchain_info,
++	iwl_mvm_phy_ctxt_set_rxchain(mvm, ctxt, &tail->rxchain_info,
+ 				     chains_static, chains_dynamic);
+ 
+ 	tail->txchain_info = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
+@@ -133,6 +135,7 @@ static void iwl_mvm_phy_ctxt_cmd_data_v1(struct iwl_mvm *mvm,
+  * Add the phy configuration to the PHY context command
+  */
+ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
++				      struct iwl_mvm_phy_ctxt *ctxt,
+ 				      struct iwl_phy_context_cmd *cmd,
+ 				      struct cfg80211_chan_def *chandef,
+ 				      u8 chains_static, u8 chains_dynamic)
+@@ -143,7 +146,7 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
+ 	/* Set the channel info data */
+ 	iwl_mvm_set_chan_info_chandef(mvm, &cmd->ci, chandef);
+ 
+-	iwl_mvm_phy_ctxt_set_rxchain(mvm, &cmd->rxchain_info,
++	iwl_mvm_phy_ctxt_set_rxchain(mvm, ctxt, &cmd->rxchain_info,
+ 				     chains_static, chains_dynamic);
+ }
+ 
+@@ -170,7 +173,7 @@ static int iwl_mvm_phy_ctxt_apply(struct iwl_mvm *mvm,
+ 		iwl_mvm_phy_ctxt_cmd_hdr(ctxt, &cmd, action);
+ 
+ 		/* Set the command data */
+-		iwl_mvm_phy_ctxt_cmd_data(mvm, &cmd, chandef,
++		iwl_mvm_phy_ctxt_cmd_data(mvm, ctxt, &cmd, chandef,
+ 					  chains_static,
+ 					  chains_dynamic);
+ 
+@@ -186,7 +189,7 @@ static int iwl_mvm_phy_ctxt_apply(struct iwl_mvm *mvm,
+ 					 action);
+ 
+ 		/* Set the command data */
+-		iwl_mvm_phy_ctxt_cmd_data_v1(mvm, &cmd, chandef,
++		iwl_mvm_phy_ctxt_cmd_data_v1(mvm, ctxt, &cmd, chandef,
+ 					     chains_static,
+ 					     chains_dynamic);
+ 		ret = iwl_mvm_send_cmd_pdu(mvm, PHY_CONTEXT_CMD,
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
+index 83342a6a6d5b5..f19081a6f0460 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
+@@ -310,6 +310,8 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
+ 			 * and know the dtim period.
+ 			 */
+ 			iwl_mvm_te_check_disconnect(mvm, te_data->vif,
++				!te_data->vif->bss_conf.assoc ?
++				"Not associated and the time event is over already..." :
+ 				"No beacon heard and the time event is over already...");
+ 			break;
+ 		default:
+@@ -808,6 +810,8 @@ void iwl_mvm_rx_session_protect_notif(struct iwl_mvm *mvm,
+ 			 * and know the dtim period.
+ 			 */
+ 			iwl_mvm_te_check_disconnect(mvm, vif,
++						    !vif->bss_conf.assoc ?
++						    "Not associated and the session protection is over already..." :
+ 						    "No beacon heard and the session protection is over already...");
+ 			spin_lock_bh(&mvm->time_event_lock);
+ 			iwl_mvm_te_clear_data(mvm, te_data);
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
+index c566be99a4c74..a89eb7c40ee7c 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
+@@ -683,23 +683,37 @@ void iwl_mvm_accu_radio_stats(struct iwl_mvm *mvm)
+ 	mvm->accu_radio_stats.on_time_scan += mvm->radio_stats.on_time_scan;
+ }
+ 
++struct iwl_mvm_diversity_iter_data {
++	struct iwl_mvm_phy_ctxt *ctxt;
++	bool result;
++};
++
+ static void iwl_mvm_diversity_iter(void *_data, u8 *mac,
+ 				   struct ieee80211_vif *vif)
+ {
+ 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+-	bool *result = _data;
++	struct iwl_mvm_diversity_iter_data *data = _data;
+ 	int i;
+ 
++	if (mvmvif->phy_ctxt != data->ctxt)
++		return;
++
+ 	for (i = 0; i < NUM_IWL_MVM_SMPS_REQ; i++) {
+ 		if (mvmvif->smps_requests[i] == IEEE80211_SMPS_STATIC ||
+-		    mvmvif->smps_requests[i] == IEEE80211_SMPS_DYNAMIC)
+-			*result = false;
++		    mvmvif->smps_requests[i] == IEEE80211_SMPS_DYNAMIC) {
++			data->result = false;
++			break;
++		}
+ 	}
+ }
+ 
+-bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm *mvm)
++bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm *mvm,
++				  struct iwl_mvm_phy_ctxt *ctxt)
+ {
+-	bool result = true;
++	struct iwl_mvm_diversity_iter_data data = {
++		.ctxt = ctxt,
++		.result = true,
++	};
+ 
+ 	lockdep_assert_held(&mvm->mutex);
+ 
+@@ -711,9 +725,9 @@ bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm *mvm)
+ 
+ 	ieee80211_iterate_active_interfaces_atomic(
+ 			mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
+-			iwl_mvm_diversity_iter, &result);
++			iwl_mvm_diversity_iter, &data);
+ 
+-	return result;
++	return data.result;
+ }
+ 
+ void iwl_mvm_send_low_latency_cmd(struct iwl_mvm *mvm,
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
+index cecc32e7dbe8a..2dbc51daa2f8a 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
+@@ -79,7 +79,6 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
+ 	struct iwl_prph_scratch *prph_scratch;
+ 	struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl;
+ 	struct iwl_prph_info *prph_info;
+-	void *iml_img;
+ 	u32 control_flags = 0;
+ 	int ret;
+ 	int cmdq_size = max_t(u32, IWL_CMD_QUEUE_SIZE,
+@@ -187,14 +186,15 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
+ 	trans_pcie->prph_scratch = prph_scratch;
+ 
+ 	/* Allocate IML */
+-	iml_img = dma_alloc_coherent(trans->dev, trans->iml_len,
+-				     &trans_pcie->iml_dma_addr, GFP_KERNEL);
+-	if (!iml_img) {
++	trans_pcie->iml = dma_alloc_coherent(trans->dev, trans->iml_len,
++					     &trans_pcie->iml_dma_addr,
++					     GFP_KERNEL);
++	if (!trans_pcie->iml) {
+ 		ret = -ENOMEM;
+ 		goto err_free_ctxt_info;
+ 	}
+ 
+-	memcpy(iml_img, trans->iml, trans->iml_len);
++	memcpy(trans_pcie->iml, trans->iml, trans->iml_len);
+ 
+ 	iwl_enable_fw_load_int_ctx_info(trans);
+ 
+@@ -243,6 +243,11 @@ void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans)
+ 	trans_pcie->ctxt_info_dma_addr = 0;
+ 	trans_pcie->ctxt_info_gen3 = NULL;
+ 
++	dma_free_coherent(trans->dev, trans->iml_len, trans_pcie->iml,
++			  trans_pcie->iml_dma_addr);
++	trans_pcie->iml_dma_addr = 0;
++	trans_pcie->iml = NULL;
++
+ 	iwl_pcie_ctxt_info_free_fw_img(trans);
+ 
+ 	dma_free_coherent(trans->dev, sizeof(*trans_pcie->prph_scratch),
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+index 76a512cd2e5c8..3f7cfbf707fdc 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+@@ -279,6 +279,8 @@ struct cont_rec {
+  *	Context information addresses will be taken from here.
+  *	This is driver's local copy for keeping track of size and
+  *	count for allocating and freeing the memory.
++ * @iml: image loader image virtual address
++ * @iml_dma_addr: image loader image DMA address
+  * @trans: pointer to the generic transport area
+  * @scd_base_addr: scheduler sram base address in SRAM
+  * @kw: keep warm address
+@@ -329,6 +331,7 @@ struct iwl_trans_pcie {
+ 	};
+ 	struct iwl_prph_info *prph_info;
+ 	struct iwl_prph_scratch *prph_scratch;
++	void *iml;
+ 	dma_addr_t ctxt_info_dma_addr;
+ 	dma_addr_t prph_info_dma_addr;
+ 	dma_addr_t prph_scratch_dma_addr;
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
+index 1bcd36e9e0086..9ce195d80c512 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
+@@ -254,7 +254,8 @@ void iwl_trans_pcie_gen2_fw_alive(struct iwl_trans *trans, u32 scd_addr)
+ 	/* now that we got alive we can free the fw image & the context info.
+ 	 * paging memory cannot be freed included since FW will still use it
+ 	 */
+-	iwl_pcie_ctxt_info_free(trans);
++	if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
++		iwl_pcie_ctxt_info_free(trans);
+ 
+ 	/*
+ 	 * Re-enable all the interrupts, including the RF-Kill one, now that
+diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
+index 7a6fd46d0c6e8..ceb089e4a136a 100644
+--- a/drivers/net/wireless/mac80211_hwsim.c
++++ b/drivers/net/wireless/mac80211_hwsim.c
+@@ -626,6 +626,7 @@ struct mac80211_hwsim_data {
+ 	u32 ciphers[ARRAY_SIZE(hwsim_ciphers)];
+ 
+ 	struct mac_address addresses[2];
++	struct ieee80211_chanctx_conf *chanctx;
+ 	int channels, idx;
+ 	bool use_chanctx;
+ 	bool destroy_on_close;
+@@ -1257,7 +1258,8 @@ static inline u16 trans_tx_rate_flags_ieee2hwsim(struct ieee80211_tx_rate *rate)
+ 
+ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
+ 				       struct sk_buff *my_skb,
+-				       int dst_portid)
++				       int dst_portid,
++				       struct ieee80211_channel *channel)
+ {
+ 	struct sk_buff *skb;
+ 	struct mac80211_hwsim_data *data = hw->priv;
+@@ -1312,7 +1314,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
+ 	if (nla_put_u32(skb, HWSIM_ATTR_FLAGS, hwsim_flags))
+ 		goto nla_put_failure;
+ 
+-	if (nla_put_u32(skb, HWSIM_ATTR_FREQ, data->channel->center_freq))
++	if (nla_put_u32(skb, HWSIM_ATTR_FREQ, channel->center_freq))
+ 		goto nla_put_failure;
+ 
+ 	/* We get the tx control (rate and retries) info*/
+@@ -1659,7 +1661,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
+ 	_portid = READ_ONCE(data->wmediumd);
+ 
+ 	if (_portid || hwsim_virtio_enabled)
+-		return mac80211_hwsim_tx_frame_nl(hw, skb, _portid);
++		return mac80211_hwsim_tx_frame_nl(hw, skb, _portid, channel);
+ 
+ 	/* NO wmediumd detected, perfect medium simulation */
+ 	data->tx_pkts++;
+@@ -1775,7 +1777,7 @@ static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
+ 	mac80211_hwsim_monitor_rx(hw, skb, chan);
+ 
+ 	if (_pid || hwsim_virtio_enabled)
+-		return mac80211_hwsim_tx_frame_nl(hw, skb, _pid);
++		return mac80211_hwsim_tx_frame_nl(hw, skb, _pid, chan);
+ 
+ 	mac80211_hwsim_tx_frame_no_nl(hw, skb, chan);
+ 	dev_kfree_skb(skb);
+@@ -2514,6 +2516,11 @@ static int mac80211_hwsim_croc(struct ieee80211_hw *hw,
+ static int mac80211_hwsim_add_chanctx(struct ieee80211_hw *hw,
+ 				      struct ieee80211_chanctx_conf *ctx)
+ {
++	struct mac80211_hwsim_data *hwsim = hw->priv;
++
++	mutex_lock(&hwsim->mutex);
++	hwsim->chanctx = ctx;
++	mutex_unlock(&hwsim->mutex);
+ 	hwsim_set_chanctx_magic(ctx);
+ 	wiphy_dbg(hw->wiphy,
+ 		  "add channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
+@@ -2525,6 +2532,11 @@ static int mac80211_hwsim_add_chanctx(struct ieee80211_hw *hw,
+ static void mac80211_hwsim_remove_chanctx(struct ieee80211_hw *hw,
+ 					  struct ieee80211_chanctx_conf *ctx)
+ {
++	struct mac80211_hwsim_data *hwsim = hw->priv;
++
++	mutex_lock(&hwsim->mutex);
++	hwsim->chanctx = NULL;
++	mutex_unlock(&hwsim->mutex);
+ 	wiphy_dbg(hw->wiphy,
+ 		  "remove channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
+ 		  ctx->def.chan->center_freq, ctx->def.width,
+@@ -2537,6 +2549,11 @@ static void mac80211_hwsim_change_chanctx(struct ieee80211_hw *hw,
+ 					  struct ieee80211_chanctx_conf *ctx,
+ 					  u32 changed)
+ {
++	struct mac80211_hwsim_data *hwsim = hw->priv;
++
++	mutex_lock(&hwsim->mutex);
++	hwsim->chanctx = ctx;
++	mutex_unlock(&hwsim->mutex);
+ 	hwsim_check_chanctx_magic(ctx);
+ 	wiphy_dbg(hw->wiphy,
+ 		  "change channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
+@@ -3129,6 +3146,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
+ 		hw->wiphy->max_remain_on_channel_duration = 1000;
+ 		data->if_combination.radar_detect_widths = 0;
+ 		data->if_combination.num_different_channels = data->channels;
++		data->chanctx = NULL;
+ 	} else {
+ 		data->if_combination.num_different_channels = 1;
+ 		data->if_combination.radar_detect_widths =
+@@ -3638,6 +3656,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
+ 	int frame_data_len;
+ 	void *frame_data;
+ 	struct sk_buff *skb = NULL;
++	struct ieee80211_channel *channel = NULL;
+ 
+ 	if (!info->attrs[HWSIM_ATTR_ADDR_RECEIVER] ||
+ 	    !info->attrs[HWSIM_ATTR_FRAME] ||
+@@ -3664,6 +3683,17 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
+ 	if (!data2)
+ 		goto out;
+ 
++	if (data2->use_chanctx) {
++		if (data2->tmp_chan)
++			channel = data2->tmp_chan;
++		else if (data2->chanctx)
++			channel = data2->chanctx->def.chan;
++	} else {
++		channel = data2->channel;
++	}
++	if (!channel)
++		goto out;
++
+ 	if (!hwsim_virtio_enabled) {
+ 		if (hwsim_net_get_netgroup(genl_info_net(info)) !=
+ 		    data2->netgroup)
+@@ -3675,7 +3705,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
+ 
+ 	/* check if radio is configured properly */
+ 
+-	if (data2->idle || !data2->started)
++	if ((data2->idle && !data2->tmp_chan) || !data2->started)
+ 		goto out;
+ 
+ 	/* A frame is received from user space */
+@@ -3688,18 +3718,16 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
+ 		mutex_lock(&data2->mutex);
+ 		rx_status.freq = nla_get_u32(info->attrs[HWSIM_ATTR_FREQ]);
+ 
+-		if (rx_status.freq != data2->channel->center_freq &&
+-		    (!data2->tmp_chan ||
+-		     rx_status.freq != data2->tmp_chan->center_freq)) {
++		if (rx_status.freq != channel->center_freq) {
+ 			mutex_unlock(&data2->mutex);
+ 			goto out;
+ 		}
+ 		mutex_unlock(&data2->mutex);
+ 	} else {
+-		rx_status.freq = data2->channel->center_freq;
++		rx_status.freq = channel->center_freq;
+ 	}
+ 
+-	rx_status.band = data2->channel->band;
++	rx_status.band = channel->band;
+ 	rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]);
+ 	rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]);
+ 
+diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
+index 529dfd8b7ae85..17399d4aa1290 100644
+--- a/drivers/net/wireless/marvell/mwifiex/main.c
++++ b/drivers/net/wireless/marvell/mwifiex/main.c
+@@ -1445,11 +1445,18 @@ static void mwifiex_uninit_sw(struct mwifiex_adapter *adapter)
+ 		if (!priv)
+ 			continue;
+ 		rtnl_lock();
+-		wiphy_lock(adapter->wiphy);
+ 		if (priv->netdev &&
+-		    priv->wdev.iftype != NL80211_IFTYPE_UNSPECIFIED)
++		    priv->wdev.iftype != NL80211_IFTYPE_UNSPECIFIED) {
++			/*
++			 * Close the netdev now, because if we do it later, the
++			 * netdev notifiers will need to acquire the wiphy lock
++			 * again --> deadlock.
++			 */
++			dev_close(priv->wdev.netdev);
++			wiphy_lock(adapter->wiphy);
+ 			mwifiex_del_virtual_intf(adapter->wiphy, &priv->wdev);
+-		wiphy_unlock(adapter->wiphy);
++			wiphy_unlock(adapter->wiphy);
++		}
+ 		rtnl_unlock();
+ 	}
+ 
+diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
+index 72b1cc0ecfda3..e5c324dd24f93 100644
+--- a/drivers/net/wireless/mediatek/mt76/dma.c
++++ b/drivers/net/wireless/mediatek/mt76/dma.c
+@@ -349,6 +349,9 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
+ 		      struct sk_buff *skb, struct mt76_wcid *wcid,
+ 		      struct ieee80211_sta *sta)
+ {
++	struct ieee80211_tx_status status = {
++		.sta = sta,
++	};
+ 	struct mt76_tx_info tx_info = {
+ 		.skb = skb,
+ 	};
+@@ -360,11 +363,9 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
+ 	u8 *txwi;
+ 
+ 	t = mt76_get_txwi(dev);
+-	if (!t) {
+-		hw = mt76_tx_status_get_hw(dev, skb);
+-		ieee80211_free_txskb(hw, skb);
+-		return -ENOMEM;
+-	}
++	if (!t)
++		goto free_skb;
++
+ 	txwi = mt76_get_txwi_ptr(dev, t);
+ 
+ 	skb->prev = skb->next = NULL;
+@@ -427,8 +428,13 @@ free:
+ 	}
+ #endif
+ 
+-	dev_kfree_skb(tx_info.skb);
+ 	mt76_put_txwi(dev, t);
++
++free_skb:
++	status.skb = tx_info.skb;
++	hw = mt76_tx_status_get_hw(dev, tx_info.skb);
++	ieee80211_tx_status_ext(hw, &status);
++
+ 	return ret;
+ }
+ 
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
+index 36ede65919f8e..0c23edbfbdbbf 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76.h
++++ b/drivers/net/wireless/mediatek/mt76/mt76.h
+@@ -87,6 +87,22 @@ enum mt76_rxq_id {
+ 	__MT_RXQ_MAX
+ };
+ 
++enum mt76_cipher_type {
++	MT_CIPHER_NONE,
++	MT_CIPHER_WEP40,
++	MT_CIPHER_TKIP,
++	MT_CIPHER_TKIP_NO_MIC,
++	MT_CIPHER_AES_CCMP,
++	MT_CIPHER_WEP104,
++	MT_CIPHER_BIP_CMAC_128,
++	MT_CIPHER_WEP128,
++	MT_CIPHER_WAPI,
++	MT_CIPHER_CCMP_CCX,
++	MT_CIPHER_CCMP_256,
++	MT_CIPHER_GCMP,
++	MT_CIPHER_GCMP_256,
++};
++
+ struct mt76_queue_buf {
+ 	dma_addr_t addr;
+ 	u16 len;
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+index fbceb07c5f378..3aa7483e929f1 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+@@ -550,14 +550,27 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb)
+ 		u8 *data = (u8 *)rxd;
+ 
+ 		if (status->flag & RX_FLAG_DECRYPTED) {
+-			status->iv[0] = data[5];
+-			status->iv[1] = data[4];
+-			status->iv[2] = data[3];
+-			status->iv[3] = data[2];
+-			status->iv[4] = data[1];
+-			status->iv[5] = data[0];
+-
+-			insert_ccmp_hdr = FIELD_GET(MT_RXD2_NORMAL_FRAG, rxd2);
++			switch (FIELD_GET(MT_RXD2_NORMAL_SEC_MODE, rxd2)) {
++			case MT_CIPHER_AES_CCMP:
++			case MT_CIPHER_CCMP_CCX:
++			case MT_CIPHER_CCMP_256:
++				insert_ccmp_hdr =
++					FIELD_GET(MT_RXD2_NORMAL_FRAG, rxd2);
++				fallthrough;
++			case MT_CIPHER_TKIP:
++			case MT_CIPHER_TKIP_NO_MIC:
++			case MT_CIPHER_GCMP:
++			case MT_CIPHER_GCMP_256:
++				status->iv[0] = data[5];
++				status->iv[1] = data[4];
++				status->iv[2] = data[3];
++				status->iv[3] = data[2];
++				status->iv[4] = data[1];
++				status->iv[5] = data[0];
++				break;
++			default:
++				break;
++			}
+ 		}
+ 
+ 		rxd += 4;
+@@ -831,7 +844,7 @@ void mt7603_wtbl_set_rates(struct mt7603_dev *dev, struct mt7603_sta *sta,
+ 	sta->wcid.tx_info |= MT_WCID_TX_INFO_SET;
+ }
+ 
+-static enum mt7603_cipher_type
++static enum mt76_cipher_type
+ mt7603_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data)
+ {
+ 	memset(key_data, 0, 32);
+@@ -863,7 +876,7 @@ mt7603_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data)
+ int mt7603_wtbl_set_key(struct mt7603_dev *dev, int wcid,
+ 			struct ieee80211_key_conf *key)
+ {
+-	enum mt7603_cipher_type cipher;
++	enum mt76_cipher_type cipher;
+ 	u32 addr = mt7603_wtbl3_addr(wcid);
+ 	u8 key_data[32];
+ 	int key_len = sizeof(key_data);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/regs.h b/drivers/net/wireless/mediatek/mt76/mt7603/regs.h
+index 6741e69071940..3b901090b29c6 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7603/regs.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7603/regs.h
+@@ -765,16 +765,4 @@ enum {
+ #define MT_WTBL1_OR			(MT_WTBL1_BASE + 0x2300)
+ #define MT_WTBL1_OR_PSM_WRITE		BIT(31)
+ 
+-enum mt7603_cipher_type {
+-	MT_CIPHER_NONE,
+-	MT_CIPHER_WEP40,
+-	MT_CIPHER_TKIP,
+-	MT_CIPHER_TKIP_NO_MIC,
+-	MT_CIPHER_AES_CCMP,
+-	MT_CIPHER_WEP104,
+-	MT_CIPHER_BIP_CMAC_128,
+-	MT_CIPHER_WEP128,
+-	MT_CIPHER_WAPI,
+-};
+-
+ #endif
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/init.c b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
+index d20f05a7717d0..0d01fd3c77b5c 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
+@@ -362,7 +362,7 @@ mt7615_init_wiphy(struct ieee80211_hw *hw)
+ 	wiphy->reg_notifier = mt7615_regd_notifier;
+ 
+ 	wiphy->max_sched_scan_plan_interval =
+-		MT76_CONNAC_MAX_SCHED_SCAN_INTERVAL;
++		MT76_CONNAC_MAX_TIME_SCHED_SCAN_INTERVAL;
+ 	wiphy->max_sched_scan_ie_len = IEEE80211_MAX_DATA_LEN;
+ 	wiphy->max_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN;
+ 	wiphy->max_sched_scan_ssids = MT76_CONNAC_MAX_SCHED_SCAN_SSID;
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
+index e2dcfee6be81e..4873154d082ec 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
+@@ -57,6 +57,33 @@ static const struct mt7615_dfs_radar_spec jp_radar_specs = {
+ 	},
+ };
+ 
++static enum mt76_cipher_type
++mt7615_mac_get_cipher(int cipher)
++{
++	switch (cipher) {
++	case WLAN_CIPHER_SUITE_WEP40:
++		return MT_CIPHER_WEP40;
++	case WLAN_CIPHER_SUITE_WEP104:
++		return MT_CIPHER_WEP104;
++	case WLAN_CIPHER_SUITE_TKIP:
++		return MT_CIPHER_TKIP;
++	case WLAN_CIPHER_SUITE_AES_CMAC:
++		return MT_CIPHER_BIP_CMAC_128;
++	case WLAN_CIPHER_SUITE_CCMP:
++		return MT_CIPHER_AES_CCMP;
++	case WLAN_CIPHER_SUITE_CCMP_256:
++		return MT_CIPHER_CCMP_256;
++	case WLAN_CIPHER_SUITE_GCMP:
++		return MT_CIPHER_GCMP;
++	case WLAN_CIPHER_SUITE_GCMP_256:
++		return MT_CIPHER_GCMP_256;
++	case WLAN_CIPHER_SUITE_SMS4:
++		return MT_CIPHER_WAPI;
++	default:
++		return MT_CIPHER_NONE;
++	}
++}
++
+ static struct mt76_wcid *mt7615_rx_get_wcid(struct mt7615_dev *dev,
+ 					    u8 idx, bool unicast)
+ {
+@@ -313,14 +340,27 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
+ 		u8 *data = (u8 *)rxd;
+ 
+ 		if (status->flag & RX_FLAG_DECRYPTED) {
+-			status->iv[0] = data[5];
+-			status->iv[1] = data[4];
+-			status->iv[2] = data[3];
+-			status->iv[3] = data[2];
+-			status->iv[4] = data[1];
+-			status->iv[5] = data[0];
+-
+-			insert_ccmp_hdr = FIELD_GET(MT_RXD2_NORMAL_FRAG, rxd2);
++			switch (FIELD_GET(MT_RXD2_NORMAL_SEC_MODE, rxd2)) {
++			case MT_CIPHER_AES_CCMP:
++			case MT_CIPHER_CCMP_CCX:
++			case MT_CIPHER_CCMP_256:
++				insert_ccmp_hdr =
++					FIELD_GET(MT_RXD2_NORMAL_FRAG, rxd2);
++				fallthrough;
++			case MT_CIPHER_TKIP:
++			case MT_CIPHER_TKIP_NO_MIC:
++			case MT_CIPHER_GCMP:
++			case MT_CIPHER_GCMP_256:
++				status->iv[0] = data[5];
++				status->iv[1] = data[4];
++				status->iv[2] = data[3];
++				status->iv[3] = data[2];
++				status->iv[4] = data[1];
++				status->iv[5] = data[0];
++				break;
++			default:
++				break;
++			}
+ 		}
+ 		rxd += 4;
+ 		if ((u8 *)rxd - skb->data >= skb->len)
+@@ -1078,7 +1118,7 @@ EXPORT_SYMBOL_GPL(mt7615_mac_set_rates);
+ static int
+ mt7615_mac_wtbl_update_key(struct mt7615_dev *dev, struct mt76_wcid *wcid,
+ 			   struct ieee80211_key_conf *key,
+-			   enum mt7615_cipher_type cipher, u16 cipher_mask,
++			   enum mt76_cipher_type cipher, u16 cipher_mask,
+ 			   enum set_key_cmd cmd)
+ {
+ 	u32 addr = mt7615_mac_wtbl_addr(dev, wcid->idx) + 30 * 4;
+@@ -1118,7 +1158,7 @@ mt7615_mac_wtbl_update_key(struct mt7615_dev *dev, struct mt76_wcid *wcid,
+ 
+ static int
+ mt7615_mac_wtbl_update_pk(struct mt7615_dev *dev, struct mt76_wcid *wcid,
+-			  enum mt7615_cipher_type cipher, u16 cipher_mask,
++			  enum mt76_cipher_type cipher, u16 cipher_mask,
+ 			  int keyidx, enum set_key_cmd cmd)
+ {
+ 	u32 addr = mt7615_mac_wtbl_addr(dev, wcid->idx), w0, w1;
+@@ -1157,7 +1197,7 @@ mt7615_mac_wtbl_update_pk(struct mt7615_dev *dev, struct mt76_wcid *wcid,
+ 
+ static void
+ mt7615_mac_wtbl_update_cipher(struct mt7615_dev *dev, struct mt76_wcid *wcid,
+-			      enum mt7615_cipher_type cipher, u16 cipher_mask,
++			      enum mt76_cipher_type cipher, u16 cipher_mask,
+ 			      enum set_key_cmd cmd)
+ {
+ 	u32 addr = mt7615_mac_wtbl_addr(dev, wcid->idx);
+@@ -1183,7 +1223,7 @@ int __mt7615_mac_wtbl_set_key(struct mt7615_dev *dev,
+ 			      struct ieee80211_key_conf *key,
+ 			      enum set_key_cmd cmd)
+ {
+-	enum mt7615_cipher_type cipher;
++	enum mt76_cipher_type cipher;
+ 	u16 cipher_mask = wcid->cipher;
+ 	int err;
+ 
+@@ -1235,22 +1275,20 @@ static bool mt7615_fill_txs(struct mt7615_dev *dev, struct mt7615_sta *sta,
+ 	int first_idx = 0, last_idx;
+ 	int i, idx, count;
+ 	bool fixed_rate, ack_timeout;
+-	bool probe, ampdu, cck = false;
++	bool ampdu, cck = false;
+ 	bool rs_idx;
+ 	u32 rate_set_tsf;
+ 	u32 final_rate, final_rate_flags, final_nss, txs;
+ 
+-	fixed_rate = info->status.rates[0].count;
+-	probe = !!(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE);
+-
+ 	txs = le32_to_cpu(txs_data[1]);
+-	ampdu = !fixed_rate && (txs & MT_TXS1_AMPDU);
++	ampdu = txs & MT_TXS1_AMPDU;
+ 
+ 	txs = le32_to_cpu(txs_data[3]);
+ 	count = FIELD_GET(MT_TXS3_TX_COUNT, txs);
+ 	last_idx = FIELD_GET(MT_TXS3_LAST_TX_RATE, txs);
+ 
+ 	txs = le32_to_cpu(txs_data[0]);
++	fixed_rate = txs & MT_TXS0_FIXED_RATE;
+ 	final_rate = FIELD_GET(MT_TXS0_TX_RATE, txs);
+ 	ack_timeout = txs & MT_TXS0_ACK_TIMEOUT;
+ 
+@@ -1272,7 +1310,7 @@ static bool mt7615_fill_txs(struct mt7615_dev *dev, struct mt7615_sta *sta,
+ 
+ 	first_idx = max_t(int, 0, last_idx - (count - 1) / MT7615_RATE_RETRY);
+ 
+-	if (fixed_rate && !probe) {
++	if (fixed_rate) {
+ 		info->status.rates[0].count = count;
+ 		i = 0;
+ 		goto out;
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.h b/drivers/net/wireless/mediatek/mt76/mt7615/mac.h
+index 6bf9da0401966..46f283eb8d0f4 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.h
+@@ -383,48 +383,6 @@ struct mt7615_dfs_radar_spec {
+ 	struct mt7615_dfs_pattern radar_pattern[16];
+ };
+ 
+-enum mt7615_cipher_type {
+-	MT_CIPHER_NONE,
+-	MT_CIPHER_WEP40,
+-	MT_CIPHER_TKIP,
+-	MT_CIPHER_TKIP_NO_MIC,
+-	MT_CIPHER_AES_CCMP,
+-	MT_CIPHER_WEP104,
+-	MT_CIPHER_BIP_CMAC_128,
+-	MT_CIPHER_WEP128,
+-	MT_CIPHER_WAPI,
+-	MT_CIPHER_CCMP_256 = 10,
+-	MT_CIPHER_GCMP,
+-	MT_CIPHER_GCMP_256,
+-};
+-
+-static inline enum mt7615_cipher_type
+-mt7615_mac_get_cipher(int cipher)
+-{
+-	switch (cipher) {
+-	case WLAN_CIPHER_SUITE_WEP40:
+-		return MT_CIPHER_WEP40;
+-	case WLAN_CIPHER_SUITE_WEP104:
+-		return MT_CIPHER_WEP104;
+-	case WLAN_CIPHER_SUITE_TKIP:
+-		return MT_CIPHER_TKIP;
+-	case WLAN_CIPHER_SUITE_AES_CMAC:
+-		return MT_CIPHER_BIP_CMAC_128;
+-	case WLAN_CIPHER_SUITE_CCMP:
+-		return MT_CIPHER_AES_CCMP;
+-	case WLAN_CIPHER_SUITE_CCMP_256:
+-		return MT_CIPHER_CCMP_256;
+-	case WLAN_CIPHER_SUITE_GCMP:
+-		return MT_CIPHER_GCMP;
+-	case WLAN_CIPHER_SUITE_GCMP_256:
+-		return MT_CIPHER_GCMP_256;
+-	case WLAN_CIPHER_SUITE_SMS4:
+-		return MT_CIPHER_WAPI;
+-	default:
+-		return MT_CIPHER_NONE;
+-	}
+-}
+-
+ static inline struct mt7615_txp_common *
+ mt7615_txwi_to_txp(struct mt76_dev *dev, struct mt76_txwi_cache *t)
+ {
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
+index ae2191371f511..257a2c4ddf367 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
+@@ -1123,12 +1123,14 @@ mt7615_mcu_sta_rx_ba(struct mt7615_dev *dev,
+ 
+ static int
+ __mt7615_mcu_add_sta(struct mt76_phy *phy, struct ieee80211_vif *vif,
+-		     struct ieee80211_sta *sta, bool enable, int cmd)
++		     struct ieee80211_sta *sta, bool enable, int cmd,
++		     bool offload_fw)
+ {
+ 	struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
+ 	struct mt76_sta_cmd_info info = {
+ 		.sta = sta,
+ 		.vif = vif,
++		.offload_fw = offload_fw,
+ 		.enable = enable,
+ 		.cmd = cmd,
+ 	};
+@@ -1142,7 +1144,7 @@ mt7615_mcu_add_sta(struct mt7615_phy *phy, struct ieee80211_vif *vif,
+ 		   struct ieee80211_sta *sta, bool enable)
+ {
+ 	return __mt7615_mcu_add_sta(phy->mt76, vif, sta, enable,
+-				    MCU_EXT_CMD_STA_REC_UPDATE);
++				    MCU_EXT_CMD_STA_REC_UPDATE, false);
+ }
+ 
+ static const struct mt7615_mcu_ops sta_update_ops = {
+@@ -1283,7 +1285,7 @@ mt7615_mcu_uni_add_sta(struct mt7615_phy *phy, struct ieee80211_vif *vif,
+ 		       struct ieee80211_sta *sta, bool enable)
+ {
+ 	return __mt7615_mcu_add_sta(phy->mt76, vif, sta, enable,
+-				    MCU_UNI_CMD_STA_REC_UPDATE);
++				    MCU_UNI_CMD_STA_REC_UPDATE, true);
+ }
+ 
+ static int
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
+index c26cfef425ed8..75223b6e1c874 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h
++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
+@@ -7,7 +7,8 @@
+ #include "mt76.h"
+ 
+ #define MT76_CONNAC_SCAN_IE_LEN			600
+-#define MT76_CONNAC_MAX_SCHED_SCAN_INTERVAL	10
++#define MT76_CONNAC_MAX_NUM_SCHED_SCAN_INTERVAL	 10
++#define MT76_CONNAC_MAX_TIME_SCHED_SCAN_INTERVAL U16_MAX
+ #define MT76_CONNAC_MAX_SCHED_SCAN_SSID		10
+ #define MT76_CONNAC_MAX_SCAN_MATCH		16
+ 
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+index eb19721f9d79a..e5721603586f8 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+@@ -841,10 +841,12 @@ int mt76_connac_mcu_add_sta_cmd(struct mt76_phy *phy,
+ 	if (IS_ERR(skb))
+ 		return PTR_ERR(skb);
+ 
+-	mt76_connac_mcu_sta_basic_tlv(skb, info->vif, info->sta, info->enable);
+-	if (info->enable && info->sta)
+-		mt76_connac_mcu_sta_tlv(phy, skb, info->sta, info->vif,
+-					info->rcpi);
++	if (info->sta || !info->offload_fw)
++		mt76_connac_mcu_sta_basic_tlv(skb, info->vif, info->sta,
++					      info->enable);
++	if (info->sta && info->enable)
++		mt76_connac_mcu_sta_tlv(phy, skb, info->sta,
++					info->vif, info->rcpi);
+ 
+ 	sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,
+ 					   sizeof(struct tlv));
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
+index 3bcae732872ed..facebed1e3017 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
+@@ -770,7 +770,7 @@ struct mt76_connac_sched_scan_req {
+ 	u8 intervals_num;
+ 	u8 scan_func; /* MT7663: BIT(0) eable random mac address */
+ 	struct mt76_connac_mcu_scan_channel channels[64];
+-	__le16 intervals[MT76_CONNAC_MAX_SCHED_SCAN_INTERVAL];
++	__le16 intervals[MT76_CONNAC_MAX_NUM_SCHED_SCAN_INTERVAL];
+ 	union {
+ 		struct {
+ 			u8 random_mac[ETH_ALEN];
+@@ -899,6 +899,7 @@ struct mt76_sta_cmd_info {
+ 
+ 	struct ieee80211_vif *vif;
+ 
++	bool offload_fw;
+ 	bool enable;
+ 	int cmd;
+ 	u8 rcpi;
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+index 0da37867cb64c..10d66775c3917 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+@@ -34,24 +34,24 @@ mt76x02_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data)
+ {
+ 	memset(key_data, 0, 32);
+ 	if (!key)
+-		return MT_CIPHER_NONE;
++		return MT76X02_CIPHER_NONE;
+ 
+ 	if (key->keylen > 32)
+-		return MT_CIPHER_NONE;
++		return MT76X02_CIPHER_NONE;
+ 
+ 	memcpy(key_data, key->key, key->keylen);
+ 
+ 	switch (key->cipher) {
+ 	case WLAN_CIPHER_SUITE_WEP40:
+-		return MT_CIPHER_WEP40;
++		return MT76X02_CIPHER_WEP40;
+ 	case WLAN_CIPHER_SUITE_WEP104:
+-		return MT_CIPHER_WEP104;
++		return MT76X02_CIPHER_WEP104;
+ 	case WLAN_CIPHER_SUITE_TKIP:
+-		return MT_CIPHER_TKIP;
++		return MT76X02_CIPHER_TKIP;
+ 	case WLAN_CIPHER_SUITE_CCMP:
+-		return MT_CIPHER_AES_CCMP;
++		return MT76X02_CIPHER_AES_CCMP;
+ 	default:
+-		return MT_CIPHER_NONE;
++		return MT76X02_CIPHER_NONE;
+ 	}
+ }
+ 
+@@ -63,7 +63,7 @@ int mt76x02_mac_shared_key_setup(struct mt76x02_dev *dev, u8 vif_idx,
+ 	u32 val;
+ 
+ 	cipher = mt76x02_mac_get_key_info(key, key_data);
+-	if (cipher == MT_CIPHER_NONE && key)
++	if (cipher == MT76X02_CIPHER_NONE && key)
+ 		return -EOPNOTSUPP;
+ 
+ 	val = mt76_rr(dev, MT_SKEY_MODE(vif_idx));
+@@ -91,10 +91,10 @@ void mt76x02_mac_wcid_sync_pn(struct mt76x02_dev *dev, u8 idx,
+ 	eiv = mt76_rr(dev, MT_WCID_IV(idx) + 4);
+ 
+ 	pn = (u64)eiv << 16;
+-	if (cipher == MT_CIPHER_TKIP) {
++	if (cipher == MT76X02_CIPHER_TKIP) {
+ 		pn |= (iv >> 16) & 0xff;
+ 		pn |= (iv & 0xff) << 8;
+-	} else if (cipher >= MT_CIPHER_AES_CCMP) {
++	} else if (cipher >= MT76X02_CIPHER_AES_CCMP) {
+ 		pn |= iv & 0xffff;
+ 	} else {
+ 		return;
+@@ -112,7 +112,7 @@ int mt76x02_mac_wcid_set_key(struct mt76x02_dev *dev, u8 idx,
+ 	u64 pn;
+ 
+ 	cipher = mt76x02_mac_get_key_info(key, key_data);
+-	if (cipher == MT_CIPHER_NONE && key)
++	if (cipher == MT76X02_CIPHER_NONE && key)
+ 		return -EOPNOTSUPP;
+ 
+ 	mt76_wr_copy(dev, MT_WCID_KEY(idx), key_data, sizeof(key_data));
+@@ -126,16 +126,16 @@ int mt76x02_mac_wcid_set_key(struct mt76x02_dev *dev, u8 idx,
+ 		pn = atomic64_read(&key->tx_pn);
+ 
+ 		iv_data[3] = key->keyidx << 6;
+-		if (cipher >= MT_CIPHER_TKIP) {
++		if (cipher >= MT76X02_CIPHER_TKIP) {
+ 			iv_data[3] |= 0x20;
+ 			put_unaligned_le32(pn >> 16, &iv_data[4]);
+ 		}
+ 
+-		if (cipher == MT_CIPHER_TKIP) {
++		if (cipher == MT76X02_CIPHER_TKIP) {
+ 			iv_data[0] = (pn >> 8) & 0xff;
+ 			iv_data[1] = (iv_data[0] | 0x20) & 0x7f;
+ 			iv_data[2] = pn & 0xff;
+-		} else if (cipher >= MT_CIPHER_AES_CCMP) {
++		} else if (cipher >= MT76X02_CIPHER_AES_CCMP) {
+ 			put_unaligned_le16((pn & 0xffff), &iv_data[0]);
+ 		}
+ 	}
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h b/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h
+index 3e722276b5c2f..fa7872ac22bf8 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h
++++ b/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h
+@@ -692,15 +692,15 @@ struct mt76_wcid_key {
+ } __packed __aligned(4);
+ 
+ enum mt76x02_cipher_type {
+-	MT_CIPHER_NONE,
+-	MT_CIPHER_WEP40,
+-	MT_CIPHER_WEP104,
+-	MT_CIPHER_TKIP,
+-	MT_CIPHER_AES_CCMP,
+-	MT_CIPHER_CKIP40,
+-	MT_CIPHER_CKIP104,
+-	MT_CIPHER_CKIP128,
+-	MT_CIPHER_WAPI,
++	MT76X02_CIPHER_NONE,
++	MT76X02_CIPHER_WEP40,
++	MT76X02_CIPHER_WEP104,
++	MT76X02_CIPHER_TKIP,
++	MT76X02_CIPHER_AES_CCMP,
++	MT76X02_CIPHER_CKIP40,
++	MT76X02_CIPHER_CKIP104,
++	MT76X02_CIPHER_CKIP128,
++	MT76X02_CIPHER_WAPI,
+ };
+ 
+ #endif
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h
+index 30bf41b8ed152..a43389a418006 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h
+@@ -99,12 +99,15 @@ static inline bool
+ mt7915_tssi_enabled(struct mt7915_dev *dev, enum nl80211_band band)
+ {
+ 	u8 *eep = dev->mt76.eeprom.data;
++	u8 val = eep[MT_EE_WIFI_CONF + 7];
+ 
+-	/* TODO: DBDC */
+-	if (band == NL80211_BAND_5GHZ)
+-		return eep[MT_EE_WIFI_CONF + 7] & MT_EE_WIFI_CONF7_TSSI0_5G;
++	if (band == NL80211_BAND_2GHZ)
++		return val & MT_EE_WIFI_CONF7_TSSI0_2G;
++
++	if (dev->dbdc_support)
++		return val & MT_EE_WIFI_CONF7_TSSI1_5G;
+ 	else
+-		return eep[MT_EE_WIFI_CONF + 7] & MT_EE_WIFI_CONF7_TSSI0_2G;
++		return val & MT_EE_WIFI_CONF7_TSSI0_5G;
+ }
+ 
+ extern const u8 mt7915_sku_group_len[MAX_SKU_RATE_GROUP_NUM];
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+index 822f3aa6bb8b5..feb2aa57ef221 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+@@ -480,6 +480,9 @@ mt7915_set_stream_he_txbf_caps(struct ieee80211_sta_he_cap *he_cap,
+ 	if (nss < 2)
+ 		return;
+ 
++	/* the maximum cap is 4 x 3, (Nr, Nc) = (3, 2) */
++	elem->phy_cap_info[7] |= min_t(int, nss - 1, 2) << 3;
++
+ 	if (vif != NL80211_IFTYPE_AP)
+ 		return;
+ 
+@@ -493,9 +496,6 @@ mt7915_set_stream_he_txbf_caps(struct ieee80211_sta_he_cap *he_cap,
+ 	c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB |
+ 	    IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB;
+ 	elem->phy_cap_info[6] |= c;
+-
+-	/* the maximum cap is 4 x 3, (Nr, Nc) = (3, 2) */
+-	elem->phy_cap_info[7] |= min_t(int, nss - 1, 2) << 3;
+ }
+ 
+ static void
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+index 7a9759fb79d89..f4544c46c1731 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+@@ -412,14 +412,27 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
+ 		u8 *data = (u8 *)rxd;
+ 
+ 		if (status->flag & RX_FLAG_DECRYPTED) {
+-			status->iv[0] = data[5];
+-			status->iv[1] = data[4];
+-			status->iv[2] = data[3];
+-			status->iv[3] = data[2];
+-			status->iv[4] = data[1];
+-			status->iv[5] = data[0];
+-
+-			insert_ccmp_hdr = FIELD_GET(MT_RXD2_NORMAL_FRAG, rxd2);
++			switch (FIELD_GET(MT_RXD1_NORMAL_SEC_MODE, rxd1)) {
++			case MT_CIPHER_AES_CCMP:
++			case MT_CIPHER_CCMP_CCX:
++			case MT_CIPHER_CCMP_256:
++				insert_ccmp_hdr =
++					FIELD_GET(MT_RXD2_NORMAL_FRAG, rxd2);
++				fallthrough;
++			case MT_CIPHER_TKIP:
++			case MT_CIPHER_TKIP_NO_MIC:
++			case MT_CIPHER_GCMP:
++			case MT_CIPHER_GCMP_256:
++				status->iv[0] = data[5];
++				status->iv[1] = data[4];
++				status->iv[2] = data[3];
++				status->iv[3] = data[2];
++				status->iv[4] = data[1];
++				status->iv[5] = data[0];
++				break;
++			default:
++				break;
++			}
+ 		}
+ 		rxd += 4;
+ 		if ((u8 *)rxd - skb->data >= skb->len)
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+index 764f25a828fa2..607980321d275 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+@@ -88,28 +88,28 @@ struct mt7915_fw_region {
+ #define HE_PHY(p, c)			u8_get_bits(c, IEEE80211_HE_PHY_##p)
+ #define HE_MAC(m, c)			u8_get_bits(c, IEEE80211_HE_MAC_##m)
+ 
+-static enum mt7915_cipher_type
++static enum mcu_cipher_type
+ mt7915_mcu_get_cipher(int cipher)
+ {
+ 	switch (cipher) {
+ 	case WLAN_CIPHER_SUITE_WEP40:
+-		return MT_CIPHER_WEP40;
++		return MCU_CIPHER_WEP40;
+ 	case WLAN_CIPHER_SUITE_WEP104:
+-		return MT_CIPHER_WEP104;
++		return MCU_CIPHER_WEP104;
+ 	case WLAN_CIPHER_SUITE_TKIP:
+-		return MT_CIPHER_TKIP;
++		return MCU_CIPHER_TKIP;
+ 	case WLAN_CIPHER_SUITE_AES_CMAC:
+-		return MT_CIPHER_BIP_CMAC_128;
++		return MCU_CIPHER_BIP_CMAC_128;
+ 	case WLAN_CIPHER_SUITE_CCMP:
+-		return MT_CIPHER_AES_CCMP;
++		return MCU_CIPHER_AES_CCMP;
+ 	case WLAN_CIPHER_SUITE_CCMP_256:
+-		return MT_CIPHER_CCMP_256;
++		return MCU_CIPHER_CCMP_256;
+ 	case WLAN_CIPHER_SUITE_GCMP:
+-		return MT_CIPHER_GCMP;
++		return MCU_CIPHER_GCMP;
+ 	case WLAN_CIPHER_SUITE_GCMP_256:
+-		return MT_CIPHER_GCMP_256;
++		return MCU_CIPHER_GCMP_256;
+ 	case WLAN_CIPHER_SUITE_SMS4:
+-		return MT_CIPHER_WAPI;
++		return MCU_CIPHER_WAPI;
+ 	default:
+ 		return MT_CIPHER_NONE;
+ 	}
+@@ -1072,14 +1072,14 @@ mt7915_mcu_sta_key_tlv(struct mt7915_sta *msta, struct sk_buff *skb,
+ 		sec_key = &sec->key[0];
+ 		sec_key->cipher_len = sizeof(*sec_key);
+ 
+-		if (cipher == MT_CIPHER_BIP_CMAC_128) {
+-			sec_key->cipher_id = MT_CIPHER_AES_CCMP;
++		if (cipher == MCU_CIPHER_BIP_CMAC_128) {
++			sec_key->cipher_id = MCU_CIPHER_AES_CCMP;
+ 			sec_key->key_id = bip->keyidx;
+ 			sec_key->key_len = 16;
+ 			memcpy(sec_key->key, bip->key, 16);
+ 
+ 			sec_key = &sec->key[1];
+-			sec_key->cipher_id = MT_CIPHER_BIP_CMAC_128;
++			sec_key->cipher_id = MCU_CIPHER_BIP_CMAC_128;
+ 			sec_key->cipher_len = sizeof(*sec_key);
+ 			sec_key->key_len = 16;
+ 			memcpy(sec_key->key, key->key, 16);
+@@ -1091,14 +1091,14 @@ mt7915_mcu_sta_key_tlv(struct mt7915_sta *msta, struct sk_buff *skb,
+ 			sec_key->key_len = key->keylen;
+ 			memcpy(sec_key->key, key->key, key->keylen);
+ 
+-			if (cipher == MT_CIPHER_TKIP) {
++			if (cipher == MCU_CIPHER_TKIP) {
+ 				/* Rx/Tx MIC keys are swapped */
+ 				memcpy(sec_key->key + 16, key->key + 24, 8);
+ 				memcpy(sec_key->key + 24, key->key + 16, 8);
+ 			}
+ 
+ 			/* store key_conf for BIP batch update */
+-			if (cipher == MT_CIPHER_AES_CCMP) {
++			if (cipher == MCU_CIPHER_AES_CCMP) {
+ 				memcpy(bip->key, key->key, key->keylen);
+ 				bip->keyidx = key->keyidx;
+ 			}
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
+index 42582a66e42dd..517621044d9e9 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
+@@ -1034,18 +1034,17 @@ enum {
+ 	STA_REC_MAX_NUM
+ };
+ 
+-enum mt7915_cipher_type {
+-	MT_CIPHER_NONE,
+-	MT_CIPHER_WEP40,
+-	MT_CIPHER_WEP104,
+-	MT_CIPHER_WEP128,
+-	MT_CIPHER_TKIP,
+-	MT_CIPHER_AES_CCMP,
+-	MT_CIPHER_CCMP_256,
+-	MT_CIPHER_GCMP,
+-	MT_CIPHER_GCMP_256,
+-	MT_CIPHER_WAPI,
+-	MT_CIPHER_BIP_CMAC_128,
++enum mcu_cipher_type {
++	MCU_CIPHER_WEP40 = 1,
++	MCU_CIPHER_WEP104,
++	MCU_CIPHER_WEP128,
++	MCU_CIPHER_TKIP,
++	MCU_CIPHER_AES_CCMP,
++	MCU_CIPHER_CCMP_256,
++	MCU_CIPHER_GCMP,
++	MCU_CIPHER_GCMP_256,
++	MCU_CIPHER_WAPI,
++	MCU_CIPHER_BIP_CMAC_128,
+ };
+ 
+ enum {
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
+index bd9143dc865f9..7fca7dc466b85 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
+@@ -402,6 +402,10 @@ int mt7921_dma_init(struct mt7921_dev *dev)
+ 	if (ret)
+ 		return ret;
+ 
++	ret = mt7921_wfsys_reset(dev);
++	if (ret)
++		return ret;
++
+ 	/* init tx queue */
+ 	ret = mt7921_init_tx_queues(&dev->phy, MT7921_TXQ_BAND0,
+ 				    MT7921_TX_RING_SIZE);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+index 2cb0252e63b21..db7e436076b37 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+@@ -93,7 +93,7 @@ mt7921_init_wiphy(struct ieee80211_hw *hw)
+ 	wiphy->max_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN;
+ 	wiphy->max_scan_ssids = 4;
+ 	wiphy->max_sched_scan_plan_interval =
+-		MT76_CONNAC_MAX_SCHED_SCAN_INTERVAL;
++		MT76_CONNAC_MAX_TIME_SCHED_SCAN_INTERVAL;
+ 	wiphy->max_sched_scan_ie_len = IEEE80211_MAX_DATA_LEN;
+ 	wiphy->max_sched_scan_ssids = MT76_CONNAC_MAX_SCHED_SCAN_SSID;
+ 	wiphy->max_match_sets = MT76_CONNAC_MAX_SCAN_MATCH;
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+index 493c2aba2f791..d7d8c909acdff 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+@@ -386,14 +386,27 @@ int mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
+ 		u8 *data = (u8 *)rxd;
+ 
+ 		if (status->flag & RX_FLAG_DECRYPTED) {
+-			status->iv[0] = data[5];
+-			status->iv[1] = data[4];
+-			status->iv[2] = data[3];
+-			status->iv[3] = data[2];
+-			status->iv[4] = data[1];
+-			status->iv[5] = data[0];
+-
+-			insert_ccmp_hdr = FIELD_GET(MT_RXD2_NORMAL_FRAG, rxd2);
++			switch (FIELD_GET(MT_RXD1_NORMAL_SEC_MODE, rxd1)) {
++			case MT_CIPHER_AES_CCMP:
++			case MT_CIPHER_CCMP_CCX:
++			case MT_CIPHER_CCMP_256:
++				insert_ccmp_hdr =
++					FIELD_GET(MT_RXD2_NORMAL_FRAG, rxd2);
++				fallthrough;
++			case MT_CIPHER_TKIP:
++			case MT_CIPHER_TKIP_NO_MIC:
++			case MT_CIPHER_GCMP:
++			case MT_CIPHER_GCMP_256:
++				status->iv[0] = data[5];
++				status->iv[1] = data[4];
++				status->iv[2] = data[3];
++				status->iv[3] = data[2];
++				status->iv[4] = data[1];
++				status->iv[5] = data[0];
++				break;
++			default:
++				break;
++			}
+ 		}
+ 		rxd += 4;
+ 		if ((u8 *)rxd - skb->data >= skb->len)
+@@ -1245,9 +1258,10 @@ mt7921_mac_reset(struct mt7921_dev *dev)
+ 	mt76_worker_enable(&dev->mt76.tx_worker);
+ 
+ 	clear_bit(MT76_MCU_RESET, &dev->mphy.state);
+-	clear_bit(MT76_STATE_PM, &dev->mphy.state);
+ 
+-	mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0);
++	mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA,
++		MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_ALL |
++		MT_INT_MCU_CMD);
+ 	mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
+ 
+ 	err = mt7921_run_firmware(dev);
+@@ -1265,23 +1279,24 @@ mt7921_mac_reset(struct mt7921_dev *dev)
+ /* system error recovery */
+ void mt7921_mac_reset_work(struct work_struct *work)
+ {
+-	struct ieee80211_hw *hw;
+-	struct mt7921_dev *dev;
++	struct mt7921_dev *dev = container_of(work, struct mt7921_dev,
++					      reset_work);
++	struct ieee80211_hw *hw = mt76_hw(dev);
++	struct mt76_connac_pm *pm = &dev->pm;
+ 	int i;
+ 
+-	dev = container_of(work, struct mt7921_dev, reset_work);
+-	hw = mt76_hw(dev);
+-
+ 	dev_err(dev->mt76.dev, "chip reset\n");
+ 	dev->hw_full_reset = true;
+ 	ieee80211_stop_queues(hw);
+ 
+ 	cancel_delayed_work_sync(&dev->mphy.mac_work);
+-	cancel_delayed_work_sync(&dev->pm.ps_work);
+-	cancel_work_sync(&dev->pm.wake_work);
++	cancel_delayed_work_sync(&pm->ps_work);
++	cancel_work_sync(&pm->wake_work);
+ 
+ 	mutex_lock(&dev->mt76.mutex);
+ 	for (i = 0; i < 10; i++) {
++		__mt7921_mcu_drv_pmctrl(dev);
++
+ 		if (!mt7921_mac_reset(dev))
+ 			break;
+ 	}
+@@ -1303,6 +1318,7 @@ void mt7921_mac_reset_work(struct work_struct *work)
+ 	ieee80211_iterate_active_interfaces(hw,
+ 					    IEEE80211_IFACE_ITER_RESUME_ALL,
+ 					    mt7921_vif_connect_iter, NULL);
++	mt76_connac_power_save_sched(&dev->mt76.phy, pm);
+ }
+ 
+ void mt7921_reset(struct mt76_dev *mdev)
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+index bd77a04a15fb2..992a74e122e50 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+@@ -376,6 +376,10 @@ static int mt7921_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ 		key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIE;
+ 		wcid_keyidx = &wcid->hw_key_idx2;
+ 		break;
++	case WLAN_CIPHER_SUITE_WEP40:
++	case WLAN_CIPHER_SUITE_WEP104:
++		if (!mvif->wep_sta)
++			return -EOPNOTSUPP;
+ 	case WLAN_CIPHER_SUITE_TKIP:
+ 	case WLAN_CIPHER_SUITE_CCMP:
+ 	case WLAN_CIPHER_SUITE_CCMP_256:
+@@ -383,8 +387,6 @@ static int mt7921_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ 	case WLAN_CIPHER_SUITE_GCMP_256:
+ 	case WLAN_CIPHER_SUITE_SMS4:
+ 		break;
+-	case WLAN_CIPHER_SUITE_WEP40:
+-	case WLAN_CIPHER_SUITE_WEP104:
+ 	default:
+ 		return -EOPNOTSUPP;
+ 	}
+@@ -402,6 +404,12 @@ static int mt7921_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ 			    cmd == SET_KEY ? key : NULL);
+ 
+ 	err = mt7921_mcu_add_key(dev, vif, msta, key, cmd);
++	if (err)
++		goto out;
++
++	if (key->cipher == WLAN_CIPHER_SUITE_WEP104 ||
++	    key->cipher == WLAN_CIPHER_SUITE_WEP40)
++		err = mt7921_mcu_add_key(dev, vif, mvif->wep_sta, key, cmd);
+ out:
+ 	mt7921_mutex_release(dev);
+ 
+@@ -608,9 +616,12 @@ int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ 	if (ret)
+ 		return ret;
+ 
+-	if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
+-		mt76_connac_mcu_uni_add_bss(&dev->mphy, vif, &mvif->sta.wcid,
+-					    true);
++	if (vif->type == NL80211_IFTYPE_STATION) {
++		mvif->wep_sta = msta;
++		if (!sta->tdls)
++			mt76_connac_mcu_uni_add_bss(&dev->mphy, vif,
++						    &mvif->sta.wcid, true);
++	}
+ 
+ 	mt7921_mac_wtbl_update(dev, idx,
+ 			       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
+@@ -640,6 +651,7 @@ void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ 	if (vif->type == NL80211_IFTYPE_STATION) {
+ 		struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
+ 
++		mvif->wep_sta = NULL;
+ 		ewma_rssi_init(&mvif->rssi);
+ 		if (!sta->tdls)
+ 			mt76_connac_mcu_uni_add_bss(&dev->mphy, vif,
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+index 7c68182cad552..ee6cf189103f7 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+@@ -88,28 +88,28 @@ struct mt7921_fw_region {
+ #define to_wcid_lo(id)			FIELD_GET(GENMASK(7, 0), (u16)id)
+ #define to_wcid_hi(id)			FIELD_GET(GENMASK(9, 8), (u16)id)
+ 
+-static enum mt7921_cipher_type
++static enum mcu_cipher_type
+ mt7921_mcu_get_cipher(int cipher)
+ {
+ 	switch (cipher) {
+ 	case WLAN_CIPHER_SUITE_WEP40:
+-		return MT_CIPHER_WEP40;
++		return MCU_CIPHER_WEP40;
+ 	case WLAN_CIPHER_SUITE_WEP104:
+-		return MT_CIPHER_WEP104;
++		return MCU_CIPHER_WEP104;
+ 	case WLAN_CIPHER_SUITE_TKIP:
+-		return MT_CIPHER_TKIP;
++		return MCU_CIPHER_TKIP;
+ 	case WLAN_CIPHER_SUITE_AES_CMAC:
+-		return MT_CIPHER_BIP_CMAC_128;
++		return MCU_CIPHER_BIP_CMAC_128;
+ 	case WLAN_CIPHER_SUITE_CCMP:
+-		return MT_CIPHER_AES_CCMP;
++		return MCU_CIPHER_AES_CCMP;
+ 	case WLAN_CIPHER_SUITE_CCMP_256:
+-		return MT_CIPHER_CCMP_256;
++		return MCU_CIPHER_CCMP_256;
+ 	case WLAN_CIPHER_SUITE_GCMP:
+-		return MT_CIPHER_GCMP;
++		return MCU_CIPHER_GCMP;
+ 	case WLAN_CIPHER_SUITE_GCMP_256:
+-		return MT_CIPHER_GCMP_256;
++		return MCU_CIPHER_GCMP_256;
+ 	case WLAN_CIPHER_SUITE_SMS4:
+-		return MT_CIPHER_WAPI;
++		return MCU_CIPHER_WAPI;
+ 	default:
+ 		return MT_CIPHER_NONE;
+ 	}
+@@ -615,14 +615,14 @@ mt7921_mcu_sta_key_tlv(struct mt7921_sta *msta, struct sk_buff *skb,
+ 		sec_key = &sec->key[0];
+ 		sec_key->cipher_len = sizeof(*sec_key);
+ 
+-		if (cipher == MT_CIPHER_BIP_CMAC_128) {
+-			sec_key->cipher_id = MT_CIPHER_AES_CCMP;
++		if (cipher == MCU_CIPHER_BIP_CMAC_128) {
++			sec_key->cipher_id = MCU_CIPHER_AES_CCMP;
+ 			sec_key->key_id = bip->keyidx;
+ 			sec_key->key_len = 16;
+ 			memcpy(sec_key->key, bip->key, 16);
+ 
+ 			sec_key = &sec->key[1];
+-			sec_key->cipher_id = MT_CIPHER_BIP_CMAC_128;
++			sec_key->cipher_id = MCU_CIPHER_BIP_CMAC_128;
+ 			sec_key->cipher_len = sizeof(*sec_key);
+ 			sec_key->key_len = 16;
+ 			memcpy(sec_key->key, key->key, 16);
+@@ -634,14 +634,14 @@ mt7921_mcu_sta_key_tlv(struct mt7921_sta *msta, struct sk_buff *skb,
+ 			sec_key->key_len = key->keylen;
+ 			memcpy(sec_key->key, key->key, key->keylen);
+ 
+-			if (cipher == MT_CIPHER_TKIP) {
++			if (cipher == MCU_CIPHER_TKIP) {
+ 				/* Rx/Tx MIC keys are swapped */
+ 				memcpy(sec_key->key + 16, key->key + 24, 8);
+ 				memcpy(sec_key->key + 24, key->key + 16, 8);
+ 			}
+ 
+ 			/* store key_conf for BIP batch update */
+-			if (cipher == MT_CIPHER_AES_CCMP) {
++			if (cipher == MCU_CIPHER_AES_CCMP) {
+ 				memcpy(bip->key, key->key, key->keylen);
+ 				bip->keyidx = key->keyidx;
+ 			}
+@@ -1289,6 +1289,7 @@ int mt7921_mcu_sta_add(struct mt7921_dev *dev, struct ieee80211_sta *sta,
+ 		.vif = vif,
+ 		.enable = enable,
+ 		.cmd = MCU_UNI_CMD_STA_REC_UPDATE,
++		.offload_fw = true,
+ 		.rcpi = to_rcpi(rssi),
+ 	};
+ 	struct mt7921_sta *msta;
+@@ -1299,17 +1300,12 @@ int mt7921_mcu_sta_add(struct mt7921_dev *dev, struct ieee80211_sta *sta,
+ 	return mt76_connac_mcu_add_sta_cmd(&dev->mphy, &info);
+ }
+ 
+-int mt7921_mcu_drv_pmctrl(struct mt7921_dev *dev)
++int __mt7921_mcu_drv_pmctrl(struct mt7921_dev *dev)
+ {
+ 	struct mt76_phy *mphy = &dev->mt76.phy;
+ 	struct mt76_connac_pm *pm = &dev->pm;
+ 	int i, err = 0;
+ 
+-	mutex_lock(&pm->mutex);
+-
+-	if (!test_bit(MT76_STATE_PM, &mphy->state))
+-		goto out;
+-
+ 	for (i = 0; i < MT7921_DRV_OWN_RETRY_COUNT; i++) {
+ 		mt76_wr(dev, MT_CONN_ON_LPCTL, PCIE_LPCR_HOST_CLR_OWN);
+ 		if (mt76_poll_msec(dev, MT_CONN_ON_LPCTL,
+@@ -1329,6 +1325,22 @@ int mt7921_mcu_drv_pmctrl(struct mt7921_dev *dev)
+ 	pm->stats.last_wake_event = jiffies;
+ 	pm->stats.doze_time += pm->stats.last_wake_event -
+ 			       pm->stats.last_doze_event;
++out:
++	return err;
++}
++
++int mt7921_mcu_drv_pmctrl(struct mt7921_dev *dev)
++{
++	struct mt76_phy *mphy = &dev->mt76.phy;
++	struct mt76_connac_pm *pm = &dev->pm;
++	int err = 0;
++
++	mutex_lock(&pm->mutex);
++
++	if (!test_bit(MT76_STATE_PM, &mphy->state))
++		goto out;
++
++	err = __mt7921_mcu_drv_pmctrl(dev);
+ out:
+ 	mutex_unlock(&pm->mutex);
+ 
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h
+index 49823d0a3d0ab..07abe86f07a94 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h
+@@ -197,18 +197,17 @@ struct sta_rec_sec {
+ 	struct sec_key key[2];
+ } __packed;
+ 
+-enum mt7921_cipher_type {
+-	MT_CIPHER_NONE,
+-	MT_CIPHER_WEP40,
+-	MT_CIPHER_WEP104,
+-	MT_CIPHER_WEP128,
+-	MT_CIPHER_TKIP,
+-	MT_CIPHER_AES_CCMP,
+-	MT_CIPHER_CCMP_256,
+-	MT_CIPHER_GCMP,
+-	MT_CIPHER_GCMP_256,
+-	MT_CIPHER_WAPI,
+-	MT_CIPHER_BIP_CMAC_128,
++enum mcu_cipher_type {
++	MCU_CIPHER_WEP40 = 1,
++	MCU_CIPHER_WEP104,
++	MCU_CIPHER_WEP128,
++	MCU_CIPHER_TKIP,
++	MCU_CIPHER_AES_CCMP,
++	MCU_CIPHER_CCMP_256,
++	MCU_CIPHER_GCMP,
++	MCU_CIPHER_GCMP_256,
++	MCU_CIPHER_WAPI,
++	MCU_CIPHER_BIP_CMAC_128,
+ };
+ 
+ enum {
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+index 4cc8a372b2772..957084c3ca432 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+@@ -100,6 +100,8 @@ struct mt7921_vif {
+ 	struct mt76_vif mt76; /* must be first */
+ 
+ 	struct mt7921_sta sta;
++	struct mt7921_sta *wep_sta;
++
+ 	struct mt7921_phy *phy;
+ 
+ 	struct ewma_rssi rssi;
+@@ -369,6 +371,7 @@ int mt7921_mcu_uni_bss_bcnft(struct mt7921_dev *dev, struct ieee80211_vif *vif,
+ 			     bool enable);
+ int mt7921_mcu_set_bss_pm(struct mt7921_dev *dev, struct ieee80211_vif *vif,
+ 			  bool enable);
++int __mt7921_mcu_drv_pmctrl(struct mt7921_dev *dev);
+ int mt7921_mcu_drv_pmctrl(struct mt7921_dev *dev);
+ int mt7921_mcu_fw_pmctrl(struct mt7921_dev *dev);
+ void mt7921_pm_wake_work(struct work_struct *work);
+diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
+index d1a566cc0c9e0..01735776345a9 100644
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
+@@ -853,15 +853,10 @@ struct rtl8192eu_efuse {
+ 	u8 usb_optional_function;
+ 	u8 res9[2];
+ 	u8 mac_addr[ETH_ALEN];		/* 0xd7 */
+-	u8 res10[2];
+-	u8 vendor_name[7];
+-	u8 res11[2];
+-	u8 device_name[0x0b];		/* 0xe8 */
+-	u8 res12[2];
+-	u8 serial[0x0b];		/* 0xf5 */
+-	u8 res13[0x30];
++	u8 device_info[80];
++	u8 res11[3];
+ 	u8 unknown[0x0d];		/* 0x130 */
+-	u8 res14[0xc3];
++	u8 res12[0xc3];
+ };
+ 
+ struct rtl8xxxu_reg8val {
+diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c
+index cfe2dfdae928f..b06508d0cdf8f 100644
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c
+@@ -554,9 +554,43 @@ rtl8192e_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40)
+ 	}
+ }
+ 
++static void rtl8192eu_log_next_device_info(struct rtl8xxxu_priv *priv,
++					   char *record_name,
++					   char *device_info,
++					   unsigned int *record_offset)
++{
++	char *record = device_info + *record_offset;
++
++	/* A record is [ total length | 0x03 | value ] */
++	unsigned char l = record[0];
++
++	/*
++	 * The whole device info section seems to be 80 characters, make sure
++	 * we don't read further.
++	 */
++	if (*record_offset + l > 80) {
++		dev_warn(&priv->udev->dev,
++			 "invalid record length %d while parsing \"%s\" at offset %u.\n",
++			 l, record_name, *record_offset);
++		return;
++	}
++
++	if (l >= 2) {
++		char value[80];
++
++		memcpy(value, &record[2], l - 2);
++		value[l - 2] = '\0';
++		dev_info(&priv->udev->dev, "%s: %s\n", record_name, value);
++		*record_offset = *record_offset + l;
++	} else {
++		dev_info(&priv->udev->dev, "%s not available.\n", record_name);
++	}
++}
++
+ static int rtl8192eu_parse_efuse(struct rtl8xxxu_priv *priv)
+ {
+ 	struct rtl8192eu_efuse *efuse = &priv->efuse_wifi.efuse8192eu;
++	unsigned int record_offset;
+ 	int i;
+ 
+ 	if (efuse->rtl_id != cpu_to_le16(0x8129))
+@@ -604,12 +638,25 @@ static int rtl8192eu_parse_efuse(struct rtl8xxxu_priv *priv)
+ 	priv->has_xtalk = 1;
+ 	priv->xtalk = priv->efuse_wifi.efuse8192eu.xtal_k & 0x3f;
+ 
+-	dev_info(&priv->udev->dev, "Vendor: %.7s\n", efuse->vendor_name);
+-	dev_info(&priv->udev->dev, "Product: %.11s\n", efuse->device_name);
+-	if (memchr_inv(efuse->serial, 0xff, 11))
+-		dev_info(&priv->udev->dev, "Serial: %.11s\n", efuse->serial);
+-	else
+-		dev_info(&priv->udev->dev, "Serial not available.\n");
++	/*
++	 * device_info section seems to be laid out as records
++	 * [ total length | 0x03 | value ] so:
++	 * - vendor length + 2
++	 * - 0x03
++	 * - vendor string (not null terminated)
++	 * - product length + 2
++	 * - 0x03
++	 * - product string (not null terminated)
++	 * Then there is one or 2 0x00 on all the 4 devices I own or found
++	 * dumped online.
++	 * As previous version of the code handled an optional serial
++	 * string, I now assume there may be a third record if the
++	 * length is not 0.
++	 */
++	record_offset = 0;
++	rtl8192eu_log_next_device_info(priv, "Vendor", efuse->device_info, &record_offset);
++	rtl8192eu_log_next_device_info(priv, "Product", efuse->device_info, &record_offset);
++	rtl8192eu_log_next_device_info(priv, "Serial", efuse->device_info, &record_offset);
+ 
+ 	if (rtl8xxxu_debug & RTL8XXXU_DEBUG_EFUSE) {
+ 		unsigned char *raw = priv->efuse_wifi.raw;
+diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c
+index f59a4c462e3bc..e7d17ab8f113b 100644
+--- a/drivers/net/wireless/realtek/rtw88/pci.c
++++ b/drivers/net/wireless/realtek/rtw88/pci.c
+@@ -2,6 +2,7 @@
+ /* Copyright(c) 2018-2019  Realtek Corporation
+  */
+ 
++#include <linux/dmi.h>
+ #include <linux/module.h>
+ #include <linux/pci.h>
+ #include "main.h"
+@@ -1673,6 +1674,36 @@ static void rtw_pci_napi_deinit(struct rtw_dev *rtwdev)
+ 	netif_napi_del(&rtwpci->napi);
+ }
+ 
++enum rtw88_quirk_dis_pci_caps {
++	QUIRK_DIS_PCI_CAP_MSI,
++	QUIRK_DIS_PCI_CAP_ASPM,
++};
++
++static int disable_pci_caps(const struct dmi_system_id *dmi)
++{
++	uintptr_t dis_caps = (uintptr_t)dmi->driver_data;
++
++	if (dis_caps & BIT(QUIRK_DIS_PCI_CAP_MSI))
++		rtw_disable_msi = true;
++	if (dis_caps & BIT(QUIRK_DIS_PCI_CAP_ASPM))
++		rtw_pci_disable_aspm = true;
++
++	return 1;
++}
++
++static const struct dmi_system_id rtw88_pci_quirks[] = {
++	{
++		.callback = disable_pci_caps,
++		.ident = "Protempo Ltd L116HTN6SPW",
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Protempo Ltd"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "L116HTN6SPW"),
++		},
++		.driver_data = (void *)BIT(QUIRK_DIS_PCI_CAP_ASPM),
++	},
++	{}
++};
++
+ int rtw_pci_probe(struct pci_dev *pdev,
+ 		  const struct pci_device_id *id)
+ {
+@@ -1723,6 +1754,7 @@ int rtw_pci_probe(struct pci_dev *pdev,
+ 		goto err_destroy_pci;
+ 	}
+ 
++	dmi_check_system(rtw88_pci_quirks);
+ 	rtw_pci_phy_cfg(rtwdev);
+ 
+ 	ret = rtw_register_hw(rtwdev, hw);
+diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c_table.c b/drivers/net/wireless/realtek/rtw88/rtw8822c_table.c
+index 822f3da91f1be..f9e3d0779c597 100644
+--- a/drivers/net/wireless/realtek/rtw88/rtw8822c_table.c
++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c_table.c
+@@ -16812,53 +16812,53 @@ static const u32 rtw8822c_rf_a[] = {
+ 	0x92000002,	0x00000000,	0x40000000,	0x00000000,
+ 		0x03F, 0x00010E46,
+ 	0x93000001,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x93000002,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x93000003,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x93000004,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x93000005,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x93000006,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x93000015,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x93000016,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x94000001,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x94000002,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x94000003,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x94000004,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x94000005,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x94000006,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x94000015,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x94000016,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x95000001,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x95000002,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x95000003,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x95000004,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x95000005,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x95000006,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x95000015,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0x95000016,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00030246,
++		0x03F, 0x0003D646,
+ 	0xA0000000,	0x00000000,
+ 		0x03F, 0x00002A46,
+ 	0xB0000000,	0x00000000,
+@@ -18762,53 +18762,53 @@ static const u32 rtw8822c_rf_a[] = {
+ 	0x92000002,	0x00000000,	0x40000000,	0x00000000,
+ 		0x03F, 0x0000EA46,
+ 	0x93000001,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000002,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000003,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000004,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000005,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000006,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000015,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000016,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000001,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000002,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000003,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000004,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000005,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000006,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000015,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000016,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000001,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000002,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000003,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000004,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000005,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000006,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000015,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000016,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0xA0000000,	0x00000000,
+ 		0x03F, 0x00002A46,
+ 	0xB0000000,	0x00000000,
+@@ -18957,53 +18957,53 @@ static const u32 rtw8822c_rf_a[] = {
+ 	0x92000002,	0x00000000,	0x40000000,	0x00000000,
+ 		0x03F, 0x0000EA46,
+ 	0x93000001,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000002,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000003,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000004,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000005,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000006,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000015,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000016,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000001,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000002,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000003,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000004,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000005,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000006,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000015,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000016,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000001,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000002,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000003,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000004,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000005,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000006,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000015,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000016,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0xA0000000,	0x00000000,
+ 		0x03F, 0x00002A46,
+ 	0xB0000000,	0x00000000,
+@@ -19152,53 +19152,53 @@ static const u32 rtw8822c_rf_a[] = {
+ 	0x92000002,	0x00000000,	0x40000000,	0x00000000,
+ 		0x03F, 0x0000EA46,
+ 	0x93000001,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000002,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000003,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000004,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000005,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000006,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000015,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000016,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000001,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000002,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000003,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000004,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000005,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000006,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000015,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000016,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000001,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000002,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000003,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000004,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000005,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000006,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000015,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000016,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0xA0000000,	0x00000000,
+ 		0x03F, 0x00002A46,
+ 	0xB0000000,	0x00000000,
+@@ -19347,53 +19347,53 @@ static const u32 rtw8822c_rf_a[] = {
+ 	0x92000002,	0x00000000,	0x40000000,	0x00000000,
+ 		0x03F, 0x0000EA46,
+ 	0x93000001,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000002,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000003,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000004,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000005,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000006,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000015,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x93000016,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000001,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000002,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000003,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000004,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000005,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000006,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000015,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x94000016,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000001,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000002,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000003,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000004,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000005,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000006,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000015,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0x95000016,	0x00000000,	0x40000000,	0x00000000,
+-		0x03F, 0x00031E46,
++		0x03F, 0x0003D646,
+ 	0xA0000000,	0x00000000,
+ 		0x03F, 0x00002A46,
+ 	0xB0000000,	0x00000000,
+@@ -19610,21 +19610,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x93000002,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -19633,21 +19633,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x93000003,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -19656,21 +19656,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x93000004,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -19679,21 +19679,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x93000005,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -19702,21 +19702,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x93000006,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -19725,21 +19725,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x93000015,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -19748,21 +19748,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x93000016,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -19771,21 +19771,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x94000001,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -19794,21 +19794,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x94000002,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -19817,21 +19817,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x94000003,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -19840,21 +19840,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x94000004,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -19863,21 +19863,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x94000005,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -19886,21 +19886,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x94000006,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -19909,21 +19909,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x94000015,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -19932,21 +19932,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x94000016,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -19955,21 +19955,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x95000001,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -19978,21 +19978,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x95000002,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -20001,21 +20001,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x95000003,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -20024,21 +20024,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x95000004,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -20047,21 +20047,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x95000005,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -20070,21 +20070,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x95000006,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -20093,21 +20093,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x95000015,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -20116,21 +20116,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x95000016,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -20139,21 +20139,21 @@ static const u32 rtw8822c_rf_a[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x000008C8,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x000008CB,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x000008CE,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x000008D1,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x000008D4,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000DD1,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0xA0000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000487,
+@@ -38484,21 +38484,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x93000002,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -38507,21 +38507,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x93000003,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -38530,21 +38530,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x93000004,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -38553,21 +38553,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x93000005,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -38576,21 +38576,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x93000006,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -38599,21 +38599,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x93000015,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -38622,21 +38622,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x93000016,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -38645,21 +38645,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x94000001,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -38668,21 +38668,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x94000002,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -38691,21 +38691,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x94000003,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -38714,21 +38714,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x94000004,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -38737,21 +38737,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x94000005,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -38760,21 +38760,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x94000006,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -38783,21 +38783,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x94000015,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -38806,21 +38806,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x94000016,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -38829,21 +38829,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x95000001,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -38852,21 +38852,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x95000002,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -38875,21 +38875,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x95000003,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -38898,21 +38898,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x95000004,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -38921,21 +38921,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x95000005,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -38944,21 +38944,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x95000006,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -38967,21 +38967,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x95000015,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -38990,21 +38990,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0x95000016,	0x00000000,	0x40000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000467,
+@@ -39013,21 +39013,21 @@ static const u32 rtw8822c_rf_b[] = {
+ 		0x033, 0x00000062,
+ 		0x03F, 0x00000908,
+ 		0x033, 0x00000063,
+-		0x03F, 0x00000D09,
++		0x03F, 0x00000CC6,
+ 		0x033, 0x00000064,
+-		0x03F, 0x00000D49,
++		0x03F, 0x00000CC9,
+ 		0x033, 0x00000065,
+-		0x03F, 0x00000D8A,
++		0x03F, 0x00000CCC,
+ 		0x033, 0x00000066,
+-		0x03F, 0x00000DEB,
++		0x03F, 0x00000CCF,
+ 		0x033, 0x00000067,
+-		0x03F, 0x00000DEE,
++		0x03F, 0x00000CD2,
+ 		0x033, 0x00000068,
+-		0x03F, 0x00000DF1,
++		0x03F, 0x00000CD5,
+ 		0x033, 0x00000069,
+-		0x03F, 0x00000DF4,
++		0x03F, 0x00000DD4,
+ 		0x033, 0x0000006A,
+-		0x03F, 0x00000DF7,
++		0x03F, 0x00000DD7,
+ 	0xA0000000,	0x00000000,
+ 		0x033, 0x00000060,
+ 		0x03F, 0x00000487,
+diff --git a/drivers/net/wireless/st/cw1200/cw1200_sdio.c b/drivers/net/wireless/st/cw1200/cw1200_sdio.c
+index b65ec14136c7e..4c30b5772ce0f 100644
+--- a/drivers/net/wireless/st/cw1200/cw1200_sdio.c
++++ b/drivers/net/wireless/st/cw1200/cw1200_sdio.c
+@@ -53,6 +53,7 @@ static const struct sdio_device_id cw1200_sdio_ids[] = {
+ 	{ SDIO_DEVICE(SDIO_VENDOR_ID_STE, SDIO_DEVICE_ID_STE_CW1200) },
+ 	{ /* end: all zeroes */			},
+ };
++MODULE_DEVICE_TABLE(sdio, cw1200_sdio_ids);
+ 
+ /* hwbus_ops implemetation */
+ 
+diff --git a/drivers/net/wireless/ti/wl1251/cmd.c b/drivers/net/wireless/ti/wl1251/cmd.c
+index 498c8db2eb48b..d7a869106782f 100644
+--- a/drivers/net/wireless/ti/wl1251/cmd.c
++++ b/drivers/net/wireless/ti/wl1251/cmd.c
+@@ -454,9 +454,12 @@ int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len,
+ 		cmd->channels[i].channel = channels[i]->hw_value;
+ 	}
+ 
+-	cmd->params.ssid_len = ssid_len;
+-	if (ssid)
+-		memcpy(cmd->params.ssid, ssid, ssid_len);
++	if (ssid) {
++		int len = clamp_val(ssid_len, 0, IEEE80211_MAX_SSID_LEN);
++
++		cmd->params.ssid_len = len;
++		memcpy(cmd->params.ssid, ssid, len);
++	}
+ 
+ 	ret = wl1251_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd));
+ 	if (ret < 0) {
+diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
+index 9d7dbfe7fe0c3..c6da0cfb4afbe 100644
+--- a/drivers/net/wireless/ti/wl12xx/main.c
++++ b/drivers/net/wireless/ti/wl12xx/main.c
+@@ -1503,6 +1503,13 @@ static int wl12xx_get_fuse_mac(struct wl1271 *wl)
+ 	u32 mac1, mac2;
+ 	int ret;
+ 
++	/* Device may be in ELP from the bootloader or kexec */
++	ret = wlcore_write32(wl, WL12XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
++	if (ret < 0)
++		goto out;
++
++	usleep_range(500000, 700000);
++
+ 	ret = wlcore_set_partition(wl, &wl->ptable[PART_DRPW]);
+ 	if (ret < 0)
+ 		goto out;
+diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
+index bca671ff4e546..f9c9c98599197 100644
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -686,15 +686,17 @@ static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
+ 			continue;
+ 		if (len < 2 * sizeof(u32)) {
+ 			dev_err(dev, "nvmem: invalid reg on %pOF\n", child);
++			of_node_put(child);
+ 			return -EINVAL;
+ 		}
+ 
+ 		cell = kzalloc(sizeof(*cell), GFP_KERNEL);
+-		if (!cell)
++		if (!cell) {
++			of_node_put(child);
+ 			return -ENOMEM;
++		}
+ 
+ 		cell->nvmem = nvmem;
+-		cell->np = of_node_get(child);
+ 		cell->offset = be32_to_cpup(addr++);
+ 		cell->bytes = be32_to_cpup(addr);
+ 		cell->name = kasprintf(GFP_KERNEL, "%pOFn", child);
+@@ -715,11 +717,12 @@ static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
+ 				cell->name, nvmem->stride);
+ 			/* Cells already added will be freed later. */
+ 			kfree_const(cell->name);
+-			of_node_put(cell->np);
+ 			kfree(cell);
++			of_node_put(child);
+ 			return -EINVAL;
+ 		}
+ 
++		cell->np = of_node_get(child);
+ 		nvmem_cell_add(cell);
+ 	}
+ 
+diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
+index 504669e3afe07..fa6b12cfc0430 100644
+--- a/drivers/pci/controller/dwc/pcie-tegra194.c
++++ b/drivers/pci/controller/dwc/pcie-tegra194.c
+@@ -2214,6 +2214,8 @@ static int tegra_pcie_dw_resume_noirq(struct device *dev)
+ 		goto fail_host_init;
+ 	}
+ 
++	dw_pcie_setup_rc(&pcie->pci.pp);
++
+ 	ret = tegra_pcie_dw_start_link(&pcie->pci);
+ 	if (ret < 0)
+ 		goto fail_host_init;
+diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
+index e3f5e7ab76063..c95ebe808f92b 100644
+--- a/drivers/pci/controller/pci-aardvark.c
++++ b/drivers/pci/controller/pci-aardvark.c
+@@ -57,7 +57,7 @@
+ #define   PIO_COMPLETION_STATUS_UR		1
+ #define   PIO_COMPLETION_STATUS_CRS		2
+ #define   PIO_COMPLETION_STATUS_CA		4
+-#define   PIO_NON_POSTED_REQ			BIT(0)
++#define   PIO_NON_POSTED_REQ			BIT(10)
+ #define PIO_ADDR_LS				(PIO_BASE_ADDR + 0x8)
+ #define PIO_ADDR_MS				(PIO_BASE_ADDR + 0xc)
+ #define PIO_WR_DATA				(PIO_BASE_ADDR + 0x10)
+@@ -125,6 +125,7 @@
+ #define     LTSSM_MASK				0x3f
+ #define     LTSSM_L0				0x10
+ #define     RC_BAR_CONFIG			0x300
++#define VENDOR_ID_REG				(LMI_BASE_ADDR + 0x44)
+ 
+ /* PCIe core controller registers */
+ #define CTRL_CORE_BASE_ADDR			0x18000
+@@ -385,6 +386,16 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie)
+ 	reg |= (IS_RC_MSK << IS_RC_SHIFT);
+ 	advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);
+ 
++	/*
++	 * Replace incorrect PCI vendor id value 0x1b4b by correct value 0x11ab.
++	 * VENDOR_ID_REG contains vendor id in low 16 bits and subsystem vendor
++	 * id in high 16 bits. Updating this register changes readback value of
++	 * read-only vendor id bits in PCIE_CORE_DEV_ID_REG register. Workaround
++	 * for erratum 4.1: "The value of device and vendor ID is incorrect".
++	 */
++	reg = (PCI_VENDOR_ID_MARVELL << 16) | PCI_VENDOR_ID_MARVELL;
++	advk_writel(pcie, reg, VENDOR_ID_REG);
++
+ 	/* Set Advanced Error Capabilities and Control PF0 register */
+ 	reg = PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX |
+ 		PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN |
+diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
+index 22b2bb1109c9e..6d74386eadc2c 100644
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -27,6 +27,7 @@
+ #include <linux/nvme.h>
+ #include <linux/platform_data/x86/apple.h>
+ #include <linux/pm_runtime.h>
++#include <linux/suspend.h>
+ #include <linux/switchtec.h>
+ #include <asm/dma.h>	/* isa_dma_bridge_buggy */
+ #include "pci.h"
+@@ -3656,6 +3657,16 @@ static void quirk_apple_poweroff_thunderbolt(struct pci_dev *dev)
+ 		return;
+ 	if (pci_pcie_type(dev) != PCI_EXP_TYPE_UPSTREAM)
+ 		return;
++
++	/*
++	 * SXIO/SXFP/SXLF turns off power to the Thunderbolt controller.
++	 * We don't know how to turn it back on again, but firmware does,
++	 * so we can only use SXIO/SXFP/SXLF if we're suspending via
++	 * firmware.
++	 */
++	if (!pm_suspend_via_firmware())
++		return;
++
+ 	bridge = ACPI_HANDLE(&dev->dev);
+ 	if (!bridge)
+ 		return;
+diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
+index 2d4acf21117cc..c5950a3b4e4ce 100644
+--- a/drivers/pinctrl/pinctrl-amd.c
++++ b/drivers/pinctrl/pinctrl-amd.c
+@@ -991,6 +991,7 @@ static int amd_gpio_remove(struct platform_device *pdev)
+ static const struct acpi_device_id amd_gpio_acpi_match[] = {
+ 	{ "AMD0030", 0 },
+ 	{ "AMDI0030", 0},
++	{ "AMDI0031", 0},
+ 	{ },
+ };
+ MODULE_DEVICE_TABLE(acpi, amd_gpio_acpi_match);
+diff --git a/drivers/pinctrl/pinctrl-equilibrium.c b/drivers/pinctrl/pinctrl-equilibrium.c
+index a194d8089b6f4..38cc20fa9d5af 100644
+--- a/drivers/pinctrl/pinctrl-equilibrium.c
++++ b/drivers/pinctrl/pinctrl-equilibrium.c
+@@ -939,6 +939,7 @@ static const struct of_device_id eqbr_pinctrl_dt_match[] = {
+ 	{ .compatible = "intel,lgm-io" },
+ 	{}
+ };
++MODULE_DEVICE_TABLE(of, eqbr_pinctrl_dt_match);
+ 
+ static struct platform_driver eqbr_pinctrl_driver = {
+ 	.probe	= eqbr_pinctrl_probe,
+diff --git a/drivers/pinctrl/pinctrl-mcp23s08.c b/drivers/pinctrl/pinctrl-mcp23s08.c
+index ce2d8014b7e0b..d0259577934e9 100644
+--- a/drivers/pinctrl/pinctrl-mcp23s08.c
++++ b/drivers/pinctrl/pinctrl-mcp23s08.c
+@@ -351,6 +351,11 @@ static irqreturn_t mcp23s08_irq(int irq, void *data)
+ 	if (mcp_read(mcp, MCP_INTF, &intf))
+ 		goto unlock;
+ 
++	if (intf == 0) {
++		/* There is no interrupt pending */
++		goto unlock;
++	}
++
+ 	if (mcp_read(mcp, MCP_INTCAP, &intcap))
+ 		goto unlock;
+ 
+@@ -368,11 +373,6 @@ static irqreturn_t mcp23s08_irq(int irq, void *data)
+ 	mcp->cached_gpio = gpio;
+ 	mutex_unlock(&mcp->lock);
+ 
+-	if (intf == 0) {
+-		/* There is no interrupt pending */
+-		return IRQ_HANDLED;
+-	}
+-
+ 	dev_dbg(mcp->chip.parent,
+ 		"intcap 0x%04X intf 0x%04X gpio_orig 0x%04X gpio 0x%04X\n",
+ 		intcap, intf, gpio_orig, gpio);
+diff --git a/drivers/power/supply/ab8500-chargalg.h b/drivers/power/supply/ab8500-chargalg.h
+index 94a6f9068bc56..07e6ff50084f0 100644
+--- a/drivers/power/supply/ab8500-chargalg.h
++++ b/drivers/power/supply/ab8500-chargalg.h
+@@ -15,7 +15,7 @@
+  * - POWER_SUPPLY_TYPE_USB,
+  * because only them store as drv_data pointer to struct ux500_charger.
+  */
+-#define psy_to_ux500_charger(x) power_supply_get_drvdata(psy)
++#define psy_to_ux500_charger(x) power_supply_get_drvdata(x)
+ 
+ /* Forward declaration */
+ struct ux500_charger;
+diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
+index 9e6f2a895a234..5b1355fae9b41 100644
+--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
++++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
+@@ -100,24 +100,27 @@ static ssize_t tcc_offset_degree_celsius_show(struct device *dev,
+ 	if (err)
+ 		return err;
+ 
+-	val = (val >> 24) & 0xff;
++	val = (val >> 24) & 0x3f;
+ 	return sprintf(buf, "%d\n", (int)val);
+ }
+ 
+-static int tcc_offset_update(int tcc)
++static int tcc_offset_update(unsigned int tcc)
+ {
+ 	u64 val;
+ 	int err;
+ 
+-	if (!tcc)
++	if (tcc > 63)
+ 		return -EINVAL;
+ 
+ 	err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val);
+ 	if (err)
+ 		return err;
+ 
+-	val &= ~GENMASK_ULL(31, 24);
+-	val |= (tcc & 0xff) << 24;
++	if (val & BIT(31))
++		return -EPERM;
++
++	val &= ~GENMASK_ULL(29, 24);
++	val |= (tcc & 0x3f) << 24;
+ 
+ 	err = wrmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, val);
+ 	if (err)
+@@ -126,14 +129,15 @@ static int tcc_offset_update(int tcc)
+ 	return 0;
+ }
+ 
+-static int tcc_offset_save;
++static unsigned int tcc_offset_save;
+ 
+ static ssize_t tcc_offset_degree_celsius_store(struct device *dev,
+ 				struct device_attribute *attr, const char *buf,
+ 				size_t count)
+ {
++	unsigned int tcc;
+ 	u64 val;
+-	int tcc, err;
++	int err;
+ 
+ 	err = rdmsrl_safe(MSR_PLATFORM_INFO, &val);
+ 	if (err)
+@@ -142,7 +146,7 @@ static ssize_t tcc_offset_degree_celsius_store(struct device *dev,
+ 	if (!(val & BIT(30)))
+ 		return -EACCES;
+ 
+-	if (kstrtoint(buf, 0, &tcc))
++	if (kstrtouint(buf, 0, &tcc))
+ 		return -EINVAL;
+ 
+ 	err = tcc_offset_update(tcc);
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index 37002663d5212..a179c0bbc12ef 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -1488,6 +1488,7 @@ struct ext4_sb_info {
+ 	struct kobject s_kobj;
+ 	struct completion s_kobj_unregister;
+ 	struct super_block *s_sb;
++	struct buffer_head *s_mmp_bh;
+ 
+ 	/* Journaling */
+ 	struct journal_s *s_journal;
+@@ -3720,6 +3721,9 @@ extern struct ext4_io_end_vec *ext4_last_io_end_vec(ext4_io_end_t *io_end);
+ /* mmp.c */
+ extern int ext4_multi_mount_protect(struct super_block *, ext4_fsblk_t);
+ 
++/* mmp.c */
++extern void ext4_stop_mmpd(struct ext4_sb_info *sbi);
++
+ /* verity.c */
+ extern const struct fsverity_operations ext4_verityops;
+ 
+diff --git a/fs/ext4/mmp.c b/fs/ext4/mmp.c
+index 68fbeedd627bc..bc364c119af6a 100644
+--- a/fs/ext4/mmp.c
++++ b/fs/ext4/mmp.c
+@@ -127,9 +127,9 @@ void __dump_mmp_msg(struct super_block *sb, struct mmp_struct *mmp,
+  */
+ static int kmmpd(void *data)
+ {
+-	struct super_block *sb = ((struct mmpd_data *) data)->sb;
+-	struct buffer_head *bh = ((struct mmpd_data *) data)->bh;
++	struct super_block *sb = (struct super_block *) data;
+ 	struct ext4_super_block *es = EXT4_SB(sb)->s_es;
++	struct buffer_head *bh = EXT4_SB(sb)->s_mmp_bh;
+ 	struct mmp_struct *mmp;
+ 	ext4_fsblk_t mmp_block;
+ 	u32 seq = 0;
+@@ -156,7 +156,12 @@ static int kmmpd(void *data)
+ 	memcpy(mmp->mmp_nodename, init_utsname()->nodename,
+ 	       sizeof(mmp->mmp_nodename));
+ 
+-	while (!kthread_should_stop()) {
++	while (!kthread_should_stop() && !sb_rdonly(sb)) {
++		if (!ext4_has_feature_mmp(sb)) {
++			ext4_warning(sb, "kmmpd being stopped since MMP feature"
++				     " has been disabled.");
++			goto wait_to_exit;
++		}
+ 		if (++seq > EXT4_MMP_SEQ_MAX)
+ 			seq = 1;
+ 
+@@ -177,16 +182,6 @@ static int kmmpd(void *data)
+ 			failed_writes++;
+ 		}
+ 
+-		if (!(le32_to_cpu(es->s_feature_incompat) &
+-		    EXT4_FEATURE_INCOMPAT_MMP)) {
+-			ext4_warning(sb, "kmmpd being stopped since MMP feature"
+-				     " has been disabled.");
+-			goto exit_thread;
+-		}
+-
+-		if (sb_rdonly(sb))
+-			break;
+-
+ 		diff = jiffies - last_update_time;
+ 		if (diff < mmp_update_interval * HZ)
+ 			schedule_timeout_interruptible(mmp_update_interval *
+@@ -207,7 +202,7 @@ static int kmmpd(void *data)
+ 				ext4_error_err(sb, -retval,
+ 					       "error reading MMP data: %d",
+ 					       retval);
+-				goto exit_thread;
++				goto wait_to_exit;
+ 			}
+ 
+ 			mmp_check = (struct mmp_struct *)(bh_check->b_data);
+@@ -221,7 +216,7 @@ static int kmmpd(void *data)
+ 				ext4_error_err(sb, EBUSY, "abort");
+ 				put_bh(bh_check);
+ 				retval = -EBUSY;
+-				goto exit_thread;
++				goto wait_to_exit;
+ 			}
+ 			put_bh(bh_check);
+ 		}
+@@ -244,13 +239,25 @@ static int kmmpd(void *data)
+ 
+ 	retval = write_mmp_block(sb, bh);
+ 
+-exit_thread:
+-	EXT4_SB(sb)->s_mmp_tsk = NULL;
+-	kfree(data);
+-	brelse(bh);
++wait_to_exit:
++	while (!kthread_should_stop()) {
++		set_current_state(TASK_INTERRUPTIBLE);
++		if (!kthread_should_stop())
++			schedule();
++	}
++	set_current_state(TASK_RUNNING);
+ 	return retval;
+ }
+ 
++void ext4_stop_mmpd(struct ext4_sb_info *sbi)
++{
++	if (sbi->s_mmp_tsk) {
++		kthread_stop(sbi->s_mmp_tsk);
++		brelse(sbi->s_mmp_bh);
++		sbi->s_mmp_tsk = NULL;
++	}
++}
++
+ /*
+  * Get a random new sequence number but make sure it is not greater than
+  * EXT4_MMP_SEQ_MAX.
+@@ -275,7 +282,6 @@ int ext4_multi_mount_protect(struct super_block *sb,
+ 	struct ext4_super_block *es = EXT4_SB(sb)->s_es;
+ 	struct buffer_head *bh = NULL;
+ 	struct mmp_struct *mmp = NULL;
+-	struct mmpd_data *mmpd_data;
+ 	u32 seq;
+ 	unsigned int mmp_check_interval = le16_to_cpu(es->s_mmp_update_interval);
+ 	unsigned int wait_time = 0;
+@@ -364,24 +370,17 @@ skip:
+ 		goto failed;
+ 	}
+ 
+-	mmpd_data = kmalloc(sizeof(*mmpd_data), GFP_KERNEL);
+-	if (!mmpd_data) {
+-		ext4_warning(sb, "not enough memory for mmpd_data");
+-		goto failed;
+-	}
+-	mmpd_data->sb = sb;
+-	mmpd_data->bh = bh;
++	EXT4_SB(sb)->s_mmp_bh = bh;
+ 
+ 	/*
+ 	 * Start a kernel thread to update the MMP block periodically.
+ 	 */
+-	EXT4_SB(sb)->s_mmp_tsk = kthread_run(kmmpd, mmpd_data, "kmmpd-%.*s",
++	EXT4_SB(sb)->s_mmp_tsk = kthread_run(kmmpd, sb, "kmmpd-%.*s",
+ 					     (int)sizeof(mmp->mmp_bdevname),
+ 					     bdevname(bh->b_bdev,
+ 						      mmp->mmp_bdevname));
+ 	if (IS_ERR(EXT4_SB(sb)->s_mmp_tsk)) {
+ 		EXT4_SB(sb)->s_mmp_tsk = NULL;
+-		kfree(mmpd_data);
+ 		ext4_warning(sb, "Unable to create kmmpd thread for %s.",
+ 			     sb->s_id);
+ 		goto failed;
+@@ -393,5 +392,3 @@ failed:
+ 	brelse(bh);
+ 	return 1;
+ }
+-
+-
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 736724ce86d73..09f1f02e1d6d6 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -1245,8 +1245,8 @@ static void ext4_put_super(struct super_block *sb)
+ 	ext4_xattr_destroy_cache(sbi->s_ea_block_cache);
+ 	sbi->s_ea_block_cache = NULL;
+ 
+-	if (sbi->s_mmp_tsk)
+-		kthread_stop(sbi->s_mmp_tsk);
++	ext4_stop_mmpd(sbi);
++
+ 	brelse(sbi->s_sbh);
+ 	sb->s_fs_info = NULL;
+ 	/*
+@@ -5194,8 +5194,7 @@ failed_mount3a:
+ failed_mount3:
+ 	flush_work(&sbi->s_error_work);
+ 	del_timer_sync(&sbi->s_err_report);
+-	if (sbi->s_mmp_tsk)
+-		kthread_stop(sbi->s_mmp_tsk);
++	ext4_stop_mmpd(sbi);
+ failed_mount2:
+ 	rcu_read_lock();
+ 	group_desc = rcu_dereference(sbi->s_group_desc);
+@@ -5997,8 +5996,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
+ 				 */
+ 				ext4_mark_recovery_complete(sb, es);
+ 			}
+-			if (sbi->s_mmp_tsk)
+-				kthread_stop(sbi->s_mmp_tsk);
+ 		} else {
+ 			/* Make sure we can mount this feature set readwrite */
+ 			if (ext4_has_feature_readonly(sb) ||
+@@ -6112,6 +6109,9 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
+ 	if (!test_opt(sb, BLOCK_VALIDITY) && sbi->s_system_blks)
+ 		ext4_release_system_zone(sb);
+ 
++	if (!ext4_has_feature_mmp(sb) || sb_rdonly(sb))
++		ext4_stop_mmpd(sbi);
++
+ 	/*
+ 	 * Some options can be enabled by ext4 and/or by VFS mount flag
+ 	 * either way we need to make sure it matches in both *flags and
+@@ -6145,6 +6145,8 @@ restore_opts:
+ 	for (i = 0; i < EXT4_MAXQUOTAS; i++)
+ 		kfree(to_free[i]);
+ #endif
++	if (!ext4_has_feature_mmp(sb) || sb_rdonly(sb))
++		ext4_stop_mmpd(sbi);
+ 	kfree(orig_data);
+ 	return err;
+ }
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index c83d90125ebd9..a5de48e768d7b 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -3566,6 +3566,8 @@ void f2fs_destroy_garbage_collection_cache(void);
+  */
+ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only);
+ bool f2fs_space_for_roll_forward(struct f2fs_sb_info *sbi);
++int __init f2fs_create_recovery_cache(void);
++void f2fs_destroy_recovery_cache(void);
+ 
+ /*
+  * debug.c
+diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
+index 422146c6d866d..4b2f7d1d5bf4b 100644
+--- a/fs/f2fs/recovery.c
++++ b/fs/f2fs/recovery.c
+@@ -788,13 +788,6 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only)
+ 	quota_enabled = f2fs_enable_quota_files(sbi, s_flags & SB_RDONLY);
+ #endif
+ 
+-	fsync_entry_slab = f2fs_kmem_cache_create("f2fs_fsync_inode_entry",
+-			sizeof(struct fsync_inode_entry));
+-	if (!fsync_entry_slab) {
+-		err = -ENOMEM;
+-		goto out;
+-	}
+-
+ 	INIT_LIST_HEAD(&inode_list);
+ 	INIT_LIST_HEAD(&tmp_inode_list);
+ 	INIT_LIST_HEAD(&dir_list);
+@@ -867,8 +860,6 @@ skip:
+ 		}
+ 	}
+ 
+-	kmem_cache_destroy(fsync_entry_slab);
+-out:
+ #ifdef CONFIG_QUOTA
+ 	/* Turn quotas off */
+ 	if (quota_enabled)
+@@ -878,3 +869,17 @@ out:
+ 
+ 	return ret ? ret : err;
+ }
++
++int __init f2fs_create_recovery_cache(void)
++{
++	fsync_entry_slab = f2fs_kmem_cache_create("f2fs_fsync_inode_entry",
++					sizeof(struct fsync_inode_entry));
++	if (!fsync_entry_slab)
++		return -ENOMEM;
++	return 0;
++}
++
++void f2fs_destroy_recovery_cache(void)
++{
++	kmem_cache_destroy(fsync_entry_slab);
++}
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 7d325bfaf65ae..096492caaa6bf 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -4227,9 +4227,12 @@ static int __init init_f2fs_fs(void)
+ 	err = f2fs_create_checkpoint_caches();
+ 	if (err)
+ 		goto free_segment_manager_caches;
+-	err = f2fs_create_extent_cache();
++	err = f2fs_create_recovery_cache();
+ 	if (err)
+ 		goto free_checkpoint_caches;
++	err = f2fs_create_extent_cache();
++	if (err)
++		goto free_recovery_cache;
+ 	err = f2fs_create_garbage_collection_cache();
+ 	if (err)
+ 		goto free_extent_cache;
+@@ -4278,6 +4281,8 @@ free_garbage_collection_cache:
+ 	f2fs_destroy_garbage_collection_cache();
+ free_extent_cache:
+ 	f2fs_destroy_extent_cache();
++free_recovery_cache:
++	f2fs_destroy_recovery_cache();
+ free_checkpoint_caches:
+ 	f2fs_destroy_checkpoint_caches();
+ free_segment_manager_caches:
+@@ -4303,6 +4308,7 @@ static void __exit exit_f2fs_fs(void)
+ 	f2fs_exit_sysfs();
+ 	f2fs_destroy_garbage_collection_cache();
+ 	f2fs_destroy_extent_cache();
++	f2fs_destroy_recovery_cache();
+ 	f2fs_destroy_checkpoint_caches();
+ 	f2fs_destroy_segment_manager_caches();
+ 	f2fs_destroy_node_manager_caches();
+diff --git a/fs/io-wq.c b/fs/io-wq.c
+index b3e8624a37d09..60f58efdb5f48 100644
+--- a/fs/io-wq.c
++++ b/fs/io-wq.c
+@@ -241,7 +241,8 @@ static void io_wqe_wake_worker(struct io_wqe *wqe, struct io_wqe_acct *acct)
+ 	 * Most likely an attempt to queue unbounded work on an io_wq that
+ 	 * wasn't setup with any unbounded workers.
+ 	 */
+-	WARN_ON_ONCE(!acct->max_workers);
++	if (unlikely(!acct->max_workers))
++		pr_warn_once("io-wq is not configured for unbound workers");
+ 
+ 	rcu_read_lock();
+ 	ret = io_wqe_activate_free_worker(wqe);
+@@ -906,6 +907,8 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data)
+ 
+ 	if (WARN_ON_ONCE(!data->free_work || !data->do_work))
+ 		return ERR_PTR(-EINVAL);
++	if (WARN_ON_ONCE(!bounded))
++		return ERR_PTR(-EINVAL);
+ 
+ 	wq = kzalloc(sizeof(*wq), GFP_KERNEL);
+ 	if (!wq)
+diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
+index 6f65bfa9f18d5..b0eb9c85eea0c 100644
+--- a/fs/jfs/inode.c
++++ b/fs/jfs/inode.c
+@@ -151,7 +151,8 @@ void jfs_evict_inode(struct inode *inode)
+ 			if (test_cflag(COMMIT_Freewmap, inode))
+ 				jfs_free_zero_link(inode);
+ 
+-			diFree(inode);
++			if (JFS_SBI(inode->i_sb)->ipimap)
++				diFree(inode);
+ 
+ 			/*
+ 			 * Free the inode from the quota allocation.
+diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
+index 9edc8e2b154e0..0834b101c316d 100644
+--- a/fs/reiserfs/journal.c
++++ b/fs/reiserfs/journal.c
+@@ -2758,6 +2758,20 @@ int journal_init(struct super_block *sb, const char *j_dev_name,
+ 		goto free_and_return;
+ 	}
+ 
++	/*
++	 * Sanity check to see if journal first block is correct.
++	 * If journal first block is invalid it can cause
++	 * zeroing important superblock members.
++	 */
++	if (!SB_ONDISK_JOURNAL_DEVICE(sb) &&
++	    SB_ONDISK_JOURNAL_1st_BLOCK(sb) < SB_JOURNAL_1st_RESERVED_BLOCK(sb)) {
++		reiserfs_warning(sb, "journal-1393",
++				 "journal 1st super block is invalid: 1st reserved block %d, but actual 1st block is %d",
++				 SB_JOURNAL_1st_RESERVED_BLOCK(sb),
++				 SB_ONDISK_JOURNAL_1st_BLOCK(sb));
++		goto free_and_return;
++	}
++
+ 	if (journal_init_dev(sb, journal, j_dev_name) != 0) {
+ 		reiserfs_warning(sb, "sh-462",
+ 				 "unable to initialize journal device");
+diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
+index 7b572e1414ba2..e279a069a26b0 100644
+--- a/fs/ubifs/super.c
++++ b/fs/ubifs/super.c
+@@ -275,6 +275,7 @@ static struct inode *ubifs_alloc_inode(struct super_block *sb)
+ 	memset((void *)ui + sizeof(struct inode), 0,
+ 	       sizeof(struct ubifs_inode) - sizeof(struct inode));
+ 	mutex_init(&ui->ui_mutex);
++	init_rwsem(&ui->xattr_sem);
+ 	spin_lock_init(&ui->ui_lock);
+ 	return &ui->vfs_inode;
+ };
+diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
+index b65c599a386a4..7e978f421430a 100644
+--- a/fs/ubifs/ubifs.h
++++ b/fs/ubifs/ubifs.h
+@@ -356,6 +356,7 @@ struct ubifs_gced_idx_leb {
+  * @ui_mutex: serializes inode write-back with the rest of VFS operations,
+  *            serializes "clean <-> dirty" state changes, serializes bulk-read,
+  *            protects @dirty, @bulk_read, @ui_size, and @xattr_size
++ * @xattr_sem: serilizes write operations (remove|set|create) on xattr
+  * @ui_lock: protects @synced_i_size
+  * @synced_i_size: synchronized size of inode, i.e. the value of inode size
+  *                 currently stored on the flash; used only for regular file
+@@ -409,6 +410,7 @@ struct ubifs_inode {
+ 	unsigned int bulk_read:1;
+ 	unsigned int compr_type:2;
+ 	struct mutex ui_mutex;
++	struct rw_semaphore xattr_sem;
+ 	spinlock_t ui_lock;
+ 	loff_t synced_i_size;
+ 	loff_t ui_size;
+diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
+index 6b1e9830b2745..1fce27e9b7697 100644
+--- a/fs/ubifs/xattr.c
++++ b/fs/ubifs/xattr.c
+@@ -285,6 +285,7 @@ int ubifs_xattr_set(struct inode *host, const char *name, const void *value,
+ 	if (!xent)
+ 		return -ENOMEM;
+ 
++	down_write(&ubifs_inode(host)->xattr_sem);
+ 	/*
+ 	 * The extended attribute entries are stored in LNC, so multiple
+ 	 * look-ups do not involve reading the flash.
+@@ -319,6 +320,7 @@ int ubifs_xattr_set(struct inode *host, const char *name, const void *value,
+ 	iput(inode);
+ 
+ out_free:
++	up_write(&ubifs_inode(host)->xattr_sem);
+ 	kfree(xent);
+ 	return err;
+ }
+@@ -341,18 +343,19 @@ ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf,
+ 	if (!xent)
+ 		return -ENOMEM;
+ 
++	down_read(&ubifs_inode(host)->xattr_sem);
+ 	xent_key_init(c, &key, host->i_ino, &nm);
+ 	err = ubifs_tnc_lookup_nm(c, &key, xent, &nm);
+ 	if (err) {
+ 		if (err == -ENOENT)
+ 			err = -ENODATA;
+-		goto out_unlock;
++		goto out_cleanup;
+ 	}
+ 
+ 	inode = iget_xattr(c, le64_to_cpu(xent->inum));
+ 	if (IS_ERR(inode)) {
+ 		err = PTR_ERR(inode);
+-		goto out_unlock;
++		goto out_cleanup;
+ 	}
+ 
+ 	ui = ubifs_inode(inode);
+@@ -374,7 +377,8 @@ ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf,
+ out_iput:
+ 	mutex_unlock(&ui->ui_mutex);
+ 	iput(inode);
+-out_unlock:
++out_cleanup:
++	up_read(&ubifs_inode(host)->xattr_sem);
+ 	kfree(xent);
+ 	return err;
+ }
+@@ -406,16 +410,21 @@ ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size)
+ 	dbg_gen("ino %lu ('%pd'), buffer size %zd", host->i_ino,
+ 		dentry, size);
+ 
++	down_read(&host_ui->xattr_sem);
+ 	len = host_ui->xattr_names + host_ui->xattr_cnt;
+-	if (!buffer)
++	if (!buffer) {
+ 		/*
+ 		 * We should return the minimum buffer size which will fit a
+ 		 * null-terminated list of all the extended attribute names.
+ 		 */
+-		return len;
++		err = len;
++		goto out_err;
++	}
+ 
+-	if (len > size)
+-		return -ERANGE;
++	if (len > size) {
++		err = -ERANGE;
++		goto out_err;
++	}
+ 
+ 	lowest_xent_key(c, &key, host->i_ino);
+ 	while (1) {
+@@ -437,8 +446,9 @@ ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size)
+ 		pxent = xent;
+ 		key_read(c, &xent->key, &key);
+ 	}
+-
+ 	kfree(pxent);
++	up_read(&host_ui->xattr_sem);
++
+ 	if (err != -ENOENT) {
+ 		ubifs_err(c, "cannot find next direntry, error %d", err);
+ 		return err;
+@@ -446,6 +456,10 @@ ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size)
+ 
+ 	ubifs_assert(c, written <= size);
+ 	return written;
++
++out_err:
++	up_read(&host_ui->xattr_sem);
++	return err;
+ }
+ 
+ static int remove_xattr(struct ubifs_info *c, struct inode *host,
+@@ -504,6 +518,7 @@ int ubifs_purge_xattrs(struct inode *host)
+ 	ubifs_warn(c, "inode %lu has too many xattrs, doing a non-atomic deletion",
+ 		   host->i_ino);
+ 
++	down_write(&ubifs_inode(host)->xattr_sem);
+ 	lowest_xent_key(c, &key, host->i_ino);
+ 	while (1) {
+ 		xent = ubifs_tnc_next_ent(c, &key, &nm);
+@@ -523,7 +538,7 @@ int ubifs_purge_xattrs(struct inode *host)
+ 			ubifs_ro_mode(c, err);
+ 			kfree(pxent);
+ 			kfree(xent);
+-			return err;
++			goto out_err;
+ 		}
+ 
+ 		ubifs_assert(c, ubifs_inode(xino)->xattr);
+@@ -535,7 +550,7 @@ int ubifs_purge_xattrs(struct inode *host)
+ 			kfree(xent);
+ 			iput(xino);
+ 			ubifs_err(c, "cannot remove xattr, error %d", err);
+-			return err;
++			goto out_err;
+ 		}
+ 
+ 		iput(xino);
+@@ -544,14 +559,19 @@ int ubifs_purge_xattrs(struct inode *host)
+ 		pxent = xent;
+ 		key_read(c, &xent->key, &key);
+ 	}
+-
+ 	kfree(pxent);
++	up_write(&ubifs_inode(host)->xattr_sem);
++
+ 	if (err != -ENOENT) {
+ 		ubifs_err(c, "cannot find next direntry, error %d", err);
+ 		return err;
+ 	}
+ 
+ 	return 0;
++
++out_err:
++	up_write(&ubifs_inode(host)->xattr_sem);
++	return err;
+ }
+ 
+ /**
+@@ -594,6 +614,7 @@ static int ubifs_xattr_remove(struct inode *host, const char *name)
+ 	if (!xent)
+ 		return -ENOMEM;
+ 
++	down_write(&ubifs_inode(host)->xattr_sem);
+ 	xent_key_init(c, &key, host->i_ino, &nm);
+ 	err = ubifs_tnc_lookup_nm(c, &key, xent, &nm);
+ 	if (err) {
+@@ -618,6 +639,7 @@ static int ubifs_xattr_remove(struct inode *host, const char *name)
+ 	iput(inode);
+ 
+ out_free:
++	up_write(&ubifs_inode(host)->xattr_sem);
+ 	kfree(xent);
+ 	return err;
+ }
+diff --git a/fs/udf/namei.c b/fs/udf/namei.c
+index 3ae9f1e919846..7c7c9bbbfa571 100644
+--- a/fs/udf/namei.c
++++ b/fs/udf/namei.c
+@@ -934,6 +934,10 @@ static int udf_symlink(struct user_namespace *mnt_userns, struct inode *dir,
+ 				iinfo->i_location.partitionReferenceNum,
+ 				0);
+ 		epos.bh = udf_tgetblk(sb, block);
++		if (unlikely(!epos.bh)) {
++			err = -ENOMEM;
++			goto out_no_entry;
++		}
+ 		lock_buffer(epos.bh);
+ 		memset(epos.bh->b_data, 0x00, bsize);
+ 		set_buffer_uptodate(epos.bh);
+diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
+index db026b6ec15ab..e5cf12f102a21 100644
+--- a/include/linux/blk_types.h
++++ b/include/linux/blk_types.h
+@@ -304,6 +304,7 @@ enum {
+ 	BIO_CGROUP_ACCT,	/* has been accounted to a cgroup */
+ 	BIO_TRACKED,		/* set if bio goes through the rq_qos path */
+ 	BIO_REMAPPED,
++	BIO_ZONE_WRITE_LOCKED,	/* Owns a zoned device zone write lock */
+ 	BIO_FLAG_LAST
+ };
+ 
+diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
+index 3de38d6a0aeac..2c6b9e4162254 100644
+--- a/include/linux/netdev_features.h
++++ b/include/linux/netdev_features.h
+@@ -93,7 +93,7 @@ enum {
+ 
+ 	/*
+ 	 * Add your fresh new feature above and remember to update
+-	 * netdev_features_strings[] in net/core/ethtool.c and maybe
++	 * netdev_features_strings[] in net/ethtool/common.c and maybe
+ 	 * some feature mask #defines below. Please also describe it
+ 	 * in Documentation/networking/netdev-features.rst.
+ 	 */
+diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h
+index 2b05e7f7c2385..da633d34ab866 100644
+--- a/include/linux/of_mdio.h
++++ b/include/linux/of_mdio.h
+@@ -72,6 +72,13 @@ static inline int of_mdiobus_register(struct mii_bus *mdio, struct device_node *
+ 	return mdiobus_register(mdio);
+ }
+ 
++static inline int devm_of_mdiobus_register(struct device *dev,
++					   struct mii_bus *mdio,
++					   struct device_node *np)
++{
++	return devm_mdiobus_register(dev, mdio);
++}
++
+ static inline struct mdio_device *of_mdio_find_device(struct device_node *np)
+ {
+ 	return NULL;
+diff --git a/include/linux/wait.h b/include/linux/wait.h
+index fe10e8570a522..6598ae35e1b5a 100644
+--- a/include/linux/wait.h
++++ b/include/linux/wait.h
+@@ -1136,7 +1136,7 @@ do {										\
+  * Waitqueues which are removed from the waitqueue_head at wakeup time
+  */
+ void prepare_to_wait(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state);
+-void prepare_to_wait_exclusive(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state);
++bool prepare_to_wait_exclusive(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state);
+ long prepare_to_wait_event(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state);
+ void finish_wait(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry);
+ long wait_woken(struct wait_queue_entry *wq_entry, unsigned mode, long timeout);
+diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
+index d0e9a5bdb08bb..6078dd29f3e77 100644
+--- a/include/media/v4l2-subdev.h
++++ b/include/media/v4l2-subdev.h
+@@ -162,6 +162,9 @@ struct v4l2_subdev_io_pin_config {
+  * @s_gpio: set GPIO pins. Very simple right now, might need to be extended with
+  *	a direction argument if needed.
+  *
++ * @command: called by in-kernel drivers in order to call functions internal
++ *	   to subdev drivers driver that have a separate callback.
++ *
+  * @ioctl: called at the end of ioctl() syscall handler at the V4L2 core.
+  *	   used to provide support for private ioctls used on the driver.
+  *
+@@ -193,6 +196,7 @@ struct v4l2_subdev_core_ops {
+ 	int (*load_fw)(struct v4l2_subdev *sd);
+ 	int (*reset)(struct v4l2_subdev *sd, u32 val);
+ 	int (*s_gpio)(struct v4l2_subdev *sd, u32 val);
++	long (*command)(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
+ 	long (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
+ #ifdef CONFIG_COMPAT
+ 	long (*compat_ioctl32)(struct v4l2_subdev *sd, unsigned int cmd,
+diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h
+index dc5c1e69cd9f2..69c9eabf83252 100644
+--- a/include/net/flow_offload.h
++++ b/include/net/flow_offload.h
+@@ -319,12 +319,14 @@ flow_action_mixed_hw_stats_check(const struct flow_action *action,
+ 	if (flow_offload_has_one_action(action))
+ 		return true;
+ 
+-	flow_action_for_each(i, action_entry, action) {
+-		if (i && action_entry->hw_stats != last_hw_stats) {
+-			NL_SET_ERR_MSG_MOD(extack, "Mixing HW stats types for actions is not supported");
+-			return false;
++	if (action) {
++		flow_action_for_each(i, action_entry, action) {
++			if (i && action_entry->hw_stats != last_hw_stats) {
++				NL_SET_ERR_MSG_MOD(extack, "Mixing HW stats types for actions is not supported");
++				return false;
++			}
++			last_hw_stats = action_entry->hw_stats;
+ 		}
+-		last_hw_stats = action_entry->hw_stats;
+ 	}
+ 	return true;
+ }
+diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
+index 1aa585216f34b..d49593c72a555 100644
+--- a/include/net/sctp/structs.h
++++ b/include/net/sctp/structs.h
+@@ -461,7 +461,7 @@ struct sctp_af {
+ 					 int saddr);
+ 	void		(*from_sk)	(union sctp_addr *,
+ 					 struct sock *sk);
+-	void		(*from_addr_param) (union sctp_addr *,
++	bool		(*from_addr_param) (union sctp_addr *,
+ 					    union sctp_addr_param *,
+ 					    __be16 port, int iif);
+ 	int		(*to_addr_param) (const union sctp_addr *,
+diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h
+index 4dcd13d097a9e..d588c244ec2fa 100644
+--- a/include/uapi/asm-generic/socket.h
++++ b/include/uapi/asm-generic/socket.h
+@@ -122,6 +122,8 @@
+ #define SO_PREFER_BUSY_POLL	69
+ #define SO_BUSY_POLL_BUDGET	70
+ 
++#define SO_NETNS_COOKIE		71
++
+ #if !defined(__KERNEL__)
+ 
+ #if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))
+diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
+index cfef6b08169a1..67aa7134b3019 100644
+--- a/include/uapi/linux/ethtool.h
++++ b/include/uapi/linux/ethtool.h
+@@ -233,7 +233,7 @@ enum tunable_id {
+ 	ETHTOOL_PFC_PREVENTION_TOUT, /* timeout in msecs */
+ 	/*
+ 	 * Add your fresh new tunable attribute above and remember to update
+-	 * tunable_strings[] in net/core/ethtool.c
++	 * tunable_strings[] in net/ethtool/common.c
+ 	 */
+ 	__ETHTOOL_TUNABLE_COUNT,
+ };
+@@ -297,7 +297,7 @@ enum phy_tunable_id {
+ 	ETHTOOL_PHY_EDPD,
+ 	/*
+ 	 * Add your fresh new phy tunable attribute above and remember to update
+-	 * phy_tunable_strings[] in net/core/ethtool.c
++	 * phy_tunable_strings[] in net/ethtool/common.c
+ 	 */
+ 	__ETHTOOL_PHY_TUNABLE_COUNT,
+ };
+diff --git a/include/uapi/linux/icmp.h b/include/uapi/linux/icmp.h
+index c1da8244c5e18..163c0998aec9e 100644
+--- a/include/uapi/linux/icmp.h
++++ b/include/uapi/linux/icmp.h
+@@ -20,7 +20,6 @@
+ 
+ #include <linux/types.h>
+ #include <asm/byteorder.h>
+-#include <linux/in.h>
+ #include <linux/if.h>
+ #include <linux/in6.h>
+ 
+@@ -154,7 +153,7 @@ struct icmp_ext_echo_iio {
+ 		struct {
+ 			struct icmp_ext_echo_ctype3_hdr ctype3_hdr;
+ 			union {
+-				struct in_addr	ipv4_addr;
++				__be32		ipv4_addr;
+ 				struct in6_addr	ipv6_addr;
+ 			} ip_addr;
+ 		} addr;
+diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
+index 5e31ee9f75129..034ad93a1ad71 100644
+--- a/kernel/bpf/core.c
++++ b/kernel/bpf/core.c
+@@ -1392,29 +1392,54 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn)
+ select_insn:
+ 	goto *jumptable[insn->code];
+ 
+-	/* ALU */
+-#define ALU(OPCODE, OP)			\
+-	ALU64_##OPCODE##_X:		\
+-		DST = DST OP SRC;	\
+-		CONT;			\
+-	ALU_##OPCODE##_X:		\
+-		DST = (u32) DST OP (u32) SRC;	\
+-		CONT;			\
+-	ALU64_##OPCODE##_K:		\
+-		DST = DST OP IMM;		\
+-		CONT;			\
+-	ALU_##OPCODE##_K:		\
+-		DST = (u32) DST OP (u32) IMM;	\
++	/* Explicitly mask the register-based shift amounts with 63 or 31
++	 * to avoid undefined behavior. Normally this won't affect the
++	 * generated code, for example, in case of native 64 bit archs such
++	 * as x86-64 or arm64, the compiler is optimizing the AND away for
++	 * the interpreter. In case of JITs, each of the JIT backends compiles
++	 * the BPF shift operations to machine instructions which produce
++	 * implementation-defined results in such a case; the resulting
++	 * contents of the register may be arbitrary, but program behaviour
++	 * as a whole remains defined. In other words, in case of JIT backends,
++	 * the AND must /not/ be added to the emitted LSH/RSH/ARSH translation.
++	 */
++	/* ALU (shifts) */
++#define SHT(OPCODE, OP)					\
++	ALU64_##OPCODE##_X:				\
++		DST = DST OP (SRC & 63);		\
++		CONT;					\
++	ALU_##OPCODE##_X:				\
++		DST = (u32) DST OP ((u32) SRC & 31);	\
++		CONT;					\
++	ALU64_##OPCODE##_K:				\
++		DST = DST OP IMM;			\
++		CONT;					\
++	ALU_##OPCODE##_K:				\
++		DST = (u32) DST OP (u32) IMM;		\
++		CONT;
++	/* ALU (rest) */
++#define ALU(OPCODE, OP)					\
++	ALU64_##OPCODE##_X:				\
++		DST = DST OP SRC;			\
++		CONT;					\
++	ALU_##OPCODE##_X:				\
++		DST = (u32) DST OP (u32) SRC;		\
++		CONT;					\
++	ALU64_##OPCODE##_K:				\
++		DST = DST OP IMM;			\
++		CONT;					\
++	ALU_##OPCODE##_K:				\
++		DST = (u32) DST OP (u32) IMM;		\
+ 		CONT;
+-
+ 	ALU(ADD,  +)
+ 	ALU(SUB,  -)
+ 	ALU(AND,  &)
+ 	ALU(OR,   |)
+-	ALU(LSH, <<)
+-	ALU(RSH, >>)
+ 	ALU(XOR,  ^)
+ 	ALU(MUL,  *)
++	SHT(LSH, <<)
++	SHT(RSH, >>)
++#undef SHT
+ #undef ALU
+ 	ALU_NEG:
+ 		DST = (u32) -DST;
+@@ -1439,13 +1464,13 @@ select_insn:
+ 		insn++;
+ 		CONT;
+ 	ALU_ARSH_X:
+-		DST = (u64) (u32) (((s32) DST) >> SRC);
++		DST = (u64) (u32) (((s32) DST) >> (SRC & 31));
+ 		CONT;
+ 	ALU_ARSH_K:
+ 		DST = (u64) (u32) (((s32) DST) >> IMM);
+ 		CONT;
+ 	ALU64_ARSH_X:
+-		(*(s64 *) &DST) >>= SRC;
++		(*(s64 *) &DST) >>= (SRC & 63);
+ 		CONT;
+ 	ALU64_ARSH_K:
+ 		(*(s64 *) &DST) >>= IMM;
+diff --git a/kernel/bpf/ringbuf.c b/kernel/bpf/ringbuf.c
+index 84b3b35fc0d05..9e0c10c6892ad 100644
+--- a/kernel/bpf/ringbuf.c
++++ b/kernel/bpf/ringbuf.c
+@@ -8,6 +8,7 @@
+ #include <linux/vmalloc.h>
+ #include <linux/wait.h>
+ #include <linux/poll.h>
++#include <linux/kmemleak.h>
+ #include <uapi/linux/btf.h>
+ 
+ #define RINGBUF_CREATE_FLAG_MASK (BPF_F_NUMA_NODE)
+@@ -105,6 +106,7 @@ static struct bpf_ringbuf *bpf_ringbuf_area_alloc(size_t data_sz, int numa_node)
+ 	rb = vmap(pages, nr_meta_pages + 2 * nr_data_pages,
+ 		  VM_ALLOC | VM_USERMAP, PAGE_KERNEL);
+ 	if (rb) {
++		kmemleak_not_leak(pages);
+ 		rb->pages = pages;
+ 		rb->nr_pages = nr_pages;
+ 		return rb;
+diff --git a/kernel/cpu.c b/kernel/cpu.c
+index e538518556f47..d2e1692d7bdf8 100644
+--- a/kernel/cpu.c
++++ b/kernel/cpu.c
+@@ -32,6 +32,7 @@
+ #include <linux/relay.h>
+ #include <linux/slab.h>
+ #include <linux/percpu-rwsem.h>
++#include <linux/cpuset.h>
+ 
+ #include <trace/events/power.h>
+ #define CREATE_TRACE_POINTS
+@@ -873,6 +874,52 @@ void __init cpuhp_threads_init(void)
+ 	kthread_unpark(this_cpu_read(cpuhp_state.thread));
+ }
+ 
++/*
++ *
++ * Serialize hotplug trainwrecks outside of the cpu_hotplug_lock
++ * protected region.
++ *
++ * The operation is still serialized against concurrent CPU hotplug via
++ * cpu_add_remove_lock, i.e. CPU map protection.  But it is _not_
++ * serialized against other hotplug related activity like adding or
++ * removing of state callbacks and state instances, which invoke either the
++ * startup or the teardown callback of the affected state.
++ *
++ * This is required for subsystems which are unfixable vs. CPU hotplug and
++ * evade lock inversion problems by scheduling work which has to be
++ * completed _before_ cpu_up()/_cpu_down() returns.
++ *
++ * Don't even think about adding anything to this for any new code or even
++ * drivers. It's only purpose is to keep existing lock order trainwrecks
++ * working.
++ *
++ * For cpu_down() there might be valid reasons to finish cleanups which are
++ * not required to be done under cpu_hotplug_lock, but that's a different
++ * story and would be not invoked via this.
++ */
++static void cpu_up_down_serialize_trainwrecks(bool tasks_frozen)
++{
++	/*
++	 * cpusets delegate hotplug operations to a worker to "solve" the
++	 * lock order problems. Wait for the worker, but only if tasks are
++	 * _not_ frozen (suspend, hibernate) as that would wait forever.
++	 *
++	 * The wait is required because otherwise the hotplug operation
++	 * returns with inconsistent state, which could even be observed in
++	 * user space when a new CPU is brought up. The CPU plug uevent
++	 * would be delivered and user space reacting on it would fail to
++	 * move tasks to the newly plugged CPU up to the point where the
++	 * work has finished because up to that point the newly plugged CPU
++	 * is not assignable in cpusets/cgroups. On unplug that's not
++	 * necessarily a visible issue, but it is still inconsistent state,
++	 * which is the real problem which needs to be "fixed". This can't
++	 * prevent the transient state between scheduling the work and
++	 * returning from waiting for it.
++	 */
++	if (!tasks_frozen)
++		cpuset_wait_for_hotplug();
++}
++
+ #ifdef CONFIG_HOTPLUG_CPU
+ #ifndef arch_clear_mm_cpumask_cpu
+ #define arch_clear_mm_cpumask_cpu(cpu, mm) cpumask_clear_cpu(cpu, mm_cpumask(mm))
+@@ -1108,6 +1155,7 @@ out:
+ 	 */
+ 	lockup_detector_cleanup();
+ 	arch_smt_update();
++	cpu_up_down_serialize_trainwrecks(tasks_frozen);
+ 	return ret;
+ }
+ 
+@@ -1302,6 +1350,7 @@ static int _cpu_up(unsigned int cpu, int tasks_frozen, enum cpuhp_state target)
+ out:
+ 	cpus_write_unlock();
+ 	arch_smt_update();
++	cpu_up_down_serialize_trainwrecks(tasks_frozen);
+ 	return ret;
+ }
+ 
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index e807b743353d1..7dd0d859d95bb 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -3716,15 +3716,15 @@ update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq)
+ 
+ 		r = removed_load;
+ 		sub_positive(&sa->load_avg, r);
+-		sub_positive(&sa->load_sum, r * divider);
++		sa->load_sum = sa->load_avg * divider;
+ 
+ 		r = removed_util;
+ 		sub_positive(&sa->util_avg, r);
+-		sub_positive(&sa->util_sum, r * divider);
++		sa->util_sum = sa->util_avg * divider;
+ 
+ 		r = removed_runnable;
+ 		sub_positive(&sa->runnable_avg, r);
+-		sub_positive(&sa->runnable_sum, r * divider);
++		sa->runnable_sum = sa->runnable_avg * divider;
+ 
+ 		/*
+ 		 * removed_runnable is the unweighted version of removed_load so we
+diff --git a/kernel/sched/wait.c b/kernel/sched/wait.c
+index 183cc6ae68a68..76577d1642a5d 100644
+--- a/kernel/sched/wait.c
++++ b/kernel/sched/wait.c
+@@ -264,17 +264,22 @@ prepare_to_wait(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_ent
+ }
+ EXPORT_SYMBOL(prepare_to_wait);
+ 
+-void
++/* Returns true if we are the first waiter in the queue, false otherwise. */
++bool
+ prepare_to_wait_exclusive(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state)
+ {
+ 	unsigned long flags;
++	bool was_empty = false;
+ 
+ 	wq_entry->flags |= WQ_FLAG_EXCLUSIVE;
+ 	spin_lock_irqsave(&wq_head->lock, flags);
+-	if (list_empty(&wq_entry->entry))
++	if (list_empty(&wq_entry->entry)) {
++		was_empty = list_empty(&wq_head->head);
+ 		__add_wait_queue_entry_tail(wq_head, wq_entry);
++	}
+ 	set_current_state(state);
+ 	spin_unlock_irqrestore(&wq_head->lock, flags);
++	return was_empty;
+ }
+ EXPORT_SYMBOL(prepare_to_wait_exclusive);
+ 
+diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
+index d23a09d3eb37b..1afd3b57ae517 100644
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -2184,8 +2184,15 @@ void tracing_reset_all_online_cpus(void)
+ 	}
+ }
+ 
++/*
++ * The tgid_map array maps from pid to tgid; i.e. the value stored at index i
++ * is the tgid last observed corresponding to pid=i.
++ */
+ static int *tgid_map;
+ 
++/* The maximum valid index into tgid_map. */
++static size_t tgid_map_max;
++
+ #define SAVED_CMDLINES_DEFAULT 128
+ #define NO_CMDLINE_MAP UINT_MAX
+ static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED;
+@@ -2458,24 +2465,41 @@ void trace_find_cmdline(int pid, char comm[])
+ 	preempt_enable();
+ }
+ 
++static int *trace_find_tgid_ptr(int pid)
++{
++	/*
++	 * Pairs with the smp_store_release in set_tracer_flag() to ensure that
++	 * if we observe a non-NULL tgid_map then we also observe the correct
++	 * tgid_map_max.
++	 */
++	int *map = smp_load_acquire(&tgid_map);
++
++	if (unlikely(!map || pid > tgid_map_max))
++		return NULL;
++
++	return &map[pid];
++}
++
+ int trace_find_tgid(int pid)
+ {
+-	if (unlikely(!tgid_map || !pid || pid > PID_MAX_DEFAULT))
+-		return 0;
++	int *ptr = trace_find_tgid_ptr(pid);
+ 
+-	return tgid_map[pid];
++	return ptr ? *ptr : 0;
+ }
+ 
+ static int trace_save_tgid(struct task_struct *tsk)
+ {
++	int *ptr;
++
+ 	/* treat recording of idle task as a success */
+ 	if (!tsk->pid)
+ 		return 1;
+ 
+-	if (unlikely(!tgid_map || tsk->pid > PID_MAX_DEFAULT))
++	ptr = trace_find_tgid_ptr(tsk->pid);
++	if (!ptr)
+ 		return 0;
+ 
+-	tgid_map[tsk->pid] = tsk->tgid;
++	*ptr = tsk->tgid;
+ 	return 1;
+ }
+ 
+@@ -5171,6 +5195,8 @@ int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set)
+ 
+ int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled)
+ {
++	int *map;
++
+ 	if ((mask == TRACE_ITER_RECORD_TGID) ||
+ 	    (mask == TRACE_ITER_RECORD_CMD))
+ 		lockdep_assert_held(&event_mutex);
+@@ -5193,10 +5219,19 @@ int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled)
+ 		trace_event_enable_cmd_record(enabled);
+ 
+ 	if (mask == TRACE_ITER_RECORD_TGID) {
+-		if (!tgid_map)
+-			tgid_map = kvcalloc(PID_MAX_DEFAULT + 1,
+-					   sizeof(*tgid_map),
+-					   GFP_KERNEL);
++		if (!tgid_map) {
++			tgid_map_max = pid_max;
++			map = kvcalloc(tgid_map_max + 1, sizeof(*tgid_map),
++				       GFP_KERNEL);
++
++			/*
++			 * Pairs with smp_load_acquire() in
++			 * trace_find_tgid_ptr() to ensure that if it observes
++			 * the tgid_map we just allocated then it also observes
++			 * the corresponding tgid_map_max value.
++			 */
++			smp_store_release(&tgid_map, map);
++		}
+ 		if (!tgid_map) {
+ 			tr->trace_flags &= ~TRACE_ITER_RECORD_TGID;
+ 			return -ENOMEM;
+@@ -5608,37 +5643,16 @@ static const struct file_operations tracing_readme_fops = {
+ 
+ static void *saved_tgids_next(struct seq_file *m, void *v, loff_t *pos)
+ {
+-	int *ptr = v;
++	int pid = ++(*pos);
+ 
+-	if (*pos || m->count)
+-		ptr++;
+-
+-	(*pos)++;
+-
+-	for (; ptr <= &tgid_map[PID_MAX_DEFAULT]; ptr++) {
+-		if (trace_find_tgid(*ptr))
+-			return ptr;
+-	}
+-
+-	return NULL;
++	return trace_find_tgid_ptr(pid);
+ }
+ 
+ static void *saved_tgids_start(struct seq_file *m, loff_t *pos)
+ {
+-	void *v;
+-	loff_t l = 0;
++	int pid = *pos;
+ 
+-	if (!tgid_map)
+-		return NULL;
+-
+-	v = &tgid_map[0];
+-	while (l <= *pos) {
+-		v = saved_tgids_next(m, v, &l);
+-		if (!v)
+-			return NULL;
+-	}
+-
+-	return v;
++	return trace_find_tgid_ptr(pid);
+ }
+ 
+ static void saved_tgids_stop(struct seq_file *m, void *v)
+@@ -5647,9 +5661,14 @@ static void saved_tgids_stop(struct seq_file *m, void *v)
+ 
+ static int saved_tgids_show(struct seq_file *m, void *v)
+ {
+-	int pid = (int *)v - tgid_map;
++	int *entry = (int *)v;
++	int pid = entry - tgid_map;
++	int tgid = *entry;
++
++	if (tgid == 0)
++		return SEQ_SKIP;
+ 
+-	seq_printf(m, "%d %d\n", pid, trace_find_tgid(pid));
++	seq_printf(m, "%d %d\n", pid, tgid);
+ 	return 0;
+ }
+ 
+diff --git a/lib/seq_buf.c b/lib/seq_buf.c
+index 89c26c393bdba..6dafde8513337 100644
+--- a/lib/seq_buf.c
++++ b/lib/seq_buf.c
+@@ -229,8 +229,10 @@ int seq_buf_putmem_hex(struct seq_buf *s, const void *mem,
+ 
+ 	WARN_ON(s->size == 0);
+ 
++	BUILD_BUG_ON(MAX_MEMHEX_BYTES * 2 >= HEX_CHARS);
++
+ 	while (len) {
+-		start_len = min(len, HEX_CHARS - 1);
++		start_len = min(len, MAX_MEMHEX_BYTES);
+ #ifdef __BIG_ENDIAN
+ 		for (i = 0, j = 0; i < start_len; i++) {
+ #else
+diff --git a/mm/mremap.c b/mm/mremap.c
+index 47c255b60150b..c0d683fd00ad2 100644
+--- a/mm/mremap.c
++++ b/mm/mremap.c
+@@ -439,7 +439,7 @@ unsigned long move_page_tables(struct vm_area_struct *vma,
+ 			if (!new_pud)
+ 				break;
+ 			if (move_pgt_entry(NORMAL_PUD, vma, old_addr, new_addr,
+-					   old_pud, new_pud, need_rmap_locks))
++					   old_pud, new_pud, true))
+ 				continue;
+ 		}
+ 
+@@ -466,7 +466,7 @@ unsigned long move_page_tables(struct vm_area_struct *vma,
+ 			 * moving at the PMD level if possible.
+ 			 */
+ 			if (move_pgt_entry(NORMAL_PMD, vma, old_addr, new_addr,
+-					   old_pmd, new_pmd, need_rmap_locks))
++					   old_pmd, new_pmd, true))
+ 				continue;
+ 		}
+ 
+diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c
+index 07cfa3249f83a..0a2d78e811cf5 100644
+--- a/net/bluetooth/cmtp/core.c
++++ b/net/bluetooth/cmtp/core.c
+@@ -392,6 +392,11 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
+ 	if (!(session->flags & BIT(CMTP_LOOPBACK))) {
+ 		err = cmtp_attach_device(session);
+ 		if (err < 0) {
++			/* Caller will call fput in case of failure, and so
++			 * will cmtp_session kthread.
++			 */
++			get_file(session->sock->file);
++
+ 			atomic_inc(&session->terminate);
+ 			wake_up_interruptible(sk_sleep(session->sock->sk));
+ 			up_write(&cmtp_session_sem);
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index 7d71d104fdfda..ded55f54d9c8e 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -1721,14 +1721,6 @@ int hci_dev_do_close(struct hci_dev *hdev)
+ 
+ 	BT_DBG("%s %p", hdev->name, hdev);
+ 
+-	if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) &&
+-	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
+-	    test_bit(HCI_UP, &hdev->flags)) {
+-		/* Execute vendor specific shutdown routine */
+-		if (hdev->shutdown)
+-			hdev->shutdown(hdev);
+-	}
+-
+ 	cancel_delayed_work(&hdev->power_off);
+ 
+ 	hci_request_cancel_all(hdev);
+@@ -1805,6 +1797,14 @@ int hci_dev_do_close(struct hci_dev *hdev)
+ 		clear_bit(HCI_INIT, &hdev->flags);
+ 	}
+ 
++	if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) &&
++	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
++	    test_bit(HCI_UP, &hdev->flags)) {
++		/* Execute vendor specific shutdown routine */
++		if (hdev->shutdown)
++			hdev->shutdown(hdev);
++	}
++
+ 	/* flush cmd  work */
+ 	flush_work(&hdev->cmd_work);
+ 
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index b077d150ac529..62c99e015609d 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -4404,12 +4404,12 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
+ 
+ 	bt_dev_dbg(hdev, "SCO connected with air mode: %02x", ev->air_mode);
+ 
+-	switch (conn->setting & SCO_AIRMODE_MASK) {
+-	case SCO_AIRMODE_CVSD:
++	switch (ev->air_mode) {
++	case 0x02:
+ 		if (hdev->notify)
+ 			hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
+ 		break;
+-	case SCO_AIRMODE_TRANSP:
++	case 0x03:
+ 		if (hdev->notify)
+ 			hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
+ 		break;
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index b6a88b8256c77..9908aa53a682f 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -6066,7 +6066,7 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+ 	struct l2cap_ecred_conn_rsp *rsp = (void *) data;
+ 	struct hci_conn *hcon = conn->hcon;
+ 	u16 mtu, mps, credits, result;
+-	struct l2cap_chan *chan;
++	struct l2cap_chan *chan, *tmp;
+ 	int err = 0, sec_level;
+ 	int i = 0;
+ 
+@@ -6085,7 +6085,7 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+ 
+ 	cmd_len -= sizeof(*rsp);
+ 
+-	list_for_each_entry(chan, &conn->chan_l, list) {
++	list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
+ 		u16 dcid;
+ 
+ 		if (chan->ident != cmd->ident ||
+@@ -6248,7 +6248,7 @@ static inline int l2cap_ecred_reconf_rsp(struct l2cap_conn *conn,
+ 					 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+ 					 u8 *data)
+ {
+-	struct l2cap_chan *chan;
++	struct l2cap_chan *chan, *tmp;
+ 	struct l2cap_ecred_conn_rsp *rsp = (void *) data;
+ 	u16 result;
+ 
+@@ -6262,7 +6262,7 @@ static inline int l2cap_ecred_reconf_rsp(struct l2cap_conn *conn,
+ 	if (!result)
+ 		return 0;
+ 
+-	list_for_each_entry(chan, &conn->chan_l, list) {
++	list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
+ 		if (chan->ident != cmd->ident)
+ 			continue;
+ 
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 023a98f7c9922..470eaabb021f9 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -252,12 +252,15 @@ static const u8 mgmt_status_table[] = {
+ 	MGMT_STATUS_TIMEOUT,		/* Instant Passed */
+ 	MGMT_STATUS_NOT_SUPPORTED,	/* Pairing Not Supported */
+ 	MGMT_STATUS_FAILED,		/* Transaction Collision */
++	MGMT_STATUS_FAILED,		/* Reserved for future use */
+ 	MGMT_STATUS_INVALID_PARAMS,	/* Unacceptable Parameter */
+ 	MGMT_STATUS_REJECTED,		/* QoS Rejected */
+ 	MGMT_STATUS_NOT_SUPPORTED,	/* Classification Not Supported */
+ 	MGMT_STATUS_REJECTED,		/* Insufficient Security */
+ 	MGMT_STATUS_INVALID_PARAMS,	/* Parameter Out Of Range */
++	MGMT_STATUS_FAILED,		/* Reserved for future use */
+ 	MGMT_STATUS_BUSY,		/* Role Switch Pending */
++	MGMT_STATUS_FAILED,		/* Reserved for future use */
+ 	MGMT_STATUS_FAILED,		/* Slot Violation */
+ 	MGMT_STATUS_FAILED,		/* Role Switch Failed */
+ 	MGMT_STATUS_INVALID_PARAMS,	/* EIR Too Large */
+@@ -4058,6 +4061,8 @@ static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
+ 
+ 	hci_dev_lock(hdev);
+ 
++	memset(&rp, 0, sizeof(rp));
++
+ 	if (cp->addr.type == BDADDR_BREDR) {
+ 		br_params = hci_bdaddr_list_lookup_with_flags(&hdev->whitelist,
+ 							      &cp->addr.bdaddr,
+diff --git a/net/bridge/br_mrp.c b/net/bridge/br_mrp.c
+index cd2b1e424e54e..f7012b7d7ce40 100644
+--- a/net/bridge/br_mrp.c
++++ b/net/bridge/br_mrp.c
+@@ -627,8 +627,7 @@ int br_mrp_set_ring_state(struct net_bridge *br,
+ 	if (!mrp)
+ 		return -EINVAL;
+ 
+-	if (mrp->ring_state == BR_MRP_RING_STATE_CLOSED &&
+-	    state->ring_state != BR_MRP_RING_STATE_CLOSED)
++	if (mrp->ring_state != state->ring_state)
+ 		mrp->ring_transitions++;
+ 
+ 	mrp->ring_state = state->ring_state;
+@@ -715,8 +714,7 @@ int br_mrp_set_in_state(struct net_bridge *br, struct br_mrp_in_state *state)
+ 	if (!mrp)
+ 		return -EINVAL;
+ 
+-	if (mrp->in_state == BR_MRP_IN_STATE_CLOSED &&
+-	    state->in_state != BR_MRP_IN_STATE_CLOSED)
++	if (mrp->in_state != state->in_state)
+ 		mrp->in_transitions++;
+ 
+ 	mrp->in_state = state->in_state;
+diff --git a/net/core/dev.c b/net/core/dev.c
+index ef8cf7619bafa..50531a2d0b20d 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -6520,11 +6520,18 @@ EXPORT_SYMBOL(napi_schedule_prep);
+  * __napi_schedule_irqoff - schedule for receive
+  * @n: entry to schedule
+  *
+- * Variant of __napi_schedule() assuming hard irqs are masked
++ * Variant of __napi_schedule() assuming hard irqs are masked.
++ *
++ * On PREEMPT_RT enabled kernels this maps to __napi_schedule()
++ * because the interrupt disabled assumption might not be true
++ * due to force-threaded interrupts and spinlock substitution.
+  */
+ void __napi_schedule_irqoff(struct napi_struct *n)
+ {
+-	____napi_schedule(this_cpu_ptr(&softnet_data), n);
++	if (!IS_ENABLED(CONFIG_PREEMPT_RT))
++		____napi_schedule(this_cpu_ptr(&softnet_data), n);
++	else
++		__napi_schedule(n);
+ }
+ EXPORT_SYMBOL(__napi_schedule_irqoff);
+ 
+diff --git a/net/core/sock.c b/net/core/sock.c
+index 946888afef880..2003c5ebb4c2e 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -1622,6 +1622,13 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
+ 		v.val = sk->sk_bound_dev_if;
+ 		break;
+ 
++	case SO_NETNS_COOKIE:
++		lv = sizeof(u64);
++		if (len != lv)
++			return -EINVAL;
++		v.val64 = sock_net(sk)->net_cookie;
++		break;
++
+ 	default:
+ 		/* We implement the SO_SNDLOWAT etc to not be settable
+ 		 * (1003.1g 7).
+diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c
+index bb1351c38397f..e31949479305e 100644
+--- a/net/hsr/hsr_framereg.c
++++ b/net/hsr/hsr_framereg.c
+@@ -397,7 +397,8 @@ void hsr_register_frame_in(struct hsr_node *node, struct hsr_port *port,
+ 	 * ensures entries of restarted nodes gets pruned so that they can
+ 	 * re-register and resume communications.
+ 	 */
+-	if (seq_nr_before(sequence_nr, node->seq_out[port->type]))
++	if (!(port->dev->features & NETIF_F_HW_HSR_TAG_RM) &&
++	    seq_nr_before(sequence_nr, node->seq_out[port->type]))
+ 		return;
+ 
+ 	node->time_in[port->type] = jiffies;
+diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
+index 752e392083e64..0a57f1892e7e0 100644
+--- a/net/ipv4/icmp.c
++++ b/net/ipv4/icmp.c
+@@ -1066,7 +1066,7 @@ static bool icmp_echo(struct sk_buff *skb)
+ 			if (ident_len != sizeof(iio->ident.addr.ctype3_hdr) +
+ 					 sizeof(struct in_addr))
+ 				goto send_mal_query;
+-			dev = ip_dev_find(net, iio->ident.addr.ip_addr.ipv4_addr.s_addr);
++			dev = ip_dev_find(net, iio->ident.addr.ip_addr.ipv4_addr);
+ 			break;
+ #if IS_ENABLED(CONFIG_IPV6)
+ 		case ICMP_AFI_IP6:
+diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
+index c3efc7d658f6c..8d8a8da3ae7e0 100644
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -1054,7 +1054,7 @@ static int __ip_append_data(struct sock *sk,
+ 			unsigned int datalen;
+ 			unsigned int fraglen;
+ 			unsigned int fraggap;
+-			unsigned int alloclen;
++			unsigned int alloclen, alloc_extra;
+ 			unsigned int pagedlen;
+ 			struct sk_buff *skb_prev;
+ alloc_new_skb:
+@@ -1074,35 +1074,39 @@ alloc_new_skb:
+ 			fraglen = datalen + fragheaderlen;
+ 			pagedlen = 0;
+ 
++			alloc_extra = hh_len + 15;
++			alloc_extra += exthdrlen;
++
++			/* The last fragment gets additional space at tail.
++			 * Note, with MSG_MORE we overallocate on fragments,
++			 * because we have no idea what fragment will be
++			 * the last.
++			 */
++			if (datalen == length + fraggap)
++				alloc_extra += rt->dst.trailer_len;
++
+ 			if ((flags & MSG_MORE) &&
+ 			    !(rt->dst.dev->features&NETIF_F_SG))
+ 				alloclen = mtu;
+-			else if (!paged)
++			else if (!paged &&
++				 (fraglen + alloc_extra < SKB_MAX_ALLOC ||
++				  !(rt->dst.dev->features & NETIF_F_SG)))
+ 				alloclen = fraglen;
+ 			else {
+ 				alloclen = min_t(int, fraglen, MAX_HEADER);
+ 				pagedlen = fraglen - alloclen;
+ 			}
+ 
+-			alloclen += exthdrlen;
+-
+-			/* The last fragment gets additional space at tail.
+-			 * Note, with MSG_MORE we overallocate on fragments,
+-			 * because we have no idea what fragment will be
+-			 * the last.
+-			 */
+-			if (datalen == length + fraggap)
+-				alloclen += rt->dst.trailer_len;
++			alloclen += alloc_extra;
+ 
+ 			if (transhdrlen) {
+-				skb = sock_alloc_send_skb(sk,
+-						alloclen + hh_len + 15,
++				skb = sock_alloc_send_skb(sk, alloclen,
+ 						(flags & MSG_DONTWAIT), &err);
+ 			} else {
+ 				skb = NULL;
+ 				if (refcount_read(&sk->sk_wmem_alloc) + wmem_alloc_delta <=
+ 				    2 * sk->sk_sndbuf)
+-					skb = alloc_skb(alloclen + hh_len + 15,
++					skb = alloc_skb(alloclen,
+ 							sk->sk_allocation);
+ 				if (unlikely(!skb))
+ 					err = -ENOBUFS;
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index 4cf4dd532d1c6..bc266514ce589 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -2816,8 +2816,17 @@ static void tcp_process_loss(struct sock *sk, int flag, int num_dupack,
+ 	*rexmit = REXMIT_LOST;
+ }
+ 
++static bool tcp_force_fast_retransmit(struct sock *sk)
++{
++	struct tcp_sock *tp = tcp_sk(sk);
++
++	return after(tcp_highest_sack_seq(tp),
++		     tp->snd_una + tp->reordering * tp->mss_cache);
++}
++
+ /* Undo during fast recovery after partial ACK. */
+-static bool tcp_try_undo_partial(struct sock *sk, u32 prior_snd_una)
++static bool tcp_try_undo_partial(struct sock *sk, u32 prior_snd_una,
++				 bool *do_lost)
+ {
+ 	struct tcp_sock *tp = tcp_sk(sk);
+ 
+@@ -2842,7 +2851,9 @@ static bool tcp_try_undo_partial(struct sock *sk, u32 prior_snd_una)
+ 		tcp_undo_cwnd_reduction(sk, true);
+ 		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPPARTIALUNDO);
+ 		tcp_try_keep_open(sk);
+-		return true;
++	} else {
++		/* Partial ACK arrived. Force fast retransmit. */
++		*do_lost = tcp_force_fast_retransmit(sk);
+ 	}
+ 	return false;
+ }
+@@ -2866,14 +2877,6 @@ static void tcp_identify_packet_loss(struct sock *sk, int *ack_flag)
+ 	}
+ }
+ 
+-static bool tcp_force_fast_retransmit(struct sock *sk)
+-{
+-	struct tcp_sock *tp = tcp_sk(sk);
+-
+-	return after(tcp_highest_sack_seq(tp),
+-		     tp->snd_una + tp->reordering * tp->mss_cache);
+-}
+-
+ /* Process an event, which can update packets-in-flight not trivially.
+  * Main goal of this function is to calculate new estimate for left_out,
+  * taking into account both packets sitting in receiver's buffer and
+@@ -2943,17 +2946,21 @@ static void tcp_fastretrans_alert(struct sock *sk, const u32 prior_snd_una,
+ 		if (!(flag & FLAG_SND_UNA_ADVANCED)) {
+ 			if (tcp_is_reno(tp))
+ 				tcp_add_reno_sack(sk, num_dupack, ece_ack);
+-		} else {
+-			if (tcp_try_undo_partial(sk, prior_snd_una))
+-				return;
+-			/* Partial ACK arrived. Force fast retransmit. */
+-			do_lost = tcp_force_fast_retransmit(sk);
+-		}
+-		if (tcp_try_undo_dsack(sk)) {
+-			tcp_try_keep_open(sk);
++		} else if (tcp_try_undo_partial(sk, prior_snd_una, &do_lost))
+ 			return;
+-		}
++
++		if (tcp_try_undo_dsack(sk))
++			tcp_try_keep_open(sk);
++
+ 		tcp_identify_packet_loss(sk, ack_flag);
++		if (icsk->icsk_ca_state != TCP_CA_Recovery) {
++			if (!tcp_time_to_recover(sk, flag))
++				return;
++			/* Undo reverts the recovery state. If loss is evident,
++			 * starts a new recovery (e.g. reordering then loss);
++			 */
++			tcp_enter_recovery(sk, ece_ack);
++		}
+ 		break;
+ 	case TCP_CA_Loss:
+ 		tcp_process_loss(sk, flag, num_dupack, rexmit);
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index ff4f9ebcf7f65..497974b4372a7 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -1555,7 +1555,7 @@ emsgsize:
+ 			unsigned int datalen;
+ 			unsigned int fraglen;
+ 			unsigned int fraggap;
+-			unsigned int alloclen;
++			unsigned int alloclen, alloc_extra;
+ 			unsigned int pagedlen;
+ alloc_new_skb:
+ 			/* There's no room in the current skb */
+@@ -1582,17 +1582,28 @@ alloc_new_skb:
+ 			fraglen = datalen + fragheaderlen;
+ 			pagedlen = 0;
+ 
++			alloc_extra = hh_len;
++			alloc_extra += dst_exthdrlen;
++			alloc_extra += rt->dst.trailer_len;
++
++			/* We just reserve space for fragment header.
++			 * Note: this may be overallocation if the message
++			 * (without MSG_MORE) fits into the MTU.
++			 */
++			alloc_extra += sizeof(struct frag_hdr);
++
+ 			if ((flags & MSG_MORE) &&
+ 			    !(rt->dst.dev->features&NETIF_F_SG))
+ 				alloclen = mtu;
+-			else if (!paged)
++			else if (!paged &&
++				 (fraglen + alloc_extra < SKB_MAX_ALLOC ||
++				  !(rt->dst.dev->features & NETIF_F_SG)))
+ 				alloclen = fraglen;
+ 			else {
+ 				alloclen = min_t(int, fraglen, MAX_HEADER);
+ 				pagedlen = fraglen - alloclen;
+ 			}
+-
+-			alloclen += dst_exthdrlen;
++			alloclen += alloc_extra;
+ 
+ 			if (datalen != length + fraggap) {
+ 				/*
+@@ -1602,30 +1613,21 @@ alloc_new_skb:
+ 				datalen += rt->dst.trailer_len;
+ 			}
+ 
+-			alloclen += rt->dst.trailer_len;
+ 			fraglen = datalen + fragheaderlen;
+ 
+-			/*
+-			 * We just reserve space for fragment header.
+-			 * Note: this may be overallocation if the message
+-			 * (without MSG_MORE) fits into the MTU.
+-			 */
+-			alloclen += sizeof(struct frag_hdr);
+-
+ 			copy = datalen - transhdrlen - fraggap - pagedlen;
+ 			if (copy < 0) {
+ 				err = -EINVAL;
+ 				goto error;
+ 			}
+ 			if (transhdrlen) {
+-				skb = sock_alloc_send_skb(sk,
+-						alloclen + hh_len,
++				skb = sock_alloc_send_skb(sk, alloclen,
+ 						(flags & MSG_DONTWAIT), &err);
+ 			} else {
+ 				skb = NULL;
+ 				if (refcount_read(&sk->sk_wmem_alloc) + wmem_alloc_delta <=
+ 				    2 * sk->sk_sndbuf)
+-					skb = alloc_skb(alloclen + hh_len,
++					skb = alloc_skb(alloclen,
+ 							sk->sk_allocation);
+ 				if (unlikely(!skb))
+ 					err = -ENOBUFS;
+diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c
+index af36acc1a6448..2880dc7d9a491 100644
+--- a/net/ipv6/output_core.c
++++ b/net/ipv6/output_core.c
+@@ -15,29 +15,11 @@ static u32 __ipv6_select_ident(struct net *net,
+ 			       const struct in6_addr *dst,
+ 			       const struct in6_addr *src)
+ {
+-	const struct {
+-		struct in6_addr dst;
+-		struct in6_addr src;
+-	} __aligned(SIPHASH_ALIGNMENT) combined = {
+-		.dst = *dst,
+-		.src = *src,
+-	};
+-	u32 hash, id;
+-
+-	/* Note the following code is not safe, but this is okay. */
+-	if (unlikely(siphash_key_is_zero(&net->ipv4.ip_id_key)))
+-		get_random_bytes(&net->ipv4.ip_id_key,
+-				 sizeof(net->ipv4.ip_id_key));
+-
+-	hash = siphash(&combined, sizeof(combined), &net->ipv4.ip_id_key);
+-
+-	/* Treat id of 0 as unset and if we get 0 back from ip_idents_reserve,
+-	 * set the hight order instead thus minimizing possible future
+-	 * collisions.
+-	 */
+-	id = ip_idents_reserve(hash, 1);
+-	if (unlikely(!id))
+-		id = 1 << 31;
++	u32 id;
++
++	do {
++		id = prandom_u32();
++	} while (!id);
+ 
+ 	return id;
+ }
+diff --git a/net/mac80211/main.c b/net/mac80211/main.c
+index f33a3acd7f969..2481bfdfafd09 100644
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -257,14 +257,13 @@ static void ieee80211_restart_work(struct work_struct *work)
+ 	/* wait for scan work complete */
+ 	flush_workqueue(local->workqueue);
+ 	flush_work(&local->sched_scan_stopped_work);
++	flush_work(&local->radar_detected_work);
++
++	rtnl_lock();
+ 
+ 	WARN(test_bit(SCAN_HW_SCANNING, &local->scanning),
+ 	     "%s called with hardware scan in progress\n", __func__);
+ 
+-	flush_work(&local->radar_detected_work);
+-	/* we might do interface manipulations, so need both */
+-	rtnl_lock();
+-	wiphy_lock(local->hw.wiphy);
+ 	list_for_each_entry(sdata, &local->interfaces, list) {
+ 		/*
+ 		 * XXX: there may be more work for other vif types and even
+diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
+index 13250cadb4202..e18c3855f6161 100644
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -2088,10 +2088,9 @@ static struct ieee80211_sta_rx_stats *
+ sta_get_last_rx_stats(struct sta_info *sta)
+ {
+ 	struct ieee80211_sta_rx_stats *stats = &sta->rx_stats;
+-	struct ieee80211_local *local = sta->local;
+ 	int cpu;
+ 
+-	if (!ieee80211_hw_check(&local->hw, USES_RSS))
++	if (!sta->pcpu_rx_stats)
+ 		return stats;
+ 
+ 	for_each_possible_cpu(cpu) {
+@@ -2191,9 +2190,7 @@ static void sta_set_tidstats(struct sta_info *sta,
+ 	int cpu;
+ 
+ 	if (!(tidstats->filled & BIT(NL80211_TID_STATS_RX_MSDU))) {
+-		if (!ieee80211_hw_check(&local->hw, USES_RSS))
+-			tidstats->rx_msdu +=
+-				sta_get_tidstats_msdu(&sta->rx_stats, tid);
++		tidstats->rx_msdu += sta_get_tidstats_msdu(&sta->rx_stats, tid);
+ 
+ 		if (sta->pcpu_rx_stats) {
+ 			for_each_possible_cpu(cpu) {
+@@ -2272,7 +2269,6 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo,
+ 		sinfo->rx_beacon = sdata->u.mgd.count_beacon_signal;
+ 
+ 	drv_sta_statistics(local, sdata, &sta->sta, sinfo);
+-
+ 	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME) |
+ 			 BIT_ULL(NL80211_STA_INFO_STA_FLAGS) |
+ 			 BIT_ULL(NL80211_STA_INFO_BSS_PARAM) |
+@@ -2307,8 +2303,7 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo,
+ 
+ 	if (!(sinfo->filled & (BIT_ULL(NL80211_STA_INFO_RX_BYTES64) |
+ 			       BIT_ULL(NL80211_STA_INFO_RX_BYTES)))) {
+-		if (!ieee80211_hw_check(&local->hw, USES_RSS))
+-			sinfo->rx_bytes += sta_get_stats_bytes(&sta->rx_stats);
++		sinfo->rx_bytes += sta_get_stats_bytes(&sta->rx_stats);
+ 
+ 		if (sta->pcpu_rx_stats) {
+ 			for_each_possible_cpu(cpu) {
+diff --git a/net/sched/act_api.c b/net/sched/act_api.c
+index f6d5755d669eb..d17a66aab8eea 100644
+--- a/net/sched/act_api.c
++++ b/net/sched/act_api.c
+@@ -381,7 +381,8 @@ static int tcf_del_walker(struct tcf_idrinfo *idrinfo, struct sk_buff *skb,
+ 	}
+ 	mutex_unlock(&idrinfo->lock);
+ 
+-	if (nla_put_u32(skb, TCA_FCNT, n_i))
++	ret = nla_put_u32(skb, TCA_FCNT, n_i);
++	if (ret)
+ 		goto nla_put_failure;
+ 	nla_nest_end(skb, nest);
+ 
+diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
+index 279f9e2a2319a..d73b5c5514a9f 100644
+--- a/net/sched/cls_api.c
++++ b/net/sched/cls_api.c
+@@ -1531,7 +1531,7 @@ static inline int __tcf_classify(struct sk_buff *skb,
+ 				 u32 *last_executed_chain)
+ {
+ #ifdef CONFIG_NET_CLS_ACT
+-	const int max_reclassify_loop = 4;
++	const int max_reclassify_loop = 16;
+ 	const struct tcf_proto *first_tp;
+ 	int limit = 0;
+ 
+diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
+index 53e5ed79f63f3..59e653b528b1f 100644
+--- a/net/sctp/bind_addr.c
++++ b/net/sctp/bind_addr.c
+@@ -270,22 +270,19 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list,
+ 		rawaddr = (union sctp_addr_param *)raw_addr_list;
+ 
+ 		af = sctp_get_af_specific(param_type2af(param->type));
+-		if (unlikely(!af)) {
++		if (unlikely(!af) ||
++		    !af->from_addr_param(&addr, rawaddr, htons(port), 0)) {
+ 			retval = -EINVAL;
+-			sctp_bind_addr_clean(bp);
+-			break;
++			goto out_err;
+ 		}
+ 
+-		af->from_addr_param(&addr, rawaddr, htons(port), 0);
+ 		if (sctp_bind_addr_state(bp, &addr) != -1)
+ 			goto next;
+ 		retval = sctp_add_bind_addr(bp, &addr, sizeof(addr),
+ 					    SCTP_ADDR_SRC, gfp);
+-		if (retval) {
++		if (retval)
+ 			/* Can't finish building the list, clean up. */
+-			sctp_bind_addr_clean(bp);
+-			break;
+-		}
++			goto out_err;
+ 
+ next:
+ 		len = ntohs(param->length);
+@@ -294,6 +291,12 @@ next:
+ 	}
+ 
+ 	return retval;
++
++out_err:
++	if (retval)
++		sctp_bind_addr_clean(bp);
++
++	return retval;
+ }
+ 
+ /********************************************************************
+diff --git a/net/sctp/input.c b/net/sctp/input.c
+index d508f6f3dd08a..f72bff93745c4 100644
+--- a/net/sctp/input.c
++++ b/net/sctp/input.c
+@@ -1131,7 +1131,8 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct net *net,
+ 		if (!af)
+ 			continue;
+ 
+-		af->from_addr_param(paddr, params.addr, sh->source, 0);
++		if (!af->from_addr_param(paddr, params.addr, sh->source, 0))
++			continue;
+ 
+ 		asoc = __sctp_lookup_association(net, laddr, paddr, transportp);
+ 		if (asoc)
+@@ -1174,7 +1175,8 @@ static struct sctp_association *__sctp_rcv_asconf_lookup(
+ 	if (unlikely(!af))
+ 		return NULL;
+ 
+-	af->from_addr_param(&paddr, param, peer_port, 0);
++	if (af->from_addr_param(&paddr, param, peer_port, 0))
++		return NULL;
+ 
+ 	return __sctp_lookup_association(net, laddr, &paddr, transportp);
+ }
+@@ -1245,7 +1247,7 @@ static struct sctp_association *__sctp_rcv_walk_lookup(struct net *net,
+ 
+ 		ch = (struct sctp_chunkhdr *)ch_end;
+ 		chunk_num++;
+-	} while (ch_end < skb_tail_pointer(skb));
++	} while (ch_end + sizeof(*ch) < skb_tail_pointer(skb));
+ 
+ 	return asoc;
+ }
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index bd08807c9e447..5c6f5ced9cfa6 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -551,15 +551,20 @@ static void sctp_v6_to_sk_daddr(union sctp_addr *addr, struct sock *sk)
+ }
+ 
+ /* Initialize a sctp_addr from an address parameter. */
+-static void sctp_v6_from_addr_param(union sctp_addr *addr,
++static bool sctp_v6_from_addr_param(union sctp_addr *addr,
+ 				    union sctp_addr_param *param,
+ 				    __be16 port, int iif)
+ {
++	if (ntohs(param->v6.param_hdr.length) < sizeof(struct sctp_ipv6addr_param))
++		return false;
++
+ 	addr->v6.sin6_family = AF_INET6;
+ 	addr->v6.sin6_port = port;
+ 	addr->v6.sin6_flowinfo = 0; /* BUG */
+ 	addr->v6.sin6_addr = param->v6.addr;
+ 	addr->v6.sin6_scope_id = iif;
++
++	return true;
+ }
+ 
+ /* Initialize an address parameter from a sctp_addr and return the length
+diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
+index 6f2bbfeec3a4c..25192b378e2ec 100644
+--- a/net/sctp/protocol.c
++++ b/net/sctp/protocol.c
+@@ -254,14 +254,19 @@ static void sctp_v4_to_sk_daddr(union sctp_addr *addr, struct sock *sk)
+ }
+ 
+ /* Initialize a sctp_addr from an address parameter. */
+-static void sctp_v4_from_addr_param(union sctp_addr *addr,
++static bool sctp_v4_from_addr_param(union sctp_addr *addr,
+ 				    union sctp_addr_param *param,
+ 				    __be16 port, int iif)
+ {
++	if (ntohs(param->v4.param_hdr.length) < sizeof(struct sctp_ipv4addr_param))
++		return false;
++
+ 	addr->v4.sin_family = AF_INET;
+ 	addr->v4.sin_port = port;
+ 	addr->v4.sin_addr.s_addr = param->v4.addr.s_addr;
+ 	memset(addr->v4.sin_zero, 0, sizeof(addr->v4.sin_zero));
++
++	return true;
+ }
+ 
+ /* Initialize an address parameter from a sctp_addr and return the length
+diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
+index 5b44d228b6cac..f33a870b483da 100644
+--- a/net/sctp/sm_make_chunk.c
++++ b/net/sctp/sm_make_chunk.c
+@@ -2346,11 +2346,13 @@ int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
+ 
+ 	/* Process the initialization parameters.  */
+ 	sctp_walk_params(param, peer_init, init_hdr.params) {
+-		if (!src_match && (param.p->type == SCTP_PARAM_IPV4_ADDRESS ||
+-		    param.p->type == SCTP_PARAM_IPV6_ADDRESS)) {
++		if (!src_match &&
++		    (param.p->type == SCTP_PARAM_IPV4_ADDRESS ||
++		     param.p->type == SCTP_PARAM_IPV6_ADDRESS)) {
+ 			af = sctp_get_af_specific(param_type2af(param.p->type));
+-			af->from_addr_param(&addr, param.addr,
+-					    chunk->sctp_hdr->source, 0);
++			if (!af->from_addr_param(&addr, param.addr,
++						 chunk->sctp_hdr->source, 0))
++				continue;
+ 			if (sctp_cmp_addr_exact(sctp_source(chunk), &addr))
+ 				src_match = 1;
+ 		}
+@@ -2531,7 +2533,8 @@ static int sctp_process_param(struct sctp_association *asoc,
+ 			break;
+ do_addr_param:
+ 		af = sctp_get_af_specific(param_type2af(param.p->type));
+-		af->from_addr_param(&addr, param.addr, htons(asoc->peer.port), 0);
++		if (!af->from_addr_param(&addr, param.addr, htons(asoc->peer.port), 0))
++			break;
+ 		scope = sctp_scope(peer_addr);
+ 		if (sctp_in_scope(net, &addr, scope))
+ 			if (!sctp_assoc_add_peer(asoc, &addr, gfp, SCTP_UNCONFIRMED))
+@@ -2632,15 +2635,13 @@ do_addr_param:
+ 		addr_param = param.v + sizeof(struct sctp_addip_param);
+ 
+ 		af = sctp_get_af_specific(param_type2af(addr_param->p.type));
+-		if (af == NULL)
++		if (!af)
+ 			break;
+ 
+-		af->from_addr_param(&addr, addr_param,
+-				    htons(asoc->peer.port), 0);
++		if (!af->from_addr_param(&addr, addr_param,
++					 htons(asoc->peer.port), 0))
++			break;
+ 
+-		/* if the address is invalid, we can't process it.
+-		 * XXX: see spec for what to do.
+-		 */
+ 		if (!af->addr_valid(&addr, NULL, NULL))
+ 			break;
+ 
+@@ -3054,7 +3055,8 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
+ 	if (unlikely(!af))
+ 		return SCTP_ERROR_DNS_FAILED;
+ 
+-	af->from_addr_param(&addr, addr_param, htons(asoc->peer.port), 0);
++	if (!af->from_addr_param(&addr, addr_param, htons(asoc->peer.port), 0))
++		return SCTP_ERROR_DNS_FAILED;
+ 
+ 	/* ADDIP 4.2.1  This parameter MUST NOT contain a broadcast
+ 	 * or multicast address.
+@@ -3331,7 +3333,8 @@ static void sctp_asconf_param_success(struct sctp_association *asoc,
+ 
+ 	/* We have checked the packet before, so we do not check again.	*/
+ 	af = sctp_get_af_specific(param_type2af(addr_param->p.type));
+-	af->from_addr_param(&addr, addr_param, htons(bp->port), 0);
++	if (!af->from_addr_param(&addr, addr_param, htons(bp->port), 0))
++		return;
+ 
+ 	switch (asconf_param->param_hdr.type) {
+ 	case SCTP_PARAM_ADD_IP:
+diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
+index 92a72f0e0d942..ae11311807fdc 100644
+--- a/net/vmw_vsock/af_vsock.c
++++ b/net/vmw_vsock/af_vsock.c
+@@ -1369,7 +1369,7 @@ static int vsock_stream_connect(struct socket *sock, struct sockaddr *addr,
+ 
+ 		if (signal_pending(current)) {
+ 			err = sock_intr_errno(timeout);
+-			sk->sk_state = TCP_CLOSE;
++			sk->sk_state = sk->sk_state == TCP_ESTABLISHED ? TCP_CLOSING : TCP_CLOSE;
+ 			sock->state = SS_UNCONNECTED;
+ 			vsock_transport_cancel_pkt(vsk);
+ 			goto out_wait;
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index fc9286afe3c99..912977bf3ec80 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -4781,11 +4781,10 @@ static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,
+ 		       sband->ht_cap.mcs.rx_mask,
+ 		       sizeof(mask->control[i].ht_mcs));
+ 
+-		if (!sband->vht_cap.vht_supported)
+-			continue;
+-
+-		vht_tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
+-		vht_build_mcs_mask(vht_tx_mcs_map, mask->control[i].vht_mcs);
++		if (sband->vht_cap.vht_supported) {
++			vht_tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
++			vht_build_mcs_mask(vht_tx_mcs_map, mask->control[i].vht_mcs);
++		}
+ 
+ 		he_cap = ieee80211_get_he_iftype_cap(sband, wdev->iftype);
+ 		if (!he_cap)
+diff --git a/net/wireless/wext-spy.c b/net/wireless/wext-spy.c
+index 33bef22e44e95..b379a03716539 100644
+--- a/net/wireless/wext-spy.c
++++ b/net/wireless/wext-spy.c
+@@ -120,8 +120,8 @@ int iw_handler_set_thrspy(struct net_device *	dev,
+ 		return -EOPNOTSUPP;
+ 
+ 	/* Just do it */
+-	memcpy(&(spydata->spy_thr_low), &(threshold->low),
+-	       2 * sizeof(struct iw_quality));
++	spydata->spy_thr_low = threshold->low;
++	spydata->spy_thr_high = threshold->high;
+ 
+ 	/* Clear flag */
+ 	memset(spydata->spy_thr_under, '\0', sizeof(spydata->spy_thr_under));
+@@ -147,8 +147,8 @@ int iw_handler_get_thrspy(struct net_device *	dev,
+ 		return -EOPNOTSUPP;
+ 
+ 	/* Just do it */
+-	memcpy(&(threshold->low), &(spydata->spy_thr_low),
+-	       2 * sizeof(struct iw_quality));
++	threshold->low = spydata->spy_thr_low;
++	threshold->high = spydata->spy_thr_high;
+ 
+ 	return 0;
+ }
+@@ -173,10 +173,10 @@ static void iw_send_thrspy_event(struct net_device *	dev,
+ 	memcpy(threshold.addr.sa_data, address, ETH_ALEN);
+ 	threshold.addr.sa_family = ARPHRD_ETHER;
+ 	/* Copy stats */
+-	memcpy(&(threshold.qual), wstats, sizeof(struct iw_quality));
++	threshold.qual = *wstats;
+ 	/* Copy also thresholds */
+-	memcpy(&(threshold.low), &(spydata->spy_thr_low),
+-	       2 * sizeof(struct iw_quality));
++	threshold.low = spydata->spy_thr_low;
++	threshold.high = spydata->spy_thr_high;
+ 
+ 	/* Send event to user space */
+ 	wireless_send_event(dev, SIOCGIWTHRSPY, &wrqu, (char *) &threshold);
+diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
+index f0aecee4d5392..b47d613409b70 100644
+--- a/net/xfrm/xfrm_user.c
++++ b/net/xfrm/xfrm_user.c
+@@ -580,6 +580,20 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,
+ 
+ 	copy_from_user_state(x, p);
+ 
++	if (attrs[XFRMA_ENCAP]) {
++		x->encap = kmemdup(nla_data(attrs[XFRMA_ENCAP]),
++				   sizeof(*x->encap), GFP_KERNEL);
++		if (x->encap == NULL)
++			goto error;
++	}
++
++	if (attrs[XFRMA_COADDR]) {
++		x->coaddr = kmemdup(nla_data(attrs[XFRMA_COADDR]),
++				    sizeof(*x->coaddr), GFP_KERNEL);
++		if (x->coaddr == NULL)
++			goto error;
++	}
++
+ 	if (attrs[XFRMA_SA_EXTRA_FLAGS])
+ 		x->props.extra_flags = nla_get_u32(attrs[XFRMA_SA_EXTRA_FLAGS]);
+ 
+@@ -600,23 +614,9 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,
+ 				   attrs[XFRMA_ALG_COMP])))
+ 		goto error;
+ 
+-	if (attrs[XFRMA_ENCAP]) {
+-		x->encap = kmemdup(nla_data(attrs[XFRMA_ENCAP]),
+-				   sizeof(*x->encap), GFP_KERNEL);
+-		if (x->encap == NULL)
+-			goto error;
+-	}
+-
+ 	if (attrs[XFRMA_TFCPAD])
+ 		x->tfcpad = nla_get_u32(attrs[XFRMA_TFCPAD]);
+ 
+-	if (attrs[XFRMA_COADDR]) {
+-		x->coaddr = kmemdup(nla_data(attrs[XFRMA_COADDR]),
+-				    sizeof(*x->coaddr), GFP_KERNEL);
+-		if (x->coaddr == NULL)
+-			goto error;
+-	}
+-
+ 	xfrm_mark_get(attrs, &x->mark);
+ 
+ 	xfrm_smark_init(attrs, &x->props.smark);
+diff --git a/security/selinux/avc.c b/security/selinux/avc.c
+index ad451cf9375e4..a2dc83228daf4 100644
+--- a/security/selinux/avc.c
++++ b/security/selinux/avc.c
+@@ -297,26 +297,27 @@ static struct avc_xperms_decision_node
+ 	struct avc_xperms_decision_node *xpd_node;
+ 	struct extended_perms_decision *xpd;
+ 
+-	xpd_node = kmem_cache_zalloc(avc_xperms_decision_cachep, GFP_NOWAIT);
++	xpd_node = kmem_cache_zalloc(avc_xperms_decision_cachep,
++				     GFP_NOWAIT | __GFP_NOWARN);
+ 	if (!xpd_node)
+ 		return NULL;
+ 
+ 	xpd = &xpd_node->xpd;
+ 	if (which & XPERMS_ALLOWED) {
+ 		xpd->allowed = kmem_cache_zalloc(avc_xperms_data_cachep,
+-						GFP_NOWAIT);
++						GFP_NOWAIT | __GFP_NOWARN);
+ 		if (!xpd->allowed)
+ 			goto error;
+ 	}
+ 	if (which & XPERMS_AUDITALLOW) {
+ 		xpd->auditallow = kmem_cache_zalloc(avc_xperms_data_cachep,
+-						GFP_NOWAIT);
++						GFP_NOWAIT | __GFP_NOWARN);
+ 		if (!xpd->auditallow)
+ 			goto error;
+ 	}
+ 	if (which & XPERMS_DONTAUDIT) {
+ 		xpd->dontaudit = kmem_cache_zalloc(avc_xperms_data_cachep,
+-						GFP_NOWAIT);
++						GFP_NOWAIT | __GFP_NOWARN);
+ 		if (!xpd->dontaudit)
+ 			goto error;
+ 	}
+@@ -344,7 +345,7 @@ static struct avc_xperms_node *avc_xperms_alloc(void)
+ {
+ 	struct avc_xperms_node *xp_node;
+ 
+-	xp_node = kmem_cache_zalloc(avc_xperms_cachep, GFP_NOWAIT);
++	xp_node = kmem_cache_zalloc(avc_xperms_cachep, GFP_NOWAIT | __GFP_NOWARN);
+ 	if (!xp_node)
+ 		return xp_node;
+ 	INIT_LIST_HEAD(&xp_node->xpd_head);
+@@ -500,7 +501,7 @@ static struct avc_node *avc_alloc_node(struct selinux_avc *avc)
+ {
+ 	struct avc_node *node;
+ 
+-	node = kmem_cache_zalloc(avc_node_cachep, GFP_NOWAIT);
++	node = kmem_cache_zalloc(avc_node_cachep, GFP_NOWAIT | __GFP_NOWARN);
+ 	if (!node)
+ 		goto out;
+ 
+diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
+index 22ded2c26089c..1ad7d0d1ea62e 100644
+--- a/security/smack/smackfs.c
++++ b/security/smack/smackfs.c
+@@ -855,6 +855,8 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
+ 	if (format == SMK_FIXED24_FMT &&
+ 	    (count < SMK_CIPSOMIN || count > SMK_CIPSOMAX))
+ 		return -EINVAL;
++	if (count > PAGE_SIZE)
++		return -EINVAL;
+ 
+ 	data = memdup_user_nul(buf, count);
+ 	if (IS_ERR(data))
+diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
+index 0a0efd24e4b0f..81ea6ceba689a 100644
+--- a/sound/soc/tegra/tegra_alc5632.c
++++ b/sound/soc/tegra/tegra_alc5632.c
+@@ -139,6 +139,7 @@ static struct snd_soc_dai_link tegra_alc5632_dai = {
+ 
+ static struct snd_soc_card snd_soc_tegra_alc5632 = {
+ 	.name = "tegra-alc5632",
++	.driver_name = "tegra",
+ 	.owner = THIS_MODULE,
+ 	.dai_link = &tegra_alc5632_dai,
+ 	.num_links = 1,
+diff --git a/sound/soc/tegra/tegra_max98090.c b/sound/soc/tegra/tegra_max98090.c
+index 00c19704057b6..5a649810c0c87 100644
+--- a/sound/soc/tegra/tegra_max98090.c
++++ b/sound/soc/tegra/tegra_max98090.c
+@@ -182,6 +182,7 @@ static struct snd_soc_dai_link tegra_max98090_dai = {
+ 
+ static struct snd_soc_card snd_soc_tegra_max98090 = {
+ 	.name = "tegra-max98090",
++	.driver_name = "tegra",
+ 	.owner = THIS_MODULE,
+ 	.dai_link = &tegra_max98090_dai,
+ 	.num_links = 1,
+diff --git a/sound/soc/tegra/tegra_rt5640.c b/sound/soc/tegra/tegra_rt5640.c
+index 9afba37a3b086..3344f16258bec 100644
+--- a/sound/soc/tegra/tegra_rt5640.c
++++ b/sound/soc/tegra/tegra_rt5640.c
+@@ -132,6 +132,7 @@ static struct snd_soc_dai_link tegra_rt5640_dai = {
+ 
+ static struct snd_soc_card snd_soc_tegra_rt5640 = {
+ 	.name = "tegra-rt5640",
++	.driver_name = "tegra",
+ 	.owner = THIS_MODULE,
+ 	.dai_link = &tegra_rt5640_dai,
+ 	.num_links = 1,
+diff --git a/sound/soc/tegra/tegra_rt5677.c b/sound/soc/tegra/tegra_rt5677.c
+index d30f8b6deda4b..0f03e97d93558 100644
+--- a/sound/soc/tegra/tegra_rt5677.c
++++ b/sound/soc/tegra/tegra_rt5677.c
+@@ -175,6 +175,7 @@ static struct snd_soc_dai_link tegra_rt5677_dai = {
+ 
+ static struct snd_soc_card snd_soc_tegra_rt5677 = {
+ 	.name = "tegra-rt5677",
++	.driver_name = "tegra",
+ 	.owner = THIS_MODULE,
+ 	.dai_link = &tegra_rt5677_dai,
+ 	.num_links = 1,
+diff --git a/sound/soc/tegra/tegra_sgtl5000.c b/sound/soc/tegra/tegra_sgtl5000.c
+index 885332170c77b..ef6a553e0b7da 100644
+--- a/sound/soc/tegra/tegra_sgtl5000.c
++++ b/sound/soc/tegra/tegra_sgtl5000.c
+@@ -97,6 +97,7 @@ static struct snd_soc_dai_link tegra_sgtl5000_dai = {
+ 
+ static struct snd_soc_card snd_soc_tegra_sgtl5000 = {
+ 	.name = "tegra-sgtl5000",
++	.driver_name = "tegra",
+ 	.owner = THIS_MODULE,
+ 	.dai_link = &tegra_sgtl5000_dai,
+ 	.num_links = 1,
+diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c
+index efd7938866895..27089077f2ea4 100644
+--- a/sound/soc/tegra/tegra_wm8753.c
++++ b/sound/soc/tegra/tegra_wm8753.c
+@@ -101,6 +101,7 @@ static struct snd_soc_dai_link tegra_wm8753_dai = {
+ 
+ static struct snd_soc_card snd_soc_tegra_wm8753 = {
+ 	.name = "tegra-wm8753",
++	.driver_name = "tegra",
+ 	.owner = THIS_MODULE,
+ 	.dai_link = &tegra_wm8753_dai,
+ 	.num_links = 1,
+diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
+index e4863fa37b0c6..f219c26d66a31 100644
+--- a/sound/soc/tegra/tegra_wm8903.c
++++ b/sound/soc/tegra/tegra_wm8903.c
+@@ -235,6 +235,7 @@ static struct snd_soc_dai_link tegra_wm8903_dai = {
+ 
+ static struct snd_soc_card snd_soc_tegra_wm8903 = {
+ 	.name = "tegra-wm8903",
++	.driver_name = "tegra",
+ 	.owner = THIS_MODULE,
+ 	.dai_link = &tegra_wm8903_dai,
+ 	.num_links = 1,
+diff --git a/sound/soc/tegra/tegra_wm9712.c b/sound/soc/tegra/tegra_wm9712.c
+index 4f09a178049d3..c66da161c85aa 100644
+--- a/sound/soc/tegra/tegra_wm9712.c
++++ b/sound/soc/tegra/tegra_wm9712.c
+@@ -54,6 +54,7 @@ static struct snd_soc_dai_link tegra_wm9712_dai = {
+ 
+ static struct snd_soc_card snd_soc_tegra_wm9712 = {
+ 	.name = "tegra-wm9712",
++	.driver_name = "tegra",
+ 	.owner = THIS_MODULE,
+ 	.dai_link = &tegra_wm9712_dai,
+ 	.num_links = 1,
+diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c
+index 6c1cc3d0ac336..cb4c8f72e4e67 100644
+--- a/sound/soc/tegra/trimslice.c
++++ b/sound/soc/tegra/trimslice.c
+@@ -94,6 +94,7 @@ static struct snd_soc_dai_link trimslice_tlv320aic23_dai = {
+ 
+ static struct snd_soc_card snd_soc_trimslice = {
+ 	.name = "tegra-trimslice",
++	.driver_name = "tegra",
+ 	.owner = THIS_MODULE,
+ 	.dai_link = &trimslice_tlv320aic23_dai,
+ 	.num_links = 1,
+diff --git a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l3_drops.sh b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l3_drops.sh
+index 4029833f7e271..160891dcb4bcb 100755
+--- a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l3_drops.sh
++++ b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l3_drops.sh
+@@ -109,6 +109,9 @@ router_destroy()
+ 	__addr_add_del $rp1 del 192.0.2.2/24 2001:db8:1::2/64
+ 
+ 	tc qdisc del dev $rp2 clsact
++
++	ip link set dev $rp2 down
++	ip link set dev $rp1 down
+ }
+ 
+ setup_prepare()
+diff --git a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l3_exceptions.sh b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l3_exceptions.sh
+index 42d44e27802cd..190c1b6b5365a 100755
+--- a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l3_exceptions.sh
++++ b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l3_exceptions.sh
+@@ -111,6 +111,9 @@ router_destroy()
+ 	__addr_add_del $rp1 del 192.0.2.2/24 2001:db8:1::2/64
+ 
+ 	tc qdisc del dev $rp2 clsact
++
++	ip link set dev $rp2 down
++	ip link set dev $rp1 down
+ }
+ 
+ setup_prepare()
+diff --git a/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_bridge.sh b/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_bridge.sh
+index 5cbff8038f84c..28a570006d4d9 100755
+--- a/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_bridge.sh
++++ b/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_bridge.sh
+@@ -93,7 +93,9 @@ switch_destroy()
+ 	lldptool -T -i $swp1 -V APP -d $(dscp_map 10) >/dev/null
+ 	lldpad_app_wait_del
+ 
++	ip link set dev $swp2 down
+ 	ip link set dev $swp2 nomaster
++	ip link set dev $swp1 down
+ 	ip link set dev $swp1 nomaster
+ 	ip link del dev br1
+ }
+diff --git a/tools/testing/selftests/lkdtm/tests.txt b/tools/testing/selftests/lkdtm/tests.txt
+index 11ef159be0fd4..a5fce7fd4520d 100644
+--- a/tools/testing/selftests/lkdtm/tests.txt
++++ b/tools/testing/selftests/lkdtm/tests.txt
+@@ -11,7 +11,7 @@ CORRUPT_LIST_ADD list_add corruption
+ CORRUPT_LIST_DEL list_del corruption
+ STACK_GUARD_PAGE_LEADING
+ STACK_GUARD_PAGE_TRAILING
+-UNSET_SMEP CR4 bits went missing
++UNSET_SMEP pinned CR4 bits changed:
+ DOUBLE_FAULT
+ CORRUPT_PAC
+ UNALIGNED_LOAD_STORE_WRITE
+diff --git a/tools/testing/selftests/net/forwarding/pedit_dsfield.sh b/tools/testing/selftests/net/forwarding/pedit_dsfield.sh
+index 55eeacf592411..64fbd211d907b 100755
+--- a/tools/testing/selftests/net/forwarding/pedit_dsfield.sh
++++ b/tools/testing/selftests/net/forwarding/pedit_dsfield.sh
+@@ -75,7 +75,9 @@ switch_destroy()
+ 	tc qdisc del dev $swp2 clsact
+ 	tc qdisc del dev $swp1 clsact
+ 
++	ip link set dev $swp2 down
+ 	ip link set dev $swp2 nomaster
++	ip link set dev $swp1 down
+ 	ip link set dev $swp1 nomaster
+ 	ip link del dev br1
+ }
+diff --git a/tools/testing/selftests/net/forwarding/pedit_l4port.sh b/tools/testing/selftests/net/forwarding/pedit_l4port.sh
+index 5f20d289ee43c..10e594c551175 100755
+--- a/tools/testing/selftests/net/forwarding/pedit_l4port.sh
++++ b/tools/testing/selftests/net/forwarding/pedit_l4port.sh
+@@ -71,7 +71,9 @@ switch_destroy()
+ 	tc qdisc del dev $swp2 clsact
+ 	tc qdisc del dev $swp1 clsact
+ 
++	ip link set dev $swp2 down
+ 	ip link set dev $swp2 nomaster
++	ip link set dev $swp1 down
+ 	ip link set dev $swp1 nomaster
+ 	ip link del dev br1
+ }
+diff --git a/tools/testing/selftests/net/forwarding/skbedit_priority.sh b/tools/testing/selftests/net/forwarding/skbedit_priority.sh
+index e3bd8a6bb8b40..bde11dc27873c 100755
+--- a/tools/testing/selftests/net/forwarding/skbedit_priority.sh
++++ b/tools/testing/selftests/net/forwarding/skbedit_priority.sh
+@@ -72,7 +72,9 @@ switch_destroy()
+ 	tc qdisc del dev $swp2 clsact
+ 	tc qdisc del dev $swp1 clsact
+ 
++	ip link set dev $swp2 down
+ 	ip link set dev $swp2 nomaster
++	ip link set dev $swp1 down
+ 	ip link set dev $swp1 nomaster
+ 	ip link del dev br1
+ }


             reply	other threads:[~2021-07-19 11:15 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-19 11:15 Mike Pagano [this message]
  -- strict thread matches above, loose matches on Subject: below --
2021-09-20 22:01 [gentoo-commits] proj/linux-patches:5.13 commit in: / Mike Pagano
2021-09-18 16:08 Mike Pagano
2021-09-17 12:49 Mike Pagano
2021-09-17 12:42 Mike Pagano
2021-09-16 11:02 Mike Pagano
2021-09-15 11:59 Mike Pagano
2021-09-12 14:37 Mike Pagano
2021-09-08 13:55 Alice Ferrazzi
2021-09-03 11:50 Mike Pagano
2021-09-03 11:19 Mike Pagano
2021-08-29 14:48 Mike Pagano
2021-08-26 14:33 Mike Pagano
2021-08-25 16:23 Mike Pagano
2021-08-24 20:00 Mike Pagano
2021-08-24 19:56 Mike Pagano
2021-08-21 14:27 Mike Pagano
2021-08-18 22:42 Mike Pagano
2021-08-18 12:45 Mike Pagano
2021-08-15 20:04 Mike Pagano
2021-08-13 14:30 Mike Pagano
2021-08-12 11:54 Mike Pagano
2021-08-10 12:13 Mike Pagano
2021-08-10 12:13 Mike Pagano
2021-08-08 13:35 Mike Pagano
2021-08-04 11:50 Mike Pagano
2021-08-03 11:03 Mike Pagano
2021-08-02 22:34 Mike Pagano
2021-07-31 10:28 Alice Ferrazzi
2021-07-28 13:23 Mike Pagano
2021-07-25 17:25 Mike Pagano
2021-07-20 15:51 Alice Ferrazzi
2021-07-14 16:16 Mike Pagano
2021-07-13 12:35 Mike Pagano
2021-07-12 11:36 Mike Pagano
2021-07-07 13:26 Mike Pagano
2021-07-07 13:11 Mike Pagano
2021-07-05 14:11 Mike Pagano
2021-07-04 15:43 Mike Pagano
2021-07-01 14:29 Mike Pagano
2021-06-13 20:14 Mike Pagano
2021-05-25 17:49 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=1626693229.251a2869d4d1cff8f96751d70c93211e5b7a34ab.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