From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 98840138334 for ; Fri, 6 Sep 2019 17:26:38 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id B1DDEE09D0; Fri, 6 Sep 2019 17:26:36 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 64FCAE09D0 for ; Fri, 6 Sep 2019 17:26:36 +0000 (UTC) Received: from oystercatcher.gentoo.org (unknown [IPv6:2a01:4f8:202:4333:225:90ff:fed9:fc84]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id E3D7634AD61 for ; Fri, 6 Sep 2019 17:26:34 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 9677E71A for ; Fri, 6 Sep 2019 17:26:33 +0000 (UTC) From: "Mike Pagano" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Mike Pagano" Message-ID: <1567790775.50acba1d52c3a0eeae20f935118bf8e76cab062b.mpagano@gentoo> Subject: [gentoo-commits] proj/linux-patches:5.2 commit in: / X-VCS-Repository: proj/linux-patches X-VCS-Files: 1011_linux-5.2.12.patch 1012_linux-5.2.13.patch X-VCS-Directories: / X-VCS-Committer: mpagano X-VCS-Committer-Name: Mike Pagano X-VCS-Revision: 50acba1d52c3a0eeae20f935118bf8e76cab062b X-VCS-Branch: 5.2 Date: Fri, 6 Sep 2019 17:26:33 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: 5ccfae61-ab2c-4f72-bba1-ba9084296439 X-Archives-Hash: e20f430a9e7f67fd871a50ccc0b70c35 commit: 50acba1d52c3a0eeae20f935118bf8e76cab062b Author: Mike Pagano gentoo org> AuthorDate: Fri Sep 6 17:26:15 2019 +0000 Commit: Mike Pagano gentoo org> CommitDate: Fri Sep 6 17:26:15 2019 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=50acba1d Linux patch 5.2.12 and 5.2.13 Signed-off-by: Mike Pagano gentoo.org> 1011_linux-5.2.12.patch | 5532 +++++++++++++++++++++++++++++++++++++++++++++++ 1012_linux-5.2.13.patch | 92 + 2 files changed, 5624 insertions(+) diff --git a/1011_linux-5.2.12.patch b/1011_linux-5.2.12.patch new file mode 100644 index 0000000..0df54ef --- /dev/null +++ b/1011_linux-5.2.12.patch @@ -0,0 +1,5532 @@ +diff --git a/Makefile b/Makefile +index a3b26dcfc5c8..e26d52d93bb1 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 2 +-SUBLEVEL = 11 ++SUBLEVEL = 12 + EXTRAVERSION = + NAME = Bobtail Squid + +diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c +index ae63eedea1c1..68faf535f40a 100644 +--- a/arch/arm64/kernel/cpufeature.c ++++ b/arch/arm64/kernel/cpufeature.c +@@ -184,9 +184,17 @@ static const struct arm64_ftr_bits ftr_id_aa64zfr0[] = { + }; + + static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = { +- S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_TGRAN4_SHIFT, 4, ID_AA64MMFR0_TGRAN4_NI), +- S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_TGRAN64_SHIFT, 4, ID_AA64MMFR0_TGRAN64_NI), +- ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_TGRAN16_SHIFT, 4, ID_AA64MMFR0_TGRAN16_NI), ++ /* ++ * We already refuse to boot CPUs that don't support our configured ++ * page size, so we can only detect mismatches for a page size other ++ * than the one we're currently using. Unfortunately, SoCs like this ++ * exist in the wild so, even though we don't like it, we'll have to go ++ * along with it and treat them as non-strict. ++ */ ++ S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_TGRAN4_SHIFT, 4, ID_AA64MMFR0_TGRAN4_NI), ++ S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_TGRAN64_SHIFT, 4, ID_AA64MMFR0_TGRAN64_NI), ++ ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_TGRAN16_SHIFT, 4, ID_AA64MMFR0_TGRAN16_NI), ++ + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_BIGENDEL0_SHIFT, 4, 0), + /* Linux shouldn't care about secure memory */ + ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_SNSMEM_SHIFT, 4, 0), +diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c +index 5bf05cc774e2..446d91d6cf70 100644 +--- a/arch/powerpc/kvm/book3s_64_vio.c ++++ b/arch/powerpc/kvm/book3s_64_vio.c +@@ -696,8 +696,10 @@ long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu, + } + tce = be64_to_cpu(tce); + +- if (kvmppc_tce_to_ua(vcpu->kvm, tce, &ua)) +- return H_PARAMETER; ++ if (kvmppc_tce_to_ua(vcpu->kvm, tce, &ua)) { ++ ret = H_PARAMETER; ++ goto unlock_exit; ++ } + + list_for_each_entry_lockless(stit, &stt->iommu_tables, next) { + ret = kvmppc_tce_iommu_map(vcpu->kvm, stt, +diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c +index f50bbeedfc66..b4f20f13b860 100644 +--- a/arch/powerpc/kvm/book3s_64_vio_hv.c ++++ b/arch/powerpc/kvm/book3s_64_vio_hv.c +@@ -556,8 +556,10 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu, + unsigned long tce = be64_to_cpu(((u64 *)tces)[i]); + + ua = 0; +- if (kvmppc_rm_tce_to_ua(vcpu->kvm, tce, &ua, NULL)) +- return H_PARAMETER; ++ if (kvmppc_rm_tce_to_ua(vcpu->kvm, tce, &ua, NULL)) { ++ ret = H_PARAMETER; ++ goto unlock_exit; ++ } + + list_for_each_entry_lockless(stit, &stt->iommu_tables, next) { + ret = kvmppc_rm_tce_iommu_map(vcpu->kvm, stt, +diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h +index 687dd19735a7..4d9bbe8438bf 100644 +--- a/arch/riscv/include/asm/tlbflush.h ++++ b/arch/riscv/include/asm/tlbflush.h +@@ -53,10 +53,17 @@ static inline void remote_sfence_vma(struct cpumask *cmask, unsigned long start, + } + + #define flush_tlb_all() sbi_remote_sfence_vma(NULL, 0, -1) +-#define flush_tlb_page(vma, addr) flush_tlb_range(vma, addr, 0) ++ + #define flush_tlb_range(vma, start, end) \ + remote_sfence_vma(mm_cpumask((vma)->vm_mm), start, (end) - (start)) +-#define flush_tlb_mm(mm) \ ++ ++static inline void flush_tlb_page(struct vm_area_struct *vma, ++ unsigned long addr) ++{ ++ flush_tlb_range(vma, addr, addr + PAGE_SIZE); ++} ++ ++#define flush_tlb_mm(mm) \ + remote_sfence_vma(mm_cpumask(mm), 0, -1) + + #endif /* CONFIG_SMP */ +diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c +index 2f067b443326..97c3a1c9502e 100644 +--- a/arch/x86/kernel/apic/apic.c ++++ b/arch/x86/kernel/apic/apic.c +@@ -1152,6 +1152,10 @@ void clear_local_APIC(void) + apic_write(APIC_LVT0, v | APIC_LVT_MASKED); + v = apic_read(APIC_LVT1); + apic_write(APIC_LVT1, v | APIC_LVT_MASKED); ++ if (!x2apic_enabled()) { ++ v = apic_read(APIC_LDR) & ~APIC_LDR_MASK; ++ apic_write(APIC_LDR, v); ++ } + if (maxlvt >= 4) { + v = apic_read(APIC_LVTPC); + apic_write(APIC_LVTPC, v | APIC_LVT_MASKED); +diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c +index afee386ff711..caedd8d60d36 100644 +--- a/arch/x86/kernel/apic/bigsmp_32.c ++++ b/arch/x86/kernel/apic/bigsmp_32.c +@@ -38,32 +38,12 @@ static int bigsmp_early_logical_apicid(int cpu) + return early_per_cpu(x86_cpu_to_apicid, cpu); + } + +-static inline unsigned long calculate_ldr(int cpu) +-{ +- unsigned long val, id; +- +- val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; +- id = per_cpu(x86_bios_cpu_apicid, cpu); +- val |= SET_APIC_LOGICAL_ID(id); +- +- return val; +-} +- + /* +- * Set up the logical destination ID. +- * +- * Intel recommends to set DFR, LDR and TPR before enabling +- * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel +- * document number 292116). So here it goes... ++ * bigsmp enables physical destination mode ++ * and doesn't use LDR and DFR + */ + static void bigsmp_init_apic_ldr(void) + { +- unsigned long val; +- int cpu = smp_processor_id(); +- +- apic_write(APIC_DFR, APIC_DFR_FLAT); +- val = calculate_ldr(cpu); +- apic_write(APIC_LDR, val); + } + + static void bigsmp_setup_apic_routing(void) +diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c +index e9d0bc3a5e88..00fccf952d9b 100644 +--- a/arch/x86/kernel/ptrace.c ++++ b/arch/x86/kernel/ptrace.c +@@ -644,11 +644,10 @@ static unsigned long ptrace_get_debugreg(struct task_struct *tsk, int n) + { + struct thread_struct *thread = &tsk->thread; + unsigned long val = 0; +- int index = n; + + if (n < HBP_NUM) { ++ int index = array_index_nospec(n, HBP_NUM); + struct perf_event *bp = thread->ptrace_bps[index]; +- index = array_index_nospec(index, HBP_NUM); + + if (bp) + val = bp->hw.info.address; +diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c +index 918b5092a85f..0b16309898c6 100644 +--- a/arch/x86/kernel/uprobes.c ++++ b/arch/x86/kernel/uprobes.c +@@ -508,9 +508,12 @@ struct uprobe_xol_ops { + void (*abort)(struct arch_uprobe *, struct pt_regs *); + }; + +-static inline int sizeof_long(void) ++static inline int sizeof_long(struct pt_regs *regs) + { +- return in_ia32_syscall() ? 4 : 8; ++ /* ++ * Check registers for mode as in_xxx_syscall() does not apply here. ++ */ ++ return user_64bit_mode(regs) ? 8 : 4; + } + + static int default_pre_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs) +@@ -521,9 +524,9 @@ static int default_pre_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs) + + static int emulate_push_stack(struct pt_regs *regs, unsigned long val) + { +- unsigned long new_sp = regs->sp - sizeof_long(); ++ unsigned long new_sp = regs->sp - sizeof_long(regs); + +- if (copy_to_user((void __user *)new_sp, &val, sizeof_long())) ++ if (copy_to_user((void __user *)new_sp, &val, sizeof_long(regs))) + return -EFAULT; + + regs->sp = new_sp; +@@ -556,7 +559,7 @@ static int default_post_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs + long correction = utask->vaddr - utask->xol_vaddr; + regs->ip += correction; + } else if (auprobe->defparam.fixups & UPROBE_FIX_CALL) { +- regs->sp += sizeof_long(); /* Pop incorrect return address */ ++ regs->sp += sizeof_long(regs); /* Pop incorrect return address */ + if (emulate_push_stack(regs, utask->vaddr + auprobe->defparam.ilen)) + return -ERESTART; + } +@@ -675,7 +678,7 @@ static int branch_post_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs) + * "call" insn was executed out-of-line. Just restore ->sp and restart. + * We could also restore ->ip and try to call branch_emulate_op() again. + */ +- regs->sp += sizeof_long(); ++ regs->sp += sizeof_long(regs); + return -ERESTART; + } + +@@ -1056,7 +1059,7 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) + unsigned long + arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs) + { +- int rasize = sizeof_long(), nleft; ++ int rasize = sizeof_long(regs), nleft; + unsigned long orig_ret_vaddr = 0; /* clear high bits for 32-bit apps */ + + if (copy_from_user(&orig_ret_vaddr, (void __user *)regs->sp, rasize)) +diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c +index a39e38f13029..742ecf5b6c00 100644 +--- a/arch/x86/kvm/hyperv.c ++++ b/arch/x86/kvm/hyperv.c +@@ -1783,7 +1783,7 @@ int kvm_vm_ioctl_hv_eventfd(struct kvm *kvm, struct kvm_hyperv_eventfd *args) + int kvm_vcpu_ioctl_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid, + struct kvm_cpuid_entry2 __user *entries) + { +- uint16_t evmcs_ver = kvm_x86_ops->nested_get_evmcs_version(vcpu); ++ uint16_t evmcs_ver = 0; + struct kvm_cpuid_entry2 cpuid_entries[] = { + { .function = HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS }, + { .function = HYPERV_CPUID_INTERFACE }, +@@ -1795,6 +1795,9 @@ int kvm_vcpu_ioctl_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid, + }; + int i, nent = ARRAY_SIZE(cpuid_entries); + ++ if (kvm_x86_ops->nested_get_evmcs_version) ++ evmcs_ver = kvm_x86_ops->nested_get_evmcs_version(vcpu); ++ + /* Skip NESTED_FEATURES if eVMCS is not supported */ + if (!evmcs_ver) + --nent; +diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c +index 4dabc318adb8..8d22c79f5333 100644 +--- a/arch/x86/kvm/lapic.c ++++ b/arch/x86/kvm/lapic.c +@@ -212,6 +212,9 @@ static void recalculate_apic_map(struct kvm *kvm) + if (!apic_x2apic_mode(apic) && !new->phys_map[xapic_id]) + new->phys_map[xapic_id] = apic; + ++ if (!kvm_apic_sw_enabled(apic)) ++ continue; ++ + ldr = kvm_lapic_get_reg(apic, APIC_LDR); + + if (apic_x2apic_mode(apic)) { +@@ -254,6 +257,8 @@ static inline void apic_set_spiv(struct kvm_lapic *apic, u32 val) + static_key_slow_dec_deferred(&apic_sw_disabled); + else + static_key_slow_inc(&apic_sw_disabled.key); ++ ++ recalculate_apic_map(apic->vcpu->kvm); + } + } + +diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c +index 14384a1ec53f..2c7daa3b968d 100644 +--- a/arch/x86/kvm/svm.c ++++ b/arch/x86/kvm/svm.c +@@ -7107,12 +7107,6 @@ failed: + return ret; + } + +-static uint16_t nested_get_evmcs_version(struct kvm_vcpu *vcpu) +-{ +- /* Not supported */ +- return 0; +-} +- + static int nested_enable_evmcs(struct kvm_vcpu *vcpu, + uint16_t *vmcs_version) + { +@@ -7283,7 +7277,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = { + .mem_enc_unreg_region = svm_unregister_enc_region, + + .nested_enable_evmcs = nested_enable_evmcs, +- .nested_get_evmcs_version = nested_get_evmcs_version, ++ .nested_get_evmcs_version = NULL, + + .need_emulation_on_page_fault = svm_need_emulation_on_page_fault, + }; +diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c +index 4b830c0adcf8..d5c12d5a5905 100644 +--- a/arch/x86/kvm/vmx/vmx.c ++++ b/arch/x86/kvm/vmx/vmx.c +@@ -7733,6 +7733,7 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = { + .set_nested_state = NULL, + .get_vmcs12_pages = NULL, + .nested_enable_evmcs = NULL, ++ .nested_get_evmcs_version = NULL, + .need_emulation_on_page_fault = vmx_need_emulation_on_page_fault, + }; + +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index cbced8ff29d4..1f80fd560ede 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -6547,12 +6547,13 @@ restart: + unsigned long rflags = kvm_x86_ops->get_rflags(vcpu); + toggle_interruptibility(vcpu, ctxt->interruptibility); + vcpu->arch.emulate_regs_need_sync_to_vcpu = false; +- kvm_rip_write(vcpu, ctxt->eip); +- if (r == EMULATE_DONE && ctxt->tf) +- kvm_vcpu_do_singlestep(vcpu, &r); + if (!ctxt->have_exception || +- exception_type(ctxt->exception.vector) == EXCPT_TRAP) ++ exception_type(ctxt->exception.vector) == EXCPT_TRAP) { ++ kvm_rip_write(vcpu, ctxt->eip); ++ if (r == EMULATE_DONE && ctxt->tf) ++ kvm_vcpu_do_singlestep(vcpu, &r); + __kvm_set_rflags(vcpu, ctxt->eflags); ++ } + + /* + * For STI, interrupts are shadowed; so KVM_REQ_EVENT will +diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c +index 6a9a77a403c9..e14e95ea7338 100644 +--- a/arch/x86/mm/pageattr.c ++++ b/arch/x86/mm/pageattr.c +@@ -516,7 +516,7 @@ static inline void check_conflict(int warnlvl, pgprot_t prot, pgprotval_t val, + */ + static inline pgprot_t static_protections(pgprot_t prot, unsigned long start, + unsigned long pfn, unsigned long npg, +- int warnlvl) ++ unsigned long lpsize, int warnlvl) + { + pgprotval_t forbidden, res; + unsigned long end; +@@ -535,9 +535,17 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long start, + check_conflict(warnlvl, prot, res, start, end, pfn, "Text NX"); + forbidden = res; + +- res = protect_kernel_text_ro(start, end); +- check_conflict(warnlvl, prot, res, start, end, pfn, "Text RO"); +- forbidden |= res; ++ /* ++ * Special case to preserve a large page. If the change spawns the ++ * full large page mapping then there is no point to split it ++ * up. Happens with ftrace and is going to be removed once ftrace ++ * switched to text_poke(). ++ */ ++ if (lpsize != (npg * PAGE_SIZE) || (start & (lpsize - 1))) { ++ res = protect_kernel_text_ro(start, end); ++ check_conflict(warnlvl, prot, res, start, end, pfn, "Text RO"); ++ forbidden |= res; ++ } + + /* Check the PFN directly */ + res = protect_pci_bios(pfn, pfn + npg - 1); +@@ -819,7 +827,7 @@ static int __should_split_large_page(pte_t *kpte, unsigned long address, + * extra conditional required here. + */ + chk_prot = static_protections(old_prot, lpaddr, old_pfn, numpages, +- CPA_CONFLICT); ++ psize, CPA_CONFLICT); + + if (WARN_ON_ONCE(pgprot_val(chk_prot) != pgprot_val(old_prot))) { + /* +@@ -855,7 +863,7 @@ static int __should_split_large_page(pte_t *kpte, unsigned long address, + * protection requirement in the large page. + */ + new_prot = static_protections(req_prot, lpaddr, old_pfn, numpages, +- CPA_DETECT); ++ psize, CPA_DETECT); + + /* + * If there is a conflict, split the large page. +@@ -906,7 +914,8 @@ static void split_set_pte(struct cpa_data *cpa, pte_t *pte, unsigned long pfn, + if (!cpa->force_static_prot) + goto set; + +- prot = static_protections(ref_prot, address, pfn, npg, CPA_PROTECT); ++ /* Hand in lpsize = 0 to enforce the protection mechanism */ ++ prot = static_protections(ref_prot, address, pfn, npg, 0, CPA_PROTECT); + + if (pgprot_val(prot) == pgprot_val(ref_prot)) + goto set; +@@ -1503,7 +1512,8 @@ repeat: + pgprot_val(new_prot) |= pgprot_val(cpa->mask_set); + + cpa_inc_4k_install(); +- new_prot = static_protections(new_prot, address, pfn, 1, ++ /* Hand in lpsize = 0 to enforce the protection mechanism */ ++ new_prot = static_protections(new_prot, address, pfn, 1, 0, + CPA_PROTECT); + + new_prot = pgprot_clear_protnone_bits(new_prot); +diff --git a/drivers/auxdisplay/panel.c b/drivers/auxdisplay/panel.c +index e06de63497cf..e6bd727da503 100644 +--- a/drivers/auxdisplay/panel.c ++++ b/drivers/auxdisplay/panel.c +@@ -1617,6 +1617,8 @@ static void panel_attach(struct parport *port) + return; + + err_lcd_unreg: ++ if (scan_timer.function) ++ del_timer_sync(&scan_timer); + if (lcd.enabled) + charlcd_unregister(lcd.charlcd); + err_unreg_device: +diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c +index 3ac6a5d18071..b90dbcd99c03 100644 +--- a/drivers/block/xen-blkback/xenbus.c ++++ b/drivers/block/xen-blkback/xenbus.c +@@ -965,6 +965,7 @@ static int read_per_ring_refs(struct xen_blkif_ring *ring, const char *dir) + } + } + ++ err = -ENOMEM; + for (i = 0; i < nr_grefs * XEN_BLKIF_REQS_PER_PAGE; i++) { + req = kzalloc(sizeof(*req), GFP_KERNEL); + if (!req) +@@ -987,7 +988,7 @@ static int read_per_ring_refs(struct xen_blkif_ring *ring, const char *dir) + err = xen_blkif_map(ring, ring_ref, nr_grefs, evtchn); + if (err) { + xenbus_dev_fatal(dev, err, "mapping ring-ref port %u", evtchn); +- return err; ++ goto fail; + } + + return 0; +@@ -1007,8 +1008,7 @@ fail: + } + kfree(req); + } +- return -ENOMEM; +- ++ return err; + } + + static int connect_ring(struct backend_info *be) +diff --git a/drivers/bus/hisi_lpc.c b/drivers/bus/hisi_lpc.c +index 19d7b6ff2f17..20c957185af2 100644 +--- a/drivers/bus/hisi_lpc.c ++++ b/drivers/bus/hisi_lpc.c +@@ -456,6 +456,17 @@ struct hisi_lpc_acpi_cell { + size_t pdata_size; + }; + ++static void hisi_lpc_acpi_remove(struct device *hostdev) ++{ ++ struct acpi_device *adev = ACPI_COMPANION(hostdev); ++ struct acpi_device *child; ++ ++ device_for_each_child(hostdev, NULL, hisi_lpc_acpi_remove_subdev); ++ ++ list_for_each_entry(child, &adev->children, node) ++ acpi_device_clear_enumerated(child); ++} ++ + /* + * hisi_lpc_acpi_probe - probe children for ACPI FW + * @hostdev: LPC host device pointer +@@ -555,8 +566,7 @@ static int hisi_lpc_acpi_probe(struct device *hostdev) + return 0; + + fail: +- device_for_each_child(hostdev, NULL, +- hisi_lpc_acpi_remove_subdev); ++ hisi_lpc_acpi_remove(hostdev); + return ret; + } + +@@ -569,6 +579,10 @@ static int hisi_lpc_acpi_probe(struct device *dev) + { + return -ENODEV; + } ++ ++static void hisi_lpc_acpi_remove(struct device *hostdev) ++{ ++} + #endif // CONFIG_ACPI + + /* +@@ -606,24 +620,27 @@ static int hisi_lpc_probe(struct platform_device *pdev) + range->fwnode = dev->fwnode; + range->flags = LOGIC_PIO_INDIRECT; + range->size = PIO_INDIRECT_SIZE; ++ range->hostdata = lpcdev; ++ range->ops = &hisi_lpc_ops; ++ lpcdev->io_host = range; + + ret = logic_pio_register_range(range); + if (ret) { + dev_err(dev, "register IO range failed (%d)!\n", ret); + return ret; + } +- lpcdev->io_host = range; + + /* register the LPC host PIO resources */ + if (acpi_device) + ret = hisi_lpc_acpi_probe(dev); + else + ret = of_platform_populate(dev->of_node, NULL, NULL, dev); +- if (ret) ++ if (ret) { ++ logic_pio_unregister_range(range); + return ret; ++ } + +- lpcdev->io_host->hostdata = lpcdev; +- lpcdev->io_host->ops = &hisi_lpc_ops; ++ dev_set_drvdata(dev, lpcdev); + + io_end = lpcdev->io_host->io_start + lpcdev->io_host->size; + dev_info(dev, "registered range [%pa - %pa]\n", +@@ -632,6 +649,23 @@ static int hisi_lpc_probe(struct platform_device *pdev) + return ret; + } + ++static int hisi_lpc_remove(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct acpi_device *acpi_device = ACPI_COMPANION(dev); ++ struct hisi_lpc_dev *lpcdev = dev_get_drvdata(dev); ++ struct logic_pio_hwaddr *range = lpcdev->io_host; ++ ++ if (acpi_device) ++ hisi_lpc_acpi_remove(dev); ++ else ++ of_platform_depopulate(dev); ++ ++ logic_pio_unregister_range(range); ++ ++ return 0; ++} ++ + static const struct of_device_id hisi_lpc_of_match[] = { + { .compatible = "hisilicon,hip06-lpc", }, + { .compatible = "hisilicon,hip07-lpc", }, +@@ -645,5 +679,6 @@ static struct platform_driver hisi_lpc_driver = { + .acpi_match_table = ACPI_PTR(hisi_lpc_acpi_match), + }, + .probe = hisi_lpc_probe, ++ .remove = hisi_lpc_remove, + }; + builtin_platform_driver(hisi_lpc_driver); +diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c +index f79eede71c62..edefa669153f 100644 +--- a/drivers/crypto/ccp/ccp-dev.c ++++ b/drivers/crypto/ccp/ccp-dev.c +@@ -540,6 +540,10 @@ int ccp_dev_suspend(struct sp_device *sp, pm_message_t state) + unsigned long flags; + unsigned int i; + ++ /* If there's no device there's nothing to do */ ++ if (!ccp) ++ return 0; ++ + spin_lock_irqsave(&ccp->cmd_lock, flags); + + ccp->suspending = 1; +@@ -564,6 +568,10 @@ int ccp_dev_resume(struct sp_device *sp) + unsigned long flags; + unsigned int i; + ++ /* If there's no device there's nothing to do */ ++ if (!ccp) ++ return 0; ++ + spin_lock_irqsave(&ccp->cmd_lock, flags); + + ccp->suspending = 0; +diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c +index 89d710899010..de8bfd9a76e9 100644 +--- a/drivers/dma/ste_dma40.c ++++ b/drivers/dma/ste_dma40.c +@@ -142,7 +142,7 @@ enum d40_events { + * when the DMA hw is powered off. + * TODO: Add save/restore of D40_DREG_GCC on dma40 v3 or later, if that works. + */ +-static u32 d40_backup_regs[] = { ++static __maybe_unused u32 d40_backup_regs[] = { + D40_DREG_LCPA, + D40_DREG_LCLA, + D40_DREG_PRMSE, +@@ -211,7 +211,7 @@ static u32 d40_backup_regs_v4b[] = { + + #define BACKUP_REGS_SZ_V4B ARRAY_SIZE(d40_backup_regs_v4b) + +-static u32 d40_backup_regs_chan[] = { ++static __maybe_unused u32 d40_backup_regs_chan[] = { + D40_CHAN_REG_SSCFG, + D40_CHAN_REG_SSELT, + D40_CHAN_REG_SSPTR, +diff --git a/drivers/dma/stm32-mdma.c b/drivers/dma/stm32-mdma.c +index d6e919d3936a..1311de74bfdd 100644 +--- a/drivers/dma/stm32-mdma.c ++++ b/drivers/dma/stm32-mdma.c +@@ -1366,7 +1366,7 @@ static irqreturn_t stm32_mdma_irq_handler(int irq, void *devid) + + chan = &dmadev->chan[id]; + if (!chan) { +- dev_err(chan2dev(chan), "MDMA channel not initialized\n"); ++ dev_dbg(mdma2dev(dmadev), "MDMA channel not initialized\n"); + goto exit; + } + +diff --git a/drivers/dma/ti/omap-dma.c b/drivers/dma/ti/omap-dma.c +index ba2489d4ea24..ba27802efcd0 100644 +--- a/drivers/dma/ti/omap-dma.c ++++ b/drivers/dma/ti/omap-dma.c +@@ -1234,7 +1234,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_interleaved( + if (src_icg) { + d->ccr |= CCR_SRC_AMODE_DBLIDX; + d->ei = 1; +- d->fi = src_icg; ++ d->fi = src_icg + 1; + } else if (xt->src_inc) { + d->ccr |= CCR_SRC_AMODE_POSTINC; + d->fi = 0; +@@ -1249,7 +1249,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_interleaved( + if (dst_icg) { + d->ccr |= CCR_DST_AMODE_DBLIDX; + sg->ei = 1; +- sg->fi = dst_icg; ++ sg->fi = dst_icg + 1; + } else if (xt->dst_inc) { + d->ccr |= CCR_DST_AMODE_POSTINC; + sg->fi = 0; +diff --git a/drivers/fsi/fsi-scom.c b/drivers/fsi/fsi-scom.c +index 343153d47e5b..004dc03ccf09 100644 +--- a/drivers/fsi/fsi-scom.c ++++ b/drivers/fsi/fsi-scom.c +@@ -38,8 +38,7 @@ + #define SCOM_STATUS_PIB_RESP_MASK 0x00007000 + #define SCOM_STATUS_PIB_RESP_SHIFT 12 + +-#define SCOM_STATUS_ANY_ERR (SCOM_STATUS_ERR_SUMMARY | \ +- SCOM_STATUS_PROTECTION | \ ++#define SCOM_STATUS_ANY_ERR (SCOM_STATUS_PROTECTION | \ + SCOM_STATUS_PARITY | \ + SCOM_STATUS_PIB_ABORT | \ + SCOM_STATUS_PIB_RESP_MASK) +@@ -251,11 +250,6 @@ static int handle_fsi2pib_status(struct scom_device *scom, uint32_t status) + /* Return -EBUSY on PIB abort to force a retry */ + if (status & SCOM_STATUS_PIB_ABORT) + return -EBUSY; +- if (status & SCOM_STATUS_ERR_SUMMARY) { +- fsi_device_write(scom->fsi_dev, SCOM_FSI2PIB_RESET_REG, &dummy, +- sizeof(uint32_t)); +- return -EIO; +- } + return 0; + } + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +index 9b384a94d2f3..3e35a8f2c5e5 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +@@ -574,6 +574,7 @@ static const struct amdgpu_px_quirk amdgpu_px_quirk_list[] = { + { 0x1002, 0x6900, 0x1002, 0x0124, AMDGPU_PX_QUIRK_FORCE_ATPX }, + { 0x1002, 0x6900, 0x1028, 0x0812, AMDGPU_PX_QUIRK_FORCE_ATPX }, + { 0x1002, 0x6900, 0x1028, 0x0813, AMDGPU_PX_QUIRK_FORCE_ATPX }, ++ { 0x1002, 0x699f, 0x1028, 0x0814, AMDGPU_PX_QUIRK_FORCE_ATPX }, + { 0x1002, 0x6900, 0x1025, 0x125A, AMDGPU_PX_QUIRK_FORCE_ATPX }, + { 0x1002, 0x6900, 0x17AA, 0x3806, AMDGPU_PX_QUIRK_FORCE_ATPX }, + { 0, 0, 0, 0, 0 }, +diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +index 0332177c0302..2a3090c45e6b 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +@@ -588,14 +588,14 @@ static void gfx_v9_0_check_if_need_gfxoff(struct amdgpu_device *adev) + case CHIP_VEGA20: + break; + case CHIP_RAVEN: +- if (adev->rev_id >= 0x8 || adev->pdev->device == 0x15d8) +- break; +- if ((adev->gfx.rlc_fw_version != 106 && +- adev->gfx.rlc_fw_version < 531) || +- (adev->gfx.rlc_fw_version == 53815) || +- (adev->gfx.rlc_feature_version < 1) || +- !adev->gfx.rlc.is_rlc_v2_1) ++ if (!(adev->rev_id >= 0x8 || adev->pdev->device == 0x15d8) ++ &&((adev->gfx.rlc_fw_version != 106 && ++ adev->gfx.rlc_fw_version < 531) || ++ (adev->gfx.rlc_fw_version == 53815) || ++ (adev->gfx.rlc_feature_version < 1) || ++ !adev->gfx.rlc.is_rlc_v2_1)) + adev->pm.pp_feature &= ~PP_GFXOFF_MASK; ++ + if (adev->pm.pp_feature & PP_GFXOFF_MASK) + adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG | + AMD_PG_SUPPORT_CP | +diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c +index 2854399856ba..4aebe21e6ad9 100644 +--- a/drivers/gpu/drm/ast/ast_main.c ++++ b/drivers/gpu/drm/ast/ast_main.c +@@ -131,8 +131,8 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post) + + + /* Enable extended register access */ +- ast_enable_mmio(dev); + ast_open_key(ast); ++ ast_enable_mmio(dev); + + /* Find out whether P2A works or whether to use device-tree */ + ast_detect_config_mode(dev, &scu_rev); +@@ -576,6 +576,9 @@ void ast_driver_unload(struct drm_device *dev) + { + struct ast_private *ast = dev->dev_private; + ++ /* enable standard VGA decode */ ++ ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x04); ++ + ast_release_firmware(dev); + kfree(ast->dp501_fw_addr); + ast_mode_fini(dev); +diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c +index 97fed0627d1c..74da15a3341a 100644 +--- a/drivers/gpu/drm/ast/ast_mode.c ++++ b/drivers/gpu/drm/ast/ast_mode.c +@@ -601,7 +601,7 @@ static int ast_crtc_mode_set(struct drm_crtc *crtc, + return -EINVAL; + ast_open_key(ast); + +- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x04); ++ ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06); + + ast_set_std_reg(crtc, adjusted_mode, &vbios_mode); + ast_set_crtc_reg(crtc, adjusted_mode, &vbios_mode); +diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c +index f7d421359d56..c1d1ac51d1c2 100644 +--- a/drivers/gpu/drm/ast/ast_post.c ++++ b/drivers/gpu/drm/ast/ast_post.c +@@ -46,7 +46,7 @@ void ast_enable_mmio(struct drm_device *dev) + { + struct ast_private *ast = dev->dev_private; + +- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x04); ++ ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06); + } + + +diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c b/drivers/gpu/drm/bridge/ti-tfp410.c +index 3a8af9978ebd..791f164bdadc 100644 +--- a/drivers/gpu/drm/bridge/ti-tfp410.c ++++ b/drivers/gpu/drm/bridge/ti-tfp410.c +@@ -66,7 +66,12 @@ static int tfp410_get_modes(struct drm_connector *connector) + + drm_connector_update_edid_property(connector, edid); + +- return drm_add_edid_modes(connector, edid); ++ ret = drm_add_edid_modes(connector, edid); ++ ++ kfree(edid); ++ ++ return ret; ++ + fallback: + /* No EDID, fallback on the XGA standard modes */ + ret = drm_add_modes_noedid(connector, 1920, 1200); +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 1ad88e6d7c04..d485d49c473b 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -1569,6 +1569,12 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) + + pci_set_master(pdev); + ++ /* ++ * We don't have a max segment size, so set it to the max so sg's ++ * debugging layer doesn't complain ++ */ ++ dma_set_max_seg_size(&pdev->dev, UINT_MAX); ++ + /* overlay on gen2 is broken and can't address above 1G */ + if (IS_GEN(dev_priv, 2)) { + ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(30)); +diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c +index 94d3992b599d..724627afdedc 100644 +--- a/drivers/gpu/drm/i915/i915_vgpu.c ++++ b/drivers/gpu/drm/i915/i915_vgpu.c +@@ -101,6 +101,9 @@ static struct _balloon_info_ bl_info; + static void vgt_deballoon_space(struct i915_ggtt *ggtt, + struct drm_mm_node *node) + { ++ if (!drm_mm_node_allocated(node)) ++ return; ++ + DRM_DEBUG_DRIVER("deballoon space: range [0x%llx - 0x%llx] %llu KiB.\n", + node->start, + node->start + node->size, +diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c +index 8839eaea8371..d89120dcac67 100644 +--- a/drivers/gpu/drm/i915/intel_dp_mst.c ++++ b/drivers/gpu/drm/i915/intel_dp_mst.c +@@ -535,7 +535,15 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo + + intel_attach_force_audio_property(connector); + intel_attach_broadcast_rgb_property(connector); +- drm_connector_attach_max_bpc_property(connector, 6, 12); ++ ++ /* ++ * Reuse the prop from the SST connector because we're ++ * not allowed to create new props after device registration. ++ */ ++ connector->max_bpc_property = ++ intel_dp->attached_connector->base.max_bpc_property; ++ if (connector->max_bpc_property) ++ drm_connector_attach_max_bpc_property(connector, 6, 12); + + return connector; + +diff --git a/drivers/gpu/drm/i915/intel_vdsc.c b/drivers/gpu/drm/i915/intel_vdsc.c +index 3f9921ba4a76..eb978e7238c2 100644 +--- a/drivers/gpu/drm/i915/intel_vdsc.c ++++ b/drivers/gpu/drm/i915/intel_vdsc.c +@@ -539,7 +539,7 @@ static void intel_configure_pps_for_dsc_encoder(struct intel_encoder *encoder, + pps_val |= DSC_PIC_HEIGHT(vdsc_cfg->pic_height) | + DSC_PIC_WIDTH(vdsc_cfg->pic_width / num_vdsc_instances); + DRM_INFO("PPS2 = 0x%08x\n", pps_val); +- if (encoder->type == INTEL_OUTPUT_EDP) { ++ if (cpu_transcoder == TRANSCODER_EDP) { + I915_WRITE(DSCA_PICTURE_PARAMETER_SET_2, pps_val); + /* + * If 2 VDSC instances are needed, configure PPS for second +diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c +index 35ddbec1375a..671c90f34ede 100644 +--- a/drivers/gpu/drm/scheduler/sched_entity.c ++++ b/drivers/gpu/drm/scheduler/sched_entity.c +@@ -95,7 +95,7 @@ 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_peek(&entity->job_queue) == NULL) ++ spsc_queue_count(&entity->job_queue) == 0) + return true; + + return false; +@@ -281,7 +281,7 @@ void drm_sched_entity_fini(struct drm_sched_entity *entity) + /* Consumption of existing IBs wasn't completed. Forcefully + * remove them here. + */ +- if (spsc_queue_peek(&entity->job_queue)) { ++ if (spsc_queue_count(&entity->job_queue)) { + if (sched) { + /* Park the kernel for a moment to make sure it isn't processing + * our enity. +diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c +index 34e2b3f9d540..4effce12607b 100644 +--- a/drivers/hid/hid-logitech-hidpp.c ++++ b/drivers/hid/hid-logitech-hidpp.c +@@ -3769,8 +3769,6 @@ static const struct hid_device_id hidpp_devices[] = { + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC332) }, + { /* Logitech G502 Hero Gaming Mouse over USB */ + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC08B) }, +- { /* Logitech G700 Gaming Mouse over USB */ +- HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC06B) }, + { /* Logitech G700s Gaming Mouse over USB */ + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC07C) }, + { /* Logitech G703 Gaming Mouse over USB */ +diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c +index c0378c3de9a4..91dfeba62485 100644 +--- a/drivers/hwtracing/intel_th/pci.c ++++ b/drivers/hwtracing/intel_th/pci.c +@@ -164,6 +164,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa1a6), + .driver_data = (kernel_ulong_t)0, + }, ++ { ++ /* Lewisburg PCH */ ++ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa226), ++ .driver_data = (kernel_ulong_t)0, ++ }, + { + /* Gemini Lake */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e), +@@ -199,6 +204,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x45c5), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, ++ { ++ /* Tiger Lake PCH */ ++ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa0a6), ++ .driver_data = (kernel_ulong_t)&intel_th_2x, ++ }, + { 0 }, + }; + +diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c +index e55b902560de..181e7ff1ec4f 100644 +--- a/drivers/hwtracing/stm/core.c ++++ b/drivers/hwtracing/stm/core.c +@@ -1276,7 +1276,6 @@ int stm_source_register_device(struct device *parent, + + err: + put_device(&src->dev); +- kfree(src); + + return err; + } +diff --git a/drivers/i2c/busses/i2c-emev2.c b/drivers/i2c/busses/i2c-emev2.c +index 35b302d983e0..959d4912ec0d 100644 +--- a/drivers/i2c/busses/i2c-emev2.c ++++ b/drivers/i2c/busses/i2c-emev2.c +@@ -69,6 +69,7 @@ struct em_i2c_device { + struct completion msg_done; + struct clk *sclk; + struct i2c_client *slave; ++ int irq; + }; + + static inline void em_clear_set_bit(struct em_i2c_device *priv, u8 clear, u8 set, u8 reg) +@@ -339,6 +340,12 @@ static int em_i2c_unreg_slave(struct i2c_client *slave) + + writeb(0, priv->base + I2C_OFS_SVA0); + ++ /* ++ * Wait for interrupt to finish. New slave irqs cannot happen because we ++ * cleared the slave address and, thus, only extension codes will be ++ * detected which do not use the slave ptr. ++ */ ++ synchronize_irq(priv->irq); + priv->slave = NULL; + + return 0; +@@ -355,7 +362,7 @@ static int em_i2c_probe(struct platform_device *pdev) + { + struct em_i2c_device *priv; + struct resource *r; +- int irq, ret; ++ int ret; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) +@@ -390,8 +397,8 @@ static int em_i2c_probe(struct platform_device *pdev) + + em_i2c_reset(&priv->adap); + +- irq = platform_get_irq(pdev, 0); +- ret = devm_request_irq(&pdev->dev, irq, em_i2c_irq_handler, 0, ++ priv->irq = platform_get_irq(pdev, 0); ++ ret = devm_request_irq(&pdev->dev, priv->irq, em_i2c_irq_handler, 0, + "em_i2c", priv); + if (ret) + goto err_clk; +@@ -401,7 +408,8 @@ static int em_i2c_probe(struct platform_device *pdev) + if (ret) + goto err_clk; + +- dev_info(&pdev->dev, "Added i2c controller %d, irq %d\n", priv->adap.nr, irq); ++ dev_info(&pdev->dev, "Added i2c controller %d, irq %d\n", priv->adap.nr, ++ priv->irq); + + return 0; + +diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c +index c46c4bddc7ca..cba325eb852f 100644 +--- a/drivers/i2c/busses/i2c-piix4.c ++++ b/drivers/i2c/busses/i2c-piix4.c +@@ -91,7 +91,7 @@ + #define SB800_PIIX4_PORT_IDX_MASK 0x06 + #define SB800_PIIX4_PORT_IDX_SHIFT 1 + +-/* On kerncz, SmBus0Sel is at bit 20:19 of PMx00 DecodeEn */ ++/* On kerncz and Hudson2, SmBus0Sel is at bit 20:19 of PMx00 DecodeEn */ + #define SB800_PIIX4_PORT_IDX_KERNCZ 0x02 + #define SB800_PIIX4_PORT_IDX_MASK_KERNCZ 0x18 + #define SB800_PIIX4_PORT_IDX_SHIFT_KERNCZ 3 +@@ -358,18 +358,16 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, + /* Find which register is used for port selection */ + if (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD || + PIIX4_dev->vendor == PCI_VENDOR_ID_HYGON) { +- switch (PIIX4_dev->device) { +- case PCI_DEVICE_ID_AMD_KERNCZ_SMBUS: ++ if (PIIX4_dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS || ++ (PIIX4_dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS && ++ PIIX4_dev->revision >= 0x1F)) { + piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_KERNCZ; + piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK_KERNCZ; + piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT_KERNCZ; +- break; +- case PCI_DEVICE_ID_AMD_HUDSON2_SMBUS: +- default: ++ } else { + piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_ALT; + piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK; + piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT; +- break; + } + } else { + if (!request_muxed_region(SB800_PIIX4_SMB_IDX, 2, +diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c +index d39a4606f72d..531c01100b56 100644 +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -139,6 +139,7 @@ struct rcar_i2c_priv { + enum dma_data_direction dma_direction; + + struct reset_control *rstc; ++ int irq; + }; + + #define rcar_i2c_priv_to_dev(p) ((p)->adap.dev.parent) +@@ -861,9 +862,11 @@ static int rcar_unreg_slave(struct i2c_client *slave) + + WARN_ON(!priv->slave); + ++ /* disable irqs and ensure none is running before clearing ptr */ + rcar_i2c_write(priv, ICSIER, 0); + rcar_i2c_write(priv, ICSCR, 0); + ++ synchronize_irq(priv->irq); + priv->slave = NULL; + + pm_runtime_put(rcar_i2c_priv_to_dev(priv)); +@@ -918,7 +921,7 @@ static int rcar_i2c_probe(struct platform_device *pdev) + struct i2c_adapter *adap; + struct device *dev = &pdev->dev; + struct i2c_timings i2c_t; +- int irq, ret; ++ int ret; + + /* Otherwise logic will break because some bytes must always use PIO */ + BUILD_BUG_ON_MSG(RCAR_MIN_DMA_LEN < 3, "Invalid min DMA length"); +@@ -984,10 +987,10 @@ static int rcar_i2c_probe(struct platform_device *pdev) + pm_runtime_put(dev); + + +- irq = platform_get_irq(pdev, 0); +- ret = devm_request_irq(dev, irq, rcar_i2c_irq, 0, dev_name(dev), priv); ++ priv->irq = platform_get_irq(pdev, 0); ++ ret = devm_request_irq(dev, priv->irq, rcar_i2c_irq, 0, dev_name(dev), priv); + if (ret < 0) { +- dev_err(dev, "cannot get irq %d\n", irq); ++ dev_err(dev, "cannot get irq %d\n", priv->irq); + goto out_pm_disable; + } + +diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c +index e4b13a32692a..5e5f7dd82c50 100644 +--- a/drivers/infiniband/core/umem_odp.c ++++ b/drivers/infiniband/core/umem_odp.c +@@ -114,10 +114,6 @@ static int ib_umem_notifier_release_trampoline(struct ib_umem_odp *umem_odp, + * prevent any further fault handling on this MR. + */ + ib_umem_notifier_start_account(umem_odp); +- umem_odp->dying = 1; +- /* Make sure that the fact the umem is dying is out before we release +- * all pending page faults. */ +- smp_wmb(); + complete_all(&umem_odp->notifier_completion); + umem->context->invalidate_range(umem_odp, ib_umem_start(umem), + ib_umem_end(umem)); +diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c +index f6e5351ba4d5..fda3dfd6f87b 100644 +--- a/drivers/infiniband/hw/mlx5/odp.c ++++ b/drivers/infiniband/hw/mlx5/odp.c +@@ -581,7 +581,6 @@ static int pagefault_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr, + u32 flags) + { + int npages = 0, current_seq, page_shift, ret, np; +- bool implicit = false; + struct ib_umem_odp *odp_mr = to_ib_umem_odp(mr->umem); + bool downgrade = flags & MLX5_PF_FLAGS_DOWNGRADE; + bool prefetch = flags & MLX5_PF_FLAGS_PREFETCH; +@@ -596,7 +595,6 @@ static int pagefault_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr, + if (IS_ERR(odp)) + return PTR_ERR(odp); + mr = odp->private; +- implicit = true; + } else { + odp = odp_mr; + } +@@ -684,19 +682,15 @@ next_mr: + + out: + if (ret == -EAGAIN) { +- if (implicit || !odp->dying) { +- unsigned long timeout = +- msecs_to_jiffies(MMU_NOTIFIER_TIMEOUT); +- +- if (!wait_for_completion_timeout( +- &odp->notifier_completion, +- timeout)) { +- mlx5_ib_warn(dev, "timeout waiting for mmu notifier. seq %d against %d. notifiers_count=%d\n", +- current_seq, odp->notifiers_seq, odp->notifiers_count); +- } +- } else { +- /* The MR is being killed, kill the QP as well. */ +- ret = -EFAULT; ++ unsigned long timeout = msecs_to_jiffies(MMU_NOTIFIER_TIMEOUT); ++ ++ if (!wait_for_completion_timeout(&odp->notifier_completion, ++ timeout)) { ++ mlx5_ib_warn( ++ dev, ++ "timeout waiting for mmu notifier. seq %d against %d. notifiers_count=%d\n", ++ current_seq, odp->notifiers_seq, ++ odp->notifiers_count); + } + } + +diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c +index 379318266468..8c02d2283d64 100644 +--- a/drivers/iommu/dma-iommu.c ++++ b/drivers/iommu/dma-iommu.c +@@ -710,7 +710,7 @@ static int __finalise_sg(struct device *dev, struct scatterlist *sg, int nents, + * - and wouldn't make the resulting output segment too long + */ + if (cur_len && !s_iova_off && (dma_addr & seg_mask) && +- (cur_len + s_length <= max_len)) { ++ (max_len - cur_len >= s_length)) { + /* ...then concatenate it with the previous one */ + cur_len += s_length; + } else { +diff --git a/drivers/media/platform/omap/omap_vout_vrfb.c b/drivers/media/platform/omap/omap_vout_vrfb.c +index 29e3f5da59c1..11ec048929e8 100644 +--- a/drivers/media/platform/omap/omap_vout_vrfb.c ++++ b/drivers/media/platform/omap/omap_vout_vrfb.c +@@ -253,8 +253,7 @@ int omap_vout_prepare_vrfb(struct omap_vout_device *vout, + */ + + pixsize = vout->bpp * vout->vrfb_bpp; +- dst_icg = ((MAX_PIXELS_PER_LINE * pixsize) - +- (vout->pix.width * vout->bpp)) + 1; ++ dst_icg = MAX_PIXELS_PER_LINE * pixsize - vout->pix.width * vout->bpp; + + xt->src_start = vout->buf_phy_addr[vb->i]; + xt->dst_start = vout->vrfb_context[vb->i].paddr[0]; +diff --git a/drivers/misc/habanalabs/goya/goya.c b/drivers/misc/habanalabs/goya/goya.c +index 02d116b01a1a..ac6b252a1ddc 100644 +--- a/drivers/misc/habanalabs/goya/goya.c ++++ b/drivers/misc/habanalabs/goya/goya.c +@@ -2716,9 +2716,10 @@ void goya_ring_doorbell(struct hl_device *hdev, u32 hw_queue_id, u32 pi) + GOYA_ASYNC_EVENT_ID_PI_UPDATE); + } + +-void goya_flush_pq_write(struct hl_device *hdev, u64 *pq, u64 exp_val) ++void goya_pqe_write(struct hl_device *hdev, __le64 *pqe, struct hl_bd *bd) + { +- /* Not needed in Goya */ ++ /* The QMANs are on the SRAM so need to copy to IO space */ ++ memcpy_toio((void __iomem *) pqe, bd, sizeof(struct hl_bd)); + } + + static void *goya_dma_alloc_coherent(struct hl_device *hdev, size_t size, +@@ -3310,9 +3311,11 @@ static int goya_validate_dma_pkt_no_mmu(struct hl_device *hdev, + int rc; + + dev_dbg(hdev->dev, "DMA packet details:\n"); +- dev_dbg(hdev->dev, "source == 0x%llx\n", user_dma_pkt->src_addr); +- dev_dbg(hdev->dev, "destination == 0x%llx\n", user_dma_pkt->dst_addr); +- dev_dbg(hdev->dev, "size == %u\n", user_dma_pkt->tsize); ++ dev_dbg(hdev->dev, "source == 0x%llx\n", ++ le64_to_cpu(user_dma_pkt->src_addr)); ++ dev_dbg(hdev->dev, "destination == 0x%llx\n", ++ le64_to_cpu(user_dma_pkt->dst_addr)); ++ dev_dbg(hdev->dev, "size == %u\n", le32_to_cpu(user_dma_pkt->tsize)); + + ctl = le32_to_cpu(user_dma_pkt->ctl); + user_dir = (ctl & GOYA_PKT_LIN_DMA_CTL_DMA_DIR_MASK) >> +@@ -3341,9 +3344,11 @@ static int goya_validate_dma_pkt_mmu(struct hl_device *hdev, + struct packet_lin_dma *user_dma_pkt) + { + dev_dbg(hdev->dev, "DMA packet details:\n"); +- dev_dbg(hdev->dev, "source == 0x%llx\n", user_dma_pkt->src_addr); +- dev_dbg(hdev->dev, "destination == 0x%llx\n", user_dma_pkt->dst_addr); +- dev_dbg(hdev->dev, "size == %u\n", user_dma_pkt->tsize); ++ dev_dbg(hdev->dev, "source == 0x%llx\n", ++ le64_to_cpu(user_dma_pkt->src_addr)); ++ dev_dbg(hdev->dev, "destination == 0x%llx\n", ++ le64_to_cpu(user_dma_pkt->dst_addr)); ++ dev_dbg(hdev->dev, "size == %u\n", le32_to_cpu(user_dma_pkt->tsize)); + + /* + * WA for HW-23. +@@ -3383,7 +3388,8 @@ static int goya_validate_wreg32(struct hl_device *hdev, + + dev_dbg(hdev->dev, "WREG32 packet details:\n"); + dev_dbg(hdev->dev, "reg_offset == 0x%x\n", reg_offset); +- dev_dbg(hdev->dev, "value == 0x%x\n", wreg_pkt->value); ++ dev_dbg(hdev->dev, "value == 0x%x\n", ++ le32_to_cpu(wreg_pkt->value)); + + if (reg_offset != (mmDMA_CH_0_WR_COMP_ADDR_LO & 0x1FFF)) { + dev_err(hdev->dev, "WREG32 packet with illegal address 0x%x\n", +@@ -3425,12 +3431,13 @@ static int goya_validate_cb(struct hl_device *hdev, + while (cb_parsed_length < parser->user_cb_size) { + enum packet_id pkt_id; + u16 pkt_size; +- void *user_pkt; ++ struct goya_packet *user_pkt; + +- user_pkt = (void *) (uintptr_t) ++ user_pkt = (struct goya_packet *) (uintptr_t) + (parser->user_cb->kernel_address + cb_parsed_length); + +- pkt_id = (enum packet_id) (((*(u64 *) user_pkt) & ++ pkt_id = (enum packet_id) ( ++ (le64_to_cpu(user_pkt->header) & + PACKET_HEADER_PACKET_ID_MASK) >> + PACKET_HEADER_PACKET_ID_SHIFT); + +@@ -3450,7 +3457,8 @@ static int goya_validate_cb(struct hl_device *hdev, + * need to validate here as well because patch_cb() is + * not called in MMU path while this function is called + */ +- rc = goya_validate_wreg32(hdev, parser, user_pkt); ++ rc = goya_validate_wreg32(hdev, ++ parser, (struct packet_wreg32 *) user_pkt); + break; + + case PACKET_WREG_BULK: +@@ -3478,10 +3486,10 @@ static int goya_validate_cb(struct hl_device *hdev, + case PACKET_LIN_DMA: + if (is_mmu) + rc = goya_validate_dma_pkt_mmu(hdev, parser, +- user_pkt); ++ (struct packet_lin_dma *) user_pkt); + else + rc = goya_validate_dma_pkt_no_mmu(hdev, parser, +- user_pkt); ++ (struct packet_lin_dma *) user_pkt); + break; + + case PACKET_MSG_LONG: +@@ -3654,15 +3662,16 @@ static int goya_patch_cb(struct hl_device *hdev, + enum packet_id pkt_id; + u16 pkt_size; + u32 new_pkt_size = 0; +- void *user_pkt, *kernel_pkt; ++ struct goya_packet *user_pkt, *kernel_pkt; + +- user_pkt = (void *) (uintptr_t) ++ user_pkt = (struct goya_packet *) (uintptr_t) + (parser->user_cb->kernel_address + cb_parsed_length); +- kernel_pkt = (void *) (uintptr_t) ++ kernel_pkt = (struct goya_packet *) (uintptr_t) + (parser->patched_cb->kernel_address + + cb_patched_cur_length); + +- pkt_id = (enum packet_id) (((*(u64 *) user_pkt) & ++ pkt_id = (enum packet_id) ( ++ (le64_to_cpu(user_pkt->header) & + PACKET_HEADER_PACKET_ID_MASK) >> + PACKET_HEADER_PACKET_ID_SHIFT); + +@@ -3677,15 +3686,18 @@ static int goya_patch_cb(struct hl_device *hdev, + + switch (pkt_id) { + case PACKET_LIN_DMA: +- rc = goya_patch_dma_packet(hdev, parser, user_pkt, +- kernel_pkt, &new_pkt_size); ++ rc = goya_patch_dma_packet(hdev, parser, ++ (struct packet_lin_dma *) user_pkt, ++ (struct packet_lin_dma *) kernel_pkt, ++ &new_pkt_size); + cb_patched_cur_length += new_pkt_size; + break; + + case PACKET_WREG_32: + memcpy(kernel_pkt, user_pkt, pkt_size); + cb_patched_cur_length += pkt_size; +- rc = goya_validate_wreg32(hdev, parser, kernel_pkt); ++ rc = goya_validate_wreg32(hdev, parser, ++ (struct packet_wreg32 *) kernel_pkt); + break; + + case PACKET_WREG_BULK: +@@ -4245,6 +4257,8 @@ static int goya_unmask_irq_arr(struct hl_device *hdev, u32 *irq_arr, + size_t total_pkt_size; + long result; + int rc; ++ int irq_num_entries, irq_arr_index; ++ __le32 *goya_irq_arr; + + total_pkt_size = sizeof(struct armcp_unmask_irq_arr_packet) + + irq_arr_size; +@@ -4262,8 +4276,16 @@ static int goya_unmask_irq_arr(struct hl_device *hdev, u32 *irq_arr, + if (!pkt) + return -ENOMEM; + +- pkt->length = cpu_to_le32(irq_arr_size / sizeof(irq_arr[0])); +- memcpy(&pkt->irqs, irq_arr, irq_arr_size); ++ irq_num_entries = irq_arr_size / sizeof(irq_arr[0]); ++ pkt->length = cpu_to_le32(irq_num_entries); ++ ++ /* We must perform any necessary endianness conversation on the irq ++ * array being passed to the goya hardware ++ */ ++ for (irq_arr_index = 0, goya_irq_arr = (__le32 *) &pkt->irqs; ++ irq_arr_index < irq_num_entries ; irq_arr_index++) ++ goya_irq_arr[irq_arr_index] = ++ cpu_to_le32(irq_arr[irq_arr_index]); + + pkt->armcp_pkt.ctl = cpu_to_le32(ARMCP_PACKET_UNMASK_RAZWI_IRQ_ARRAY << + ARMCP_PKT_CTL_OPCODE_SHIFT); +@@ -4778,7 +4800,7 @@ static const struct hl_asic_funcs goya_funcs = { + .resume = goya_resume, + .cb_mmap = goya_cb_mmap, + .ring_doorbell = goya_ring_doorbell, +- .flush_pq_write = goya_flush_pq_write, ++ .pqe_write = goya_pqe_write, + .asic_dma_alloc_coherent = goya_dma_alloc_coherent, + .asic_dma_free_coherent = goya_dma_free_coherent, + .get_int_queue_base = goya_get_int_queue_base, +diff --git a/drivers/misc/habanalabs/goya/goyaP.h b/drivers/misc/habanalabs/goya/goyaP.h +index c83cab0d641e..e2040fd331ca 100644 +--- a/drivers/misc/habanalabs/goya/goyaP.h ++++ b/drivers/misc/habanalabs/goya/goyaP.h +@@ -170,7 +170,7 @@ int goya_late_init(struct hl_device *hdev); + void goya_late_fini(struct hl_device *hdev); + + void goya_ring_doorbell(struct hl_device *hdev, u32 hw_queue_id, u32 pi); +-void goya_flush_pq_write(struct hl_device *hdev, u64 *pq, u64 exp_val); ++void goya_pqe_write(struct hl_device *hdev, __le64 *pqe, struct hl_bd *bd); + void goya_update_eq_ci(struct hl_device *hdev, u32 val); + void goya_restore_phase_topology(struct hl_device *hdev); + int goya_context_switch(struct hl_device *hdev, u32 asid); +diff --git a/drivers/misc/habanalabs/habanalabs.h b/drivers/misc/habanalabs/habanalabs.h +index adef7d9d7488..d56ab65d5b2a 100644 +--- a/drivers/misc/habanalabs/habanalabs.h ++++ b/drivers/misc/habanalabs/habanalabs.h +@@ -449,7 +449,11 @@ enum hl_pll_frequency { + * @resume: handles IP specific H/W or SW changes for resume. + * @cb_mmap: maps a CB. + * @ring_doorbell: increment PI on a given QMAN. +- * @flush_pq_write: flush PQ entry write if necessary, WARN if flushing failed. ++ * @pqe_write: Write the PQ entry to the PQ. This is ASIC-specific ++ * function because the PQs are located in different memory areas ++ * per ASIC (SRAM, DRAM, Host memory) and therefore, the method of ++ * writing the PQE must match the destination memory area ++ * properties. + * @asic_dma_alloc_coherent: Allocate coherent DMA memory by calling + * dma_alloc_coherent(). This is ASIC function because + * its implementation is not trivial when the driver +@@ -518,7 +522,8 @@ struct hl_asic_funcs { + int (*cb_mmap)(struct hl_device *hdev, struct vm_area_struct *vma, + u64 kaddress, phys_addr_t paddress, u32 size); + void (*ring_doorbell)(struct hl_device *hdev, u32 hw_queue_id, u32 pi); +- void (*flush_pq_write)(struct hl_device *hdev, u64 *pq, u64 exp_val); ++ void (*pqe_write)(struct hl_device *hdev, __le64 *pqe, ++ struct hl_bd *bd); + void* (*asic_dma_alloc_coherent)(struct hl_device *hdev, size_t size, + dma_addr_t *dma_handle, gfp_t flag); + void (*asic_dma_free_coherent)(struct hl_device *hdev, size_t size, +diff --git a/drivers/misc/habanalabs/hw_queue.c b/drivers/misc/habanalabs/hw_queue.c +index 2894d8975933..bb7679474727 100644 +--- a/drivers/misc/habanalabs/hw_queue.c ++++ b/drivers/misc/habanalabs/hw_queue.c +@@ -290,23 +290,19 @@ static void int_hw_queue_schedule_job(struct hl_cs_job *job) + struct hl_device *hdev = job->cs->ctx->hdev; + struct hl_hw_queue *q = &hdev->kernel_queues[job->hw_queue_id]; + struct hl_bd bd; +- u64 *pi, *pbd = (u64 *) &bd; ++ __le64 *pi; + + bd.ctl = 0; +- bd.len = __cpu_to_le32(job->job_cb_size); +- bd.ptr = __cpu_to_le64((u64) (uintptr_t) job->user_cb); ++ bd.len = cpu_to_le32(job->job_cb_size); ++ bd.ptr = cpu_to_le64((u64) (uintptr_t) job->user_cb); + +- pi = (u64 *) (uintptr_t) (q->kernel_address + ++ pi = (__le64 *) (uintptr_t) (q->kernel_address + + ((q->pi & (q->int_queue_len - 1)) * sizeof(bd))); + +- pi[0] = pbd[0]; +- pi[1] = pbd[1]; +- + q->pi++; + q->pi &= ((q->int_queue_len << 1) - 1); + +- /* Flush PQ entry write. Relevant only for specific ASICs */ +- hdev->asic_funcs->flush_pq_write(hdev, pi, pbd[0]); ++ hdev->asic_funcs->pqe_write(hdev, pi, &bd); + + hdev->asic_funcs->ring_doorbell(hdev, q->hw_queue_id, q->pi); + } +diff --git a/drivers/misc/habanalabs/include/goya/goya_packets.h b/drivers/misc/habanalabs/include/goya/goya_packets.h +index a14407b975e4..ef54bad20509 100644 +--- a/drivers/misc/habanalabs/include/goya/goya_packets.h ++++ b/drivers/misc/habanalabs/include/goya/goya_packets.h +@@ -52,6 +52,19 @@ enum goya_dma_direction { + #define GOYA_PKT_CTL_MB_SHIFT 31 + #define GOYA_PKT_CTL_MB_MASK 0x80000000 + ++/* All packets have, at least, an 8-byte header, which contains ++ * the packet type. The kernel driver uses the packet header for packet ++ * validation and to perform any necessary required preparation before ++ * sending them off to the hardware. ++ */ ++struct goya_packet { ++ __le64 header; ++ /* The rest of the packet data follows. Use the corresponding ++ * packet_XXX struct to deference the data, based on packet type ++ */ ++ u8 contents[0]; ++}; ++ + struct packet_nop { + __le32 reserved; + __le32 ctl; +diff --git a/drivers/misc/habanalabs/irq.c b/drivers/misc/habanalabs/irq.c +index ea9f72ff456c..199791b57caf 100644 +--- a/drivers/misc/habanalabs/irq.c ++++ b/drivers/misc/habanalabs/irq.c +@@ -80,8 +80,7 @@ irqreturn_t hl_irq_handler_cq(int irq, void *arg) + struct hl_cs_job *job; + bool shadow_index_valid; + u16 shadow_index; +- u32 *cq_entry; +- u32 *cq_base; ++ struct hl_cq_entry *cq_entry, *cq_base; + + if (hdev->disabled) { + dev_dbg(hdev->dev, +@@ -90,29 +89,29 @@ irqreturn_t hl_irq_handler_cq(int irq, void *arg) + return IRQ_HANDLED; + } + +- cq_base = (u32 *) (uintptr_t) cq->kernel_address; ++ cq_base = (struct hl_cq_entry *) (uintptr_t) cq->kernel_address; + + while (1) { +- bool entry_ready = ((cq_base[cq->ci] & CQ_ENTRY_READY_MASK) ++ bool entry_ready = ((le32_to_cpu(cq_base[cq->ci].data) & ++ CQ_ENTRY_READY_MASK) + >> CQ_ENTRY_READY_SHIFT); + + if (!entry_ready) + break; + +- cq_entry = (u32 *) &cq_base[cq->ci]; ++ cq_entry = (struct hl_cq_entry *) &cq_base[cq->ci]; + +- /* +- * Make sure we read CQ entry contents after we've ++ /* Make sure we read CQ entry contents after we've + * checked the ownership bit. + */ + dma_rmb(); + +- shadow_index_valid = +- ((*cq_entry & CQ_ENTRY_SHADOW_INDEX_VALID_MASK) ++ shadow_index_valid = ((le32_to_cpu(cq_entry->data) & ++ CQ_ENTRY_SHADOW_INDEX_VALID_MASK) + >> CQ_ENTRY_SHADOW_INDEX_VALID_SHIFT); + +- shadow_index = (u16) +- ((*cq_entry & CQ_ENTRY_SHADOW_INDEX_MASK) ++ shadow_index = (u16) ((le32_to_cpu(cq_entry->data) & ++ CQ_ENTRY_SHADOW_INDEX_MASK) + >> CQ_ENTRY_SHADOW_INDEX_SHIFT); + + queue = &hdev->kernel_queues[cq->hw_queue_id]; +@@ -122,8 +121,7 @@ irqreturn_t hl_irq_handler_cq(int irq, void *arg) + queue_work(hdev->cq_wq, &job->finish_work); + } + +- /* +- * Update ci of the context's queue. There is no ++ /* Update ci of the context's queue. There is no + * need to protect it with spinlock because this update is + * done only inside IRQ and there is a different IRQ per + * queue +@@ -131,7 +129,8 @@ irqreturn_t hl_irq_handler_cq(int irq, void *arg) + queue->ci = hl_queue_inc_ptr(queue->ci); + + /* Clear CQ entry ready bit */ +- cq_base[cq->ci] &= ~CQ_ENTRY_READY_MASK; ++ cq_entry->data = cpu_to_le32(le32_to_cpu(cq_entry->data) & ++ ~CQ_ENTRY_READY_MASK); + + cq->ci = hl_cq_inc_ptr(cq->ci); + +diff --git a/drivers/misc/habanalabs/memory.c b/drivers/misc/habanalabs/memory.c +index 693877e37fd8..924a438ba973 100644 +--- a/drivers/misc/habanalabs/memory.c ++++ b/drivers/misc/habanalabs/memory.c +@@ -1629,6 +1629,8 @@ void hl_vm_ctx_fini(struct hl_ctx *ctx) + dev_dbg(hdev->dev, + "page list 0x%p of asid %d is still alive\n", + phys_pg_list, ctx->asid); ++ atomic64_sub(phys_pg_list->total_size, ++ &hdev->dram_used_mem); + free_phys_pg_pack(hdev, phys_pg_list); + idr_remove(&vm->phys_pg_pack_handles, i); + } +diff --git a/drivers/misc/lkdtm/bugs.c b/drivers/misc/lkdtm/bugs.c +index 17f839dee976..018da2c3f92b 100644 +--- a/drivers/misc/lkdtm/bugs.c ++++ b/drivers/misc/lkdtm/bugs.c +@@ -22,7 +22,7 @@ struct lkdtm_list { + * recurse past the end of THREAD_SIZE by default. + */ + #if defined(CONFIG_FRAME_WARN) && (CONFIG_FRAME_WARN > 0) +-#define REC_STACK_SIZE (CONFIG_FRAME_WARN / 2) ++#define REC_STACK_SIZE (_AC(CONFIG_FRAME_WARN, UL) / 2) + #else + #define REC_STACK_SIZE (THREAD_SIZE / 8) + #endif +@@ -91,7 +91,7 @@ void lkdtm_LOOP(void) + + void lkdtm_EXHAUST_STACK(void) + { +- pr_info("Calling function with %d frame size to depth %d ...\n", ++ pr_info("Calling function with %lu frame size to depth %d ...\n", + REC_STACK_SIZE, recur_count); + recursive_loop(recur_count); + pr_info("FAIL: survived without exhausting stack?!\n"); +diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h +index 6c0173772162..77f7dff7098d 100644 +--- a/drivers/misc/mei/hw-me-regs.h ++++ b/drivers/misc/mei/hw-me-regs.h +@@ -81,6 +81,8 @@ + + #define MEI_DEV_ID_ICP_LP 0x34E0 /* Ice Lake Point LP */ + ++#define MEI_DEV_ID_TGP_LP 0xA0E0 /* Tiger Lake Point LP */ ++ + #define MEI_DEV_ID_MCC 0x4B70 /* Mule Creek Canyon (EHL) */ + #define MEI_DEV_ID_MCC_4 0x4B75 /* Mule Creek Canyon 4 (EHL) */ + +diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c +index 57cb68f5cc64..541538eff8b1 100644 +--- a/drivers/misc/mei/pci-me.c ++++ b/drivers/misc/mei/pci-me.c +@@ -98,6 +98,8 @@ static const struct pci_device_id mei_me_pci_tbl[] = { + + {MEI_PCI_DEVICE(MEI_DEV_ID_ICP_LP, MEI_ME_PCH12_CFG)}, + ++ {MEI_PCI_DEVICE(MEI_DEV_ID_TGP_LP, MEI_ME_PCH12_CFG)}, ++ + {MEI_PCI_DEVICE(MEI_DEV_ID_MCC, MEI_ME_PCH12_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_MCC_4, MEI_ME_PCH8_CFG)}, + +diff --git a/drivers/misc/vmw_vmci/vmci_doorbell.c b/drivers/misc/vmw_vmci/vmci_doorbell.c +index bad89b6e0802..345addd9306d 100644 +--- a/drivers/misc/vmw_vmci/vmci_doorbell.c ++++ b/drivers/misc/vmw_vmci/vmci_doorbell.c +@@ -310,7 +310,8 @@ int vmci_dbell_host_context_notify(u32 src_cid, struct vmci_handle handle) + + entry = container_of(resource, struct dbell_entry, resource); + if (entry->run_delayed) { +- schedule_work(&entry->work); ++ if (!schedule_work(&entry->work)) ++ vmci_resource_put(resource); + } else { + entry->notify_cb(entry->client_data); + vmci_resource_put(resource); +@@ -361,7 +362,8 @@ static void dbell_fire_entries(u32 notify_idx) + atomic_read(&dbell->active) == 1) { + if (dbell->run_delayed) { + vmci_resource_get(&dbell->resource); +- schedule_work(&dbell->work); ++ if (!schedule_work(&dbell->work)) ++ vmci_resource_put(&dbell->resource); + } else { + dbell->notify_cb(dbell->client_data); + } +diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c +index d681e8aaca83..fe914ff5f5d6 100644 +--- a/drivers/mmc/core/sd.c ++++ b/drivers/mmc/core/sd.c +@@ -1292,6 +1292,12 @@ int mmc_attach_sd(struct mmc_host *host) + goto err; + } + ++ /* ++ * Some SD cards claims an out of spec VDD voltage range. Let's treat ++ * these bits as being in-valid and especially also bit7. ++ */ ++ ocr &= ~0x7FFF; ++ + rocr = mmc_select_voltage(host, ocr); + + /* +diff --git a/drivers/mmc/host/sdhci-cadence.c b/drivers/mmc/host/sdhci-cadence.c +index 163d1cf4367e..44139fceac24 100644 +--- a/drivers/mmc/host/sdhci-cadence.c ++++ b/drivers/mmc/host/sdhci-cadence.c +@@ -369,6 +369,7 @@ static int sdhci_cdns_probe(struct platform_device *pdev) + host->mmc_host_ops.execute_tuning = sdhci_cdns_execute_tuning; + host->mmc_host_ops.hs400_enhanced_strobe = + sdhci_cdns_hs400_enhanced_strobe; ++ sdhci_enable_v4_mode(host); + + sdhci_get_of_property(pdev); + +diff --git a/drivers/mmc/host/sdhci-of-at91.c b/drivers/mmc/host/sdhci-of-at91.c +index e377b9bc55a4..d4993582f0f6 100644 +--- a/drivers/mmc/host/sdhci-of-at91.c ++++ b/drivers/mmc/host/sdhci-of-at91.c +@@ -357,6 +357,9 @@ static int sdhci_at91_probe(struct platform_device *pdev) + pm_runtime_set_autosuspend_delay(&pdev->dev, 50); + pm_runtime_use_autosuspend(&pdev->dev); + ++ /* HS200 is broken at this moment */ ++ host->quirks2 = SDHCI_QUIRK2_BROKEN_HS200; ++ + ret = sdhci_add_host(host); + if (ret) + goto pm_runtime_disable; +diff --git a/drivers/mmc/host/sdhci-sprd.c b/drivers/mmc/host/sdhci-sprd.c +index 06f84a4d79e0..fc892a8d882f 100644 +--- a/drivers/mmc/host/sdhci-sprd.c ++++ b/drivers/mmc/host/sdhci-sprd.c +@@ -174,10 +174,11 @@ static inline void _sdhci_sprd_set_clock(struct sdhci_host *host, + struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host); + u32 div, val, mask; + +- div = sdhci_sprd_calc_div(sprd_host->base_rate, clk); ++ sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); + +- clk |= ((div & 0x300) >> 2) | ((div & 0xFF) << 8); +- sdhci_enable_clk(host, clk); ++ div = sdhci_sprd_calc_div(sprd_host->base_rate, clk); ++ div = ((div & 0x300) >> 2) | ((div & 0xFF) << 8); ++ sdhci_enable_clk(host, div); + + /* enable auto gate sdhc_enable_auto_gate */ + val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI); +@@ -284,6 +285,17 @@ static void sdhci_sprd_hw_reset(struct sdhci_host *host) + usleep_range(300, 500); + } + ++static unsigned int sdhci_sprd_get_max_timeout_count(struct sdhci_host *host) ++{ ++ /* The Spredtrum controller actual maximum timeout count is 1 << 31 */ ++ return 1 << 31; ++} ++ ++static unsigned int sdhci_sprd_get_ro(struct sdhci_host *host) ++{ ++ return 0; ++} ++ + static struct sdhci_ops sdhci_sprd_ops = { + .read_l = sdhci_sprd_readl, + .write_l = sdhci_sprd_writel, +@@ -295,6 +307,8 @@ static struct sdhci_ops sdhci_sprd_ops = { + .reset = sdhci_reset, + .set_uhs_signaling = sdhci_sprd_set_uhs_signaling, + .hw_reset = sdhci_sprd_hw_reset, ++ .get_max_timeout_count = sdhci_sprd_get_max_timeout_count, ++ .get_ro = sdhci_sprd_get_ro, + }; + + static void sdhci_sprd_request(struct mmc_host *mmc, struct mmc_request *mrq) +@@ -318,9 +332,12 @@ static void sdhci_sprd_request(struct mmc_host *mmc, struct mmc_request *mrq) + } + + static const struct sdhci_pltfm_data sdhci_sprd_pdata = { +- .quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK, ++ .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | ++ SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | ++ SDHCI_QUIRK_MISSING_CAPS, + .quirks2 = SDHCI_QUIRK2_BROKEN_HS200 | +- SDHCI_QUIRK2_USE_32BIT_BLK_CNT, ++ SDHCI_QUIRK2_USE_32BIT_BLK_CNT | ++ SDHCI_QUIRK2_PRESET_VALUE_BROKEN, + .ops = &sdhci_sprd_ops, + }; + +@@ -386,6 +403,16 @@ static int sdhci_sprd_probe(struct platform_device *pdev) + + sdhci_enable_v4_mode(host); + ++ /* ++ * Supply the existing CAPS, but clear the UHS-I modes. This ++ * will allow these modes to be specified only by device ++ * tree properties through mmc_of_parse(). ++ */ ++ host->caps = sdhci_readl(host, SDHCI_CAPABILITIES); ++ host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); ++ host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 | ++ SDHCI_SUPPORT_DDR50); ++ + ret = sdhci_setup_host(host); + if (ret) + goto pm_runtime_disable; +diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c +index 781a3e106d9a..e6b0f21679c1 100644 +--- a/drivers/mmc/host/sdhci-tegra.c ++++ b/drivers/mmc/host/sdhci-tegra.c +@@ -258,6 +258,16 @@ static void tegra210_sdhci_writew(struct sdhci_host *host, u16 val, int reg) + } + } + ++static unsigned int tegra_sdhci_get_ro(struct sdhci_host *host) ++{ ++ /* ++ * Write-enable shall be assumed if GPIO is missing in a board's ++ * device-tree because SDHCI's WRITE_PROTECT bit doesn't work on ++ * Tegra. ++ */ ++ return mmc_gpio_get_ro(host->mmc); ++} ++ + static bool tegra_sdhci_is_pad_and_regulator_valid(struct sdhci_host *host) + { + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); +@@ -1224,6 +1234,7 @@ static const struct cqhci_host_ops sdhci_tegra_cqhci_ops = { + }; + + static const struct sdhci_ops tegra_sdhci_ops = { ++ .get_ro = tegra_sdhci_get_ro, + .read_w = tegra_sdhci_readw, + .write_l = tegra_sdhci_writel, + .set_clock = tegra_sdhci_set_clock, +@@ -1279,6 +1290,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra30 = { + }; + + static const struct sdhci_ops tegra114_sdhci_ops = { ++ .get_ro = tegra_sdhci_get_ro, + .read_w = tegra_sdhci_readw, + .write_w = tegra_sdhci_writew, + .write_l = tegra_sdhci_writel, +@@ -1332,6 +1344,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra124 = { + }; + + static const struct sdhci_ops tegra210_sdhci_ops = { ++ .get_ro = tegra_sdhci_get_ro, + .read_w = tegra_sdhci_readw, + .write_w = tegra210_sdhci_writew, + .write_l = tegra_sdhci_writel, +@@ -1366,6 +1379,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra210 = { + }; + + static const struct sdhci_ops tegra186_sdhci_ops = { ++ .get_ro = tegra_sdhci_get_ro, + .read_w = tegra_sdhci_readw, + .write_l = tegra_sdhci_writel, + .set_clock = tegra_sdhci_set_clock, +diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c +index 4e3026f9abed..962dbb3acd77 100644 +--- a/drivers/net/ethernet/ti/cpsw.c ++++ b/drivers/net/ethernet/ti/cpsw.c +@@ -2372,6 +2372,7 @@ static int cpsw_probe(struct platform_device *pdev) + if (!cpsw) + return -ENOMEM; + ++ platform_set_drvdata(pdev, cpsw); + cpsw->dev = dev; + + mode = devm_gpiod_get_array_optional(dev, "mode", GPIOD_OUT_LOW); +@@ -2476,7 +2477,6 @@ static int cpsw_probe(struct platform_device *pdev) + goto clean_cpts; + } + +- platform_set_drvdata(pdev, ndev); + priv = netdev_priv(ndev); + priv->cpsw = cpsw; + priv->ndev = ndev; +diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +index a9c846c59289..55b713255b8e 100644 +--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c ++++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +@@ -80,8 +80,11 @@ + #define IWL_22000_QU_B_HR_B_FW_PRE "iwlwifi-Qu-b0-hr-b0-" + #define IWL_22000_HR_B_FW_PRE "iwlwifi-QuQnj-b0-hr-b0-" + #define IWL_22000_HR_A0_FW_PRE "iwlwifi-QuQnj-a0-hr-a0-" ++#define IWL_QU_C_HR_B_FW_PRE "iwlwifi-Qu-c0-hr-b0-" + #define IWL_QU_B_JF_B_FW_PRE "iwlwifi-Qu-b0-jf-b0-" ++#define IWL_QU_C_JF_B_FW_PRE "iwlwifi-Qu-c0-jf-b0-" + #define IWL_QUZ_A_HR_B_FW_PRE "iwlwifi-QuZ-a0-hr-b0-" ++#define IWL_QUZ_A_JF_B_FW_PRE "iwlwifi-QuZ-a0-jf-b0-" + #define IWL_QNJ_B_JF_B_FW_PRE "iwlwifi-QuQnj-b0-jf-b0-" + #define IWL_CC_A_FW_PRE "iwlwifi-cc-a0-" + #define IWL_22000_SO_A_JF_B_FW_PRE "iwlwifi-so-a0-jf-b0-" +@@ -106,6 +109,10 @@ + IWL_22000_HR_A0_FW_PRE __stringify(api) ".ucode" + #define IWL_QUZ_A_HR_B_MODULE_FIRMWARE(api) \ + IWL_QUZ_A_HR_B_FW_PRE __stringify(api) ".ucode" ++#define IWL_QUZ_A_JF_B_MODULE_FIRMWARE(api) \ ++ IWL_QUZ_A_JF_B_FW_PRE __stringify(api) ".ucode" ++#define IWL_QU_C_HR_B_MODULE_FIRMWARE(api) \ ++ IWL_QU_C_HR_B_FW_PRE __stringify(api) ".ucode" + #define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \ + IWL_QU_B_JF_B_FW_PRE __stringify(api) ".ucode" + #define IWL_QNJ_B_JF_B_MODULE_FIRMWARE(api) \ +@@ -241,6 +248,42 @@ const struct iwl_cfg iwl_ax101_cfg_qu_hr = { + .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + }; + ++const struct iwl_cfg iwl_ax201_cfg_qu_hr = { ++ .name = "Intel(R) Wi-Fi 6 AX201 160MHz", ++ .fw_name_pre = IWL_22000_QU_B_HR_B_FW_PRE, ++ IWL_DEVICE_22500, ++ /* ++ * This device doesn't support receiving BlockAck with a large bitmap ++ * so we need to restrict the size of transmitted aggregation to the ++ * HT size; mac80211 would otherwise pick the HE max (256) by default. ++ */ ++ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, ++}; ++ ++const struct iwl_cfg iwl_ax101_cfg_qu_c0_hr_b0 = { ++ .name = "Intel(R) Wi-Fi 6 AX101", ++ .fw_name_pre = IWL_QU_C_HR_B_FW_PRE, ++ IWL_DEVICE_22500, ++ /* ++ * This device doesn't support receiving BlockAck with a large bitmap ++ * so we need to restrict the size of transmitted aggregation to the ++ * HT size; mac80211 would otherwise pick the HE max (256) by default. ++ */ ++ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, ++}; ++ ++const struct iwl_cfg iwl_ax201_cfg_qu_c0_hr_b0 = { ++ .name = "Intel(R) Wi-Fi 6 AX201 160MHz", ++ .fw_name_pre = IWL_QU_C_HR_B_FW_PRE, ++ IWL_DEVICE_22500, ++ /* ++ * This device doesn't support receiving BlockAck with a large bitmap ++ * so we need to restrict the size of transmitted aggregation to the ++ * HT size; mac80211 would otherwise pick the HE max (256) by default. ++ */ ++ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, ++}; ++ + const struct iwl_cfg iwl_ax101_cfg_quz_hr = { + .name = "Intel(R) Wi-Fi 6 AX101", + .fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE, +@@ -253,6 +296,42 @@ const struct iwl_cfg iwl_ax101_cfg_quz_hr = { + .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + }; + ++const struct iwl_cfg iwl_ax201_cfg_quz_hr = { ++ .name = "Intel(R) Wi-Fi 6 AX201 160MHz", ++ .fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE, ++ IWL_DEVICE_22500, ++ /* ++ * This device doesn't support receiving BlockAck with a large bitmap ++ * so we need to restrict the size of transmitted aggregation to the ++ * HT size; mac80211 would otherwise pick the HE max (256) by default. ++ */ ++ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, ++}; ++ ++const struct iwl_cfg iwl_ax1650s_cfg_quz_hr = { ++ .name = "Killer(R) Wi-Fi 6 AX1650s 160MHz Wireless Network Adapter (201D2W)", ++ .fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE, ++ IWL_DEVICE_22500, ++ /* ++ * This device doesn't support receiving BlockAck with a large bitmap ++ * so we need to restrict the size of transmitted aggregation to the ++ * HT size; mac80211 would otherwise pick the HE max (256) by default. ++ */ ++ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, ++}; ++ ++const struct iwl_cfg iwl_ax1650i_cfg_quz_hr = { ++ .name = "Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW)", ++ .fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE, ++ IWL_DEVICE_22500, ++ /* ++ * This device doesn't support receiving BlockAck with a large bitmap ++ * so we need to restrict the size of transmitted aggregation to the ++ * HT size; mac80211 would otherwise pick the HE max (256) by default. ++ */ ++ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, ++}; ++ + const struct iwl_cfg iwl_ax200_cfg_cc = { + .name = "Intel(R) Wi-Fi 6 AX200 160MHz", + .fw_name_pre = IWL_CC_A_FW_PRE, +@@ -321,6 +400,30 @@ const struct iwl_cfg iwl9560_2ac_160_cfg_qu_b0_jf_b0 = { + IWL_DEVICE_22500, + }; + ++const struct iwl_cfg iwl9461_2ac_cfg_qu_c0_jf_b0 = { ++ .name = "Intel(R) Wireless-AC 9461", ++ .fw_name_pre = IWL_QU_C_JF_B_FW_PRE, ++ IWL_DEVICE_22500, ++}; ++ ++const struct iwl_cfg iwl9462_2ac_cfg_qu_c0_jf_b0 = { ++ .name = "Intel(R) Wireless-AC 9462", ++ .fw_name_pre = IWL_QU_C_JF_B_FW_PRE, ++ IWL_DEVICE_22500, ++}; ++ ++const struct iwl_cfg iwl9560_2ac_cfg_qu_c0_jf_b0 = { ++ .name = "Intel(R) Wireless-AC 9560", ++ .fw_name_pre = IWL_QU_C_JF_B_FW_PRE, ++ IWL_DEVICE_22500, ++}; ++ ++const struct iwl_cfg iwl9560_2ac_160_cfg_qu_c0_jf_b0 = { ++ .name = "Intel(R) Wireless-AC 9560 160MHz", ++ .fw_name_pre = IWL_QU_C_JF_B_FW_PRE, ++ IWL_DEVICE_22500, ++}; ++ + const struct iwl_cfg iwl9560_2ac_cfg_qnj_jf_b0 = { + .name = "Intel(R) Wireless-AC 9560 160MHz", + .fw_name_pre = IWL_QNJ_B_JF_B_FW_PRE, +@@ -333,6 +436,90 @@ const struct iwl_cfg iwl9560_2ac_cfg_qnj_jf_b0 = { + .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + }; + ++const struct iwl_cfg iwl9560_2ac_cfg_quz_a0_jf_b0_soc = { ++ .name = "Intel(R) Wireless-AC 9560 160MHz", ++ .fw_name_pre = IWL_QUZ_A_JF_B_FW_PRE, ++ IWL_DEVICE_22500, ++ /* ++ * This device doesn't support receiving BlockAck with a large bitmap ++ * so we need to restrict the size of transmitted aggregation to the ++ * HT size; mac80211 would otherwise pick the HE max (256) by default. ++ */ ++ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, ++ .integrated = true, ++ .soc_latency = 5000, ++}; ++ ++const struct iwl_cfg iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc = { ++ .name = "Intel(R) Wireless-AC 9560 160MHz", ++ .fw_name_pre = IWL_QUZ_A_JF_B_FW_PRE, ++ IWL_DEVICE_22500, ++ /* ++ * This device doesn't support receiving BlockAck with a large bitmap ++ * so we need to restrict the size of transmitted aggregation to the ++ * HT size; mac80211 would otherwise pick the HE max (256) by default. ++ */ ++ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, ++ .integrated = true, ++ .soc_latency = 5000, ++}; ++ ++const struct iwl_cfg iwl9461_2ac_cfg_quz_a0_jf_b0_soc = { ++ .name = "Intel(R) Dual Band Wireless AC 9461", ++ .fw_name_pre = IWL_QUZ_A_JF_B_FW_PRE, ++ IWL_DEVICE_22500, ++ /* ++ * This device doesn't support receiving BlockAck with a large bitmap ++ * so we need to restrict the size of transmitted aggregation to the ++ * HT size; mac80211 would otherwise pick the HE max (256) by default. ++ */ ++ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, ++ .integrated = true, ++ .soc_latency = 5000, ++}; ++ ++const struct iwl_cfg iwl9462_2ac_cfg_quz_a0_jf_b0_soc = { ++ .name = "Intel(R) Dual Band Wireless AC 9462", ++ .fw_name_pre = IWL_QUZ_A_JF_B_FW_PRE, ++ IWL_DEVICE_22500, ++ /* ++ * This device doesn't support receiving BlockAck with a large bitmap ++ * so we need to restrict the size of transmitted aggregation to the ++ * HT size; mac80211 would otherwise pick the HE max (256) by default. ++ */ ++ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, ++ .integrated = true, ++ .soc_latency = 5000, ++}; ++ ++const struct iwl_cfg iwl9560_killer_s_2ac_cfg_quz_a0_jf_b0_soc = { ++ .name = "Killer (R) Wireless-AC 1550s Wireless Network Adapter (9560NGW)", ++ .fw_name_pre = IWL_QUZ_A_JF_B_FW_PRE, ++ IWL_DEVICE_22500, ++ /* ++ * This device doesn't support receiving BlockAck with a large bitmap ++ * so we need to restrict the size of transmitted aggregation to the ++ * HT size; mac80211 would otherwise pick the HE max (256) by default. ++ */ ++ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, ++ .integrated = true, ++ .soc_latency = 5000, ++}; ++ ++const struct iwl_cfg iwl9560_killer_i_2ac_cfg_quz_a0_jf_b0_soc = { ++ .name = "Killer (R) Wireless-AC 1550i Wireless Network Adapter (9560NGW)", ++ .fw_name_pre = IWL_QUZ_A_JF_B_FW_PRE, ++ IWL_DEVICE_22500, ++ /* ++ * This device doesn't support receiving BlockAck with a large bitmap ++ * so we need to restrict the size of transmitted aggregation to the ++ * HT size; mac80211 would otherwise pick the HE max (256) by default. ++ */ ++ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, ++ .integrated = true, ++ .soc_latency = 5000, ++}; ++ + const struct iwl_cfg killer1550i_2ac_cfg_qu_b0_jf_b0 = { + .name = "Killer (R) Wireless-AC 1550i Wireless Network Adapter (9560NGW)", + .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, +@@ -369,6 +556,30 @@ const struct iwl_cfg killer1650i_2ax_cfg_qu_b0_hr_b0 = { + .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + }; + ++const struct iwl_cfg killer1650s_2ax_cfg_qu_c0_hr_b0 = { ++ .name = "Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW)", ++ .fw_name_pre = IWL_QU_C_HR_B_FW_PRE, ++ IWL_DEVICE_22500, ++ /* ++ * This device doesn't support receiving BlockAck with a large bitmap ++ * so we need to restrict the size of transmitted aggregation to the ++ * HT size; mac80211 would otherwise pick the HE max (256) by default. ++ */ ++ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, ++}; ++ ++const struct iwl_cfg killer1650i_2ax_cfg_qu_c0_hr_b0 = { ++ .name = "Killer(R) Wi-Fi 6 AX1650s 160MHz Wireless Network Adapter (201D2W)", ++ .fw_name_pre = IWL_QU_C_HR_B_FW_PRE, ++ IWL_DEVICE_22500, ++ /* ++ * This device doesn't support receiving BlockAck with a large bitmap ++ * so we need to restrict the size of transmitted aggregation to the ++ * HT size; mac80211 would otherwise pick the HE max (256) by default. ++ */ ++ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, ++}; ++ + const struct iwl_cfg iwl22000_2ax_cfg_jf = { + .name = "Intel(R) Dual Band Wireless AX 22000", + .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, +@@ -424,12 +635,12 @@ const struct iwl_cfg iwlax210_2ax_cfg_so_jf_a0 = { + }; + + const struct iwl_cfg iwlax210_2ax_cfg_so_hr_a0 = { +- .name = "Intel(R) Wi-Fi 6 AX201 160MHz", ++ .name = "Intel(R) Wi-Fi 7 AX210 160MHz", + .fw_name_pre = IWL_22000_SO_A_HR_B_FW_PRE, + IWL_DEVICE_AX210, + }; + +-const struct iwl_cfg iwlax210_2ax_cfg_so_gf_a0 = { ++const struct iwl_cfg iwlax211_2ax_cfg_so_gf_a0 = { + .name = "Intel(R) Wi-Fi 7 AX211 160MHz", + .fw_name_pre = IWL_22000_SO_A_GF_A_FW_PRE, + .uhb_supported = true, +@@ -443,8 +654,8 @@ const struct iwl_cfg iwlax210_2ax_cfg_ty_gf_a0 = { + IWL_DEVICE_AX210, + }; + +-const struct iwl_cfg iwlax210_2ax_cfg_so_gf4_a0 = { +- .name = "Intel(R) Wi-Fi 7 AX210 160MHz", ++const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0 = { ++ .name = "Intel(R) Wi-Fi 7 AX411 160MHz", + .fw_name_pre = IWL_22000_SO_A_GF4_A_FW_PRE, + IWL_DEVICE_AX210, + }; +@@ -455,8 +666,10 @@ MODULE_FIRMWARE(IWL_22000_HR_A_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); + MODULE_FIRMWARE(IWL_22000_HR_B_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); + MODULE_FIRMWARE(IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); + MODULE_FIRMWARE(IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); ++MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); + MODULE_FIRMWARE(IWL_QU_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); + MODULE_FIRMWARE(IWL_QUZ_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); ++MODULE_FIRMWARE(IWL_QUZ_A_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); + MODULE_FIRMWARE(IWL_QNJ_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); + MODULE_FIRMWARE(IWL_CC_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); + MODULE_FIRMWARE(IWL_22000_SO_A_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h +index f3e69edf8907..6c04f8223aff 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h +@@ -540,14 +540,20 @@ extern const struct iwl_cfg iwl9260_killer_2ac_cfg; + extern const struct iwl_cfg iwl9270_2ac_cfg; + extern const struct iwl_cfg iwl9460_2ac_cfg; + extern const struct iwl_cfg iwl9560_2ac_cfg; ++extern const struct iwl_cfg iwl9560_2ac_cfg_quz_a0_jf_b0_soc; + extern const struct iwl_cfg iwl9560_2ac_160_cfg; ++extern const struct iwl_cfg iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc; + extern const struct iwl_cfg iwl9460_2ac_cfg_soc; + extern const struct iwl_cfg iwl9461_2ac_cfg_soc; ++extern const struct iwl_cfg iwl9461_2ac_cfg_quz_a0_jf_b0_soc; + extern const struct iwl_cfg iwl9462_2ac_cfg_soc; ++extern const struct iwl_cfg iwl9462_2ac_cfg_quz_a0_jf_b0_soc; + extern const struct iwl_cfg iwl9560_2ac_cfg_soc; + extern const struct iwl_cfg iwl9560_2ac_160_cfg_soc; + extern const struct iwl_cfg iwl9560_killer_2ac_cfg_soc; + extern const struct iwl_cfg iwl9560_killer_s_2ac_cfg_soc; ++extern const struct iwl_cfg iwl9560_killer_i_2ac_cfg_quz_a0_jf_b0_soc; ++extern const struct iwl_cfg iwl9560_killer_s_2ac_cfg_quz_a0_jf_b0_soc; + extern const struct iwl_cfg iwl9460_2ac_cfg_shared_clk; + extern const struct iwl_cfg iwl9461_2ac_cfg_shared_clk; + extern const struct iwl_cfg iwl9462_2ac_cfg_shared_clk; +@@ -559,17 +565,30 @@ extern const struct iwl_cfg iwl22000_2ac_cfg_hr; + extern const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb; + extern const struct iwl_cfg iwl22000_2ac_cfg_jf; + extern const struct iwl_cfg iwl_ax101_cfg_qu_hr; ++extern const struct iwl_cfg iwl_ax101_cfg_qu_c0_hr_b0; + extern const struct iwl_cfg iwl_ax101_cfg_quz_hr; + extern const struct iwl_cfg iwl22000_2ax_cfg_hr; + extern const struct iwl_cfg iwl_ax200_cfg_cc; ++extern const struct iwl_cfg iwl_ax201_cfg_qu_hr; ++extern const struct iwl_cfg iwl_ax201_cfg_qu_hr; ++extern const struct iwl_cfg iwl_ax201_cfg_qu_c0_hr_b0; ++extern const struct iwl_cfg iwl_ax201_cfg_quz_hr; ++extern const struct iwl_cfg iwl_ax1650i_cfg_quz_hr; ++extern const struct iwl_cfg iwl_ax1650s_cfg_quz_hr; + extern const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0; + extern const struct iwl_cfg killer1650i_2ax_cfg_qu_b0_hr_b0; ++extern const struct iwl_cfg killer1650s_2ax_cfg_qu_c0_hr_b0; ++extern const struct iwl_cfg killer1650i_2ax_cfg_qu_c0_hr_b0; + extern const struct iwl_cfg killer1650x_2ax_cfg; + extern const struct iwl_cfg killer1650w_2ax_cfg; + extern const struct iwl_cfg iwl9461_2ac_cfg_qu_b0_jf_b0; + extern const struct iwl_cfg iwl9462_2ac_cfg_qu_b0_jf_b0; + extern const struct iwl_cfg iwl9560_2ac_cfg_qu_b0_jf_b0; + extern const struct iwl_cfg iwl9560_2ac_160_cfg_qu_b0_jf_b0; ++extern const struct iwl_cfg iwl9461_2ac_cfg_qu_c0_jf_b0; ++extern const struct iwl_cfg iwl9462_2ac_cfg_qu_c0_jf_b0; ++extern const struct iwl_cfg iwl9560_2ac_cfg_qu_c0_jf_b0; ++extern const struct iwl_cfg iwl9560_2ac_160_cfg_qu_c0_jf_b0; + extern const struct iwl_cfg killer1550i_2ac_cfg_qu_b0_jf_b0; + extern const struct iwl_cfg killer1550s_2ac_cfg_qu_b0_jf_b0; + extern const struct iwl_cfg iwl22000_2ax_cfg_jf; +@@ -580,9 +599,9 @@ extern const struct iwl_cfg iwl9560_2ac_cfg_qnj_jf_b0; + extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0; + extern const struct iwl_cfg iwlax210_2ax_cfg_so_jf_a0; + extern const struct iwl_cfg iwlax210_2ax_cfg_so_hr_a0; +-extern const struct iwl_cfg iwlax210_2ax_cfg_so_gf_a0; ++extern const struct iwl_cfg iwlax211_2ax_cfg_so_gf_a0; + extern const struct iwl_cfg iwlax210_2ax_cfg_ty_gf_a0; +-extern const struct iwl_cfg iwlax210_2ax_cfg_so_gf4_a0; ++extern const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0; + #endif /* CPTCFG_IWLMVM || CPTCFG_IWLFMAC */ + + #endif /* __IWL_CONFIG_H__ */ +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h +index 93da96a7247c..cb4c5514a556 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h +@@ -328,6 +328,8 @@ enum { + #define CSR_HW_REV_TYPE_NONE (0x00001F0) + #define CSR_HW_REV_TYPE_QNJ (0x0000360) + #define CSR_HW_REV_TYPE_QNJ_B0 (0x0000364) ++#define CSR_HW_REV_TYPE_QU_B0 (0x0000334) ++#define CSR_HW_REV_TYPE_QU_C0 (0x0000338) + #define CSR_HW_REV_TYPE_QUZ (0x0000354) + #define CSR_HW_REV_TYPE_HR_CDB (0x0000340) + #define CSR_HW_REV_TYPE_SO (0x0000370) +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +index cd035061cdd5..54cb4950f32f 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +@@ -513,62 +513,56 @@ static const struct pci_device_id iwl_hw_card_ids[] = { + {IWL_PCI_DEVICE(0x24FD, 0x9074, iwl8265_2ac_cfg)}, + + /* 9000 Series */ +- {IWL_PCI_DEVICE(0x02F0, 0x0030, iwl9560_2ac_160_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x0034, iwl9560_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x0038, iwl9560_2ac_160_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x003C, iwl9560_2ac_160_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x0040, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x02F0, 0x0044, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x02F0, 0x0060, iwl9461_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x0064, iwl9461_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x00A0, iwl9462_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x00A4, iwl9462_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x0230, iwl9560_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x0234, iwl9560_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x0238, iwl9560_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x023C, iwl9560_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x0244, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x02F0, 0x0260, iwl9461_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x0264, iwl9461_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x02A0, iwl9462_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x02A4, iwl9462_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x1551, iwl9560_killer_s_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x1552, iwl9560_killer_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x2030, iwl9560_2ac_160_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x2034, iwl9560_2ac_160_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x4030, iwl9560_2ac_160_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x4034, iwl9560_2ac_160_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x40A4, iwl9462_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x4234, iwl9560_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x02F0, 0x42A4, iwl9462_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x0030, iwl9560_2ac_160_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x0034, iwl9560_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x0038, iwl9560_2ac_160_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x003C, iwl9560_2ac_160_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x0040, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x06F0, 0x0044, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x06F0, 0x0060, iwl9461_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x0064, iwl9461_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x00A0, iwl9462_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x00A4, iwl9462_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x0230, iwl9560_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x0234, iwl9560_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x0238, iwl9560_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x023C, iwl9560_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x0244, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x06F0, 0x0260, iwl9461_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x0264, iwl9461_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x02A0, iwl9462_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x02A4, iwl9462_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x1551, iwl9560_killer_s_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x1552, iwl9560_killer_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x2030, iwl9560_2ac_160_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x2034, iwl9560_2ac_160_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x4030, iwl9560_2ac_160_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x4034, iwl9560_2ac_160_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x40A4, iwl9462_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x4234, iwl9560_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x06F0, 0x42A4, iwl9462_2ac_cfg_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x0030, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x0034, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x0038, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x003C, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x0060, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x0064, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x00A0, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x00A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x0230, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x0234, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x0238, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x023C, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x0260, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x0264, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x02A0, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x02A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x1551, iwl9560_killer_s_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x1552, iwl9560_killer_i_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x2030, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x2034, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x4030, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x4034, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x40A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x4234, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x42A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x0030, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x0034, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x0038, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x003C, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x0060, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x0064, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x00A0, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x00A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x0230, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x0234, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x0238, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x023C, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x0260, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x0264, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x02A0, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x02A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x1551, iwl9560_killer_s_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x1552, iwl9560_killer_i_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x2030, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x2034, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x4030, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x4034, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x40A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x4234, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x42A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, + {IWL_PCI_DEVICE(0x2526, 0x0010, iwl9260_2ac_160_cfg)}, + {IWL_PCI_DEVICE(0x2526, 0x0014, iwl9260_2ac_160_cfg)}, + {IWL_PCI_DEVICE(0x2526, 0x0018, iwl9260_2ac_160_cfg)}, +@@ -610,6 +604,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = { + {IWL_PCI_DEVICE(0x2526, 0x40A4, iwl9460_2ac_cfg)}, + {IWL_PCI_DEVICE(0x2526, 0x4234, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x2526, 0x42A4, iwl9462_2ac_cfg_soc)}, ++ {IWL_PCI_DEVICE(0x2526, 0x6014, iwl9260_2ac_160_cfg)}, + {IWL_PCI_DEVICE(0x2526, 0x8014, iwl9260_2ac_160_cfg)}, + {IWL_PCI_DEVICE(0x2526, 0x8010, iwl9260_2ac_160_cfg)}, + {IWL_PCI_DEVICE(0x2526, 0xA014, iwl9260_2ac_160_cfg)}, +@@ -621,7 +616,6 @@ static const struct pci_device_id iwl_hw_card_ids[] = { + {IWL_PCI_DEVICE(0x2720, 0x0034, iwl9560_2ac_160_cfg)}, + {IWL_PCI_DEVICE(0x2720, 0x0038, iwl9560_2ac_160_cfg)}, + {IWL_PCI_DEVICE(0x2720, 0x003C, iwl9560_2ac_160_cfg)}, +- {IWL_PCI_DEVICE(0x2720, 0x0044, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x2720, 0x0060, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x2720, 0x0064, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x2720, 0x00A0, iwl9462_2ac_cfg_soc)}, +@@ -630,7 +624,6 @@ static const struct pci_device_id iwl_hw_card_ids[] = { + {IWL_PCI_DEVICE(0x2720, 0x0234, iwl9560_2ac_cfg)}, + {IWL_PCI_DEVICE(0x2720, 0x0238, iwl9560_2ac_cfg)}, + {IWL_PCI_DEVICE(0x2720, 0x023C, iwl9560_2ac_cfg)}, +- {IWL_PCI_DEVICE(0x2720, 0x0244, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x2720, 0x0260, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x2720, 0x0264, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x2720, 0x02A0, iwl9462_2ac_cfg_soc)}, +@@ -708,7 +701,6 @@ static const struct pci_device_id iwl_hw_card_ids[] = { + {IWL_PCI_DEVICE(0x34F0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, +- {IWL_PCI_DEVICE(0x34F0, 0x0044, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x34F0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, +@@ -717,7 +709,6 @@ static const struct pci_device_id iwl_hw_card_ids[] = { + {IWL_PCI_DEVICE(0x34F0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, +- {IWL_PCI_DEVICE(0x34F0, 0x0244, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x34F0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, +@@ -764,7 +755,6 @@ static const struct pci_device_id iwl_hw_card_ids[] = { + {IWL_PCI_DEVICE(0x43F0, 0x0034, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x43F0, 0x0038, iwl9560_2ac_160_cfg_soc)}, + {IWL_PCI_DEVICE(0x43F0, 0x003C, iwl9560_2ac_160_cfg_soc)}, +- {IWL_PCI_DEVICE(0x43F0, 0x0044, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x43F0, 0x0060, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x43F0, 0x0064, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x43F0, 0x00A0, iwl9462_2ac_cfg_soc)}, +@@ -773,7 +763,6 @@ static const struct pci_device_id iwl_hw_card_ids[] = { + {IWL_PCI_DEVICE(0x43F0, 0x0234, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x43F0, 0x0238, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x43F0, 0x023C, iwl9560_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0x43F0, 0x0244, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x43F0, 0x0260, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x43F0, 0x0264, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x43F0, 0x02A0, iwl9462_2ac_cfg_soc)}, +@@ -833,7 +822,6 @@ static const struct pci_device_id iwl_hw_card_ids[] = { + {IWL_PCI_DEVICE(0xA0F0, 0x0034, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0038, iwl9560_2ac_160_cfg_soc)}, + {IWL_PCI_DEVICE(0xA0F0, 0x003C, iwl9560_2ac_160_cfg_soc)}, +- {IWL_PCI_DEVICE(0xA0F0, 0x0044, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0060, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0064, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0xA0F0, 0x00A0, iwl9462_2ac_cfg_soc)}, +@@ -842,7 +830,6 @@ static const struct pci_device_id iwl_hw_card_ids[] = { + {IWL_PCI_DEVICE(0xA0F0, 0x0234, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0238, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0xA0F0, 0x023C, iwl9560_2ac_cfg_soc)}, +- {IWL_PCI_DEVICE(0xA0F0, 0x0244, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0260, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0264, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0xA0F0, 0x02A0, iwl9462_2ac_cfg_soc)}, +@@ -890,63 +877,80 @@ static const struct pci_device_id iwl_hw_card_ids[] = { + {IWL_PCI_DEVICE(0x2720, 0x0030, iwl9560_2ac_cfg_qnj_jf_b0)}, + + /* 22000 Series */ +- {IWL_PCI_DEVICE(0x02F0, 0x0070, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x02F0, 0x0074, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x02F0, 0x0078, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x02F0, 0x007C, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x02F0, 0x0310, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x02F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)}, +- {IWL_PCI_DEVICE(0x02F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, +- {IWL_PCI_DEVICE(0x02F0, 0x4070, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x06F0, 0x0070, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x06F0, 0x0074, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x06F0, 0x0078, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x06F0, 0x007C, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x06F0, 0x0310, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x06F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)}, +- {IWL_PCI_DEVICE(0x06F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, +- {IWL_PCI_DEVICE(0x06F0, 0x4070, iwl_ax101_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x0070, iwl_ax201_cfg_quz_hr)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x0074, iwl_ax201_cfg_quz_hr)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x0078, iwl_ax201_cfg_quz_hr)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x007C, iwl_ax201_cfg_quz_hr)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x0244, iwl_ax101_cfg_quz_hr)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x0310, iwl_ax201_cfg_quz_hr)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x1651, iwl_ax1650s_cfg_quz_hr)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x1652, iwl_ax1650i_cfg_quz_hr)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x2074, iwl_ax201_cfg_quz_hr)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x4070, iwl_ax201_cfg_quz_hr)}, ++ {IWL_PCI_DEVICE(0x02F0, 0x4244, iwl_ax101_cfg_quz_hr)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x0070, iwl_ax201_cfg_quz_hr)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x0074, iwl_ax201_cfg_quz_hr)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x0078, iwl_ax201_cfg_quz_hr)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x007C, iwl_ax201_cfg_quz_hr)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x0244, iwl_ax101_cfg_quz_hr)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x0310, iwl_ax201_cfg_quz_hr)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x1651, iwl_ax1650s_cfg_quz_hr)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x1652, iwl_ax1650i_cfg_quz_hr)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x2074, iwl_ax201_cfg_quz_hr)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x4070, iwl_ax201_cfg_quz_hr)}, ++ {IWL_PCI_DEVICE(0x06F0, 0x4244, iwl_ax101_cfg_quz_hr)}, + {IWL_PCI_DEVICE(0x2720, 0x0000, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x2720, 0x0040, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x2720, 0x0070, iwl22000_2ac_cfg_hr_cdb)}, +- {IWL_PCI_DEVICE(0x2720, 0x0074, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x2720, 0x0078, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x2720, 0x007C, iwl_ax101_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x2720, 0x0044, iwl_ax101_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x2720, 0x0070, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x2720, 0x0074, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x2720, 0x0078, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x2720, 0x007C, iwl_ax201_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x2720, 0x0090, iwl22000_2ac_cfg_hr_cdb)}, +- {IWL_PCI_DEVICE(0x2720, 0x0310, iwl22000_2ac_cfg_hr_cdb)}, +- {IWL_PCI_DEVICE(0x2720, 0x0A10, iwl22000_2ac_cfg_hr_cdb)}, ++ {IWL_PCI_DEVICE(0x2720, 0x0244, iwl_ax101_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x2720, 0x0310, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x2720, 0x0A10, iwl_ax201_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x2720, 0x1080, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x2720, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, +- {IWL_PCI_DEVICE(0x2720, 0x4070, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x34F0, 0x0040, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x34F0, 0x0070, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x34F0, 0x0074, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x34F0, 0x0078, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x34F0, 0x007C, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x34F0, 0x0310, iwl_ax101_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x2720, 0x2074, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x2720, 0x4070, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x2720, 0x4244, iwl_ax101_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x34F0, 0x0044, iwl_ax101_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x34F0, 0x0070, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x34F0, 0x0074, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x34F0, 0x0078, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x34F0, 0x007C, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x34F0, 0x0244, iwl_ax101_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x34F0, 0x0310, iwl_ax201_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x34F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, +- {IWL_PCI_DEVICE(0x34F0, 0x4070, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x43F0, 0x0040, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x43F0, 0x0070, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x43F0, 0x0074, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x43F0, 0x0078, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0x43F0, 0x007C, iwl_ax101_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x34F0, 0x2074, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x34F0, 0x4070, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x34F0, 0x4244, iwl_ax101_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x43F0, 0x0044, iwl_ax101_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x43F0, 0x0070, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x43F0, 0x0074, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x43F0, 0x0078, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x43F0, 0x007C, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x43F0, 0x0244, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x43F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, +- {IWL_PCI_DEVICE(0x43F0, 0x4070, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0xA0F0, 0x0000, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0xA0F0, 0x0040, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0xA0F0, 0x0070, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0xA0F0, 0x0074, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0xA0F0, 0x0078, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0xA0F0, 0x007C, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0xA0F0, 0x00B0, iwl_ax101_cfg_qu_hr)}, +- {IWL_PCI_DEVICE(0xA0F0, 0x0A10, iwl_ax101_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x43F0, 0x2074, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x43F0, 0x4070, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0x43F0, 0x4244, iwl_ax101_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0xA0F0, 0x0044, iwl_ax101_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0xA0F0, 0x0070, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0xA0F0, 0x0074, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0xA0F0, 0x0078, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0xA0F0, 0x007C, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0xA0F0, 0x0244, iwl_ax101_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0xA0F0, 0x0A10, iwl_ax201_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0xA0F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, +- {IWL_PCI_DEVICE(0xA0F0, 0x4070, iwl_ax101_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0xA0F0, 0x2074, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0xA0F0, 0x4070, iwl_ax201_cfg_qu_hr)}, ++ {IWL_PCI_DEVICE(0xA0F0, 0x4244, iwl_ax101_cfg_qu_hr)}, + + {IWL_PCI_DEVICE(0x2723, 0x0080, iwl_ax200_cfg_cc)}, + {IWL_PCI_DEVICE(0x2723, 0x0084, iwl_ax200_cfg_cc)}, +@@ -958,13 +962,20 @@ static const struct pci_device_id iwl_hw_card_ids[] = { + {IWL_PCI_DEVICE(0x2723, 0x4080, iwl_ax200_cfg_cc)}, + {IWL_PCI_DEVICE(0x2723, 0x4088, iwl_ax200_cfg_cc)}, + +- {IWL_PCI_DEVICE(0x2725, 0x0090, iwlax210_2ax_cfg_so_hr_a0)}, +- {IWL_PCI_DEVICE(0x7A70, 0x0090, iwlax210_2ax_cfg_so_hr_a0)}, +- {IWL_PCI_DEVICE(0x7A70, 0x0310, iwlax210_2ax_cfg_so_hr_a0)}, +- {IWL_PCI_DEVICE(0x2725, 0x0020, iwlax210_2ax_cfg_so_hr_a0)}, +- {IWL_PCI_DEVICE(0x2725, 0x0310, iwlax210_2ax_cfg_so_hr_a0)}, +- {IWL_PCI_DEVICE(0x2725, 0x0A10, iwlax210_2ax_cfg_so_hr_a0)}, +- {IWL_PCI_DEVICE(0x2725, 0x00B0, iwlax210_2ax_cfg_so_hr_a0)}, ++ {IWL_PCI_DEVICE(0x2725, 0x0090, iwlax211_2ax_cfg_so_gf_a0)}, ++ {IWL_PCI_DEVICE(0x2725, 0x0020, iwlax210_2ax_cfg_ty_gf_a0)}, ++ {IWL_PCI_DEVICE(0x2725, 0x0310, iwlax210_2ax_cfg_ty_gf_a0)}, ++ {IWL_PCI_DEVICE(0x2725, 0x0510, iwlax210_2ax_cfg_ty_gf_a0)}, ++ {IWL_PCI_DEVICE(0x2725, 0x0A10, iwlax210_2ax_cfg_ty_gf_a0)}, ++ {IWL_PCI_DEVICE(0x2725, 0x00B0, iwlax411_2ax_cfg_so_gf4_a0)}, ++ {IWL_PCI_DEVICE(0x7A70, 0x0090, iwlax211_2ax_cfg_so_gf_a0)}, ++ {IWL_PCI_DEVICE(0x7A70, 0x0310, iwlax211_2ax_cfg_so_gf_a0)}, ++ {IWL_PCI_DEVICE(0x7A70, 0x0510, iwlax211_2ax_cfg_so_gf_a0)}, ++ {IWL_PCI_DEVICE(0x7A70, 0x0A10, iwlax211_2ax_cfg_so_gf_a0)}, ++ {IWL_PCI_DEVICE(0x7AF0, 0x0090, iwlax211_2ax_cfg_so_gf_a0)}, ++ {IWL_PCI_DEVICE(0x7AF0, 0x0310, iwlax211_2ax_cfg_so_gf_a0)}, ++ {IWL_PCI_DEVICE(0x7AF0, 0x0510, iwlax211_2ax_cfg_so_gf_a0)}, ++ {IWL_PCI_DEVICE(0x7AF0, 0x0A10, iwlax211_2ax_cfg_so_gf_a0)}, + + #endif /* CONFIG_IWLMVM */ + +@@ -1028,6 +1039,31 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + } + iwl_trans->cfg = cfg; + } ++ ++ /* ++ * This is a hack to switch from Qu B0 to Qu C0. We need to ++ * do this for all cfgs that use Qu B0. All this code is in ++ * urgent need for a refactor, but for now this is the easiest ++ * thing to do to support Qu C-step. ++ */ ++ if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QU_C0) { ++ if (iwl_trans->cfg == &iwl_ax101_cfg_qu_hr) ++ iwl_trans->cfg = &iwl_ax101_cfg_qu_c0_hr_b0; ++ else if (iwl_trans->cfg == &iwl_ax201_cfg_qu_hr) ++ iwl_trans->cfg = &iwl_ax201_cfg_qu_c0_hr_b0; ++ else if (iwl_trans->cfg == &iwl9461_2ac_cfg_qu_b0_jf_b0) ++ iwl_trans->cfg = &iwl9461_2ac_cfg_qu_c0_jf_b0; ++ else if (iwl_trans->cfg == &iwl9462_2ac_cfg_qu_b0_jf_b0) ++ iwl_trans->cfg = &iwl9462_2ac_cfg_qu_c0_jf_b0; ++ else if (iwl_trans->cfg == &iwl9560_2ac_cfg_qu_b0_jf_b0) ++ iwl_trans->cfg = &iwl9560_2ac_cfg_qu_c0_jf_b0; ++ else if (iwl_trans->cfg == &iwl9560_2ac_160_cfg_qu_b0_jf_b0) ++ iwl_trans->cfg = &iwl9560_2ac_160_cfg_qu_c0_jf_b0; ++ else if (iwl_trans->cfg == &killer1650s_2ax_cfg_qu_b0_hr_b0) ++ iwl_trans->cfg = &killer1650s_2ax_cfg_qu_c0_hr_b0; ++ else if (iwl_trans->cfg == &killer1650i_2ax_cfg_qu_b0_hr_b0) ++ iwl_trans->cfg = &killer1650i_2ax_cfg_qu_c0_hr_b0; ++ } + #endif + + pci_set_drvdata(pdev, iwl_trans); +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +index 199eddea82a9..dc95a5abc4d6 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +@@ -3569,10 +3569,10 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, + trans->cfg = &iwlax210_2ax_cfg_so_jf_a0; + } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == + CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF)) { +- trans->cfg = &iwlax210_2ax_cfg_so_gf_a0; ++ trans->cfg = &iwlax211_2ax_cfg_so_gf_a0; + } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == + CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF4)) { +- trans->cfg = &iwlax210_2ax_cfg_so_gf4_a0; ++ trans->cfg = &iwlax411_2ax_cfg_so_gf4_a0; + } + } else if (cfg == &iwl_ax101_cfg_qu_hr) { + if ((CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == +@@ -3600,10 +3600,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, + } + } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == + CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) && +- ((trans->cfg != &iwl_ax200_cfg_cc && +- trans->cfg != &killer1650x_2ax_cfg && +- trans->cfg != &killer1650w_2ax_cfg) || +- trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0)) { ++ trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0) { + u32 hw_status; + + hw_status = iwl_read_prph(trans, UMAG_GEN_HW_STATUS); +diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h +index 8ecbf81a906f..889b76deb703 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76.h ++++ b/drivers/net/wireless/mediatek/mt76/mt76.h +@@ -30,6 +30,7 @@ + #define MT_TX_RING_SIZE 256 + #define MT_MCU_RING_SIZE 32 + #define MT_RX_BUF_SIZE 2048 ++#define MT_SKB_HEAD_LEN 128 + + struct mt76_dev; + struct mt76_wcid; +diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +index 2dc67e68c6a2..109309b5d24a 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c ++++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +@@ -136,11 +136,11 @@ static const struct ieee80211_ops mt76x0u_ops = { + .release_buffered_frames = mt76_release_buffered_frames, + }; + +-static int mt76x0u_init_hardware(struct mt76x02_dev *dev) ++static int mt76x0u_init_hardware(struct mt76x02_dev *dev, bool reset) + { + int err; + +- mt76x0_chip_onoff(dev, true, true); ++ mt76x0_chip_onoff(dev, true, reset); + + if (!mt76x02_wait_for_mac(&dev->mt76)) + return -ETIMEDOUT; +@@ -173,7 +173,7 @@ static int mt76x0u_register_device(struct mt76x02_dev *dev) + if (err < 0) + goto out_err; + +- err = mt76x0u_init_hardware(dev); ++ err = mt76x0u_init_hardware(dev, true); + if (err < 0) + goto out_err; + +@@ -309,7 +309,7 @@ static int __maybe_unused mt76x0_resume(struct usb_interface *usb_intf) + if (ret < 0) + goto err; + +- ret = mt76x0u_init_hardware(dev); ++ ret = mt76x0u_init_hardware(dev, false); + if (ret) + goto err; + +diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c +index bbaa1365bbda..dd90427b2d67 100644 +--- a/drivers/net/wireless/mediatek/mt76/usb.c ++++ b/drivers/net/wireless/mediatek/mt76/usb.c +@@ -429,6 +429,42 @@ static int mt76u_get_rx_entry_len(u8 *data, u32 data_len) + return dma_len; + } + ++static struct sk_buff * ++mt76u_build_rx_skb(void *data, int len, int buf_size) ++{ ++ struct sk_buff *skb; ++ ++ if (SKB_WITH_OVERHEAD(buf_size) < MT_DMA_HDR_LEN + len) { ++ struct page *page; ++ ++ /* slow path, not enough space for data and ++ * skb_shared_info ++ */ ++ skb = alloc_skb(MT_SKB_HEAD_LEN, GFP_ATOMIC); ++ if (!skb) ++ return NULL; ++ ++ skb_put_data(skb, data + MT_DMA_HDR_LEN, MT_SKB_HEAD_LEN); ++ data += (MT_DMA_HDR_LEN + MT_SKB_HEAD_LEN); ++ page = virt_to_head_page(data); ++ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, ++ page, data - page_address(page), ++ len - MT_SKB_HEAD_LEN, buf_size); ++ ++ return skb; ++ } ++ ++ /* fast path */ ++ skb = build_skb(data, buf_size); ++ if (!skb) ++ return NULL; ++ ++ skb_reserve(skb, MT_DMA_HDR_LEN); ++ __skb_put(skb, len); ++ ++ return skb; ++} ++ + static int + mt76u_process_rx_entry(struct mt76_dev *dev, struct urb *urb) + { +@@ -446,19 +482,11 @@ mt76u_process_rx_entry(struct mt76_dev *dev, struct urb *urb) + return 0; + + data_len = min_t(int, len, data_len - MT_DMA_HDR_LEN); +- if (MT_DMA_HDR_LEN + data_len > SKB_WITH_OVERHEAD(q->buf_size)) { +- dev_err_ratelimited(dev->dev, "rx data too big %d\n", data_len); +- return 0; +- } +- +- skb = build_skb(data, q->buf_size); ++ skb = mt76u_build_rx_skb(data, data_len, q->buf_size); + if (!skb) + return 0; + +- skb_reserve(skb, MT_DMA_HDR_LEN); +- __skb_put(skb, data_len); + len -= data_len; +- + while (len > 0 && nsgs < urb->num_sgs) { + data_len = min_t(int, len, urb->sg[nsgs].length); + skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 5deb4deb3820..601509b3251a 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -1268,6 +1268,9 @@ static u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns, + */ + if (effects & (NVME_CMD_EFFECTS_LBCC | NVME_CMD_EFFECTS_CSE_MASK)) { + mutex_lock(&ctrl->scan_lock); ++ mutex_lock(&ctrl->subsys->lock); ++ nvme_mpath_start_freeze(ctrl->subsys); ++ nvme_mpath_wait_freeze(ctrl->subsys); + nvme_start_freeze(ctrl); + nvme_wait_freeze(ctrl); + } +@@ -1298,6 +1301,8 @@ static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects) + nvme_update_formats(ctrl); + if (effects & (NVME_CMD_EFFECTS_LBCC | NVME_CMD_EFFECTS_CSE_MASK)) { + nvme_unfreeze(ctrl); ++ nvme_mpath_unfreeze(ctrl->subsys); ++ mutex_unlock(&ctrl->subsys->lock); + mutex_unlock(&ctrl->scan_lock); + } + if (effects & NVME_CMD_EFFECTS_CCC) +@@ -1668,6 +1673,7 @@ static void __nvme_revalidate_disk(struct gendisk *disk, struct nvme_id_ns *id) + if (ns->head->disk) { + nvme_update_disk_info(ns->head->disk, ns, id); + blk_queue_stack_limits(ns->head->disk->queue, ns->queue); ++ revalidate_disk(ns->head->disk); + } + #endif + } +@@ -2439,6 +2445,7 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) + if (ret) { + dev_err(ctrl->device, + "failed to register subsystem device.\n"); ++ put_device(&subsys->dev); + goto out_unlock; + } + ida_init(&subsys->ns_ida); +@@ -2461,7 +2468,6 @@ out_put_subsystem: + nvme_put_subsystem(subsys); + out_unlock: + mutex_unlock(&nvme_subsystems_lock); +- put_device(&subsys->dev); + return ret; + } + +@@ -3523,6 +3529,13 @@ void nvme_remove_namespaces(struct nvme_ctrl *ctrl) + struct nvme_ns *ns, *next; + LIST_HEAD(ns_list); + ++ /* ++ * make sure to requeue I/O to all namespaces as these ++ * might result from the scan itself and must complete ++ * for the scan_work to make progress ++ */ ++ nvme_mpath_clear_ctrl_paths(ctrl); ++ + /* prevent racing with ns scanning */ + flush_work(&ctrl->scan_work); + +diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c +index e942b3e84068..747c0d4f9ff5 100644 +--- a/drivers/nvme/host/multipath.c ++++ b/drivers/nvme/host/multipath.c +@@ -12,6 +12,36 @@ module_param(multipath, bool, 0444); + MODULE_PARM_DESC(multipath, + "turn on native support for multiple controllers per subsystem"); + ++void nvme_mpath_unfreeze(struct nvme_subsystem *subsys) ++{ ++ struct nvme_ns_head *h; ++ ++ lockdep_assert_held(&subsys->lock); ++ list_for_each_entry(h, &subsys->nsheads, entry) ++ if (h->disk) ++ blk_mq_unfreeze_queue(h->disk->queue); ++} ++ ++void nvme_mpath_wait_freeze(struct nvme_subsystem *subsys) ++{ ++ struct nvme_ns_head *h; ++ ++ lockdep_assert_held(&subsys->lock); ++ list_for_each_entry(h, &subsys->nsheads, entry) ++ if (h->disk) ++ blk_mq_freeze_queue_wait(h->disk->queue); ++} ++ ++void nvme_mpath_start_freeze(struct nvme_subsystem *subsys) ++{ ++ struct nvme_ns_head *h; ++ ++ lockdep_assert_held(&subsys->lock); ++ list_for_each_entry(h, &subsys->nsheads, entry) ++ if (h->disk) ++ blk_freeze_queue_start(h->disk->queue); ++} ++ + /* + * If multipathing is enabled we need to always use the subsystem instance + * number for numbering our devices to avoid conflicts between subsystems that +@@ -104,18 +134,34 @@ static const char *nvme_ana_state_names[] = { + [NVME_ANA_CHANGE] = "change", + }; + +-void nvme_mpath_clear_current_path(struct nvme_ns *ns) ++bool nvme_mpath_clear_current_path(struct nvme_ns *ns) + { + struct nvme_ns_head *head = ns->head; ++ bool changed = false; + int node; + + if (!head) +- return; ++ goto out; + + for_each_node(node) { +- if (ns == rcu_access_pointer(head->current_path[node])) ++ if (ns == rcu_access_pointer(head->current_path[node])) { + rcu_assign_pointer(head->current_path[node], NULL); ++ changed = true; ++ } + } ++out: ++ return changed; ++} ++ ++void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl) ++{ ++ struct nvme_ns *ns; ++ ++ mutex_lock(&ctrl->scan_lock); ++ list_for_each_entry(ns, &ctrl->namespaces, list) ++ if (nvme_mpath_clear_current_path(ns)) ++ kblockd_schedule_work(&ns->head->requeue_work); ++ mutex_unlock(&ctrl->scan_lock); + } + + static struct nvme_ns *__nvme_find_path(struct nvme_ns_head *head, int node) +@@ -218,6 +264,24 @@ inline struct nvme_ns *nvme_find_path(struct nvme_ns_head *head) + return ns; + } + ++static bool nvme_available_path(struct nvme_ns_head *head) ++{ ++ struct nvme_ns *ns; ++ ++ list_for_each_entry_rcu(ns, &head->list, siblings) { ++ switch (ns->ctrl->state) { ++ case NVME_CTRL_LIVE: ++ case NVME_CTRL_RESETTING: ++ case NVME_CTRL_CONNECTING: ++ /* fallthru */ ++ return true; ++ default: ++ break; ++ } ++ } ++ return false; ++} ++ + static blk_qc_t nvme_ns_head_make_request(struct request_queue *q, + struct bio *bio) + { +@@ -244,14 +308,14 @@ static blk_qc_t nvme_ns_head_make_request(struct request_queue *q, + disk_devt(ns->head->disk), + bio->bi_iter.bi_sector); + ret = direct_make_request(bio); +- } else if (!list_empty_careful(&head->list)) { +- dev_warn_ratelimited(dev, "no path available - requeuing I/O\n"); ++ } else if (nvme_available_path(head)) { ++ dev_warn_ratelimited(dev, "no usable path - requeuing I/O\n"); + + spin_lock_irq(&head->requeue_lock); + bio_list_add(&head->requeue_list, bio); + spin_unlock_irq(&head->requeue_lock); + } else { +- dev_warn_ratelimited(dev, "no path - failing I/O\n"); ++ dev_warn_ratelimited(dev, "no available path - failing I/O\n"); + + bio->bi_status = BLK_STS_IOERR; + bio_endio(bio); +diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h +index 7391cd0a7739..81215ca32671 100644 +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -477,6 +477,9 @@ static inline bool nvme_ctrl_use_ana(struct nvme_ctrl *ctrl) + return ctrl->ana_log_buf != NULL; + } + ++void nvme_mpath_unfreeze(struct nvme_subsystem *subsys); ++void nvme_mpath_wait_freeze(struct nvme_subsystem *subsys); ++void nvme_mpath_start_freeze(struct nvme_subsystem *subsys); + void nvme_set_disk_name(char *disk_name, struct nvme_ns *ns, + struct nvme_ctrl *ctrl, int *flags); + void nvme_failover_req(struct request *req); +@@ -487,7 +490,8 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head); + int nvme_mpath_init(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id); + void nvme_mpath_uninit(struct nvme_ctrl *ctrl); + void nvme_mpath_stop(struct nvme_ctrl *ctrl); +-void nvme_mpath_clear_current_path(struct nvme_ns *ns); ++bool nvme_mpath_clear_current_path(struct nvme_ns *ns); ++void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl); + struct nvme_ns *nvme_find_path(struct nvme_ns_head *head); + + static inline void nvme_mpath_check_last_path(struct nvme_ns *ns) +@@ -535,7 +539,11 @@ static inline void nvme_mpath_add_disk(struct nvme_ns *ns, + static inline void nvme_mpath_remove_disk(struct nvme_ns_head *head) + { + } +-static inline void nvme_mpath_clear_current_path(struct nvme_ns *ns) ++static inline bool nvme_mpath_clear_current_path(struct nvme_ns *ns) ++{ ++ return false; ++} ++static inline void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl) + { + } + static inline void nvme_mpath_check_last_path(struct nvme_ns *ns) +@@ -555,6 +563,15 @@ static inline void nvme_mpath_uninit(struct nvme_ctrl *ctrl) + static inline void nvme_mpath_stop(struct nvme_ctrl *ctrl) + { + } ++static inline void nvme_mpath_unfreeze(struct nvme_subsystem *subsys) ++{ ++} ++static inline void nvme_mpath_wait_freeze(struct nvme_subsystem *subsys) ++{ ++} ++static inline void nvme_mpath_start_freeze(struct nvme_subsystem *subsys) ++{ ++} + #endif /* CONFIG_NVME_MULTIPATH */ + + #ifdef CONFIG_NVM +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index f9959eaaa185..09ffd21d1809 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -2712,7 +2712,7 @@ static void nvme_async_probe(void *data, async_cookie_t cookie) + { + struct nvme_dev *dev = data; + +- nvme_reset_ctrl_sync(&dev->ctrl); ++ flush_work(&dev->ctrl.reset_work); + flush_work(&dev->ctrl.scan_work); + nvme_put_ctrl(&dev->ctrl); + } +@@ -2778,6 +2778,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) + + dev_info(dev->ctrl.device, "pci function %s\n", dev_name(&pdev->dev)); + ++ nvme_reset_ctrl(&dev->ctrl); + nvme_get_ctrl(&dev->ctrl); + async_schedule(nvme_async_probe, dev); + +diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c +index 97f668a39ae1..7b074323bcdf 100644 +--- a/drivers/nvme/host/rdma.c ++++ b/drivers/nvme/host/rdma.c +@@ -562,13 +562,17 @@ out_destroy_cm_id: + return ret; + } + ++static void __nvme_rdma_stop_queue(struct nvme_rdma_queue *queue) ++{ ++ rdma_disconnect(queue->cm_id); ++ ib_drain_qp(queue->qp); ++} ++ + static void nvme_rdma_stop_queue(struct nvme_rdma_queue *queue) + { + if (!test_and_clear_bit(NVME_RDMA_Q_LIVE, &queue->flags)) + return; +- +- rdma_disconnect(queue->cm_id); +- ib_drain_qp(queue->qp); ++ __nvme_rdma_stop_queue(queue); + } + + static void nvme_rdma_free_queue(struct nvme_rdma_queue *queue) +@@ -607,11 +611,13 @@ static int nvme_rdma_start_queue(struct nvme_rdma_ctrl *ctrl, int idx) + else + ret = nvmf_connect_admin_queue(&ctrl->ctrl); + +- if (!ret) ++ if (!ret) { + set_bit(NVME_RDMA_Q_LIVE, &queue->flags); +- else ++ } else { ++ __nvme_rdma_stop_queue(queue); + dev_info(ctrl->ctrl.device, + "failed to connect queue: %d ret=%d\n", idx, ret); ++ } + return ret; + } + +diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c +index 08dd5af357f7..3854363118cc 100644 +--- a/drivers/nvme/target/configfs.c ++++ b/drivers/nvme/target/configfs.c +@@ -673,6 +673,7 @@ static void nvmet_port_subsys_drop_link(struct config_item *parent, + + found: + list_del(&p->entry); ++ nvmet_port_del_ctrls(port, subsys); + nvmet_port_disc_changed(port, subsys); + + if (list_empty(&port->subsystems)) +diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c +index 7734a6acff85..396cbc7ea353 100644 +--- a/drivers/nvme/target/core.c ++++ b/drivers/nvme/target/core.c +@@ -43,6 +43,9 @@ inline u16 errno_to_nvme_status(struct nvmet_req *req, int errno) + u16 status; + + switch (errno) { ++ case 0: ++ status = NVME_SC_SUCCESS; ++ break; + case -ENOSPC: + req->error_loc = offsetof(struct nvme_rw_command, length); + status = NVME_SC_CAP_EXCEEDED | NVME_SC_DNR; +@@ -277,6 +280,18 @@ void nvmet_unregister_transport(const struct nvmet_fabrics_ops *ops) + } + EXPORT_SYMBOL_GPL(nvmet_unregister_transport); + ++void nvmet_port_del_ctrls(struct nvmet_port *port, struct nvmet_subsys *subsys) ++{ ++ struct nvmet_ctrl *ctrl; ++ ++ mutex_lock(&subsys->lock); ++ list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) { ++ if (ctrl->port == port) ++ ctrl->ops->delete_ctrl(ctrl); ++ } ++ mutex_unlock(&subsys->lock); ++} ++ + int nvmet_enable_port(struct nvmet_port *port) + { + const struct nvmet_fabrics_ops *ops; +diff --git a/drivers/nvme/target/loop.c b/drivers/nvme/target/loop.c +index 9e211ad6bdd3..da9cd07461fb 100644 +--- a/drivers/nvme/target/loop.c ++++ b/drivers/nvme/target/loop.c +@@ -654,6 +654,14 @@ static void nvme_loop_remove_port(struct nvmet_port *port) + mutex_lock(&nvme_loop_ports_mutex); + list_del_init(&port->entry); + mutex_unlock(&nvme_loop_ports_mutex); ++ ++ /* ++ * Ensure any ctrls that are in the process of being ++ * deleted are in fact deleted before we return ++ * and free the port. This is to prevent active ++ * ctrls from using a port after it's freed. ++ */ ++ flush_workqueue(nvme_delete_wq); + } + + static const struct nvmet_fabrics_ops nvme_loop_ops = { +diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h +index c25d88fc9dec..b6b0d483e0c5 100644 +--- a/drivers/nvme/target/nvmet.h ++++ b/drivers/nvme/target/nvmet.h +@@ -415,6 +415,9 @@ void nvmet_port_send_ana_event(struct nvmet_port *port); + int nvmet_register_transport(const struct nvmet_fabrics_ops *ops); + void nvmet_unregister_transport(const struct nvmet_fabrics_ops *ops); + ++void nvmet_port_del_ctrls(struct nvmet_port *port, ++ struct nvmet_subsys *subsys); ++ + int nvmet_enable_port(struct nvmet_port *port); + void nvmet_disable_port(struct nvmet_port *port); + +diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c +index 682789bb8ab3..57ed2e2024bf 100644 +--- a/drivers/soundwire/cadence_master.c ++++ b/drivers/soundwire/cadence_master.c +@@ -80,8 +80,8 @@ + + #define CDNS_MCP_INTSET 0x4C + +-#define CDNS_SDW_SLAVE_STAT 0x50 +-#define CDNS_MCP_SLAVE_STAT_MASK BIT(1, 0) ++#define CDNS_MCP_SLAVE_STAT 0x50 ++#define CDNS_MCP_SLAVE_STAT_MASK GENMASK(1, 0) + + #define CDNS_MCP_SLAVE_INTSTAT0 0x54 + #define CDNS_MCP_SLAVE_INTSTAT1 0x58 +@@ -95,8 +95,8 @@ + #define CDNS_MCP_SLAVE_INTMASK0 0x5C + #define CDNS_MCP_SLAVE_INTMASK1 0x60 + +-#define CDNS_MCP_SLAVE_INTMASK0_MASK GENMASK(30, 0) +-#define CDNS_MCP_SLAVE_INTMASK1_MASK GENMASK(16, 0) ++#define CDNS_MCP_SLAVE_INTMASK0_MASK GENMASK(31, 0) ++#define CDNS_MCP_SLAVE_INTMASK1_MASK GENMASK(15, 0) + + #define CDNS_MCP_PORT_INTSTAT 0x64 + #define CDNS_MCP_PDI_STAT 0x6C +diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c +index 6a5ee8e6da10..67ad40b0a05b 100644 +--- a/drivers/usb/chipidea/udc.c ++++ b/drivers/usb/chipidea/udc.c +@@ -709,12 +709,6 @@ static int _gadget_stop_activity(struct usb_gadget *gadget) + struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget); + unsigned long flags; + +- spin_lock_irqsave(&ci->lock, flags); +- ci->gadget.speed = USB_SPEED_UNKNOWN; +- ci->remote_wakeup = 0; +- ci->suspended = 0; +- spin_unlock_irqrestore(&ci->lock, flags); +- + /* flush all endpoints */ + gadget_for_each_ep(ep, gadget) { + usb_ep_fifo_flush(ep); +@@ -732,6 +726,12 @@ static int _gadget_stop_activity(struct usb_gadget *gadget) + ci->status = NULL; + } + ++ spin_lock_irqsave(&ci->lock, flags); ++ ci->gadget.speed = USB_SPEED_UNKNOWN; ++ ci->remote_wakeup = 0; ++ ci->suspended = 0; ++ spin_unlock_irqrestore(&ci->lock, flags); ++ + return 0; + } + +@@ -1303,6 +1303,10 @@ static int ep_disable(struct usb_ep *ep) + return -EBUSY; + + spin_lock_irqsave(hwep->lock, flags); ++ if (hwep->ci->gadget.speed == USB_SPEED_UNKNOWN) { ++ spin_unlock_irqrestore(hwep->lock, flags); ++ return 0; ++ } + + /* only internal SW should disable ctrl endpts */ + +@@ -1392,6 +1396,10 @@ static int ep_queue(struct usb_ep *ep, struct usb_request *req, + return -EINVAL; + + spin_lock_irqsave(hwep->lock, flags); ++ if (hwep->ci->gadget.speed == USB_SPEED_UNKNOWN) { ++ spin_unlock_irqrestore(hwep->lock, flags); ++ return 0; ++ } + retval = _ep_queue(ep, req, gfp_flags); + spin_unlock_irqrestore(hwep->lock, flags); + return retval; +@@ -1415,8 +1423,8 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req) + return -EINVAL; + + spin_lock_irqsave(hwep->lock, flags); +- +- hw_ep_flush(hwep->ci, hwep->num, hwep->dir); ++ if (hwep->ci->gadget.speed != USB_SPEED_UNKNOWN) ++ hw_ep_flush(hwep->ci, hwep->num, hwep->dir); + + list_for_each_entry_safe(node, tmpnode, &hwreq->tds, td) { + dma_pool_free(hwep->td_pool, node->ptr, node->dma); +@@ -1487,6 +1495,10 @@ static void ep_fifo_flush(struct usb_ep *ep) + } + + spin_lock_irqsave(hwep->lock, flags); ++ if (hwep->ci->gadget.speed == USB_SPEED_UNKNOWN) { ++ spin_unlock_irqrestore(hwep->lock, flags); ++ return; ++ } + + hw_ep_flush(hwep->ci, hwep->num, hwep->dir); + +@@ -1559,6 +1571,10 @@ static int ci_udc_wakeup(struct usb_gadget *_gadget) + int ret = 0; + + spin_lock_irqsave(&ci->lock, flags); ++ if (ci->gadget.speed == USB_SPEED_UNKNOWN) { ++ spin_unlock_irqrestore(&ci->lock, flags); ++ return 0; ++ } + if (!ci->remote_wakeup) { + ret = -EOPNOTSUPP; + goto out; +diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c +index 9e9caff905d5..4929c5883068 100644 +--- a/drivers/usb/class/cdc-wdm.c ++++ b/drivers/usb/class/cdc-wdm.c +@@ -587,10 +587,20 @@ static int wdm_flush(struct file *file, fl_owner_t id) + { + struct wdm_device *desc = file->private_data; + +- wait_event(desc->wait, !test_bit(WDM_IN_USE, &desc->flags)); ++ wait_event(desc->wait, ++ /* ++ * needs both flags. We cannot do with one ++ * because resetting it would cause a race ++ * with write() yet we need to signal ++ * a disconnect ++ */ ++ !test_bit(WDM_IN_USE, &desc->flags) || ++ test_bit(WDM_DISCONNECTING, &desc->flags)); + + /* cannot dereference desc->intf if WDM_DISCONNECTING */ +- if (desc->werr < 0 && !test_bit(WDM_DISCONNECTING, &desc->flags)) ++ if (test_bit(WDM_DISCONNECTING, &desc->flags)) ++ return -ENODEV; ++ if (desc->werr < 0) + dev_err(&desc->intf->dev, "Error in flush path: %d\n", + desc->werr); + +@@ -974,8 +984,6 @@ static void wdm_disconnect(struct usb_interface *intf) + spin_lock_irqsave(&desc->iuspin, flags); + set_bit(WDM_DISCONNECTING, &desc->flags); + set_bit(WDM_READ, &desc->flags); +- /* to terminate pending flushes */ +- clear_bit(WDM_IN_USE, &desc->flags); + spin_unlock_irqrestore(&desc->iuspin, flags); + wake_up_all(&desc->wait); + mutex_lock(&desc->rlock); +diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c +index 4942122b2346..36858ddd8d9b 100644 +--- a/drivers/usb/class/usbtmc.c ++++ b/drivers/usb/class/usbtmc.c +@@ -2362,8 +2362,11 @@ static int usbtmc_probe(struct usb_interface *intf, + goto err_put; + } + ++ retcode = -EINVAL; + data->bulk_in = bulk_in->bEndpointAddress; + data->wMaxPacketSize = usb_endpoint_maxp(bulk_in); ++ if (!data->wMaxPacketSize) ++ goto err_put; + dev_dbg(&intf->dev, "Found bulk in endpoint at %u\n", data->bulk_in); + + data->bulk_out = bulk_out->bEndpointAddress; +diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c +index 03432467b05f..7537681355f6 100644 +--- a/drivers/usb/core/hcd-pci.c ++++ b/drivers/usb/core/hcd-pci.c +@@ -216,17 +216,18 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) + /* EHCI, OHCI */ + hcd->rsrc_start = pci_resource_start(dev, 0); + hcd->rsrc_len = pci_resource_len(dev, 0); +- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, +- driver->description)) { ++ if (!devm_request_mem_region(&dev->dev, hcd->rsrc_start, ++ hcd->rsrc_len, driver->description)) { + dev_dbg(&dev->dev, "controller already in use\n"); + retval = -EBUSY; + goto put_hcd; + } +- hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); ++ hcd->regs = devm_ioremap_nocache(&dev->dev, hcd->rsrc_start, ++ hcd->rsrc_len); + if (hcd->regs == NULL) { + dev_dbg(&dev->dev, "error mapping memory\n"); + retval = -EFAULT; +- goto release_mem_region; ++ goto put_hcd; + } + + } else { +@@ -240,8 +241,8 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) + + hcd->rsrc_start = pci_resource_start(dev, region); + hcd->rsrc_len = pci_resource_len(dev, region); +- if (request_region(hcd->rsrc_start, hcd->rsrc_len, +- driver->description)) ++ if (devm_request_region(&dev->dev, hcd->rsrc_start, ++ hcd->rsrc_len, driver->description)) + break; + } + if (region == PCI_ROM_RESOURCE) { +@@ -275,20 +276,13 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) + } + + if (retval != 0) +- goto unmap_registers; ++ goto put_hcd; + device_wakeup_enable(hcd->self.controller); + + if (pci_dev_run_wake(dev)) + pm_runtime_put_noidle(&dev->dev); + return retval; + +-unmap_registers: +- if (driver->flags & HCD_MEMORY) { +- iounmap(hcd->regs); +-release_mem_region: +- release_mem_region(hcd->rsrc_start, hcd->rsrc_len); +- } else +- release_region(hcd->rsrc_start, hcd->rsrc_len); + put_hcd: + usb_put_hcd(hcd); + disable_pci: +@@ -347,14 +341,6 @@ void usb_hcd_pci_remove(struct pci_dev *dev) + dev_set_drvdata(&dev->dev, NULL); + up_read(&companions_rwsem); + } +- +- if (hcd->driver->flags & HCD_MEMORY) { +- iounmap(hcd->regs); +- release_mem_region(hcd->rsrc_start, hcd->rsrc_len); +- } else { +- release_region(hcd->rsrc_start, hcd->rsrc_len); +- } +- + usb_put_hcd(hcd); + pci_disable_device(dev); + } +diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c +index b8a15840b4ff..dfcabadeed01 100644 +--- a/drivers/usb/gadget/composite.c ++++ b/drivers/usb/gadget/composite.c +@@ -1976,6 +1976,7 @@ void composite_disconnect(struct usb_gadget *gadget) + * disconnect callbacks? + */ + spin_lock_irqsave(&cdev->lock, flags); ++ cdev->suspended = 0; + if (cdev->config) + reset_config(cdev); + if (cdev->driver->disconnect) +diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c +index 043f97ad8f22..f2bc8d037067 100644 +--- a/drivers/usb/gadget/function/f_mass_storage.c ++++ b/drivers/usb/gadget/function/f_mass_storage.c +@@ -261,7 +261,7 @@ struct fsg_common; + struct fsg_common { + struct usb_gadget *gadget; + struct usb_composite_dev *cdev; +- struct fsg_dev *fsg, *new_fsg; ++ struct fsg_dev *fsg; + wait_queue_head_t io_wait; + wait_queue_head_t fsg_wait; + +@@ -290,6 +290,7 @@ struct fsg_common { + unsigned int bulk_out_maxpacket; + enum fsg_state state; /* For exception handling */ + unsigned int exception_req_tag; ++ void *exception_arg; + + enum data_direction data_dir; + u32 data_size; +@@ -391,7 +392,8 @@ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) + + /* These routines may be called in process context or in_irq */ + +-static void raise_exception(struct fsg_common *common, enum fsg_state new_state) ++static void __raise_exception(struct fsg_common *common, enum fsg_state new_state, ++ void *arg) + { + unsigned long flags; + +@@ -404,6 +406,7 @@ static void raise_exception(struct fsg_common *common, enum fsg_state new_state) + if (common->state <= new_state) { + common->exception_req_tag = common->ep0_req_tag; + common->state = new_state; ++ common->exception_arg = arg; + if (common->thread_task) + send_sig_info(SIGUSR1, SEND_SIG_PRIV, + common->thread_task); +@@ -411,6 +414,10 @@ static void raise_exception(struct fsg_common *common, enum fsg_state new_state) + spin_unlock_irqrestore(&common->lock, flags); + } + ++static void raise_exception(struct fsg_common *common, enum fsg_state new_state) ++{ ++ __raise_exception(common, new_state, NULL); ++} + + /*-------------------------------------------------------------------------*/ + +@@ -2285,16 +2292,16 @@ reset: + static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) + { + struct fsg_dev *fsg = fsg_from_func(f); +- fsg->common->new_fsg = fsg; +- raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); ++ ++ __raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE, fsg); + return USB_GADGET_DELAYED_STATUS; + } + + static void fsg_disable(struct usb_function *f) + { + struct fsg_dev *fsg = fsg_from_func(f); +- fsg->common->new_fsg = NULL; +- raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); ++ ++ __raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE, NULL); + } + + +@@ -2307,6 +2314,7 @@ static void handle_exception(struct fsg_common *common) + enum fsg_state old_state; + struct fsg_lun *curlun; + unsigned int exception_req_tag; ++ struct fsg_dev *new_fsg; + + /* + * Clear the existing signals. Anything but SIGUSR1 is converted +@@ -2360,6 +2368,7 @@ static void handle_exception(struct fsg_common *common) + common->next_buffhd_to_fill = &common->buffhds[0]; + common->next_buffhd_to_drain = &common->buffhds[0]; + exception_req_tag = common->exception_req_tag; ++ new_fsg = common->exception_arg; + old_state = common->state; + common->state = FSG_STATE_NORMAL; + +@@ -2413,8 +2422,8 @@ static void handle_exception(struct fsg_common *common) + break; + + case FSG_STATE_CONFIG_CHANGE: +- do_set_interface(common, common->new_fsg); +- if (common->new_fsg) ++ do_set_interface(common, new_fsg); ++ if (new_fsg) + usb_composite_setup_continue(common->cdev); + break; + +@@ -2989,8 +2998,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f) + + DBG(fsg, "unbind\n"); + if (fsg->common->fsg == fsg) { +- fsg->common->new_fsg = NULL; +- raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); ++ __raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE, NULL); + /* FIXME: make interruptible or killable somehow? */ + wait_event(common->fsg_wait, common->fsg != fsg); + } +diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c +index 0da68df259c8..7bf621d40c5a 100644 +--- a/drivers/usb/host/fotg210-hcd.c ++++ b/drivers/usb/host/fotg210-hcd.c +@@ -1628,6 +1628,10 @@ static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + /* see what we found out */ + temp = check_reset_complete(fotg210, wIndex, status_reg, + fotg210_readl(fotg210, status_reg)); ++ ++ /* restart schedule */ ++ fotg210->command |= CMD_RUN; ++ fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command); + } + + if (!(temp & (PORT_RESUME|PORT_RESET))) { +diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c +index 210181fd98d2..af11887f5f9e 100644 +--- a/drivers/usb/host/ohci-hcd.c ++++ b/drivers/usb/host/ohci-hcd.c +@@ -418,8 +418,7 @@ static void ohci_usb_reset (struct ohci_hcd *ohci) + * other cases where the next software may expect clean state from the + * "firmware". this is bus-neutral, unlike shutdown() methods. + */ +-static void +-ohci_shutdown (struct usb_hcd *hcd) ++static void _ohci_shutdown(struct usb_hcd *hcd) + { + struct ohci_hcd *ohci; + +@@ -435,6 +434,16 @@ ohci_shutdown (struct usb_hcd *hcd) + ohci->rh_state = OHCI_RH_HALTED; + } + ++static void ohci_shutdown(struct usb_hcd *hcd) ++{ ++ struct ohci_hcd *ohci = hcd_to_ohci(hcd); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ohci->lock, flags); ++ _ohci_shutdown(hcd); ++ spin_unlock_irqrestore(&ohci->lock, flags); ++} ++ + /*-------------------------------------------------------------------------* + * HC functions + *-------------------------------------------------------------------------*/ +@@ -752,7 +761,7 @@ static void io_watchdog_func(struct timer_list *t) + died: + usb_hc_died(ohci_to_hcd(ohci)); + ohci_dump(ohci); +- ohci_shutdown(ohci_to_hcd(ohci)); ++ _ohci_shutdown(ohci_to_hcd(ohci)); + goto done; + } else { + /* No write back because the done queue was empty */ +diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c +index 8616c52849c6..2b0ccd150209 100644 +--- a/drivers/usb/host/xhci-rcar.c ++++ b/drivers/usb/host/xhci-rcar.c +@@ -104,7 +104,7 @@ static int xhci_rcar_is_gen2(struct device *dev) + return of_device_is_compatible(node, "renesas,xhci-r8a7790") || + of_device_is_compatible(node, "renesas,xhci-r8a7791") || + of_device_is_compatible(node, "renesas,xhci-r8a7793") || +- of_device_is_compatible(node, "renensas,rcar-gen2-xhci"); ++ of_device_is_compatible(node, "renesas,rcar-gen2-xhci"); + } + + static int xhci_rcar_is_gen3(struct device *dev) +diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c +index cc794e25a0b6..1d9ce9cbc831 100644 +--- a/drivers/usb/storage/realtek_cr.c ++++ b/drivers/usb/storage/realtek_cr.c +@@ -38,7 +38,7 @@ MODULE_LICENSE("GPL"); + + static int auto_delink_en = 1; + module_param(auto_delink_en, int, S_IRUGO | S_IWUSR); +-MODULE_PARM_DESC(auto_delink_en, "enable auto delink"); ++MODULE_PARM_DESC(auto_delink_en, "auto delink mode (0=firmware, 1=software [default])"); + + #ifdef CONFIG_REALTEK_AUTOPM + static int ss_en = 1; +@@ -996,12 +996,15 @@ static int init_realtek_cr(struct us_data *us) + goto INIT_FAIL; + } + +- if (CHECK_FW_VER(chip, 0x5888) || CHECK_FW_VER(chip, 0x5889) || +- CHECK_FW_VER(chip, 0x5901)) +- SET_AUTO_DELINK(chip); +- if (STATUS_LEN(chip) == 16) { +- if (SUPPORT_AUTO_DELINK(chip)) ++ if (CHECK_PID(chip, 0x0138) || CHECK_PID(chip, 0x0158) || ++ CHECK_PID(chip, 0x0159)) { ++ if (CHECK_FW_VER(chip, 0x5888) || CHECK_FW_VER(chip, 0x5889) || ++ CHECK_FW_VER(chip, 0x5901)) + SET_AUTO_DELINK(chip); ++ if (STATUS_LEN(chip) == 16) { ++ if (SUPPORT_AUTO_DELINK(chip)) ++ SET_AUTO_DELINK(chip); ++ } + } + #ifdef CONFIG_REALTEK_AUTOPM + if (ss_en) +diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h +index ea0d27a94afe..1cd9b6305b06 100644 +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -2100,7 +2100,7 @@ UNUSUAL_DEV( 0x14cd, 0x6600, 0x0201, 0x0201, + US_FL_IGNORE_RESIDUE ), + + /* Reported by Michael Büsch */ +-UNUSUAL_DEV( 0x152d, 0x0567, 0x0114, 0x0116, ++UNUSUAL_DEV( 0x152d, 0x0567, 0x0114, 0x0117, + "JMicron", + "USB to ATA/ATAPI Bridge", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, +diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c +index 15abe1d9958f..bcfdb55fd198 100644 +--- a/drivers/usb/typec/tcpm/tcpm.c ++++ b/drivers/usb/typec/tcpm/tcpm.c +@@ -1446,7 +1446,7 @@ static enum pdo_err tcpm_caps_err(struct tcpm_port *port, const u32 *pdo, + else if ((pdo_min_voltage(pdo[i]) == + pdo_min_voltage(pdo[i - 1])) && + (pdo_max_voltage(pdo[i]) == +- pdo_min_voltage(pdo[i - 1]))) ++ pdo_max_voltage(pdo[i - 1]))) + return PDO_ERR_DUPE_PDO; + break; + /* +diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c +index 560c1c54c177..f4937a91e516 100644 +--- a/drivers/watchdog/bcm2835_wdt.c ++++ b/drivers/watchdog/bcm2835_wdt.c +@@ -240,6 +240,7 @@ module_param(nowayout, bool, 0); + MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + ++MODULE_ALIAS("platform:bcm2835-wdt"); + MODULE_AUTHOR("Lubomir Rintel "); + MODULE_DESCRIPTION("Driver for Broadcom BCM2835 watchdog timer"); + MODULE_LICENSE("GPL"); +diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c +index 3451be03667f..00033a481ba0 100644 +--- a/fs/afs/cmservice.c ++++ b/fs/afs/cmservice.c +@@ -502,18 +502,14 @@ static void SRXAFSCB_ProbeUuid(struct work_struct *work) + struct afs_call *call = container_of(work, struct afs_call, work); + struct afs_uuid *r = call->request; + +- struct { +- __be32 match; +- } reply; +- + _enter(""); + + if (memcmp(r, &call->net->uuid, sizeof(call->net->uuid)) == 0) +- reply.match = htonl(0); ++ afs_send_empty_reply(call); + else +- reply.match = htonl(1); ++ rxrpc_kernel_abort_call(call->net->socket, call->rxcall, ++ 1, 1, "K-1"); + +- afs_send_simple_reply(call, &reply, sizeof(reply)); + afs_put_call(call); + _leave(""); + } +diff --git a/fs/afs/dir.c b/fs/afs/dir.c +index da9563d62b32..9620f19308f5 100644 +--- a/fs/afs/dir.c ++++ b/fs/afs/dir.c +@@ -441,7 +441,7 @@ static int afs_dir_iterate_block(struct afs_vnode *dvnode, + * iterate through the data blob that lists the contents of an AFS directory + */ + static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx, +- struct key *key) ++ struct key *key, afs_dataversion_t *_dir_version) + { + struct afs_vnode *dvnode = AFS_FS_I(dir); + struct afs_xdr_dir_page *dbuf; +@@ -461,6 +461,7 @@ static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx, + req = afs_read_dir(dvnode, key); + if (IS_ERR(req)) + return PTR_ERR(req); ++ *_dir_version = req->data_version; + + /* round the file position up to the next entry boundary */ + ctx->pos += sizeof(union afs_xdr_dirent) - 1; +@@ -515,7 +516,10 @@ out: + */ + static int afs_readdir(struct file *file, struct dir_context *ctx) + { +- return afs_dir_iterate(file_inode(file), ctx, afs_file_key(file)); ++ afs_dataversion_t dir_version; ++ ++ return afs_dir_iterate(file_inode(file), ctx, afs_file_key(file), ++ &dir_version); + } + + /* +@@ -556,7 +560,8 @@ static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name, + * - just returns the FID the dentry name maps to if found + */ + static int afs_do_lookup_one(struct inode *dir, struct dentry *dentry, +- struct afs_fid *fid, struct key *key) ++ struct afs_fid *fid, struct key *key, ++ afs_dataversion_t *_dir_version) + { + struct afs_super_info *as = dir->i_sb->s_fs_info; + struct afs_lookup_one_cookie cookie = { +@@ -569,7 +574,7 @@ static int afs_do_lookup_one(struct inode *dir, struct dentry *dentry, + _enter("{%lu},%p{%pd},", dir->i_ino, dentry, dentry); + + /* search the directory */ +- ret = afs_dir_iterate(dir, &cookie.ctx, key); ++ ret = afs_dir_iterate(dir, &cookie.ctx, key, _dir_version); + if (ret < 0) { + _leave(" = %d [iter]", ret); + return ret; +@@ -643,6 +648,7 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry, + struct afs_server *server; + struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode; + struct inode *inode = NULL, *ti; ++ afs_dataversion_t data_version = READ_ONCE(dvnode->status.data_version); + int ret, i; + + _enter("{%lu},%p{%pd},", dir->i_ino, dentry, dentry); +@@ -670,12 +676,14 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry, + cookie->fids[i].vid = as->volume->vid; + + /* search the directory */ +- ret = afs_dir_iterate(dir, &cookie->ctx, key); ++ ret = afs_dir_iterate(dir, &cookie->ctx, key, &data_version); + if (ret < 0) { + inode = ERR_PTR(ret); + goto out; + } + ++ dentry->d_fsdata = (void *)(unsigned long)data_version; ++ + inode = ERR_PTR(-ENOENT); + if (!cookie->found) + goto out; +@@ -969,7 +977,8 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) + struct dentry *parent; + struct inode *inode; + struct key *key; +- long dir_version, de_version; ++ afs_dataversion_t dir_version; ++ long de_version; + int ret; + + if (flags & LOOKUP_RCU) +@@ -1015,20 +1024,20 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) + * on a 32-bit system, we only have 32 bits in the dentry to store the + * version. + */ +- dir_version = (long)dir->status.data_version; ++ dir_version = dir->status.data_version; + de_version = (long)dentry->d_fsdata; +- if (de_version == dir_version) +- goto out_valid; ++ if (de_version == (long)dir_version) ++ goto out_valid_noupdate; + +- dir_version = (long)dir->invalid_before; +- if (de_version - dir_version >= 0) ++ dir_version = dir->invalid_before; ++ if (de_version - (long)dir_version >= 0) + goto out_valid; + + _debug("dir modified"); + afs_stat_v(dir, n_reval); + + /* search the directory for this vnode */ +- ret = afs_do_lookup_one(&dir->vfs_inode, dentry, &fid, key); ++ ret = afs_do_lookup_one(&dir->vfs_inode, dentry, &fid, key, &dir_version); + switch (ret) { + case 0: + /* the filename maps to something */ +@@ -1081,7 +1090,8 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) + } + + out_valid: +- dentry->d_fsdata = (void *)dir_version; ++ dentry->d_fsdata = (void *)(unsigned long)dir_version; ++out_valid_noupdate: + dput(parent); + key_put(key); + _leave(" = 1 [valid]"); +@@ -1186,6 +1196,20 @@ static void afs_prep_for_new_inode(struct afs_fs_cursor *fc, + iget_data->cb_s_break = fc->cbi->server->cb_s_break; + } + ++/* ++ * Note that a dentry got changed. We need to set d_fsdata to the data version ++ * number derived from the result of the operation. It doesn't matter if ++ * d_fsdata goes backwards as we'll just revalidate. ++ */ ++static void afs_update_dentry_version(struct afs_fs_cursor *fc, ++ struct dentry *dentry, ++ struct afs_status_cb *scb) ++{ ++ if (fc->ac.error == 0) ++ dentry->d_fsdata = ++ (void *)(unsigned long)scb->status.data_version; ++} ++ + /* + * create a directory on an AFS filesystem + */ +@@ -1228,6 +1252,7 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) + afs_check_for_remote_deletion(&fc, dvnode); + afs_vnode_commit_status(&fc, dvnode, fc.cb_break, + &data_version, &scb[0]); ++ afs_update_dentry_version(&fc, dentry, &scb[0]); + afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]); + ret = afs_end_vnode_operation(&fc); + if (ret < 0) +@@ -1320,6 +1345,7 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry) + + afs_vnode_commit_status(&fc, dvnode, fc.cb_break, + &data_version, scb); ++ afs_update_dentry_version(&fc, dentry, scb); + ret = afs_end_vnode_operation(&fc); + if (ret == 0) { + afs_dir_remove_subdir(dentry); +@@ -1461,6 +1487,7 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry) + &data_version, &scb[0]); + afs_vnode_commit_status(&fc, vnode, fc.cb_break_2, + &data_version_2, &scb[1]); ++ afs_update_dentry_version(&fc, dentry, &scb[0]); + ret = afs_end_vnode_operation(&fc); + if (ret == 0 && !(scb[1].have_status || scb[1].have_error)) + ret = afs_dir_remove_link(dvnode, dentry, key); +@@ -1529,6 +1556,7 @@ static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode, + afs_check_for_remote_deletion(&fc, dvnode); + afs_vnode_commit_status(&fc, dvnode, fc.cb_break, + &data_version, &scb[0]); ++ afs_update_dentry_version(&fc, dentry, &scb[0]); + afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]); + ret = afs_end_vnode_operation(&fc); + if (ret < 0) +@@ -1610,6 +1638,7 @@ static int afs_link(struct dentry *from, struct inode *dir, + afs_vnode_commit_status(&fc, vnode, fc.cb_break_2, + NULL, &scb[1]); + ihold(&vnode->vfs_inode); ++ afs_update_dentry_version(&fc, dentry, &scb[0]); + d_instantiate(dentry, &vnode->vfs_inode); + + mutex_unlock(&vnode->io_lock); +@@ -1689,6 +1718,7 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry, + afs_check_for_remote_deletion(&fc, dvnode); + afs_vnode_commit_status(&fc, dvnode, fc.cb_break, + &data_version, &scb[0]); ++ afs_update_dentry_version(&fc, dentry, &scb[0]); + afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]); + ret = afs_end_vnode_operation(&fc); + if (ret < 0) +@@ -1794,6 +1824,17 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, + } + } + ++ /* This bit is potentially nasty as there's a potential race with ++ * afs_d_revalidate{,_rcu}(). We have to change d_fsdata on the dentry ++ * to reflect it's new parent's new data_version after the op, but ++ * d_revalidate may see old_dentry between the op having taken place ++ * and the version being updated. ++ * ++ * So drop the old_dentry for now to make other threads go through ++ * lookup instead - which we hold a lock against. ++ */ ++ d_drop(old_dentry); ++ + ret = -ERESTARTSYS; + if (afs_begin_vnode_operation(&fc, orig_dvnode, key, true)) { + afs_dataversion_t orig_data_version; +@@ -1805,9 +1846,9 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, + if (orig_dvnode != new_dvnode) { + if (mutex_lock_interruptible_nested(&new_dvnode->io_lock, 1) < 0) { + afs_end_vnode_operation(&fc); +- goto error_rehash; ++ goto error_rehash_old; + } +- new_data_version = new_dvnode->status.data_version; ++ new_data_version = new_dvnode->status.data_version + 1; + } else { + new_data_version = orig_data_version; + new_scb = &scb[0]; +@@ -1830,7 +1871,7 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, + } + ret = afs_end_vnode_operation(&fc); + if (ret < 0) +- goto error_rehash; ++ goto error_rehash_old; + } + + if (ret == 0) { +@@ -1856,10 +1897,26 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, + drop_nlink(new_inode); + spin_unlock(&new_inode->i_lock); + } ++ ++ /* Now we can update d_fsdata on the dentries to reflect their ++ * new parent's data_version. ++ * ++ * Note that if we ever implement RENAME_EXCHANGE, we'll have ++ * to update both dentries with opposing dir versions. ++ */ ++ if (new_dvnode != orig_dvnode) { ++ afs_update_dentry_version(&fc, old_dentry, &scb[1]); ++ afs_update_dentry_version(&fc, new_dentry, &scb[1]); ++ } else { ++ afs_update_dentry_version(&fc, old_dentry, &scb[0]); ++ afs_update_dentry_version(&fc, new_dentry, &scb[0]); ++ } + d_move(old_dentry, new_dentry); + goto error_tmp; + } + ++error_rehash_old: ++ d_rehash(new_dentry); + error_rehash: + if (rehash) + d_rehash(rehash); +diff --git a/fs/afs/file.c b/fs/afs/file.c +index 8fd7d3b9a1b1..87beabc7114e 100644 +--- a/fs/afs/file.c ++++ b/fs/afs/file.c +@@ -191,11 +191,13 @@ void afs_put_read(struct afs_read *req) + int i; + + if (refcount_dec_and_test(&req->usage)) { +- for (i = 0; i < req->nr_pages; i++) +- if (req->pages[i]) +- put_page(req->pages[i]); +- if (req->pages != req->array) +- kfree(req->pages); ++ if (req->pages) { ++ for (i = 0; i < req->nr_pages; i++) ++ if (req->pages[i]) ++ put_page(req->pages[i]); ++ if (req->pages != req->array) ++ kfree(req->pages); ++ } + kfree(req); + } + } +diff --git a/fs/afs/vlclient.c b/fs/afs/vlclient.c +index d7e0fd3c00df..cfb0ac4bd039 100644 +--- a/fs/afs/vlclient.c ++++ b/fs/afs/vlclient.c +@@ -56,23 +56,24 @@ static int afs_deliver_vl_get_entry_by_name_u(struct afs_call *call) + struct afs_uuid__xdr *xdr; + struct afs_uuid *uuid; + int j; ++ int n = entry->nr_servers; + + tmp = ntohl(uvldb->serverFlags[i]); + if (tmp & AFS_VLSF_DONTUSE || + (new_only && !(tmp & AFS_VLSF_NEWREPSITE))) + continue; + if (tmp & AFS_VLSF_RWVOL) { +- entry->fs_mask[i] |= AFS_VOL_VTM_RW; ++ entry->fs_mask[n] |= AFS_VOL_VTM_RW; + if (vlflags & AFS_VLF_BACKEXISTS) +- entry->fs_mask[i] |= AFS_VOL_VTM_BAK; ++ entry->fs_mask[n] |= AFS_VOL_VTM_BAK; + } + if (tmp & AFS_VLSF_ROVOL) +- entry->fs_mask[i] |= AFS_VOL_VTM_RO; +- if (!entry->fs_mask[i]) ++ entry->fs_mask[n] |= AFS_VOL_VTM_RO; ++ if (!entry->fs_mask[n]) + continue; + + xdr = &uvldb->serverNumber[i]; +- uuid = (struct afs_uuid *)&entry->fs_server[i]; ++ uuid = (struct afs_uuid *)&entry->fs_server[n]; + uuid->time_low = xdr->time_low; + uuid->time_mid = htons(ntohl(xdr->time_mid)); + uuid->time_hi_and_version = htons(ntohl(xdr->time_hi_and_version)); +diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c +index 5faf057f6f37..b8f472087902 100644 +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -11226,6 +11226,7 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range) + struct btrfs_device *device; + struct list_head *devices; + u64 group_trimmed; ++ u64 range_end = U64_MAX; + u64 start; + u64 end; + u64 trimmed = 0; +@@ -11235,16 +11236,23 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range) + int dev_ret = 0; + int ret = 0; + ++ /* ++ * Check range overflow if range->len is set. ++ * The default range->len is U64_MAX. ++ */ ++ if (range->len != U64_MAX && ++ check_add_overflow(range->start, range->len, &range_end)) ++ return -EINVAL; ++ + cache = btrfs_lookup_first_block_group(fs_info, range->start); + for (; cache; cache = next_block_group(cache)) { +- if (cache->key.objectid >= (range->start + range->len)) { ++ if (cache->key.objectid >= range_end) { + btrfs_put_block_group(cache); + break; + } + + start = max(range->start, cache->key.objectid); +- end = min(range->start + range->len, +- cache->key.objectid + cache->key.offset); ++ end = min(range_end, cache->key.objectid + cache->key.offset); + + if (end - start >= range->minlen) { + if (!block_group_cache_done(cache)) { +diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c +index 0cb442406168..222d7115db71 100644 +--- a/fs/nfs/direct.c ++++ b/fs/nfs/direct.c +@@ -401,15 +401,21 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *hdr) + unsigned long bytes = 0; + struct nfs_direct_req *dreq = hdr->dreq; + +- if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) +- goto out_put; +- + spin_lock(&dreq->lock); +- if (test_bit(NFS_IOHDR_ERROR, &hdr->flags) && (hdr->good_bytes == 0)) ++ if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) + dreq->error = hdr->error; +- else ++ ++ if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) { ++ spin_unlock(&dreq->lock); ++ goto out_put; ++ } ++ ++ if (hdr->good_bytes != 0) + nfs_direct_good_bytes(dreq, hdr); + ++ if (test_bit(NFS_IOHDR_EOF, &hdr->flags)) ++ dreq->error = 0; ++ + spin_unlock(&dreq->lock); + + while (!list_empty(&hdr->pages)) { +@@ -782,16 +788,19 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr) + bool request_commit = false; + struct nfs_page *req = nfs_list_entry(hdr->pages.next); + +- if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) +- goto out_put; +- + nfs_init_cinfo_from_dreq(&cinfo, dreq); + + spin_lock(&dreq->lock); + + if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) + dreq->error = hdr->error; +- if (dreq->error == 0) { ++ ++ if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) { ++ spin_unlock(&dreq->lock); ++ goto out_put; ++ } ++ ++ if (hdr->good_bytes != 0) { + nfs_direct_good_bytes(dreq, hdr); + if (nfs_write_need_commit(hdr)) { + if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES) +diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c +index bcff3bf5ae09..c67cdbb36ce7 100644 +--- a/fs/nfs/flexfilelayout/flexfilelayout.c ++++ b/fs/nfs/flexfilelayout/flexfilelayout.c +@@ -1128,8 +1128,6 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task, + break; + case -NFS4ERR_RETRY_UNCACHED_REP: + break; +- case -EAGAIN: +- return -NFS4ERR_RESET_TO_PNFS; + /* Invalidate Layout errors */ + case -NFS4ERR_PNFS_NO_LAYOUT: + case -ESTALE: /* mapped NFS4ERR_STALE */ +@@ -1190,7 +1188,6 @@ static int ff_layout_async_handle_error_v3(struct rpc_task *task, + case -EBADHANDLE: + case -ELOOP: + case -ENOSPC: +- case -EAGAIN: + break; + case -EJUKEBOX: + nfs_inc_stats(lseg->pls_layout->plh_inode, NFSIOS_DELAY); +@@ -1425,16 +1422,6 @@ static void ff_layout_read_prepare_v4(struct rpc_task *task, void *data) + ff_layout_read_prepare_common(task, hdr); + } + +-static void +-ff_layout_io_prepare_transmit(struct rpc_task *task, +- void *data) +-{ +- struct nfs_pgio_header *hdr = data; +- +- if (!pnfs_is_valid_lseg(hdr->lseg)) +- rpc_exit(task, -EAGAIN); +-} +- + static void ff_layout_read_call_done(struct rpc_task *task, void *data) + { + struct nfs_pgio_header *hdr = data; +@@ -1720,7 +1707,6 @@ static void ff_layout_commit_release(void *data) + + static const struct rpc_call_ops ff_layout_read_call_ops_v3 = { + .rpc_call_prepare = ff_layout_read_prepare_v3, +- .rpc_call_prepare_transmit = ff_layout_io_prepare_transmit, + .rpc_call_done = ff_layout_read_call_done, + .rpc_count_stats = ff_layout_read_count_stats, + .rpc_release = ff_layout_read_release, +@@ -1728,7 +1714,6 @@ static const struct rpc_call_ops ff_layout_read_call_ops_v3 = { + + static const struct rpc_call_ops ff_layout_read_call_ops_v4 = { + .rpc_call_prepare = ff_layout_read_prepare_v4, +- .rpc_call_prepare_transmit = ff_layout_io_prepare_transmit, + .rpc_call_done = ff_layout_read_call_done, + .rpc_count_stats = ff_layout_read_count_stats, + .rpc_release = ff_layout_read_release, +@@ -1736,7 +1721,6 @@ static const struct rpc_call_ops ff_layout_read_call_ops_v4 = { + + static const struct rpc_call_ops ff_layout_write_call_ops_v3 = { + .rpc_call_prepare = ff_layout_write_prepare_v3, +- .rpc_call_prepare_transmit = ff_layout_io_prepare_transmit, + .rpc_call_done = ff_layout_write_call_done, + .rpc_count_stats = ff_layout_write_count_stats, + .rpc_release = ff_layout_write_release, +@@ -1744,7 +1728,6 @@ static const struct rpc_call_ops ff_layout_write_call_ops_v3 = { + + static const struct rpc_call_ops ff_layout_write_call_ops_v4 = { + .rpc_call_prepare = ff_layout_write_prepare_v4, +- .rpc_call_prepare_transmit = ff_layout_io_prepare_transmit, + .rpc_call_done = ff_layout_write_call_done, + .rpc_count_stats = ff_layout_write_count_stats, + .rpc_release = ff_layout_write_release, +diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c +index 6ef5278326b6..8b6211753228 100644 +--- a/fs/nfs/pagelist.c ++++ b/fs/nfs/pagelist.c +@@ -1253,20 +1253,23 @@ static void nfs_pageio_complete_mirror(struct nfs_pageio_descriptor *desc, + int nfs_pageio_resend(struct nfs_pageio_descriptor *desc, + struct nfs_pgio_header *hdr) + { +- LIST_HEAD(failed); ++ LIST_HEAD(pages); + + desc->pg_io_completion = hdr->io_completion; + desc->pg_dreq = hdr->dreq; +- while (!list_empty(&hdr->pages)) { +- struct nfs_page *req = nfs_list_entry(hdr->pages.next); ++ list_splice_init(&hdr->pages, &pages); ++ while (!list_empty(&pages)) { ++ struct nfs_page *req = nfs_list_entry(pages.next); + + if (!nfs_pageio_add_request(desc, req)) +- nfs_list_move_request(req, &failed); ++ break; + } + nfs_pageio_complete(desc); +- if (!list_empty(&failed)) { +- list_move(&failed, &hdr->pages); +- return desc->pg_error < 0 ? desc->pg_error : -EIO; ++ if (!list_empty(&pages)) { ++ int err = desc->pg_error < 0 ? desc->pg_error : -EIO; ++ hdr->completion_ops->error_cleanup(&pages, err); ++ nfs_set_pgio_error(hdr, err, hdr->io_start); ++ return err; + } + return 0; + } +diff --git a/include/linux/logic_pio.h b/include/linux/logic_pio.h +index cbd9d8495690..88e1e6304a71 100644 +--- a/include/linux/logic_pio.h ++++ b/include/linux/logic_pio.h +@@ -117,6 +117,7 @@ struct logic_pio_hwaddr *find_io_range_by_fwnode(struct fwnode_handle *fwnode); + unsigned long logic_pio_trans_hwaddr(struct fwnode_handle *fwnode, + resource_size_t hw_addr, resource_size_t size); + int logic_pio_register_range(struct logic_pio_hwaddr *newrange); ++void logic_pio_unregister_range(struct logic_pio_hwaddr *range); + resource_size_t logic_pio_to_hwaddr(unsigned long pio); + unsigned long logic_pio_trans_cpuaddr(resource_size_t hw_addr); + +diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h +index d0e451868f02..c72dfd518782 100644 +--- a/include/linux/sunrpc/sched.h ++++ b/include/linux/sunrpc/sched.h +@@ -98,7 +98,6 @@ typedef void (*rpc_action)(struct rpc_task *); + + struct rpc_call_ops { + void (*rpc_call_prepare)(struct rpc_task *, void *); +- void (*rpc_call_prepare_transmit)(struct rpc_task *, void *); + void (*rpc_call_done)(struct rpc_task *, void *); + void (*rpc_count_stats)(struct rpc_task *, void *); + void (*rpc_release)(void *); +diff --git a/include/net/addrconf.h b/include/net/addrconf.h +index becdad576859..3f62b347b04a 100644 +--- a/include/net/addrconf.h ++++ b/include/net/addrconf.h +@@ -206,7 +206,7 @@ static inline int ipv6_mc_may_pull(struct sk_buff *skb, + unsigned int len) + { + if (skb_transport_offset(skb) + ipv6_transport_len(skb) < len) +- return -EINVAL; ++ return 0; + + return pskb_may_pull(skb, len); + } +diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c +index 42d17f730780..d2146277071f 100644 +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -1686,20 +1686,26 @@ static int bpf_prog_load(union bpf_attr *attr, union bpf_attr __user *uattr) + if (err) + goto free_used_maps; + +- err = bpf_prog_new_fd(prog); +- if (err < 0) { +- /* failed to allocate fd. +- * bpf_prog_put() is needed because the above +- * bpf_prog_alloc_id() has published the prog +- * to the userspace and the userspace may +- * have refcnt-ed it through BPF_PROG_GET_FD_BY_ID. +- */ +- bpf_prog_put(prog); +- return err; +- } +- ++ /* Upon success of bpf_prog_alloc_id(), the BPF prog is ++ * effectively publicly exposed. However, retrieving via ++ * bpf_prog_get_fd_by_id() will take another reference, ++ * therefore it cannot be gone underneath us. ++ * ++ * Only for the time /after/ successful bpf_prog_new_fd() ++ * and before returning to userspace, we might just hold ++ * one reference and any parallel close on that fd could ++ * rip everything out. Hence, below notifications must ++ * happen before bpf_prog_new_fd(). ++ * ++ * Also, any failure handling from this point onwards must ++ * be using bpf_prog_put() given the program is exposed. ++ */ + bpf_prog_kallsyms_add(prog); + perf_event_bpf_event(prog, PERF_BPF_EVENT_PROG_LOAD, 0); ++ ++ err = bpf_prog_new_fd(prog); ++ if (err < 0) ++ bpf_prog_put(prog); + return err; + + free_used_maps: +diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c +index 2c2772e9702a..9912be7a970d 100644 +--- a/kernel/dma/direct.c ++++ b/kernel/dma/direct.c +@@ -55,9 +55,6 @@ u64 dma_direct_get_required_mask(struct device *dev) + { + u64 max_dma = phys_to_dma_direct(dev, (max_pfn - 1) << PAGE_SHIFT); + +- if (dev->bus_dma_mask && dev->bus_dma_mask < max_dma) +- max_dma = dev->bus_dma_mask; +- + return (1ULL << (fls64(max_dma) - 1)) * 2 - 1; + } + +diff --git a/kernel/locking/rwsem-xadd.c b/kernel/locking/rwsem-xadd.c +index 0b1f77957240..385ebcfc31a6 100644 +--- a/kernel/locking/rwsem-xadd.c ++++ b/kernel/locking/rwsem-xadd.c +@@ -454,6 +454,8 @@ __rwsem_down_read_failed_common(struct rw_semaphore *sem, int state) + * been set in the count. + */ + if (atomic_long_read(&sem->count) >= 0) { ++ /* Provide lock ACQUIRE */ ++ smp_acquire__after_ctrl_dep(); + raw_spin_unlock_irq(&sem->wait_lock); + rwsem_set_reader_owned(sem); + lockevent_inc(rwsem_rlock_fast); +@@ -483,8 +485,10 @@ __rwsem_down_read_failed_common(struct rw_semaphore *sem, int state) + /* wait to be given the lock */ + while (true) { + set_current_state(state); +- if (!waiter.task) ++ if (!smp_load_acquire(&waiter.task)) { ++ /* Orders against rwsem_mark_wake()'s smp_store_release() */ + break; ++ } + if (signal_pending_state(state, current)) { + raw_spin_lock_irq(&sem->wait_lock); + if (waiter.task) +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index 208220d526e8..2373311b4a43 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -3095,6 +3095,14 @@ t_probe_next(struct seq_file *m, loff_t *pos) + hnd = &iter->probe_entry->hlist; + + hash = iter->probe->ops.func_hash->filter_hash; ++ ++ /* ++ * A probe being registered may temporarily have an empty hash ++ * and it's at the end of the func_probes list. ++ */ ++ if (!hash || hash == EMPTY_HASH) ++ return NULL; ++ + size = 1 << hash->size_bits; + + retry: +@@ -4320,12 +4328,21 @@ register_ftrace_function_probe(char *glob, struct trace_array *tr, + + mutex_unlock(&ftrace_lock); + ++ /* ++ * Note, there's a small window here that the func_hash->filter_hash ++ * may be NULL or empty. Need to be carefule when reading the loop. ++ */ + mutex_lock(&probe->ops.func_hash->regex_lock); + + orig_hash = &probe->ops.func_hash->filter_hash; + old_hash = *orig_hash; + hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, old_hash); + ++ if (!hash) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ + ret = ftrace_match_records(hash, glob, strlen(glob)); + + /* Nothing found? */ +diff --git a/lib/logic_pio.c b/lib/logic_pio.c +index feea48fd1a0d..905027574e5d 100644 +--- a/lib/logic_pio.c ++++ b/lib/logic_pio.c +@@ -35,7 +35,7 @@ int logic_pio_register_range(struct logic_pio_hwaddr *new_range) + struct logic_pio_hwaddr *range; + resource_size_t start; + resource_size_t end; +- resource_size_t mmio_sz = 0; ++ resource_size_t mmio_end = 0; + resource_size_t iio_sz = MMIO_UPPER_LIMIT; + int ret = 0; + +@@ -46,7 +46,7 @@ int logic_pio_register_range(struct logic_pio_hwaddr *new_range) + end = new_range->hw_start + new_range->size; + + mutex_lock(&io_range_mutex); +- list_for_each_entry_rcu(range, &io_range_list, list) { ++ list_for_each_entry(range, &io_range_list, list) { + if (range->fwnode == new_range->fwnode) { + /* range already there */ + goto end_register; +@@ -56,7 +56,7 @@ int logic_pio_register_range(struct logic_pio_hwaddr *new_range) + /* for MMIO ranges we need to check for overlap */ + if (start >= range->hw_start + range->size || + end < range->hw_start) { +- mmio_sz += range->size; ++ mmio_end = range->io_start + range->size; + } else { + ret = -EFAULT; + goto end_register; +@@ -69,16 +69,16 @@ int logic_pio_register_range(struct logic_pio_hwaddr *new_range) + + /* range not registered yet, check for available space */ + if (new_range->flags == LOGIC_PIO_CPU_MMIO) { +- if (mmio_sz + new_range->size - 1 > MMIO_UPPER_LIMIT) { ++ if (mmio_end + new_range->size - 1 > MMIO_UPPER_LIMIT) { + /* if it's too big check if 64K space can be reserved */ +- if (mmio_sz + SZ_64K - 1 > MMIO_UPPER_LIMIT) { ++ if (mmio_end + SZ_64K - 1 > MMIO_UPPER_LIMIT) { + ret = -E2BIG; + goto end_register; + } + new_range->size = SZ_64K; + pr_warn("Requested IO range too big, new size set to 64K\n"); + } +- new_range->io_start = mmio_sz; ++ new_range->io_start = mmio_end; + } else if (new_range->flags == LOGIC_PIO_INDIRECT) { + if (iio_sz + new_range->size - 1 > IO_SPACE_LIMIT) { + ret = -E2BIG; +@@ -98,6 +98,20 @@ end_register: + return ret; + } + ++/** ++ * logic_pio_unregister_range - unregister a logical PIO range for a host ++ * @range: pointer to the IO range which has been already registered. ++ * ++ * Unregister a previously-registered IO range node. ++ */ ++void logic_pio_unregister_range(struct logic_pio_hwaddr *range) ++{ ++ mutex_lock(&io_range_mutex); ++ list_del_rcu(&range->list); ++ mutex_unlock(&io_range_mutex); ++ synchronize_rcu(); ++} ++ + /** + * find_io_range_by_fwnode - find logical PIO range for given FW node + * @fwnode: FW node handle associated with logical PIO range +@@ -108,26 +122,38 @@ end_register: + */ + struct logic_pio_hwaddr *find_io_range_by_fwnode(struct fwnode_handle *fwnode) + { +- struct logic_pio_hwaddr *range; ++ struct logic_pio_hwaddr *range, *found_range = NULL; + ++ rcu_read_lock(); + list_for_each_entry_rcu(range, &io_range_list, list) { +- if (range->fwnode == fwnode) +- return range; ++ if (range->fwnode == fwnode) { ++ found_range = range; ++ break; ++ } + } +- return NULL; ++ rcu_read_unlock(); ++ ++ return found_range; + } + + /* Return a registered range given an input PIO token */ + static struct logic_pio_hwaddr *find_io_range(unsigned long pio) + { +- struct logic_pio_hwaddr *range; ++ struct logic_pio_hwaddr *range, *found_range = NULL; + ++ rcu_read_lock(); + list_for_each_entry_rcu(range, &io_range_list, list) { +- if (in_range(pio, range->io_start, range->size)) +- return range; ++ if (in_range(pio, range->io_start, range->size)) { ++ found_range = range; ++ break; ++ } + } +- pr_err("PIO entry token %lx invalid\n", pio); +- return NULL; ++ rcu_read_unlock(); ++ ++ if (!found_range) ++ pr_err("PIO entry token 0x%lx invalid\n", pio); ++ ++ return found_range; + } + + /** +@@ -180,14 +206,23 @@ unsigned long logic_pio_trans_cpuaddr(resource_size_t addr) + { + struct logic_pio_hwaddr *range; + ++ rcu_read_lock(); + list_for_each_entry_rcu(range, &io_range_list, list) { + if (range->flags != LOGIC_PIO_CPU_MMIO) + continue; +- if (in_range(addr, range->hw_start, range->size)) +- return addr - range->hw_start + range->io_start; ++ if (in_range(addr, range->hw_start, range->size)) { ++ unsigned long cpuaddr; ++ ++ cpuaddr = addr - range->hw_start + range->io_start; ++ ++ rcu_read_unlock(); ++ return cpuaddr; ++ } + } +- pr_err("addr %llx not registered in io_range_list\n", +- (unsigned long long) addr); ++ rcu_read_unlock(); ++ ++ pr_err("addr %pa not registered in io_range_list\n", &addr); ++ + return ~0UL; + } + +diff --git a/mm/memcontrol.c b/mm/memcontrol.c +index bb783c27ba21..30ebecf67527 100644 +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -748,15 +748,13 @@ void __mod_lruvec_state(struct lruvec *lruvec, enum node_stat_item idx, + /* Update memcg */ + __mod_memcg_state(memcg, idx, val); + ++ /* Update lruvec */ ++ __this_cpu_add(pn->lruvec_stat_local->count[idx], val); ++ + x = val + __this_cpu_read(pn->lruvec_stat_cpu->count[idx]); + if (unlikely(abs(x) > MEMCG_CHARGE_BATCH)) { + struct mem_cgroup_per_node *pi; + +- /* +- * Batch local counters to keep them in sync with +- * the hierarchical ones. +- */ +- __this_cpu_add(pn->lruvec_stat_local->count[idx], x); + for (pi = pn; pi; pi = parent_nodeinfo(pi, pgdat->node_id)) + atomic_long_add(x, &pi->lruvec_stat[idx]); + x = 0; +@@ -3161,7 +3159,7 @@ static void memcg_flush_percpu_vmstats(struct mem_cgroup *memcg) + + for_each_online_cpu(cpu) + for (i = 0; i < MEMCG_NR_STAT; i++) +- stat[i] += raw_cpu_read(memcg->vmstats_percpu->stat[i]); ++ stat[i] += per_cpu(memcg->vmstats_percpu->stat[i], cpu); + + for (mi = memcg; mi; mi = parent_mem_cgroup(mi)) + for (i = 0; i < MEMCG_NR_STAT; i++) +@@ -3176,8 +3174,8 @@ static void memcg_flush_percpu_vmstats(struct mem_cgroup *memcg) + + for_each_online_cpu(cpu) + for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++) +- stat[i] += raw_cpu_read( +- pn->lruvec_stat_cpu->count[i]); ++ stat[i] += per_cpu( ++ pn->lruvec_stat_cpu->count[i], cpu); + + for (pi = pn; pi; pi = parent_nodeinfo(pi, node)) + for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++) +@@ -3196,8 +3194,8 @@ static void memcg_flush_percpu_vmevents(struct mem_cgroup *memcg) + + for_each_online_cpu(cpu) + for (i = 0; i < NR_VM_EVENT_ITEMS; i++) +- events[i] += raw_cpu_read( +- memcg->vmstats_percpu->events[i]); ++ events[i] += per_cpu(memcg->vmstats_percpu->events[i], ++ cpu); + + for (mi = memcg; mi; mi = parent_mem_cgroup(mi)) + for (i = 0; i < NR_VM_EVENT_ITEMS; i++) +diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c +index 515b00801af2..7d62ef2daf83 100644 +--- a/mm/zsmalloc.c ++++ b/mm/zsmalloc.c +@@ -2432,7 +2432,9 @@ struct zs_pool *zs_create_pool(const char *name) + if (!pool->name) + goto err; + ++#ifdef CONFIG_COMPACTION + init_waitqueue_head(&pool->migration_wait); ++#endif + + if (create_cache(pool)) + goto err; +diff --git a/net/core/stream.c b/net/core/stream.c +index e94bb02a5629..4f1d4aa5fb38 100644 +--- a/net/core/stream.c ++++ b/net/core/stream.c +@@ -120,7 +120,6 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p) + int err = 0; + long vm_wait = 0; + long current_timeo = *timeo_p; +- bool noblock = (*timeo_p ? false : true); + DEFINE_WAIT_FUNC(wait, woken_wake_function); + + if (sk_stream_memory_free(sk)) +@@ -133,11 +132,8 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p) + + if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) + goto do_error; +- if (!*timeo_p) { +- if (noblock) +- set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); +- goto do_nonblock; +- } ++ if (!*timeo_p) ++ goto do_eagain; + if (signal_pending(current)) + goto do_interrupted; + sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); +@@ -169,7 +165,13 @@ out: + do_error: + err = -EPIPE; + goto out; +-do_nonblock: ++do_eagain: ++ /* Make sure that whenever EAGAIN is returned, EPOLLOUT event can ++ * be generated later. ++ * When TCP receives ACK packets that make room, tcp_check_space() ++ * only calls tcp_new_space() if SOCK_NOSPACE is set. ++ */ ++ set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); + err = -EAGAIN; + goto out; + do_interrupted: +diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c +index 15c72065df79..08c02dbb3d69 100644 +--- a/net/hsr/hsr_device.c ++++ b/net/hsr/hsr_device.c +@@ -229,7 +229,6 @@ static int hsr_dev_xmit(struct sk_buff *skb, struct net_device *dev) + master = hsr_port_get_hsr(hsr, HSR_PT_MASTER); + skb->dev = master->dev; + hsr_forward_skb(skb, master); +- + return NETDEV_TX_OK; + } + +@@ -344,8 +343,9 @@ static void hsr_announce(struct timer_list *t) + rcu_read_unlock(); + } + +-/* According to comments in the declaration of struct net_device, this function +- * is "Called from unregister, can be used to call free_netdev". Ok then... ++/* This has to be called after all the readers are gone. ++ * Otherwise we would have to check the return value of ++ * hsr_port_get_hsr(). + */ + static void hsr_dev_destroy(struct net_device *hsr_dev) + { +@@ -356,15 +356,14 @@ static void hsr_dev_destroy(struct net_device *hsr_dev) + + hsr_debugfs_term(hsr); + +- rtnl_lock(); + hsr_for_each_port(hsr, port) + hsr_del_port(port); +- rtnl_unlock(); + + del_timer_sync(&hsr->prune_timer); + del_timer_sync(&hsr->announce_timer); + +- synchronize_rcu(); ++ hsr_del_self_node(&hsr->self_node_db); ++ hsr_del_nodes(&hsr->node_db); + } + + static const struct net_device_ops hsr_device_ops = { +@@ -373,6 +372,7 @@ static const struct net_device_ops hsr_device_ops = { + .ndo_stop = hsr_dev_close, + .ndo_start_xmit = hsr_dev_xmit, + .ndo_fix_features = hsr_fix_features, ++ .ndo_uninit = hsr_dev_destroy, + }; + + static struct device_type hsr_type = { +@@ -391,7 +391,6 @@ void hsr_dev_setup(struct net_device *dev) + dev->priv_flags |= IFF_NO_QUEUE; + + dev->needs_free_netdev = true; +- dev->priv_destructor = hsr_dev_destroy; + + dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | + NETIF_F_GSO_MASK | NETIF_F_HW_CSUM | +@@ -495,7 +494,7 @@ fail: + hsr_for_each_port(hsr, port) + hsr_del_port(port); + err_add_port: +- hsr_del_node(&hsr->self_node_db); ++ hsr_del_self_node(&hsr->self_node_db); + + return res; + } +diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c +index 2d7a19750436..292be446007b 100644 +--- a/net/hsr/hsr_framereg.c ++++ b/net/hsr/hsr_framereg.c +@@ -104,7 +104,7 @@ int hsr_create_self_node(struct list_head *self_node_db, + return 0; + } + +-void hsr_del_node(struct list_head *self_node_db) ++void hsr_del_self_node(struct list_head *self_node_db) + { + struct hsr_node *node; + +@@ -117,6 +117,15 @@ void hsr_del_node(struct list_head *self_node_db) + } + } + ++void hsr_del_nodes(struct list_head *node_db) ++{ ++ struct hsr_node *node; ++ struct hsr_node *tmp; ++ ++ list_for_each_entry_safe(node, tmp, node_db, mac_list) ++ kfree(node); ++} ++ + /* Allocate an hsr_node and add it to node_db. 'addr' is the node's address_A; + * seq_out is used to initialize filtering of outgoing duplicate frames + * originating from the newly added node. +diff --git a/net/hsr/hsr_framereg.h b/net/hsr/hsr_framereg.h +index a3bdcdab469d..89a3ce38151d 100644 +--- a/net/hsr/hsr_framereg.h ++++ b/net/hsr/hsr_framereg.h +@@ -12,7 +12,8 @@ + + struct hsr_node; + +-void hsr_del_node(struct list_head *self_node_db); ++void hsr_del_self_node(struct list_head *self_node_db); ++void hsr_del_nodes(struct list_head *node_db); + struct hsr_node *hsr_add_node(struct list_head *node_db, unsigned char addr[], + u16 seq_out); + struct hsr_node *hsr_get_node(struct hsr_port *port, struct sk_buff *skb, +diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c +index 7c857c72aad1..92b3d2d1139e 100644 +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -582,7 +582,13 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info, + + if (!rt) + goto out; +- net = dev_net(rt->dst.dev); ++ ++ if (rt->dst.dev) ++ net = dev_net(rt->dst.dev); ++ else if (skb_in->dev) ++ net = dev_net(skb_in->dev); ++ else ++ goto out; + + /* + * Find the original header. It is expected to be valid, of course. +diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c +index 85107bf812f2..b5b0834ec5ee 100644 +--- a/net/ipv4/igmp.c ++++ b/net/ipv4/igmp.c +@@ -1474,7 +1474,7 @@ EXPORT_SYMBOL(__ip_mc_inc_group); + + void ip_mc_inc_group(struct in_device *in_dev, __be32 addr) + { +- __ip_mc_inc_group(in_dev, addr, MCAST_EXCLUDE); ++ __ip_mc_inc_group(in_dev, addr, GFP_KERNEL); + } + EXPORT_SYMBOL(ip_mc_inc_group); + +@@ -2196,7 +2196,7 @@ static int __ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr, + iml->sflist = NULL; + iml->sfmode = mode; + rcu_assign_pointer(inet->mc_list, iml); +- __ip_mc_inc_group(in_dev, addr, mode); ++ ____ip_mc_inc_group(in_dev, addr, mode, GFP_KERNEL); + err = 0; + done: + return err; +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index 081bb517e40d..2454fce6fbfa 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -1045,7 +1045,8 @@ ipv6_add_addr(struct inet6_dev *idev, struct ifa6_config *cfg, + int err = 0; + + if (addr_type == IPV6_ADDR_ANY || +- addr_type & IPV6_ADDR_MULTICAST || ++ (addr_type & IPV6_ADDR_MULTICAST && ++ !(cfg->ifa_flags & IFA_F_MCAUTOJOIN)) || + (!(idev->dev->flags & IFF_LOOPBACK) && + !netif_is_l3_master(idev->dev) && + addr_type & IPV6_ADDR_LOOPBACK)) +diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c +index b8288125e05d..1c55d3b7bc15 100644 +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -1543,6 +1543,11 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, + if (is_multicast_ether_addr(mac)) + return -EINVAL; + ++ if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER) && ++ sdata->vif.type == NL80211_IFTYPE_STATION && ++ !sdata->u.mgd.associated) ++ return -EINVAL; ++ + sta = sta_info_alloc(sdata, mac, GFP_KERNEL); + if (!sta) + return -ENOMEM; +@@ -1550,10 +1555,6 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, + if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) + sta->sta.tdls = true; + +- if (sta->sta.tdls && sdata->vif.type == NL80211_IFTYPE_STATION && +- !sdata->u.mgd.associated) +- return -EINVAL; +- + err = sta_apply_parameters(local, sta, params); + if (err) { + sta_info_free(local, sta); +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index 3c1ab870fefe..768d14c9a716 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -2447,11 +2447,13 @@ static void ieee80211_deliver_skb_to_local_stack(struct sk_buff *skb, + skb->protocol == cpu_to_be16(ETH_P_PREAUTH)) && + sdata->control_port_over_nl80211)) { + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); +- bool noencrypt = status->flag & RX_FLAG_DECRYPTED; ++ bool noencrypt = !(status->flag & RX_FLAG_DECRYPTED); + + cfg80211_rx_control_port(dev, skb, noencrypt); + dev_kfree_skb(skb); + } else { ++ memset(skb->cb, 0, sizeof(skb->cb)); ++ + /* deliver to local stack */ + if (rx->napi) + napi_gro_receive(rx->napi, skb); +@@ -2546,8 +2548,6 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) + + if (skb) { + skb->protocol = eth_type_trans(skb, dev); +- memset(skb->cb, 0, sizeof(skb->cb)); +- + ieee80211_deliver_skb_to_local_stack(skb, rx); + } + +diff --git a/net/mpls/mpls_iptunnel.c b/net/mpls/mpls_iptunnel.c +index d25e91d7bdc1..44b675016393 100644 +--- a/net/mpls/mpls_iptunnel.c ++++ b/net/mpls/mpls_iptunnel.c +@@ -133,12 +133,12 @@ static int mpls_xmit(struct sk_buff *skb) + mpls_stats_inc_outucastpkts(out_dev, skb); + + if (rt) { +- if (rt->rt_gw_family == AF_INET) +- err = neigh_xmit(NEIGH_ARP_TABLE, out_dev, &rt->rt_gw4, +- skb); +- else if (rt->rt_gw_family == AF_INET6) ++ if (rt->rt_gw_family == AF_INET6) + err = neigh_xmit(NEIGH_ND_TABLE, out_dev, &rt->rt_gw6, + skb); ++ else ++ err = neigh_xmit(NEIGH_ARP_TABLE, out_dev, &rt->rt_gw4, ++ skb); + } else if (rt6) { + if (ipv6_addr_v4mapped(&rt6->rt6i_gateway)) { + /* 6PE (RFC 4798) */ +diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c +index 848c6eb55064..4d7896135e73 100644 +--- a/net/openvswitch/conntrack.c ++++ b/net/openvswitch/conntrack.c +@@ -67,6 +67,7 @@ struct ovs_conntrack_info { + struct md_mark mark; + struct md_labels labels; + char timeout[CTNL_TIMEOUT_NAME_MAX]; ++ struct nf_ct_timeout *nf_ct_timeout; + #if IS_ENABLED(CONFIG_NF_NAT) + struct nf_nat_range2 range; /* Only present for SRC NAT and DST NAT. */ + #endif +@@ -697,6 +698,14 @@ static bool skb_nfct_cached(struct net *net, + if (help && rcu_access_pointer(help->helper) != info->helper) + return false; + } ++ if (info->nf_ct_timeout) { ++ struct nf_conn_timeout *timeout_ext; ++ ++ timeout_ext = nf_ct_timeout_find(ct); ++ if (!timeout_ext || info->nf_ct_timeout != ++ rcu_dereference(timeout_ext->timeout)) ++ return false; ++ } + /* Force conntrack entry direction to the current packet? */ + if (info->force && CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) { + /* Delete the conntrack entry if confirmed, else just release +@@ -1657,6 +1666,10 @@ int ovs_ct_copy_action(struct net *net, const struct nlattr *attr, + ct_info.timeout)) + pr_info_ratelimited("Failed to associated timeout " + "policy `%s'\n", ct_info.timeout); ++ else ++ ct_info.nf_ct_timeout = rcu_dereference( ++ nf_ct_timeout_find(ct_info.ct)->timeout); ++ + } + + if (helper) { +diff --git a/net/smc/smc_tx.c b/net/smc/smc_tx.c +index f0de323d15d6..6c8f09c1ce51 100644 +--- a/net/smc/smc_tx.c ++++ b/net/smc/smc_tx.c +@@ -76,13 +76,11 @@ static int smc_tx_wait(struct smc_sock *smc, int flags) + DEFINE_WAIT_FUNC(wait, woken_wake_function); + struct smc_connection *conn = &smc->conn; + struct sock *sk = &smc->sk; +- bool noblock; + long timeo; + int rc = 0; + + /* similar to sk_stream_wait_memory */ + timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); +- noblock = timeo ? false : true; + add_wait_queue(sk_sleep(sk), &wait); + while (1) { + sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk); +@@ -97,8 +95,8 @@ static int smc_tx_wait(struct smc_sock *smc, int flags) + break; + } + if (!timeo) { +- if (noblock) +- set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); ++ /* ensure EPOLLOUT is subsequently generated */ ++ set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); + rc = -EAGAIN; + break; + } +diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c +index 9e1743b364ec..a680d28c231e 100644 +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -1893,6 +1893,7 @@ call_bind(struct rpc_task *task) + static void + call_bind_status(struct rpc_task *task) + { ++ struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt; + int status = -EIO; + + if (rpc_task_transmitted(task)) { +@@ -1900,14 +1901,15 @@ call_bind_status(struct rpc_task *task) + return; + } + +- if (task->tk_status >= 0) { +- dprint_status(task); ++ dprint_status(task); ++ trace_rpc_bind_status(task); ++ if (task->tk_status >= 0) ++ goto out_next; ++ if (xprt_bound(xprt)) { + task->tk_status = 0; +- task->tk_action = call_connect; +- return; ++ goto out_next; + } + +- trace_rpc_bind_status(task); + switch (task->tk_status) { + case -ENOMEM: + dprintk("RPC: %5u rpcbind out of memory\n", task->tk_pid); +@@ -1966,7 +1968,9 @@ call_bind_status(struct rpc_task *task) + + rpc_call_rpcerror(task, status); + return; +- ++out_next: ++ task->tk_action = call_connect; ++ return; + retry_timeout: + task->tk_status = 0; + task->tk_action = call_bind; +@@ -2013,6 +2017,7 @@ call_connect(struct rpc_task *task) + static void + call_connect_status(struct rpc_task *task) + { ++ struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt; + struct rpc_clnt *clnt = task->tk_client; + int status = task->tk_status; + +@@ -2022,8 +2027,17 @@ call_connect_status(struct rpc_task *task) + } + + dprint_status(task); +- + trace_rpc_connect_status(task); ++ ++ if (task->tk_status == 0) { ++ clnt->cl_stats->netreconn++; ++ goto out_next; ++ } ++ if (xprt_connected(xprt)) { ++ task->tk_status = 0; ++ goto out_next; ++ } ++ + task->tk_status = 0; + switch (status) { + case -ECONNREFUSED: +@@ -2054,13 +2068,12 @@ call_connect_status(struct rpc_task *task) + case -EAGAIN: + case -ETIMEDOUT: + goto out_retry; +- case 0: +- clnt->cl_stats->netreconn++; +- task->tk_action = call_transmit; +- return; + } + rpc_call_rpcerror(task, status); + return; ++out_next: ++ task->tk_action = call_transmit; ++ return; + out_retry: + /* Check for timeouts before looping back to call_bind */ + task->tk_action = call_bind; +diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c +index 5ddd34ad64b9..f7a995bd2a6c 100644 +--- a/net/sunrpc/xprt.c ++++ b/net/sunrpc/xprt.c +@@ -1380,13 +1380,6 @@ xprt_request_transmit(struct rpc_rqst *req, struct rpc_task *snd_task) + status = -EBADMSG; + goto out_dequeue; + } +- if (task->tk_ops->rpc_call_prepare_transmit) { +- task->tk_ops->rpc_call_prepare_transmit(task, +- task->tk_calldata); +- status = task->tk_status; +- if (status < 0) +- goto out_dequeue; +- } + if (RPC_SIGNALLED(task)) { + status = -ERESTARTSYS; + goto out_dequeue; +diff --git a/net/wireless/reg.c b/net/wireless/reg.c +index 4831ad745f91..327479ce69f5 100644 +--- a/net/wireless/reg.c ++++ b/net/wireless/reg.c +@@ -2788,7 +2788,7 @@ static void reg_process_pending_hints(void) + + /* When last_request->processed becomes true this will be rescheduled */ + if (lr && !lr->processed) { +- reg_process_hint(lr); ++ pr_debug("Pending regulatory request, waiting for it to be processed...\n"); + return; + } + +diff --git a/net/wireless/util.c b/net/wireless/util.c +index d0e35b7b9e35..e74837824cea 100644 +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -233,25 +233,30 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, + + switch (params->cipher) { + case WLAN_CIPHER_SUITE_TKIP: ++ /* Extended Key ID can only be used with CCMP/GCMP ciphers */ ++ if ((pairwise && key_idx) || ++ params->mode != NL80211_KEY_RX_TX) ++ return -EINVAL; ++ break; + case WLAN_CIPHER_SUITE_CCMP: + case WLAN_CIPHER_SUITE_CCMP_256: + case WLAN_CIPHER_SUITE_GCMP: + case WLAN_CIPHER_SUITE_GCMP_256: +- /* IEEE802.11-2016 allows only 0 and - when using Extended Key +- * ID - 1 as index for pairwise keys. ++ /* IEEE802.11-2016 allows only 0 and - when supporting ++ * Extended Key ID - 1 as index for pairwise keys. + * @NL80211_KEY_NO_TX is only allowed for pairwise keys when + * the driver supports Extended Key ID. + * @NL80211_KEY_SET_TX can't be set when installing and + * validating a key. + */ +- if (params->mode == NL80211_KEY_NO_TX) { +- if (!wiphy_ext_feature_isset(&rdev->wiphy, +- NL80211_EXT_FEATURE_EXT_KEY_ID)) +- return -EINVAL; +- else if (!pairwise || key_idx < 0 || key_idx > 1) ++ if ((params->mode == NL80211_KEY_NO_TX && !pairwise) || ++ params->mode == NL80211_KEY_SET_TX) ++ return -EINVAL; ++ if (wiphy_ext_feature_isset(&rdev->wiphy, ++ NL80211_EXT_FEATURE_EXT_KEY_ID)) { ++ if (pairwise && (key_idx < 0 || key_idx > 1)) + return -EINVAL; +- } else if ((pairwise && key_idx) || +- params->mode == NL80211_KEY_SET_TX) { ++ } else if (pairwise && key_idx) { + return -EINVAL; + } + break; +diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c +index 82be7780bbe8..d5342687fdca 100644 +--- a/net/xfrm/xfrm_policy.c ++++ b/net/xfrm/xfrm_policy.c +@@ -3272,7 +3272,7 @@ decode_session4(struct sk_buff *skb, struct flowi *fl, bool reverse) + struct flowi4 *fl4 = &fl->u.ip4; + int oif = 0; + +- if (skb_dst(skb)) ++ if (skb_dst(skb) && skb_dst(skb)->dev) + oif = skb_dst(skb)->dev->ifindex; + + memset(fl4, 0, sizeof(struct flowi4)); +@@ -3390,7 +3390,7 @@ decode_session6(struct sk_buff *skb, struct flowi *fl, bool reverse) + + nexthdr = nh[nhoff]; + +- if (skb_dst(skb)) ++ if (skb_dst(skb) && skb_dst(skb)->dev) + oif = skb_dst(skb)->dev->ifindex; + + memset(fl6, 0, sizeof(struct flowi6)); +diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c +index 7737b2670064..6d9592f0ae1d 100644 +--- a/sound/core/seq/seq_clientmgr.c ++++ b/sound/core/seq/seq_clientmgr.c +@@ -1835,8 +1835,7 @@ static int snd_seq_ioctl_get_client_pool(struct snd_seq_client *client, + if (cptr->type == USER_CLIENT) { + info->input_pool = cptr->data.user.fifo_pool_size; + info->input_free = info->input_pool; +- if (cptr->data.user.fifo) +- info->input_free = snd_seq_unused_cells(cptr->data.user.fifo->pool); ++ info->input_free = snd_seq_fifo_unused_cells(cptr->data.user.fifo); + } else { + info->input_pool = 0; + info->input_free = 0; +diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c +index ea69261f269a..eaaa8b5830bb 100644 +--- a/sound/core/seq/seq_fifo.c ++++ b/sound/core/seq/seq_fifo.c +@@ -263,3 +263,20 @@ int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize) + + return 0; + } ++ ++/* get the number of unused cells safely */ ++int snd_seq_fifo_unused_cells(struct snd_seq_fifo *f) ++{ ++ unsigned long flags; ++ int cells; ++ ++ if (!f) ++ return 0; ++ ++ snd_use_lock_use(&f->use_lock); ++ spin_lock_irqsave(&f->lock, flags); ++ cells = snd_seq_unused_cells(f->pool); ++ spin_unlock_irqrestore(&f->lock, flags); ++ snd_use_lock_free(&f->use_lock); ++ return cells; ++} +diff --git a/sound/core/seq/seq_fifo.h b/sound/core/seq/seq_fifo.h +index edc68743943d..b56a7b897c9c 100644 +--- a/sound/core/seq/seq_fifo.h ++++ b/sound/core/seq/seq_fifo.h +@@ -53,5 +53,7 @@ int snd_seq_fifo_poll_wait(struct snd_seq_fifo *f, struct file *file, poll_table + /* resize pool in fifo */ + int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize); + ++/* get the number of unused cells safely */ ++int snd_seq_fifo_unused_cells(struct snd_seq_fifo *f); + + #endif +diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c +index c3096796ee05..c41865e1222c 100644 +--- a/sound/pci/hda/patch_ca0132.c ++++ b/sound/pci/hda/patch_ca0132.c +@@ -1175,6 +1175,7 @@ static const struct snd_pci_quirk ca0132_quirks[] = { + SND_PCI_QUIRK(0x1028, 0x0708, "Alienware 15 R2 2016", QUIRK_ALIENWARE), + SND_PCI_QUIRK(0x1102, 0x0010, "Sound Blaster Z", QUIRK_SBZ), + SND_PCI_QUIRK(0x1102, 0x0023, "Sound Blaster Z", QUIRK_SBZ), ++ SND_PCI_QUIRK(0x1102, 0x0027, "Sound Blaster Z", QUIRK_SBZ), + SND_PCI_QUIRK(0x1102, 0x0033, "Sound Blaster ZxR", QUIRK_SBZ), + SND_PCI_QUIRK(0x1458, 0xA016, "Recon3Di", QUIRK_R3DI), + SND_PCI_QUIRK(0x1458, 0xA026, "Gigabyte G1.Sniper Z97", QUIRK_R3DI), +diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c +index 14298ef45b21..968d3caab6ac 100644 +--- a/sound/pci/hda/patch_conexant.c ++++ b/sound/pci/hda/patch_conexant.c +@@ -611,18 +611,20 @@ static void cxt_fixup_hp_gate_mic_jack(struct hda_codec *codec, + + /* update LED status via GPIO */ + static void cxt_update_gpio_led(struct hda_codec *codec, unsigned int mask, +- bool enabled) ++ bool led_on) + { + struct conexant_spec *spec = codec->spec; + unsigned int oldval = spec->gpio_led; + + if (spec->mute_led_polarity) +- enabled = !enabled; ++ led_on = !led_on; + +- if (enabled) +- spec->gpio_led &= ~mask; +- else ++ if (led_on) + spec->gpio_led |= mask; ++ else ++ spec->gpio_led &= ~mask; ++ codec_dbg(codec, "mask:%d enabled:%d gpio_led:%d\n", ++ mask, led_on, spec->gpio_led); + if (spec->gpio_led != oldval) + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, + spec->gpio_led); +@@ -633,8 +635,8 @@ static void cxt_fixup_gpio_mute_hook(void *private_data, int enabled) + { + struct hda_codec *codec = private_data; + struct conexant_spec *spec = codec->spec; +- +- cxt_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled); ++ /* muted -> LED on */ ++ cxt_update_gpio_led(codec, spec->gpio_mute_led_mask, !enabled); + } + + /* turn on/off mic-mute LED via GPIO per capture hook */ +@@ -656,7 +658,6 @@ static void cxt_fixup_mute_led_gpio(struct hda_codec *codec, + { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03 }, + {} + }; +- codec_info(codec, "action: %d gpio_led: %d\n", action, spec->gpio_led); + + if (action == HDA_FIXUP_ACT_PRE_PROBE) { + spec->gen.vmaster_mute.hook = cxt_fixup_gpio_mute_hook; +diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c +index dd0f43a1c5e1..6aeba0d66ec5 100644 +--- a/sound/soc/soc-core.c ++++ b/sound/soc/soc-core.c +@@ -1605,11 +1605,8 @@ static int soc_probe_link_dais(struct snd_soc_card *card, + } + } + +- if (dai_link->dai_fmt) { +- ret = snd_soc_runtime_set_dai_fmt(rtd, dai_link->dai_fmt); +- if (ret) +- return ret; +- } ++ if (dai_link->dai_fmt) ++ snd_soc_runtime_set_dai_fmt(rtd, dai_link->dai_fmt); + + ret = soc_post_component_init(rtd, dai_link->name); + if (ret) +diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c +index 2c03e0f6bf72..f70211e6b174 100644 +--- a/sound/usb/line6/pcm.c ++++ b/sound/usb/line6/pcm.c +@@ -550,6 +550,15 @@ int line6_init_pcm(struct usb_line6 *line6, + line6pcm->volume_monitor = 255; + line6pcm->line6 = line6; + ++ spin_lock_init(&line6pcm->out.lock); ++ spin_lock_init(&line6pcm->in.lock); ++ line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD; ++ ++ line6->line6pcm = line6pcm; ++ ++ pcm->private_data = line6pcm; ++ pcm->private_free = line6_cleanup_pcm; ++ + line6pcm->max_packet_size_in = + usb_maxpacket(line6->usbdev, + usb_rcvisocpipe(line6->usbdev, ep_read), 0); +@@ -562,15 +571,6 @@ int line6_init_pcm(struct usb_line6 *line6, + return -EINVAL; + } + +- spin_lock_init(&line6pcm->out.lock); +- spin_lock_init(&line6pcm->in.lock); +- line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD; +- +- line6->line6pcm = line6pcm; +- +- pcm->private_data = line6pcm; +- pcm->private_free = line6_cleanup_pcm; +- + err = line6_create_audio_out_urbs(line6pcm); + if (err < 0) + return err; +diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c +index b5927c3d5bc0..eceab19766db 100644 +--- a/sound/usb/mixer.c ++++ b/sound/usb/mixer.c +@@ -739,7 +739,6 @@ static int uac_mixer_unit_get_channels(struct mixer_build *state, + struct uac_mixer_unit_descriptor *desc) + { + int mu_channels; +- void *c; + + if (desc->bLength < sizeof(*desc)) + return -EINVAL; +@@ -762,13 +761,6 @@ static int uac_mixer_unit_get_channels(struct mixer_build *state, + break; + } + +- if (!mu_channels) +- return 0; +- +- c = uac_mixer_unit_bmControls(desc, state->mixer->protocol); +- if (c - (void *)desc + (mu_channels - 1) / 8 >= desc->bLength) +- return 0; /* no bmControls -> skip */ +- + return mu_channels; + } + +@@ -2009,6 +2001,31 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, + * Mixer Unit + */ + ++/* check whether the given in/out overflows bmMixerControls matrix */ ++static bool mixer_bitmap_overflow(struct uac_mixer_unit_descriptor *desc, ++ int protocol, int num_ins, int num_outs) ++{ ++ u8 *hdr = (u8 *)desc; ++ u8 *c = uac_mixer_unit_bmControls(desc, protocol); ++ size_t rest; /* remaining bytes after bmMixerControls */ ++ ++ switch (protocol) { ++ case UAC_VERSION_1: ++ default: ++ rest = 1; /* iMixer */ ++ break; ++ case UAC_VERSION_2: ++ rest = 2; /* bmControls + iMixer */ ++ break; ++ case UAC_VERSION_3: ++ rest = 6; /* bmControls + wMixerDescrStr */ ++ break; ++ } ++ ++ /* overflow? */ ++ return c + (num_ins * num_outs + 7) / 8 + rest > hdr + hdr[0]; ++} ++ + /* + * build a mixer unit control + * +@@ -2137,6 +2154,9 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, + if (err < 0) + return err; + num_ins += iterm.channels; ++ if (mixer_bitmap_overflow(desc, state->mixer->protocol, ++ num_ins, num_outs)) ++ break; + for (; ich < num_ins; ich++) { + int och, ich_has_controls = 0; + +diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c +index 199fa157a411..27dcb3743690 100644 +--- a/sound/usb/mixer_quirks.c ++++ b/sound/usb/mixer_quirks.c +@@ -1155,17 +1155,17 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, + { + struct usb_mixer_interface *mixer; + struct usb_mixer_elem_info *cval; +- int unitid = 12; /* SamleRate ExtensionUnit ID */ ++ int unitid = 12; /* SampleRate ExtensionUnit ID */ + + list_for_each_entry(mixer, &chip->mixer_list, list) { +- cval = mixer_elem_list_to_info(mixer->id_elems[unitid]); +- if (cval) { ++ if (mixer->id_elems[unitid]) { ++ cval = mixer_elem_list_to_info(mixer->id_elems[unitid]); + snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, + cval->control << 8, + samplerate_id); + snd_usb_mixer_notify_id(mixer, unitid); ++ break; + } +- break; + } + } + +diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c +index 75b96929f76c..e4bbf79de956 100644 +--- a/sound/usb/pcm.c ++++ b/sound/usb/pcm.c +@@ -339,6 +339,7 @@ static int set_sync_ep_implicit_fb_quirk(struct snd_usb_substream *subs, + ep = 0x81; + ifnum = 2; + goto add_sync_ep_from_ifnum; ++ case USB_ID(0x1397, 0x0001): /* Behringer UFX1604 */ + case USB_ID(0x1397, 0x0002): /* Behringer UFX1204 */ + ep = 0x81; + ifnum = 1; +diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c +index d7e06fe0270e..0ce50c319cfd 100644 +--- a/tools/hv/hv_kvp_daemon.c ++++ b/tools/hv/hv_kvp_daemon.c +@@ -1386,6 +1386,8 @@ int main(int argc, char *argv[]) + daemonize = 0; + break; + case 'h': ++ print_usage(argv); ++ exit(0); + default: + print_usage(argv); + exit(EXIT_FAILURE); +diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c +index efe1e34dd91b..8f813f5233d4 100644 +--- a/tools/hv/hv_vss_daemon.c ++++ b/tools/hv/hv_vss_daemon.c +@@ -218,6 +218,8 @@ int main(int argc, char *argv[]) + daemonize = 0; + break; + case 'h': ++ print_usage(argv); ++ exit(0); + default: + print_usage(argv); + exit(EXIT_FAILURE); +diff --git a/tools/hv/lsvmbus b/tools/hv/lsvmbus +index 55e7374bade0..099f2c44dbed 100644 +--- a/tools/hv/lsvmbus ++++ b/tools/hv/lsvmbus +@@ -4,10 +4,10 @@ + import os + from optparse import OptionParser + ++help_msg = "print verbose messages. Try -vv, -vvv for more verbose messages" + parser = OptionParser() +-parser.add_option("-v", "--verbose", dest="verbose", +- help="print verbose messages. Try -vv, -vvv for \ +- more verbose messages", action="count") ++parser.add_option( ++ "-v", "--verbose", dest="verbose", help=help_msg, action="count") + + (options, args) = parser.parse_args() + +@@ -21,27 +21,28 @@ if not os.path.isdir(vmbus_sys_path): + exit(-1) + + vmbus_dev_dict = { +- '{0e0b6031-5213-4934-818b-38d90ced39db}' : '[Operating system shutdown]', +- '{9527e630-d0ae-497b-adce-e80ab0175caf}' : '[Time Synchronization]', +- '{57164f39-9115-4e78-ab55-382f3bd5422d}' : '[Heartbeat]', +- '{a9a0f4e7-5a45-4d96-b827-8a841e8c03e6}' : '[Data Exchange]', +- '{35fa2e29-ea23-4236-96ae-3a6ebacba440}' : '[Backup (volume checkpoint)]', +- '{34d14be3-dee4-41c8-9ae7-6b174977c192}' : '[Guest services]', +- '{525074dc-8985-46e2-8057-a307dc18a502}' : '[Dynamic Memory]', +- '{cfa8b69e-5b4a-4cc0-b98b-8ba1a1f3f95a}' : 'Synthetic mouse', +- '{f912ad6d-2b17-48ea-bd65-f927a61c7684}' : 'Synthetic keyboard', +- '{da0a7802-e377-4aac-8e77-0558eb1073f8}' : 'Synthetic framebuffer adapter', +- '{f8615163-df3e-46c5-913f-f2d2f965ed0e}' : 'Synthetic network adapter', +- '{32412632-86cb-44a2-9b5c-50d1417354f5}' : 'Synthetic IDE Controller', +- '{ba6163d9-04a1-4d29-b605-72e2ffb1dc7f}' : 'Synthetic SCSI Controller', +- '{2f9bcc4a-0069-4af3-b76b-6fd0be528cda}' : 'Synthetic fiber channel adapter', +- '{8c2eaf3d-32a7-4b09-ab99-bd1f1c86b501}' : 'Synthetic RDMA adapter', +- '{44c4f61d-4444-4400-9d52-802e27ede19f}' : 'PCI Express pass-through', +- '{276aacf4-ac15-426c-98dd-7521ad3f01fe}' : '[Reserved system device]', +- '{f8e65716-3cb3-4a06-9a60-1889c5cccab5}' : '[Reserved system device]', +- '{3375baf4-9e15-4b30-b765-67acb10d607b}' : '[Reserved system device]', ++ '{0e0b6031-5213-4934-818b-38d90ced39db}': '[Operating system shutdown]', ++ '{9527e630-d0ae-497b-adce-e80ab0175caf}': '[Time Synchronization]', ++ '{57164f39-9115-4e78-ab55-382f3bd5422d}': '[Heartbeat]', ++ '{a9a0f4e7-5a45-4d96-b827-8a841e8c03e6}': '[Data Exchange]', ++ '{35fa2e29-ea23-4236-96ae-3a6ebacba440}': '[Backup (volume checkpoint)]', ++ '{34d14be3-dee4-41c8-9ae7-6b174977c192}': '[Guest services]', ++ '{525074dc-8985-46e2-8057-a307dc18a502}': '[Dynamic Memory]', ++ '{cfa8b69e-5b4a-4cc0-b98b-8ba1a1f3f95a}': 'Synthetic mouse', ++ '{f912ad6d-2b17-48ea-bd65-f927a61c7684}': 'Synthetic keyboard', ++ '{da0a7802-e377-4aac-8e77-0558eb1073f8}': 'Synthetic framebuffer adapter', ++ '{f8615163-df3e-46c5-913f-f2d2f965ed0e}': 'Synthetic network adapter', ++ '{32412632-86cb-44a2-9b5c-50d1417354f5}': 'Synthetic IDE Controller', ++ '{ba6163d9-04a1-4d29-b605-72e2ffb1dc7f}': 'Synthetic SCSI Controller', ++ '{2f9bcc4a-0069-4af3-b76b-6fd0be528cda}': 'Synthetic fiber channel adapter', ++ '{8c2eaf3d-32a7-4b09-ab99-bd1f1c86b501}': 'Synthetic RDMA adapter', ++ '{44c4f61d-4444-4400-9d52-802e27ede19f}': 'PCI Express pass-through', ++ '{276aacf4-ac15-426c-98dd-7521ad3f01fe}': '[Reserved system device]', ++ '{f8e65716-3cb3-4a06-9a60-1889c5cccab5}': '[Reserved system device]', ++ '{3375baf4-9e15-4b30-b765-67acb10d607b}': '[Reserved system device]', + } + ++ + def get_vmbus_dev_attr(dev_name, attr): + try: + f = open('%s/%s/%s' % (vmbus_sys_path, dev_name, attr), 'r') +@@ -52,6 +53,7 @@ def get_vmbus_dev_attr(dev_name, attr): + + return lines + ++ + class VMBus_Dev: + pass + +@@ -66,12 +68,13 @@ for f in os.listdir(vmbus_sys_path): + + chn_vp_mapping = get_vmbus_dev_attr(f, 'channel_vp_mapping') + chn_vp_mapping = [c.strip() for c in chn_vp_mapping] +- chn_vp_mapping = sorted(chn_vp_mapping, +- key = lambda c : int(c.split(':')[0])) ++ chn_vp_mapping = sorted( ++ chn_vp_mapping, key=lambda c: int(c.split(':')[0])) + +- chn_vp_mapping = ['\tRel_ID=%s, target_cpu=%s' % +- (c.split(':')[0], c.split(':')[1]) +- for c in chn_vp_mapping] ++ chn_vp_mapping = [ ++ '\tRel_ID=%s, target_cpu=%s' % ++ (c.split(':')[0], c.split(':')[1]) for c in chn_vp_mapping ++ ] + d = VMBus_Dev() + d.sysfs_path = '%s/%s' % (vmbus_sys_path, f) + d.vmbus_id = vmbus_id +@@ -85,7 +88,7 @@ for f in os.listdir(vmbus_sys_path): + vmbus_dev_list.append(d) + + +-vmbus_dev_list = sorted(vmbus_dev_list, key = lambda d : int(d.vmbus_id)) ++vmbus_dev_list = sorted(vmbus_dev_list, key=lambda d: int(d.vmbus_id)) + + format0 = '%2s: %s' + format1 = '%2s: Class_ID = %s - %s\n%s' +@@ -95,9 +98,15 @@ for d in vmbus_dev_list: + if verbose == 0: + print(('VMBUS ID ' + format0) % (d.vmbus_id, d.dev_desc)) + elif verbose == 1: +- print (('VMBUS ID ' + format1) % \ +- (d.vmbus_id, d.class_id, d.dev_desc, d.chn_vp_mapping)) ++ print( ++ ('VMBUS ID ' + format1) % ++ (d.vmbus_id, d.class_id, d.dev_desc, d.chn_vp_mapping) ++ ) + else: +- print (('VMBUS ID ' + format2) % \ +- (d.vmbus_id, d.class_id, d.dev_desc, \ +- d.device_id, d.sysfs_path, d.chn_vp_mapping)) ++ print( ++ ('VMBUS ID ' + format2) % ++ ( ++ d.vmbus_id, d.class_id, d.dev_desc, ++ d.device_id, d.sysfs_path, d.chn_vp_mapping ++ ) ++ ) +diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c +index 75fc4fb9901c..1cd28ebf8443 100644 +--- a/tools/power/x86/turbostat/turbostat.c ++++ b/tools/power/x86/turbostat/turbostat.c +@@ -4002,7 +4002,7 @@ void rapl_probe_amd(unsigned int family, unsigned int model) + rapl_energy_units = ldexp(1.0, -(msr >> 8 & 0x1f)); + rapl_power_units = ldexp(1.0, -(msr & 0xf)); + +- tdp = get_tdp_amd(model); ++ tdp = get_tdp_amd(family); + + rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp; + if (!quiet) +diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile +index b9e88ccc289b..adced69d026e 100644 +--- a/tools/testing/selftests/bpf/Makefile ++++ b/tools/testing/selftests/bpf/Makefile +@@ -61,7 +61,8 @@ TEST_PROGS := test_kmod.sh \ + TEST_PROGS_EXTENDED := with_addr.sh \ + with_tunnels.sh \ + tcp_client.py \ +- tcp_server.py ++ tcp_server.py \ ++ test_xdp_vlan.sh + + # Compile but not part of 'make run_tests' + TEST_GEN_PROGS_EXTENDED = test_libbpf_open test_sock_addr test_skb_cgroup_id_user \ +diff --git a/virt/kvm/arm/vgic/vgic-mmio.c b/virt/kvm/arm/vgic/vgic-mmio.c +index 3ba7278fb533..b249220025bc 100644 +--- a/virt/kvm/arm/vgic/vgic-mmio.c ++++ b/virt/kvm/arm/vgic/vgic-mmio.c +@@ -195,6 +195,12 @@ static void vgic_hw_irq_spending(struct kvm_vcpu *vcpu, struct vgic_irq *irq, + vgic_irq_set_phys_active(irq, true); + } + ++static bool is_vgic_v2_sgi(struct kvm_vcpu *vcpu, struct vgic_irq *irq) ++{ ++ return (vgic_irq_is_sgi(irq->intid) && ++ vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V2); ++} ++ + void vgic_mmio_write_spending(struct kvm_vcpu *vcpu, + gpa_t addr, unsigned int len, + unsigned long val) +@@ -207,6 +213,12 @@ void vgic_mmio_write_spending(struct kvm_vcpu *vcpu, + for_each_set_bit(i, &val, len * 8) { + struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + ++ /* GICD_ISPENDR0 SGI bits are WI */ ++ if (is_vgic_v2_sgi(vcpu, irq)) { ++ vgic_put_irq(vcpu->kvm, irq); ++ continue; ++ } ++ + raw_spin_lock_irqsave(&irq->irq_lock, flags); + if (irq->hw) + vgic_hw_irq_spending(vcpu, irq, is_uaccess); +@@ -254,6 +266,12 @@ void vgic_mmio_write_cpending(struct kvm_vcpu *vcpu, + for_each_set_bit(i, &val, len * 8) { + struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); + ++ /* GICD_ICPENDR0 SGI bits are WI */ ++ if (is_vgic_v2_sgi(vcpu, irq)) { ++ vgic_put_irq(vcpu->kvm, irq); ++ continue; ++ } ++ + raw_spin_lock_irqsave(&irq->irq_lock, flags); + + if (irq->hw) +diff --git a/virt/kvm/arm/vgic/vgic-v2.c b/virt/kvm/arm/vgic/vgic-v2.c +index 96aab77d0471..b00aa304c260 100644 +--- a/virt/kvm/arm/vgic/vgic-v2.c ++++ b/virt/kvm/arm/vgic/vgic-v2.c +@@ -184,7 +184,10 @@ void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr) + if (vgic_irq_is_sgi(irq->intid)) { + u32 src = ffs(irq->source); + +- BUG_ON(!src); ++ if (WARN_RATELIMIT(!src, "No SGI source for INTID %d\n", ++ irq->intid)) ++ return; ++ + val |= (src - 1) << GICH_LR_PHYSID_CPUID_SHIFT; + irq->source &= ~(1 << (src - 1)); + if (irq->source) { +diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c +index 0c653a1e5215..a4ad431c92a9 100644 +--- a/virt/kvm/arm/vgic/vgic-v3.c ++++ b/virt/kvm/arm/vgic/vgic-v3.c +@@ -167,7 +167,10 @@ void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr) + model == KVM_DEV_TYPE_ARM_VGIC_V2) { + u32 src = ffs(irq->source); + +- BUG_ON(!src); ++ if (WARN_RATELIMIT(!src, "No SGI source for INTID %d\n", ++ irq->intid)) ++ return; ++ + val |= (src - 1) << GICH_LR_PHYSID_CPUID_SHIFT; + irq->source &= ~(1 << (src - 1)); + if (irq->source) { +diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c +index 13d4b38a94ec..e7bde65ba67c 100644 +--- a/virt/kvm/arm/vgic/vgic.c ++++ b/virt/kvm/arm/vgic/vgic.c +@@ -254,6 +254,13 @@ static int vgic_irq_cmp(void *priv, struct list_head *a, struct list_head *b) + bool penda, pendb; + int ret; + ++ /* ++ * list_sort may call this function with the same element when ++ * the list is fairly long. ++ */ ++ if (unlikely(irqa == irqb)) ++ return 0; ++ + raw_spin_lock(&irqa->irq_lock); + raw_spin_lock_nested(&irqb->irq_lock, SINGLE_DEPTH_NESTING); + diff --git a/1012_linux-5.2.13.patch b/1012_linux-5.2.13.patch new file mode 100644 index 0000000..c8f98ac --- /dev/null +++ b/1012_linux-5.2.13.patch @@ -0,0 +1,92 @@ +diff --git a/Makefile b/Makefile +index e26d52d93bb1..288284de8858 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 2 +-SUBLEVEL = 12 ++SUBLEVEL = 13 + EXTRAVERSION = + NAME = Bobtail Squid + +diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c +index a47c7add4e0e..a4345052abd2 100644 +--- a/drivers/input/mouse/elantech.c ++++ b/drivers/input/mouse/elantech.c +@@ -1807,30 +1807,6 @@ static int elantech_create_smbus(struct psmouse *psmouse, + leave_breadcrumbs); + } + +-static bool elantech_use_host_notify(struct psmouse *psmouse, +- struct elantech_device_info *info) +-{ +- if (ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version)) +- return true; +- +- switch (info->bus) { +- case ETP_BUS_PS2_ONLY: +- /* expected case */ +- break; +- case ETP_BUS_SMB_HST_NTFY_ONLY: +- case ETP_BUS_PS2_SMB_HST_NTFY: +- /* SMbus implementation is stable since 2018 */ +- if (dmi_get_bios_year() >= 2018) +- return true; +- default: +- psmouse_dbg(psmouse, +- "Ignoring SMBus bus provider %d\n", info->bus); +- break; +- } +- +- return false; +-} +- + /** + * elantech_setup_smbus - called once the PS/2 devices are enumerated + * and decides to instantiate a SMBus InterTouch device. +@@ -1850,7 +1826,7 @@ static int elantech_setup_smbus(struct psmouse *psmouse, + * i2c_blacklist_pnp_ids. + * Old ICs are up to the user to decide. + */ +- if (!elantech_use_host_notify(psmouse, info) || ++ if (!ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version) || + psmouse_matches_pnp_id(psmouse, i2c_blacklist_pnp_ids)) + return -ENXIO; + } +@@ -1870,6 +1846,34 @@ static int elantech_setup_smbus(struct psmouse *psmouse, + return 0; + } + ++static bool elantech_use_host_notify(struct psmouse *psmouse, ++ struct elantech_device_info *info) ++{ ++ if (ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version)) ++ return true; ++ ++ switch (info->bus) { ++ case ETP_BUS_PS2_ONLY: ++ /* expected case */ ++ break; ++ case ETP_BUS_SMB_ALERT_ONLY: ++ /* fall-through */ ++ case ETP_BUS_PS2_SMB_ALERT: ++ psmouse_dbg(psmouse, "Ignoring SMBus provider through alert protocol.\n"); ++ break; ++ case ETP_BUS_SMB_HST_NTFY_ONLY: ++ /* fall-through */ ++ case ETP_BUS_PS2_SMB_HST_NTFY: ++ return true; ++ default: ++ psmouse_dbg(psmouse, ++ "Ignoring SMBus bus provider %d.\n", ++ info->bus); ++ } ++ ++ return false; ++} ++ + int elantech_init_smbus(struct psmouse *psmouse) + { + struct elantech_device_info info;