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 AD22B13933E for ; Wed, 14 Jul 2021 16:16:30 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id D41DCE0900; Wed, 14 Jul 2021 16:16:29 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4]) (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 6AFC8E0900 for ; Wed, 14 Jul 2021 16:16:29 +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 A3C86335DB1 for ; Wed, 14 Jul 2021 16:16:27 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 536F97C2 for ; Wed, 14 Jul 2021 16:16:26 +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: <1626279337.01cc722d694c5ac80294fa112d6cf98ebb5aefd1.mpagano@gentoo> Subject: [gentoo-commits] proj/linux-patches:5.13 commit in: / X-VCS-Repository: proj/linux-patches X-VCS-Files: 0000_README 1000_linux-5.13.1.patch 1001_linux-5.13.1.patch 1001_linux-5.13.2.patch X-VCS-Directories: / X-VCS-Committer: mpagano X-VCS-Committer-Name: Mike Pagano X-VCS-Revision: 01cc722d694c5ac80294fa112d6cf98ebb5aefd1 X-VCS-Branch: 5.13 Date: Wed, 14 Jul 2021 16:16:26 +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: 08c52ba5-6981-42fb-bf28-dae05b344021 X-Archives-Hash: 044c8e9a9ac7700b4ee55b61eff4cd78 commit: 01cc722d694c5ac80294fa112d6cf98ebb5aefd1 Author: Mike Pagano gentoo org> AuthorDate: Wed Jul 14 16:15:37 2021 +0000 Commit: Mike Pagano gentoo org> CommitDate: Wed Jul 14 16:15:37 2021 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=01cc722d Linux 5.13.2 and rename 5.13.1 patch properly Signed-off-by: Mike Pagano gentoo.org> 0000_README | 4 + 1001_linux-5.13.1.patch => 1000_linux-5.13.1.patch | 0 1001_linux-5.13.2.patch | 29932 +++++++++++++++++++ 3 files changed, 29936 insertions(+) diff --git a/0000_README b/0000_README index 57ab4e6..e1ba986 100644 --- a/0000_README +++ b/0000_README @@ -47,6 +47,10 @@ Patch: 1000_linux-5.13.1.patch From: http://www.kernel.org Desc: Linux 5.13.1 +Patch: 1001_linux-5.13.2.patch +From: http://www.kernel.org +Desc: Linux 5.13.2 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1001_linux-5.13.1.patch b/1000_linux-5.13.1.patch similarity index 100% rename from 1001_linux-5.13.1.patch rename to 1000_linux-5.13.1.patch diff --git a/1001_linux-5.13.2.patch b/1001_linux-5.13.2.patch new file mode 100644 index 0000000..c6dd58d --- /dev/null +++ b/1001_linux-5.13.2.patch @@ -0,0 +1,29932 @@ +diff --git a/Documentation/ABI/testing/evm b/Documentation/ABI/testing/evm +index 3c477ba48a312..2243b72e41107 100644 +--- a/Documentation/ABI/testing/evm ++++ b/Documentation/ABI/testing/evm +@@ -49,8 +49,30 @@ Description: + modification of EVM-protected metadata and + disable all further modification of policy + +- Note that once a key has been loaded, it will no longer be +- possible to enable metadata modification. ++ Echoing a value is additive, the new value is added to the ++ existing initialization flags. ++ ++ For example, after:: ++ ++ echo 2 >/evm ++ ++ another echo can be performed:: ++ ++ echo 1 >/evm ++ ++ and the resulting value will be 3. ++ ++ Note that once an HMAC key has been loaded, it will no longer ++ be possible to enable metadata modification. Signaling that an ++ HMAC key has been loaded will clear the corresponding flag. ++ For example, if the current value is 6 (2 and 4 set):: ++ ++ echo 1 >/evm ++ ++ will set the new value to 3 (4 cleared). ++ ++ Loading an HMAC key is the only way to disable metadata ++ modification. + + Until key loading has been signaled EVM can not create + or validate the 'security.evm' xattr, but returns +diff --git a/Documentation/ABI/testing/sysfs-bus-papr-pmem b/Documentation/ABI/testing/sysfs-bus-papr-pmem +index 92e2db0e2d3de..95254cec92bfb 100644 +--- a/Documentation/ABI/testing/sysfs-bus-papr-pmem ++++ b/Documentation/ABI/testing/sysfs-bus-papr-pmem +@@ -39,9 +39,11 @@ KernelVersion: v5.9 + Contact: linuxppc-dev , nvdimm@lists.linux.dev, + Description: + (RO) Report various performance stats related to papr-scm NVDIMM +- device. Each stat is reported on a new line with each line +- composed of a stat-identifier followed by it value. Below are +- currently known dimm performance stats which are reported: ++ device. This attribute is only available for NVDIMM devices ++ that support reporting NVDIMM performance stats. Each stat is ++ reported on a new line with each line composed of a ++ stat-identifier followed by it value. Below are currently known ++ dimm performance stats which are reported: + + * "CtlResCt" : Controller Reset Count + * "CtlResTm" : Controller Reset Elapsed Time +diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +index cb89dbdedc463..995deccc28bcd 100644 +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -581,6 +581,12 @@ + loops can be debugged more effectively on production + systems. + ++ clocksource.max_cswd_read_retries= [KNL] ++ Number of clocksource_watchdog() retries due to ++ external delays before the clock will be marked ++ unstable. Defaults to three retries, that is, ++ four attempts to read the clock under test. ++ + clearcpuid=BITNUM[,BITNUM...] [X86] + Disable CPUID feature X for the kernel. See + arch/x86/include/asm/cpufeatures.h for the valid bit +diff --git a/Documentation/hwmon/max31790.rst b/Documentation/hwmon/max31790.rst +index f301385d8cef3..7b097c3b9b908 100644 +--- a/Documentation/hwmon/max31790.rst ++++ b/Documentation/hwmon/max31790.rst +@@ -38,6 +38,7 @@ Sysfs entries + fan[1-12]_input RO fan tachometer speed in RPM + fan[1-12]_fault RO fan experienced fault + fan[1-6]_target RW desired fan speed in RPM +-pwm[1-6]_enable RW regulator mode, 0=disabled, 1=manual mode, 2=rpm mode +-pwm[1-6] RW fan target duty cycle (0-255) ++pwm[1-6]_enable RW regulator mode, 0=disabled (duty cycle=0%), 1=manual mode, 2=rpm mode ++pwm[1-6] RW read: current pwm duty cycle, ++ write: target pwm duty cycle (0-255) + ================== === ======================================================= +diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +index b0de4e6e7ebd1..514b334470eab 100644 +--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst ++++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +@@ -3053,7 +3053,7 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - + :stub-columns: 0 + :widths: 1 1 2 + +- * - ``V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT`` ++ * - ``V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT_ENABLED`` + - 0x00000001 + - + * - ``V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT`` +@@ -3277,6 +3277,9 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - + * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED`` + - 0x00000100 + - ++ * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_DEPENDENT_SLICE_SEGMENT`` ++ - 0x00000200 ++ - + + .. raw:: latex + +diff --git a/Documentation/userspace-api/seccomp_filter.rst b/Documentation/userspace-api/seccomp_filter.rst +index 6efb41cc80725..d61219889e494 100644 +--- a/Documentation/userspace-api/seccomp_filter.rst ++++ b/Documentation/userspace-api/seccomp_filter.rst +@@ -259,6 +259,18 @@ and ``ioctl(SECCOMP_IOCTL_NOTIF_SEND)`` a response, indicating what should be + returned to userspace. The ``id`` member of ``struct seccomp_notif_resp`` should + be the same ``id`` as in ``struct seccomp_notif``. + ++Userspace can also add file descriptors to the notifying process via ++``ioctl(SECCOMP_IOCTL_NOTIF_ADDFD)``. The ``id`` member of ++``struct seccomp_notif_addfd`` should be the same ``id`` as in ++``struct seccomp_notif``. The ``newfd_flags`` flag may be used to set flags ++like O_EXEC on the file descriptor in the notifying process. If the supervisor ++wants to inject the file descriptor with a specific number, the ++``SECCOMP_ADDFD_FLAG_SETFD`` flag can be used, and set the ``newfd`` member to ++the specific number to use. If that file descriptor is already open in the ++notifying process it will be replaced. The supervisor can also add an FD, and ++respond atomically by using the ``SECCOMP_ADDFD_FLAG_SEND`` flag and the return ++value will be the injected file descriptor number. ++ + It is worth noting that ``struct seccomp_data`` contains the values of register + arguments to the syscall, but does not contain pointers to memory. The task's + memory is accessible to suitably privileged traces via ``ptrace()`` or +diff --git a/Makefile b/Makefile +index 069607cfe2836..31bbcc5255357 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 13 +-SUBLEVEL = 1 ++SUBLEVEL = 2 + EXTRAVERSION = + NAME = Opossums on Parade + +@@ -1039,7 +1039,7 @@ LDFLAGS_vmlinux += $(call ld-option, -X,) + endif + + ifeq ($(CONFIG_RELR),y) +-LDFLAGS_vmlinux += --pack-dyn-relocs=relr ++LDFLAGS_vmlinux += --pack-dyn-relocs=relr --use-android-relr-tags + endif + + # We never want expected sections to be placed heuristically by the +diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c +index f4dd9f3f30010..4b2575f936d46 100644 +--- a/arch/alpha/kernel/smp.c ++++ b/arch/alpha/kernel/smp.c +@@ -166,7 +166,6 @@ smp_callin(void) + DBGS(("smp_callin: commencing CPU %d current %p active_mm %p\n", + cpuid, current, current->active_mm)); + +- preempt_disable(); + cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); + } + +diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c +index 52906d3145371..db0e104d68355 100644 +--- a/arch/arc/kernel/smp.c ++++ b/arch/arc/kernel/smp.c +@@ -189,7 +189,6 @@ void start_kernel_secondary(void) + pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu); + + local_irq_enable(); +- preempt_disable(); + cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); + } + +diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi +index 05c55875835d5..f70a8528b9598 100644 +--- a/arch/arm/boot/dts/sama5d4.dtsi ++++ b/arch/arm/boot/dts/sama5d4.dtsi +@@ -787,7 +787,7 @@ + 0xffffffff 0x3ffcfe7c 0x1c010101 /* pioA */ + 0x7fffffff 0xfffccc3a 0x3f00cc3a /* pioB */ + 0xffffffff 0x3ff83fff 0xff00ffff /* pioC */ +- 0x0003ff00 0x8002a800 0x00000000 /* pioD */ ++ 0xb003ff00 0x8002a800 0x00000000 /* pioD */ + 0xffffffff 0x7fffffff 0x76fff1bf /* pioE */ + >; + +diff --git a/arch/arm/boot/dts/ste-href.dtsi b/arch/arm/boot/dts/ste-href.dtsi +index 83b179692dff7..13d2161929042 100644 +--- a/arch/arm/boot/dts/ste-href.dtsi ++++ b/arch/arm/boot/dts/ste-href.dtsi +@@ -4,6 +4,7 @@ + */ + + #include ++#include + #include "ste-href-family-pinctrl.dtsi" + + / { +@@ -64,17 +65,20 @@ + reg = <0>; + led-cur = /bits/ 8 <0x2f>; + max-cur = /bits/ 8 <0x5f>; ++ color = ; + linux,default-trigger = "heartbeat"; + }; + chan@1 { + reg = <1>; + led-cur = /bits/ 8 <0x2f>; + max-cur = /bits/ 8 <0x5f>; ++ color = ; + }; + chan@2 { + reg = <2>; + led-cur = /bits/ 8 <0x2f>; + max-cur = /bits/ 8 <0x5f>; ++ color = ; + }; + }; + lp5521@34 { +@@ -88,16 +92,19 @@ + reg = <0>; + led-cur = /bits/ 8 <0x2f>; + max-cur = /bits/ 8 <0x5f>; ++ color = ; + }; + chan@1 { + reg = <1>; + led-cur = /bits/ 8 <0x2f>; + max-cur = /bits/ 8 <0x5f>; ++ color = ; + }; + chan@2 { + reg = <2>; + led-cur = /bits/ 8 <0x2f>; + max-cur = /bits/ 8 <0x5f>; ++ color = ; + }; + }; + bh1780@29 { +diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c +index 2924d7910b106..eb2190477da10 100644 +--- a/arch/arm/kernel/perf_event_v7.c ++++ b/arch/arm/kernel/perf_event_v7.c +@@ -773,10 +773,10 @@ static inline void armv7pmu_write_counter(struct perf_event *event, u64 value) + pr_err("CPU%u writing wrong counter %d\n", + smp_processor_id(), idx); + } else if (idx == ARMV7_IDX_CYCLE_COUNTER) { +- asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value)); ++ asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" ((u32)value)); + } else { + armv7_pmnc_select_counter(idx); +- asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (value)); ++ asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" ((u32)value)); + } + } + +diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c +index 74679240a9d8e..c7bb168b0d97c 100644 +--- a/arch/arm/kernel/smp.c ++++ b/arch/arm/kernel/smp.c +@@ -432,7 +432,6 @@ asmlinkage void secondary_start_kernel(void) + #endif + pr_debug("CPU%u: Booted secondary processor\n", cpu); + +- preempt_disable(); + trace_hardirqs_off(); + + /* +diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +index 456dcd4a7793f..6ffbb099fcac7 100644 +--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi ++++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +@@ -134,7 +134,7 @@ + + uart0: serial@12000 { + compatible = "marvell,armada-3700-uart"; +- reg = <0x12000 0x200>; ++ reg = <0x12000 0x18>; + clocks = <&xtalclk>; + interrupts = + , +diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h +index 7cd7d5c8c4bc2..6336b4309114b 100644 +--- a/arch/arm64/include/asm/kvm_host.h ++++ b/arch/arm64/include/asm/kvm_host.h +@@ -46,6 +46,7 @@ + #define KVM_REQ_VCPU_RESET KVM_ARCH_REQ(2) + #define KVM_REQ_RECORD_STEAL KVM_ARCH_REQ(3) + #define KVM_REQ_RELOAD_GICv4 KVM_ARCH_REQ(4) ++#define KVM_REQ_RELOAD_PMU KVM_ARCH_REQ(5) + + #define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \ + KVM_DIRTY_LOG_INITIALLY_SET) +diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h +index d3cef91335396..eeb210997149a 100644 +--- a/arch/arm64/include/asm/mmu_context.h ++++ b/arch/arm64/include/asm/mmu_context.h +@@ -177,9 +177,9 @@ static inline void update_saved_ttbr0(struct task_struct *tsk, + return; + + if (mm == &init_mm) +- ttbr = __pa_symbol(reserved_pg_dir); ++ ttbr = phys_to_ttbr(__pa_symbol(reserved_pg_dir)); + else +- ttbr = virt_to_phys(mm->pgd) | ASID(mm) << 48; ++ ttbr = phys_to_ttbr(virt_to_phys(mm->pgd)) | ASID(mm) << 48; + + WRITE_ONCE(task_thread_info(tsk)->ttbr0, ttbr); + } +diff --git a/arch/arm64/include/asm/preempt.h b/arch/arm64/include/asm/preempt.h +index 80e946b2abee2..e83f0982b99c1 100644 +--- a/arch/arm64/include/asm/preempt.h ++++ b/arch/arm64/include/asm/preempt.h +@@ -23,7 +23,7 @@ static inline void preempt_count_set(u64 pc) + } while (0) + + #define init_idle_preempt_count(p, cpu) do { \ +- task_thread_info(p)->preempt_count = PREEMPT_ENABLED; \ ++ task_thread_info(p)->preempt_count = PREEMPT_DISABLED; \ + } while (0) + + static inline void set_preempt_need_resched(void) +diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile +index 6cc97730790e7..787c3c83edd7a 100644 +--- a/arch/arm64/kernel/Makefile ++++ b/arch/arm64/kernel/Makefile +@@ -14,6 +14,11 @@ CFLAGS_REMOVE_return_address.o = $(CC_FLAGS_FTRACE) + CFLAGS_REMOVE_syscall.o = -fstack-protector -fstack-protector-strong + CFLAGS_syscall.o += -fno-stack-protector + ++# It's not safe to invoke KCOV when portions of the kernel environment aren't ++# available or are out-of-sync with HW state. Since `noinstr` doesn't always ++# inhibit KCOV instrumentation, disable it for the entire compilation unit. ++KCOV_INSTRUMENT_entry.o := n ++ + # Object file lists. + obj-y := debug-monitors.o entry.o irq.o fpsimd.o \ + entry-common.o entry-fpsimd.o process.o ptrace.o \ +diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c +index f594957e29bd1..44b6eda69a81a 100644 +--- a/arch/arm64/kernel/perf_event.c ++++ b/arch/arm64/kernel/perf_event.c +@@ -312,7 +312,7 @@ static ssize_t slots_show(struct device *dev, struct device_attribute *attr, + struct arm_pmu *cpu_pmu = container_of(pmu, struct arm_pmu, pmu); + u32 slots = cpu_pmu->reg_pmmir & ARMV8_PMU_SLOTS_MASK; + +- return snprintf(page, PAGE_SIZE, "0x%08x\n", slots); ++ return sysfs_emit(page, "0x%08x\n", slots); + } + + static DEVICE_ATTR_RO(slots); +diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c +index 61845c0821d9d..68b30e8c22dbf 100644 +--- a/arch/arm64/kernel/setup.c ++++ b/arch/arm64/kernel/setup.c +@@ -381,7 +381,7 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p) + * faults in case uaccess_enable() is inadvertently called by the init + * thread. + */ +- init_task.thread_info.ttbr0 = __pa_symbol(reserved_pg_dir); ++ init_task.thread_info.ttbr0 = phys_to_ttbr(__pa_symbol(reserved_pg_dir)); + #endif + + if (boot_args[1] || boot_args[2] || boot_args[3]) { +diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c +index dcd7041b2b077..6671000a8b7d7 100644 +--- a/arch/arm64/kernel/smp.c ++++ b/arch/arm64/kernel/smp.c +@@ -224,7 +224,6 @@ asmlinkage notrace void secondary_start_kernel(void) + init_gic_priority_masking(); + + rcu_cpu_starting(cpu); +- preempt_disable(); + trace_hardirqs_off(); + + /* +diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c +index e720148232a06..facf4d41d32a2 100644 +--- a/arch/arm64/kvm/arm.c ++++ b/arch/arm64/kvm/arm.c +@@ -689,6 +689,10 @@ static void check_vcpu_requests(struct kvm_vcpu *vcpu) + vgic_v4_load(vcpu); + preempt_enable(); + } ++ ++ if (kvm_check_request(KVM_REQ_RELOAD_PMU, vcpu)) ++ kvm_pmu_handle_pmcr(vcpu, ++ __vcpu_sys_reg(vcpu, PMCR_EL0)); + } + } + +diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c +index fd167d4f42157..f33825c995cbb 100644 +--- a/arch/arm64/kvm/pmu-emul.c ++++ b/arch/arm64/kvm/pmu-emul.c +@@ -578,6 +578,7 @@ void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val) + kvm_pmu_set_counter_value(vcpu, ARMV8_PMU_CYCLE_IDX, 0); + + if (val & ARMV8_PMU_PMCR_P) { ++ mask &= ~BIT(ARMV8_PMU_CYCLE_IDX); + for_each_set_bit(i, &mask, 32) + kvm_pmu_set_counter_value(vcpu, i, 0); + } +@@ -850,6 +851,9 @@ int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu) + return -EINVAL; + } + ++ /* One-off reload of the PMU on first run */ ++ kvm_make_request(KVM_REQ_RELOAD_PMU, vcpu); ++ + return 0; + } + +diff --git a/arch/csky/kernel/smp.c b/arch/csky/kernel/smp.c +index 0f9f5eef93386..e2993539af8ef 100644 +--- a/arch/csky/kernel/smp.c ++++ b/arch/csky/kernel/smp.c +@@ -281,7 +281,6 @@ void csky_start_secondary(void) + pr_info("CPU%u Online: %s...\n", cpu, __func__); + + local_irq_enable(); +- preempt_disable(); + cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); + } + +diff --git a/arch/csky/mm/syscache.c b/arch/csky/mm/syscache.c +index 4e51d63850c46..cd847ad62c7ee 100644 +--- a/arch/csky/mm/syscache.c ++++ b/arch/csky/mm/syscache.c +@@ -12,15 +12,17 @@ SYSCALL_DEFINE3(cacheflush, + int, cache) + { + switch (cache) { +- case ICACHE: + case BCACHE: +- flush_icache_mm_range(current->mm, +- (unsigned long)addr, +- (unsigned long)addr + bytes); +- fallthrough; + case DCACHE: + dcache_wb_range((unsigned long)addr, + (unsigned long)addr + bytes); ++ if (cache != BCACHE) ++ break; ++ fallthrough; ++ case ICACHE: ++ flush_icache_mm_range(current->mm, ++ (unsigned long)addr, ++ (unsigned long)addr + bytes); + break; + default: + return -EINVAL; +diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c +index 36a69b4e61690..5bfc79be4cefe 100644 +--- a/arch/ia64/kernel/mca_drv.c ++++ b/arch/ia64/kernel/mca_drv.c +@@ -343,7 +343,7 @@ init_record_index_pools(void) + + /* - 2 - */ + sect_min_size = sal_log_sect_min_sizes[0]; +- for (i = 1; i < sizeof sal_log_sect_min_sizes/sizeof(size_t); i++) ++ for (i = 1; i < ARRAY_SIZE(sal_log_sect_min_sizes); i++) + if (sect_min_size > sal_log_sect_min_sizes[i]) + sect_min_size = sal_log_sect_min_sizes[i]; + +diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c +index 49b4885809399..d10f780c13b9e 100644 +--- a/arch/ia64/kernel/smpboot.c ++++ b/arch/ia64/kernel/smpboot.c +@@ -441,7 +441,6 @@ start_secondary (void *unused) + #endif + efi_map_pal_code(); + cpu_init(); +- preempt_disable(); + smp_callin(); + + cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); +diff --git a/arch/m68k/Kconfig.machine b/arch/m68k/Kconfig.machine +index 4d59ec2f5b8d6..d964c1f273995 100644 +--- a/arch/m68k/Kconfig.machine ++++ b/arch/m68k/Kconfig.machine +@@ -25,6 +25,9 @@ config ATARI + this kernel on an Atari, say Y here and browse the material + available in ; otherwise say N. + ++config ATARI_KBD_CORE ++ bool ++ + config MAC + bool "Macintosh support" + depends on MMU +diff --git a/arch/mips/include/asm/highmem.h b/arch/mips/include/asm/highmem.h +index 292d0425717f3..92a3802100178 100644 +--- a/arch/mips/include/asm/highmem.h ++++ b/arch/mips/include/asm/highmem.h +@@ -36,7 +36,7 @@ extern pte_t *pkmap_page_table; + * easily, subsequent pte tables have to be allocated in one physical + * chunk of RAM. + */ +-#ifdef CONFIG_PHYS_ADDR_T_64BIT ++#if defined(CONFIG_PHYS_ADDR_T_64BIT) || defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) + #define LAST_PKMAP 512 + #else + #define LAST_PKMAP 1024 +diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c +index ef86fbad85460..d542fb7af3ba2 100644 +--- a/arch/mips/kernel/smp.c ++++ b/arch/mips/kernel/smp.c +@@ -348,7 +348,6 @@ asmlinkage void start_secondary(void) + */ + + calibrate_delay(); +- preempt_disable(); + cpu = smp_processor_id(); + cpu_data[cpu].udelay_val = loops_per_jiffy; + +diff --git a/arch/openrisc/kernel/smp.c b/arch/openrisc/kernel/smp.c +index 48e1092a64de3..415e209732a3d 100644 +--- a/arch/openrisc/kernel/smp.c ++++ b/arch/openrisc/kernel/smp.c +@@ -145,8 +145,6 @@ asmlinkage __init void secondary_start_kernel(void) + set_cpu_online(cpu, true); + + local_irq_enable(); +- +- preempt_disable(); + /* + * OK, it's off to the idle thread for us + */ +diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c +index 10227f667c8a6..1405b603b91b6 100644 +--- a/arch/parisc/kernel/smp.c ++++ b/arch/parisc/kernel/smp.c +@@ -302,7 +302,6 @@ void __init smp_callin(unsigned long pdce_proc) + #endif + + smp_cpu_init(slave_id); +- preempt_disable(); + + flush_cache_all_local(); /* start with known state */ + flush_tlb_all_local(NULL); +diff --git a/arch/powerpc/include/asm/cputhreads.h b/arch/powerpc/include/asm/cputhreads.h +index 98c8bd155bf9d..b167186aaee4a 100644 +--- a/arch/powerpc/include/asm/cputhreads.h ++++ b/arch/powerpc/include/asm/cputhreads.h +@@ -98,6 +98,36 @@ static inline int cpu_last_thread_sibling(int cpu) + return cpu | (threads_per_core - 1); + } + ++/* ++ * tlb_thread_siblings are siblings which share a TLB. This is not ++ * architected, is not something a hypervisor could emulate and a future ++ * CPU may change behaviour even in compat mode, so this should only be ++ * used on PowerNV, and only with care. ++ */ ++static inline int cpu_first_tlb_thread_sibling(int cpu) ++{ ++ if (cpu_has_feature(CPU_FTR_ARCH_300) && (threads_per_core == 8)) ++ return cpu & ~0x6; /* Big Core */ ++ else ++ return cpu_first_thread_sibling(cpu); ++} ++ ++static inline int cpu_last_tlb_thread_sibling(int cpu) ++{ ++ if (cpu_has_feature(CPU_FTR_ARCH_300) && (threads_per_core == 8)) ++ return cpu | 0x6; /* Big Core */ ++ else ++ return cpu_last_thread_sibling(cpu); ++} ++ ++static inline int cpu_tlb_thread_sibling_step(void) ++{ ++ if (cpu_has_feature(CPU_FTR_ARCH_300) && (threads_per_core == 8)) ++ return 2; /* Big Core */ ++ else ++ return 1; ++} ++ + static inline u32 get_tensr(void) + { + #ifdef CONFIG_BOOKE +diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h +index 59f704408d65d..a26aad41ef3e7 100644 +--- a/arch/powerpc/include/asm/interrupt.h ++++ b/arch/powerpc/include/asm/interrupt.h +@@ -186,6 +186,7 @@ struct interrupt_nmi_state { + u8 irq_soft_mask; + u8 irq_happened; + u8 ftrace_enabled; ++ u64 softe; + #endif + }; + +@@ -211,6 +212,7 @@ static inline void interrupt_nmi_enter_prepare(struct pt_regs *regs, struct inte + #ifdef CONFIG_PPC64 + state->irq_soft_mask = local_paca->irq_soft_mask; + state->irq_happened = local_paca->irq_happened; ++ state->softe = regs->softe; + + /* + * Set IRQS_ALL_DISABLED unconditionally so irqs_disabled() does +@@ -263,6 +265,7 @@ static inline void interrupt_nmi_exit_prepare(struct pt_regs *regs, struct inter + + /* Check we didn't change the pending interrupt mask. */ + WARN_ON_ONCE((state->irq_happened | PACA_IRQ_HARD_DIS) != local_paca->irq_happened); ++ regs->softe = state->softe; + local_paca->irq_happened = state->irq_happened; + local_paca->irq_soft_mask = state->irq_soft_mask; + #endif +diff --git a/arch/powerpc/include/asm/kvm_guest.h b/arch/powerpc/include/asm/kvm_guest.h +index 2fca299f7e192..c63105d2c9e7c 100644 +--- a/arch/powerpc/include/asm/kvm_guest.h ++++ b/arch/powerpc/include/asm/kvm_guest.h +@@ -16,10 +16,10 @@ static inline bool is_kvm_guest(void) + return static_branch_unlikely(&kvm_guest); + } + +-bool check_kvm_guest(void); ++int check_kvm_guest(void); + #else + static inline bool is_kvm_guest(void) { return false; } +-static inline bool check_kvm_guest(void) { return false; } ++static inline int check_kvm_guest(void) { return 0; } + #endif + + #endif /* _ASM_POWERPC_KVM_GUEST_H_ */ +diff --git a/arch/powerpc/kernel/firmware.c b/arch/powerpc/kernel/firmware.c +index c9e2819b095ab..c7022c41cc314 100644 +--- a/arch/powerpc/kernel/firmware.c ++++ b/arch/powerpc/kernel/firmware.c +@@ -23,18 +23,20 @@ EXPORT_SYMBOL_GPL(powerpc_firmware_features); + + #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_KVM_GUEST) + DEFINE_STATIC_KEY_FALSE(kvm_guest); +-bool check_kvm_guest(void) ++int __init check_kvm_guest(void) + { + struct device_node *hyper_node; + + hyper_node = of_find_node_by_path("/hypervisor"); + if (!hyper_node) +- return false; ++ return 0; + + if (!of_device_is_compatible(hyper_node, "linux,kvm")) +- return false; ++ return 0; + + static_branch_enable(&kvm_guest); +- return true; ++ ++ return 0; + } ++core_initcall(check_kvm_guest); // before kvm_guest_init() + #endif +diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c +index 667104d4c4550..2fff886c549d0 100644 +--- a/arch/powerpc/kernel/mce_power.c ++++ b/arch/powerpc/kernel/mce_power.c +@@ -481,12 +481,11 @@ static int mce_find_instr_ea_and_phys(struct pt_regs *regs, uint64_t *addr, + return -1; + } + +-static int mce_handle_ierror(struct pt_regs *regs, ++static int mce_handle_ierror(struct pt_regs *regs, unsigned long srr1, + const struct mce_ierror_table table[], + struct mce_error_info *mce_err, uint64_t *addr, + uint64_t *phys_addr) + { +- uint64_t srr1 = regs->msr; + int handled = 0; + int i; + +@@ -695,19 +694,19 @@ static long mce_handle_ue_error(struct pt_regs *regs, + } + + static long mce_handle_error(struct pt_regs *regs, ++ unsigned long srr1, + const struct mce_derror_table dtable[], + const struct mce_ierror_table itable[]) + { + struct mce_error_info mce_err = { 0 }; + uint64_t addr, phys_addr = ULONG_MAX; +- uint64_t srr1 = regs->msr; + long handled; + + if (SRR1_MC_LOADSTORE(srr1)) + handled = mce_handle_derror(regs, dtable, &mce_err, &addr, + &phys_addr); + else +- handled = mce_handle_ierror(regs, itable, &mce_err, &addr, ++ handled = mce_handle_ierror(regs, srr1, itable, &mce_err, &addr, + &phys_addr); + + if (!handled && mce_err.error_type == MCE_ERROR_TYPE_UE) +@@ -723,16 +722,20 @@ long __machine_check_early_realmode_p7(struct pt_regs *regs) + /* P7 DD1 leaves top bits of DSISR undefined */ + regs->dsisr &= 0x0000ffff; + +- return mce_handle_error(regs, mce_p7_derror_table, mce_p7_ierror_table); ++ return mce_handle_error(regs, regs->msr, ++ mce_p7_derror_table, mce_p7_ierror_table); + } + + long __machine_check_early_realmode_p8(struct pt_regs *regs) + { +- return mce_handle_error(regs, mce_p8_derror_table, mce_p8_ierror_table); ++ return mce_handle_error(regs, regs->msr, ++ mce_p8_derror_table, mce_p8_ierror_table); + } + + long __machine_check_early_realmode_p9(struct pt_regs *regs) + { ++ unsigned long srr1 = regs->msr; ++ + /* + * On POWER9 DD2.1 and below, it's possible to get a machine check + * caused by a paste instruction where only DSISR bit 25 is set. This +@@ -746,10 +749,39 @@ long __machine_check_early_realmode_p9(struct pt_regs *regs) + if (SRR1_MC_LOADSTORE(regs->msr) && regs->dsisr == 0x02000000) + return 1; + +- return mce_handle_error(regs, mce_p9_derror_table, mce_p9_ierror_table); ++ /* ++ * Async machine check due to bad real address from store or foreign ++ * link time out comes with the load/store bit (PPC bit 42) set in ++ * SRR1, but the cause comes in SRR1 not DSISR. Clear bit 42 so we're ++ * directed to the ierror table so it will find the cause (which ++ * describes it correctly as a store error). ++ */ ++ if (SRR1_MC_LOADSTORE(srr1) && ++ ((srr1 & 0x081c0000) == 0x08140000 || ++ (srr1 & 0x081c0000) == 0x08180000)) { ++ srr1 &= ~PPC_BIT(42); ++ } ++ ++ return mce_handle_error(regs, srr1, ++ mce_p9_derror_table, mce_p9_ierror_table); + } + + long __machine_check_early_realmode_p10(struct pt_regs *regs) + { +- return mce_handle_error(regs, mce_p10_derror_table, mce_p10_ierror_table); ++ unsigned long srr1 = regs->msr; ++ ++ /* ++ * Async machine check due to bad real address from store comes with ++ * the load/store bit (PPC bit 42) set in SRR1, but the cause comes in ++ * SRR1 not DSISR. Clear bit 42 so we're directed to the ierror table ++ * so it will find the cause (which describes it correctly as a store ++ * error). ++ */ ++ if (SRR1_MC_LOADSTORE(srr1) && ++ (srr1 & 0x081c0000) == 0x08140000) { ++ srr1 &= ~PPC_BIT(42); ++ } ++ ++ return mce_handle_error(regs, srr1, ++ mce_p10_derror_table, mce_p10_ierror_table); + } +diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c +index 89e34aa273e21..1138f035ce747 100644 +--- a/arch/powerpc/kernel/process.c ++++ b/arch/powerpc/kernel/process.c +@@ -1213,6 +1213,19 @@ struct task_struct *__switch_to(struct task_struct *prev, + __flush_tlb_pending(batch); + batch->active = 0; + } ++ ++ /* ++ * On POWER9 the copy-paste buffer can only paste into ++ * foreign real addresses, so unprivileged processes can not ++ * see the data or use it in any way unless they have ++ * foreign real mappings. If the new process has the foreign ++ * real address mappings, we must issue a cp_abort to clear ++ * any state and prevent snooping, corruption or a covert ++ * channel. ISA v3.1 supports paste into local memory. ++ */ ++ if (new->mm && (cpu_has_feature(CPU_FTR_ARCH_31) || ++ atomic_read(&new->mm->context.vas_windows))) ++ asm volatile(PPC_CP_ABORT); + #endif /* CONFIG_PPC_BOOK3S_64 */ + + #ifdef CONFIG_PPC_ADV_DEBUG_REGS +@@ -1261,30 +1274,33 @@ struct task_struct *__switch_to(struct task_struct *prev, + #endif + last = _switch(old_thread, new_thread); + ++ /* ++ * Nothing after _switch will be run for newly created tasks, ++ * because they switch directly to ret_from_fork/ret_from_kernel_thread ++ * etc. Code added here should have a comment explaining why that is ++ * okay. ++ */ ++ + #ifdef CONFIG_PPC_BOOK3S_64 ++ /* ++ * This applies to a process that was context switched while inside ++ * arch_enter_lazy_mmu_mode(), to re-activate the batch that was ++ * deactivated above, before _switch(). This will never be the case ++ * for new tasks. ++ */ + if (current_thread_info()->local_flags & _TLF_LAZY_MMU) { + current_thread_info()->local_flags &= ~_TLF_LAZY_MMU; + batch = this_cpu_ptr(&ppc64_tlb_batch); + batch->active = 1; + } + +- if (current->thread.regs) { ++ /* ++ * Math facilities are masked out of the child MSR in copy_thread. ++ * A new task does not need to restore_math because it will ++ * demand fault them. ++ */ ++ if (current->thread.regs) + restore_math(current->thread.regs); +- +- /* +- * On POWER9 the copy-paste buffer can only paste into +- * foreign real addresses, so unprivileged processes can not +- * see the data or use it in any way unless they have +- * foreign real mappings. If the new process has the foreign +- * real address mappings, we must issue a cp_abort to clear +- * any state and prevent snooping, corruption or a covert +- * channel. ISA v3.1 supports paste into local memory. +- */ +- if (current->mm && +- (cpu_has_feature(CPU_FTR_ARCH_31) || +- atomic_read(¤t->mm->context.vas_windows))) +- asm volatile(PPC_CP_ABORT); +- } + #endif /* CONFIG_PPC_BOOK3S_64 */ + + return last; +diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c +index 2e05c783440a3..df6b468976d53 100644 +--- a/arch/powerpc/kernel/smp.c ++++ b/arch/powerpc/kernel/smp.c +@@ -619,6 +619,8 @@ static void nmi_stop_this_cpu(struct pt_regs *regs) + /* + * IRQs are already hard disabled by the smp_handle_nmi_ipi. + */ ++ set_cpu_online(smp_processor_id(), false); ++ + spin_begin(); + while (1) + spin_cpu_relax(); +@@ -634,6 +636,15 @@ void smp_send_stop(void) + static void stop_this_cpu(void *dummy) + { + hard_irq_disable(); ++ ++ /* ++ * Offlining CPUs in stop_this_cpu can result in scheduler warnings, ++ * (see commit de6e5d38417e), but printk_safe_flush_on_panic() wants ++ * to know other CPUs are offline before it breaks locks to flush ++ * printk buffers, in case we panic()ed while holding the lock. ++ */ ++ set_cpu_online(smp_processor_id(), false); ++ + spin_begin(); + while (1) + spin_cpu_relax(); +@@ -1547,7 +1558,6 @@ void start_secondary(void *unused) + smp_store_cpu_info(cpu); + set_dec(tb_ticks_per_jiffy); + rcu_cpu_starting(cpu); +- preempt_disable(); + cpu_callin_map[cpu] = 1; + + if (smp_ops->setup_cpu) +diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c +index 1deb1bf331ddb..ea0d9c36e177c 100644 +--- a/arch/powerpc/kernel/stacktrace.c ++++ b/arch/powerpc/kernel/stacktrace.c +@@ -172,17 +172,31 @@ static void handle_backtrace_ipi(struct pt_regs *regs) + + static void raise_backtrace_ipi(cpumask_t *mask) + { ++ struct paca_struct *p; + unsigned int cpu; ++ u64 delay_us; + + for_each_cpu(cpu, mask) { +- if (cpu == smp_processor_id()) ++ if (cpu == smp_processor_id()) { + handle_backtrace_ipi(NULL); +- else +- smp_send_safe_nmi_ipi(cpu, handle_backtrace_ipi, 5 * USEC_PER_SEC); +- } ++ continue; ++ } + +- for_each_cpu(cpu, mask) { +- struct paca_struct *p = paca_ptrs[cpu]; ++ delay_us = 5 * USEC_PER_SEC; ++ ++ if (smp_send_safe_nmi_ipi(cpu, handle_backtrace_ipi, delay_us)) { ++ // Now wait up to 5s for the other CPU to do its backtrace ++ while (cpumask_test_cpu(cpu, mask) && delay_us) { ++ udelay(1); ++ delay_us--; ++ } ++ ++ // Other CPU cleared itself from the mask ++ if (delay_us) ++ continue; ++ } ++ ++ p = paca_ptrs[cpu]; + + cpumask_clear_cpu(cpu, mask); + +diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c +index bc08136446660..67cc164c4ac1a 100644 +--- a/arch/powerpc/kvm/book3s_hv.c ++++ b/arch/powerpc/kvm/book3s_hv.c +@@ -2657,7 +2657,7 @@ static void radix_flush_cpu(struct kvm *kvm, int cpu, struct kvm_vcpu *vcpu) + cpumask_t *cpu_in_guest; + int i; + +- cpu = cpu_first_thread_sibling(cpu); ++ cpu = cpu_first_tlb_thread_sibling(cpu); + if (nested) { + cpumask_set_cpu(cpu, &nested->need_tlb_flush); + cpu_in_guest = &nested->cpu_in_guest; +@@ -2671,9 +2671,10 @@ static void radix_flush_cpu(struct kvm *kvm, int cpu, struct kvm_vcpu *vcpu) + * the other side is the first smp_mb() in kvmppc_run_core(). + */ + smp_mb(); +- for (i = 0; i < threads_per_core; ++i) +- if (cpumask_test_cpu(cpu + i, cpu_in_guest)) +- smp_call_function_single(cpu + i, do_nothing, NULL, 1); ++ for (i = cpu; i <= cpu_last_tlb_thread_sibling(cpu); ++ i += cpu_tlb_thread_sibling_step()) ++ if (cpumask_test_cpu(i, cpu_in_guest)) ++ smp_call_function_single(i, do_nothing, NULL, 1); + } + + static void kvmppc_prepare_radix_vcpu(struct kvm_vcpu *vcpu, int pcpu) +@@ -2704,8 +2705,8 @@ static void kvmppc_prepare_radix_vcpu(struct kvm_vcpu *vcpu, int pcpu) + */ + if (prev_cpu != pcpu) { + if (prev_cpu >= 0 && +- cpu_first_thread_sibling(prev_cpu) != +- cpu_first_thread_sibling(pcpu)) ++ cpu_first_tlb_thread_sibling(prev_cpu) != ++ cpu_first_tlb_thread_sibling(pcpu)) + radix_flush_cpu(kvm, prev_cpu, vcpu); + if (nested) + nested->prev_cpu[vcpu->arch.nested_vcpu_id] = pcpu; +diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c +index 7a0e33a9c980d..3edc25c890923 100644 +--- a/arch/powerpc/kvm/book3s_hv_builtin.c ++++ b/arch/powerpc/kvm/book3s_hv_builtin.c +@@ -800,7 +800,7 @@ void kvmppc_check_need_tlb_flush(struct kvm *kvm, int pcpu, + * Thus we make all 4 threads use the same bit. + */ + if (cpu_has_feature(CPU_FTR_ARCH_300)) +- pcpu = cpu_first_thread_sibling(pcpu); ++ pcpu = cpu_first_tlb_thread_sibling(pcpu); + + if (nested) + need_tlb_flush = &nested->need_tlb_flush; +diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c +index 60724f6744219..1b3ff0af12648 100644 +--- a/arch/powerpc/kvm/book3s_hv_nested.c ++++ b/arch/powerpc/kvm/book3s_hv_nested.c +@@ -53,7 +53,8 @@ void kvmhv_save_hv_regs(struct kvm_vcpu *vcpu, struct hv_guest_state *hr) + hr->dawrx1 = vcpu->arch.dawrx1; + } + +-static void byteswap_pt_regs(struct pt_regs *regs) ++/* Use noinline_for_stack due to https://bugs.llvm.org/show_bug.cgi?id=49610 */ ++static noinline_for_stack void byteswap_pt_regs(struct pt_regs *regs) + { + unsigned long *addr = (unsigned long *) regs; + +diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c +index 7a0f12404e0ee..502d9ebe3ae47 100644 +--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c ++++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c +@@ -56,7 +56,7 @@ static int global_invalidates(struct kvm *kvm) + * so use the bit for the first thread to represent the core. + */ + if (cpu_has_feature(CPU_FTR_ARCH_300)) +- cpu = cpu_first_thread_sibling(cpu); ++ cpu = cpu_first_tlb_thread_sibling(cpu); + cpumask_clear_cpu(cpu, &kvm->arch.need_tlb_flush); + } + +diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c +index 96d9aa1640073..ac5720371c0d9 100644 +--- a/arch/powerpc/mm/book3s64/hash_utils.c ++++ b/arch/powerpc/mm/book3s64/hash_utils.c +@@ -1522,8 +1522,8 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap, + } + EXPORT_SYMBOL_GPL(hash_page); + +-DECLARE_INTERRUPT_HANDLER_RET(__do_hash_fault); +-DEFINE_INTERRUPT_HANDLER_RET(__do_hash_fault) ++DECLARE_INTERRUPT_HANDLER(__do_hash_fault); ++DEFINE_INTERRUPT_HANDLER(__do_hash_fault) + { + unsigned long ea = regs->dar; + unsigned long dsisr = regs->dsisr; +@@ -1533,6 +1533,11 @@ DEFINE_INTERRUPT_HANDLER_RET(__do_hash_fault) + unsigned int region_id; + long err; + ++ if (unlikely(dsisr & (DSISR_BAD_FAULT_64S | DSISR_KEYFAULT))) { ++ hash__do_page_fault(regs); ++ return; ++ } ++ + region_id = get_region_id(ea); + if ((region_id == VMALLOC_REGION_ID) || (region_id == IO_REGION_ID)) + mm = &init_mm; +@@ -1571,9 +1576,10 @@ DEFINE_INTERRUPT_HANDLER_RET(__do_hash_fault) + bad_page_fault(regs, SIGBUS); + } + err = 0; +- } + +- return err; ++ } else if (err) { ++ hash__do_page_fault(regs); ++ } + } + + /* +@@ -1582,13 +1588,6 @@ DEFINE_INTERRUPT_HANDLER_RET(__do_hash_fault) + */ + DEFINE_INTERRUPT_HANDLER_RAW(do_hash_fault) + { +- unsigned long dsisr = regs->dsisr; +- +- if (unlikely(dsisr & (DSISR_BAD_FAULT_64S | DSISR_KEYFAULT))) { +- hash__do_page_fault(regs); +- return 0; +- } +- + /* + * If we are in an "NMI" (e.g., an interrupt when soft-disabled), then + * don't call hash_page, just fail the fault. This is required to +@@ -1607,8 +1606,7 @@ DEFINE_INTERRUPT_HANDLER_RAW(do_hash_fault) + return 0; + } + +- if (__do_hash_fault(regs)) +- hash__do_page_fault(regs); ++ __do_hash_fault(regs); + + return 0; + } +diff --git a/arch/powerpc/platforms/cell/smp.c b/arch/powerpc/platforms/cell/smp.c +index c855a0aeb49cc..d7ab868aab54a 100644 +--- a/arch/powerpc/platforms/cell/smp.c ++++ b/arch/powerpc/platforms/cell/smp.c +@@ -78,9 +78,6 @@ static inline int smp_startup_cpu(unsigned int lcpu) + + pcpu = get_hard_smp_processor_id(lcpu); + +- /* Fixup atomic count: it exited inside IRQ handler. */ +- task_thread_info(paca_ptrs[lcpu]->__current)->preempt_count = 0; +- + /* + * If the RTAS start-cpu token does not exist then presume the + * cpu is already spinning. +diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c +index ef26fe40efb03..d34e6eb4be0d5 100644 +--- a/arch/powerpc/platforms/pseries/papr_scm.c ++++ b/arch/powerpc/platforms/pseries/papr_scm.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + + #define BIND_ANY_ADDR (~0ul) + +@@ -900,6 +901,20 @@ static ssize_t flags_show(struct device *dev, + } + DEVICE_ATTR_RO(flags); + ++static umode_t papr_nd_attribute_visible(struct kobject *kobj, ++ struct attribute *attr, int n) ++{ ++ struct device *dev = kobj_to_dev(kobj); ++ struct nvdimm *nvdimm = to_nvdimm(dev); ++ struct papr_scm_priv *p = nvdimm_provider_data(nvdimm); ++ ++ /* For if perf-stats not available remove perf_stats sysfs */ ++ if (attr == &dev_attr_perf_stats.attr && p->stat_buffer_len == 0) ++ return 0; ++ ++ return attr->mode; ++} ++ + /* papr_scm specific dimm attributes */ + static struct attribute *papr_nd_attributes[] = { + &dev_attr_flags.attr, +@@ -909,6 +924,7 @@ static struct attribute *papr_nd_attributes[] = { + + static struct attribute_group papr_nd_attribute_group = { + .name = "papr", ++ .is_visible = papr_nd_attribute_visible, + .attrs = papr_nd_attributes, + }; + +@@ -924,7 +940,6 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p) + struct nd_region_desc ndr_desc; + unsigned long dimm_flags; + int target_nid, online_nid; +- ssize_t stat_size; + + p->bus_desc.ndctl = papr_scm_ndctl; + p->bus_desc.module = THIS_MODULE; +@@ -1009,16 +1024,6 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p) + list_add_tail(&p->region_list, &papr_nd_regions); + mutex_unlock(&papr_ndr_lock); + +- /* Try retriving the stat buffer and see if its supported */ +- stat_size = drc_pmem_query_stats(p, NULL, 0); +- if (stat_size > 0) { +- p->stat_buffer_len = stat_size; +- dev_dbg(&p->pdev->dev, "Max perf-stat size %lu-bytes\n", +- p->stat_buffer_len); +- } else { +- dev_info(&p->pdev->dev, "Dimm performance stats unavailable\n"); +- } +- + return 0; + + err: nvdimm_bus_unregister(p->bus); +@@ -1094,8 +1099,10 @@ static int papr_scm_probe(struct platform_device *pdev) + u32 drc_index, metadata_size; + u64 blocks, block_size; + struct papr_scm_priv *p; ++ u8 uuid_raw[UUID_SIZE]; + const char *uuid_str; +- u64 uuid[2]; ++ ssize_t stat_size; ++ uuid_t uuid; + int rc; + + /* check we have all the required DT properties */ +@@ -1138,16 +1145,23 @@ static int papr_scm_probe(struct platform_device *pdev) + p->hcall_flush_required = of_property_read_bool(dn, "ibm,hcall-flush-required"); + + /* We just need to ensure that set cookies are unique across */ +- uuid_parse(uuid_str, (uuid_t *) uuid); ++ uuid_parse(uuid_str, &uuid); ++ + /* +- * cookie1 and cookie2 are not really little endian +- * we store a little endian representation of the +- * uuid str so that we can compare this with the label +- * area cookie irrespective of the endian config with which +- * the kernel is built. ++ * The cookie1 and cookie2 are not really little endian. ++ * We store a raw buffer representation of the ++ * uuid string so that we can compare this with the label ++ * area cookie irrespective of the endian configuration ++ * with which the kernel is built. ++ * ++ * Historically we stored the cookie in the below format. ++ * for a uuid string 72511b67-0b3b-42fd-8d1d-5be3cae8bcaa ++ * cookie1 was 0xfd423b0b671b5172 ++ * cookie2 was 0xaabce8cae35b1d8d + */ +- p->nd_set.cookie1 = cpu_to_le64(uuid[0]); +- p->nd_set.cookie2 = cpu_to_le64(uuid[1]); ++ export_uuid(uuid_raw, &uuid); ++ p->nd_set.cookie1 = get_unaligned_le64(&uuid_raw[0]); ++ p->nd_set.cookie2 = get_unaligned_le64(&uuid_raw[8]); + + /* might be zero */ + p->metadata_size = metadata_size; +@@ -1172,6 +1186,14 @@ static int papr_scm_probe(struct platform_device *pdev) + p->res.name = pdev->name; + p->res.flags = IORESOURCE_MEM; + ++ /* Try retrieving the stat buffer and see if its supported */ ++ stat_size = drc_pmem_query_stats(p, NULL, 0); ++ if (stat_size > 0) { ++ p->stat_buffer_len = stat_size; ++ dev_dbg(&p->pdev->dev, "Max perf-stat size %lu-bytes\n", ++ p->stat_buffer_len); ++ } ++ + rc = papr_scm_nvdimm_init(p); + if (rc) + goto err2; +diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c +index c70b4be9f0a54..f47429323eee9 100644 +--- a/arch/powerpc/platforms/pseries/smp.c ++++ b/arch/powerpc/platforms/pseries/smp.c +@@ -105,9 +105,6 @@ static inline int smp_startup_cpu(unsigned int lcpu) + return 1; + } + +- /* Fixup atomic count: it exited inside IRQ handler. */ +- task_thread_info(paca_ptrs[lcpu]->__current)->preempt_count = 0; +- + /* + * If the RTAS start-cpu token does not exist then presume the + * cpu is already spinning. +@@ -211,7 +208,9 @@ static __init void pSeries_smp_probe(void) + if (!cpu_has_feature(CPU_FTR_SMT)) + return; + +- if (check_kvm_guest()) { ++ check_kvm_guest(); ++ ++ if (is_kvm_guest()) { + /* + * KVM emulates doorbells by disabling FSCR[MSGP] so msgsndp + * faults to the hypervisor which then reads the instruction +diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c +index 9a408e2942acf..bd82375db51a6 100644 +--- a/arch/riscv/kernel/smpboot.c ++++ b/arch/riscv/kernel/smpboot.c +@@ -180,7 +180,6 @@ asmlinkage __visible void smp_callin(void) + * Disable preemption before enabling interrupts, so we don't try to + * schedule a CPU that hasn't actually started yet. + */ +- preempt_disable(); + local_irq_enable(); + cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); + } +diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig +index b4c7c34069f81..93488bbf491b9 100644 +--- a/arch/s390/Kconfig ++++ b/arch/s390/Kconfig +@@ -164,6 +164,7 @@ config S390 + select HAVE_FUTEX_CMPXCHG if FUTEX + select HAVE_GCC_PLUGINS + select HAVE_GENERIC_VDSO ++ select HAVE_IOREMAP_PROT if PCI + select HAVE_IRQ_EXIT_ON_IRQ_STACK + select HAVE_KERNEL_BZIP2 + select HAVE_KERNEL_GZIP +@@ -853,7 +854,7 @@ config CMM_IUCV + config APPLDATA_BASE + def_bool n + prompt "Linux - VM Monitor Stream, base infrastructure" +- depends on PROC_FS ++ depends on PROC_SYSCTL + help + This provides a kernel interface for creating and updating z/VM APPLDATA + monitor records. The monitor records are updated at certain time +diff --git a/arch/s390/boot/uv.c b/arch/s390/boot/uv.c +index 87641dd65ccf9..b3501ea5039e4 100644 +--- a/arch/s390/boot/uv.c ++++ b/arch/s390/boot/uv.c +@@ -36,6 +36,7 @@ void uv_query_info(void) + uv_info.max_sec_stor_addr = ALIGN(uvcb.max_guest_stor_addr, PAGE_SIZE); + uv_info.max_num_sec_conf = uvcb.max_num_sec_conf; + uv_info.max_guest_cpu_id = uvcb.max_guest_cpu_id; ++ uv_info.uv_feature_indications = uvcb.uv_feature_indications; + } + + #ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST +diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h +index 29c7ecd5ad1d5..adea53f69bfd3 100644 +--- a/arch/s390/include/asm/pgtable.h ++++ b/arch/s390/include/asm/pgtable.h +@@ -344,8 +344,6 @@ static inline int is_module_addr(void *addr) + #define PTRS_PER_P4D _CRST_ENTRIES + #define PTRS_PER_PGD _CRST_ENTRIES + +-#define MAX_PTRS_PER_P4D PTRS_PER_P4D +- + /* + * Segment table and region3 table entry encoding + * (R = read-only, I = invalid, y = young bit): +@@ -865,6 +863,25 @@ static inline int pte_unused(pte_t pte) + return pte_val(pte) & _PAGE_UNUSED; + } + ++/* ++ * Extract the pgprot value from the given pte while at the same time making it ++ * usable for kernel address space mappings where fault driven dirty and ++ * young/old accounting is not supported, i.e _PAGE_PROTECT and _PAGE_INVALID ++ * must not be set. ++ */ ++static inline pgprot_t pte_pgprot(pte_t pte) ++{ ++ unsigned long pte_flags = pte_val(pte) & _PAGE_CHG_MASK; ++ ++ if (pte_write(pte)) ++ pte_flags |= pgprot_val(PAGE_KERNEL); ++ else ++ pte_flags |= pgprot_val(PAGE_KERNEL_RO); ++ pte_flags |= pte_val(pte) & mio_wb_bit_mask; ++ ++ return __pgprot(pte_flags); ++} ++ + /* + * pgd/pmd/pte modification functions + */ +diff --git a/arch/s390/include/asm/preempt.h b/arch/s390/include/asm/preempt.h +index b49e0492842cc..d9d5350cc3ec3 100644 +--- a/arch/s390/include/asm/preempt.h ++++ b/arch/s390/include/asm/preempt.h +@@ -29,12 +29,6 @@ static inline void preempt_count_set(int pc) + old, new) != old); + } + +-#define init_task_preempt_count(p) do { } while (0) +- +-#define init_idle_preempt_count(p, cpu) do { \ +- S390_lowcore.preempt_count = PREEMPT_ENABLED; \ +-} while (0) +- + static inline void set_preempt_need_resched(void) + { + __atomic_and(~PREEMPT_NEED_RESCHED, &S390_lowcore.preempt_count); +@@ -88,12 +82,6 @@ static inline void preempt_count_set(int pc) + S390_lowcore.preempt_count = pc; + } + +-#define init_task_preempt_count(p) do { } while (0) +- +-#define init_idle_preempt_count(p, cpu) do { \ +- S390_lowcore.preempt_count = PREEMPT_ENABLED; \ +-} while (0) +- + static inline void set_preempt_need_resched(void) + { + } +@@ -130,6 +118,10 @@ static inline bool should_resched(int preempt_offset) + + #endif /* CONFIG_HAVE_MARCH_Z196_FEATURES */ + ++#define init_task_preempt_count(p) do { } while (0) ++/* Deferred to CPU bringup time */ ++#define init_idle_preempt_count(p, cpu) do { } while (0) ++ + #ifdef CONFIG_PREEMPTION + extern void preempt_schedule(void); + #define __preempt_schedule() preempt_schedule() +diff --git a/arch/s390/include/asm/uv.h b/arch/s390/include/asm/uv.h +index 7b98d4caee779..12c5f006c1364 100644 +--- a/arch/s390/include/asm/uv.h ++++ b/arch/s390/include/asm/uv.h +@@ -73,6 +73,10 @@ enum uv_cmds_inst { + BIT_UVC_CMD_UNPIN_PAGE_SHARED = 22, + }; + ++enum uv_feat_ind { ++ BIT_UV_FEAT_MISC = 0, ++}; ++ + struct uv_cb_header { + u16 len; + u16 cmd; /* Command Code */ +@@ -97,7 +101,8 @@ struct uv_cb_qui { + u64 max_guest_stor_addr; + u8 reserved88[158 - 136]; + u16 max_guest_cpu_id; +- u8 reserveda0[200 - 160]; ++ u64 uv_feature_indications; ++ u8 reserveda0[200 - 168]; + } __packed __aligned(8); + + /* Initialize Ultravisor */ +@@ -274,6 +279,7 @@ struct uv_info { + unsigned long max_sec_stor_addr; + unsigned int max_num_sec_conf; + unsigned short max_guest_cpu_id; ++ unsigned long uv_feature_indications; + }; + + extern struct uv_info uv_info; +diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c +index 5aab59ad56881..382d73da134cf 100644 +--- a/arch/s390/kernel/setup.c ++++ b/arch/s390/kernel/setup.c +@@ -466,6 +466,7 @@ static void __init setup_lowcore_dat_off(void) + lc->br_r1_trampoline = 0x07f1; /* br %r1 */ + lc->return_lpswe = gen_lpswe(__LC_RETURN_PSW); + lc->return_mcck_lpswe = gen_lpswe(__LC_RETURN_MCCK_PSW); ++ lc->preempt_count = PREEMPT_DISABLED; + + set_prefix((u32)(unsigned long) lc); + lowcore_ptr[0] = lc; +diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c +index 2fec2b80d35d2..1fb483e06a647 100644 +--- a/arch/s390/kernel/smp.c ++++ b/arch/s390/kernel/smp.c +@@ -219,6 +219,7 @@ static int pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu) + lc->br_r1_trampoline = 0x07f1; /* br %r1 */ + lc->return_lpswe = gen_lpswe(__LC_RETURN_PSW); + lc->return_mcck_lpswe = gen_lpswe(__LC_RETURN_MCCK_PSW); ++ lc->preempt_count = PREEMPT_DISABLED; + if (nmi_alloc_per_cpu(lc)) + goto out_stack; + lowcore_ptr[cpu] = lc; +@@ -878,7 +879,6 @@ static void smp_init_secondary(void) + restore_access_regs(S390_lowcore.access_regs_save_area); + cpu_init(); + rcu_cpu_starting(cpu); +- preempt_disable(); + init_cpu_timer(); + vtime_init(); + vdso_getcpu_init(); +diff --git a/arch/s390/kernel/uv.c b/arch/s390/kernel/uv.c +index 370f664580af5..650b4b7b1e6b0 100644 +--- a/arch/s390/kernel/uv.c ++++ b/arch/s390/kernel/uv.c +@@ -364,6 +364,15 @@ static ssize_t uv_query_facilities(struct kobject *kobj, + static struct kobj_attribute uv_query_facilities_attr = + __ATTR(facilities, 0444, uv_query_facilities, NULL); + ++static ssize_t uv_query_feature_indications(struct kobject *kobj, ++ struct kobj_attribute *attr, char *buf) ++{ ++ return sysfs_emit(buf, "%lx\n", uv_info.uv_feature_indications); ++} ++ ++static struct kobj_attribute uv_query_feature_indications_attr = ++ __ATTR(feature_indications, 0444, uv_query_feature_indications, NULL); ++ + static ssize_t uv_query_max_guest_cpus(struct kobject *kobj, + struct kobj_attribute *attr, char *page) + { +@@ -396,6 +405,7 @@ static struct kobj_attribute uv_query_max_guest_addr_attr = + + static struct attribute *uv_query_attrs[] = { + &uv_query_facilities_attr.attr, ++ &uv_query_feature_indications_attr.attr, + &uv_query_max_guest_cpus_attr.attr, + &uv_query_max_guest_vms_attr.attr, + &uv_query_max_guest_addr_attr.attr, +diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c +index 1296fc10f80c8..876fc1f7282a0 100644 +--- a/arch/s390/kvm/kvm-s390.c ++++ b/arch/s390/kvm/kvm-s390.c +@@ -329,31 +329,31 @@ static void allow_cpu_feat(unsigned long nr) + + static inline int plo_test_bit(unsigned char nr) + { +- register unsigned long r0 asm("0") = (unsigned long) nr | 0x100; ++ unsigned long function = (unsigned long)nr | 0x100; + int cc; + + asm volatile( ++ " lgr 0,%[function]\n" + /* Parameter registers are ignored for "test bit" */ + " plo 0,0,0,0(0)\n" + " ipm %0\n" + " srl %0,28\n" + : "=d" (cc) +- : "d" (r0) +- : "cc"); ++ : [function] "d" (function) ++ : "cc", "0"); + return cc == 0; + } + + static __always_inline void __insn32_query(unsigned int opcode, u8 *query) + { +- register unsigned long r0 asm("0") = 0; /* query function */ +- register unsigned long r1 asm("1") = (unsigned long) query; +- + asm volatile( +- /* Parameter regs are ignored */ ++ " lghi 0,0\n" ++ " lgr 1,%[query]\n" ++ /* Parameter registers are ignored */ + " .insn rrf,%[opc] << 16,2,4,6,0\n" + : +- : "d" (r0), "a" (r1), [opc] "i" (opcode) +- : "cc", "memory"); ++ : [query] "d" ((unsigned long)query), [opc] "i" (opcode) ++ : "cc", "memory", "0", "1"); + } + + #define INSN_SORTL 0xb938 +diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c +index 826d017773616..f54f6dcd87489 100644 +--- a/arch/s390/mm/fault.c ++++ b/arch/s390/mm/fault.c +@@ -792,6 +792,32 @@ void do_secure_storage_access(struct pt_regs *regs) + struct page *page; + int rc; + ++ /* ++ * bit 61 tells us if the address is valid, if it's not we ++ * have a major problem and should stop the kernel or send a ++ * SIGSEGV to the process. Unfortunately bit 61 is not ++ * reliable without the misc UV feature so we need to check ++ * for that as well. ++ */ ++ if (test_bit_inv(BIT_UV_FEAT_MISC, &uv_info.uv_feature_indications) && ++ !test_bit_inv(61, ®s->int_parm_long)) { ++ /* ++ * When this happens, userspace did something that it ++ * was not supposed to do, e.g. branching into secure ++ * memory. Trigger a segmentation fault. ++ */ ++ if (user_mode(regs)) { ++ send_sig(SIGSEGV, current, 0); ++ return; ++ } ++ ++ /* ++ * The kernel should never run into this case and we ++ * have no way out of this situation. ++ */ ++ panic("Unexpected PGM 0x3d with TEID bit 61=0"); ++ } ++ + switch (get_fault_type(regs)) { + case USER_FAULT: + mm = current->mm; +diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c +index 372acdc9033eb..65924d9ec2459 100644 +--- a/arch/sh/kernel/smp.c ++++ b/arch/sh/kernel/smp.c +@@ -186,8 +186,6 @@ asmlinkage void start_secondary(void) + + per_cpu_trap_init(); + +- preempt_disable(); +- + notify_cpu_starting(cpu); + + local_irq_enable(); +diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c +index 50c127ab46d5b..22b148e5a5f88 100644 +--- a/arch/sparc/kernel/smp_32.c ++++ b/arch/sparc/kernel/smp_32.c +@@ -348,7 +348,6 @@ static void sparc_start_secondary(void *arg) + */ + arch_cpu_pre_starting(arg); + +- preempt_disable(); + cpu = smp_processor_id(); + + notify_cpu_starting(cpu); +diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c +index e38d8bf454e86..ae5faa1d989d2 100644 +--- a/arch/sparc/kernel/smp_64.c ++++ b/arch/sparc/kernel/smp_64.c +@@ -138,9 +138,6 @@ void smp_callin(void) + + set_cpu_online(cpuid, true); + +- /* idle thread is expected to have preempt disabled */ +- preempt_disable(); +- + local_irq_enable(); + + cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); +diff --git a/arch/x86/crypto/curve25519-x86_64.c b/arch/x86/crypto/curve25519-x86_64.c +index 6706b6cb1d0fc..38caf61cd5b7d 100644 +--- a/arch/x86/crypto/curve25519-x86_64.c ++++ b/arch/x86/crypto/curve25519-x86_64.c +@@ -1500,7 +1500,7 @@ static int __init curve25519_mod_init(void) + static void __exit curve25519_mod_exit(void) + { + if (IS_REACHABLE(CONFIG_CRYPTO_KPP) && +- (boot_cpu_has(X86_FEATURE_BMI2) || boot_cpu_has(X86_FEATURE_ADX))) ++ static_branch_likely(&curve25519_use_bmi2_adx)) + crypto_unregister_kpp(&curve25519_alg); + } + +diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S +index a16a5294d55f6..1886aaf199143 100644 +--- a/arch/x86/entry/entry_64.S ++++ b/arch/x86/entry/entry_64.S +@@ -506,7 +506,7 @@ SYM_CODE_START(\asmsym) + + movq %rsp, %rdi /* pt_regs pointer */ + +- call \cfunc ++ call kernel_\cfunc + + /* + * No need to switch back to the IST stack. The current stack is either +@@ -517,7 +517,7 @@ SYM_CODE_START(\asmsym) + + /* Switch to the regular task stack */ + .Lfrom_usermode_switch_stack_\@: +- idtentry_body safe_stack_\cfunc, has_error_code=1 ++ idtentry_body user_\cfunc, has_error_code=1 + + _ASM_NOKPROBE(\asmsym) + SYM_CODE_END(\asmsym) +diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c +index 8f71dd72ef95f..1eb45139fcc6e 100644 +--- a/arch/x86/events/core.c ++++ b/arch/x86/events/core.c +@@ -1626,6 +1626,8 @@ static void x86_pmu_del(struct perf_event *event, int flags) + if (cpuc->txn_flags & PERF_PMU_TXN_ADD) + goto do_del; + ++ __set_bit(event->hw.idx, cpuc->dirty); ++ + /* + * Not a TXN, therefore cleanup properly. + */ +@@ -2474,6 +2476,31 @@ static int x86_pmu_event_init(struct perf_event *event) + return err; + } + ++void perf_clear_dirty_counters(void) ++{ ++ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); ++ int i; ++ ++ /* Don't need to clear the assigned counter. */ ++ for (i = 0; i < cpuc->n_events; i++) ++ __clear_bit(cpuc->assign[i], cpuc->dirty); ++ ++ if (bitmap_empty(cpuc->dirty, X86_PMC_IDX_MAX)) ++ return; ++ ++ for_each_set_bit(i, cpuc->dirty, X86_PMC_IDX_MAX) { ++ /* Metrics and fake events don't have corresponding HW counters. */ ++ if (is_metric_idx(i) || (i == INTEL_PMC_IDX_FIXED_VLBR)) ++ continue; ++ else if (i >= INTEL_PMC_IDX_FIXED) ++ wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + (i - INTEL_PMC_IDX_FIXED), 0); ++ else ++ wrmsrl(x86_pmu_event_addr(i), 0); ++ } ++ ++ bitmap_zero(cpuc->dirty, X86_PMC_IDX_MAX); ++} ++ + static void x86_pmu_event_mapped(struct perf_event *event, struct mm_struct *mm) + { + if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED)) +@@ -2497,7 +2524,6 @@ static void x86_pmu_event_mapped(struct perf_event *event, struct mm_struct *mm) + + static void x86_pmu_event_unmapped(struct perf_event *event, struct mm_struct *mm) + { +- + if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED)) + return; + +diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c +index e28892270c580..d76be3bba11e4 100644 +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -280,6 +280,8 @@ static struct extra_reg intel_spr_extra_regs[] __read_mostly = { + INTEL_UEVENT_EXTRA_REG(0x012b, MSR_OFFCORE_RSP_1, 0x3fffffffffull, RSP_1), + INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd), + INTEL_UEVENT_EXTRA_REG(0x01c6, MSR_PEBS_FRONTEND, 0x7fff17, FE), ++ INTEL_UEVENT_EXTRA_REG(0x40ad, MSR_PEBS_FRONTEND, 0x7, FE), ++ INTEL_UEVENT_EXTRA_REG(0x04c2, MSR_PEBS_FRONTEND, 0x8, FE), + EVENT_EXTRA_END + }; + +@@ -4030,8 +4032,10 @@ spr_get_event_constraints(struct cpu_hw_events *cpuc, int idx, + * The :ppp indicates the Precise Distribution (PDist) facility, which + * is only supported on the GP counter 0. If a :ppp event which is not + * available on the GP counter 0, error out. ++ * Exception: Instruction PDIR is only available on the fixed counter 0. + */ +- if (event->attr.precise_ip == 3) { ++ if ((event->attr.precise_ip == 3) && ++ !constraint_match(&fixed0_constraint, event->hw.config)) { + if (c->idxmsk64 & BIT_ULL(0)) + return &counter0_constraint; + +@@ -6157,8 +6161,13 @@ __init int intel_pmu_init(void) + pmu = &x86_pmu.hybrid_pmu[X86_HYBRID_PMU_CORE_IDX]; + pmu->name = "cpu_core"; + pmu->cpu_type = hybrid_big; +- pmu->num_counters = x86_pmu.num_counters + 2; +- pmu->num_counters_fixed = x86_pmu.num_counters_fixed + 1; ++ if (cpu_feature_enabled(X86_FEATURE_HYBRID_CPU)) { ++ pmu->num_counters = x86_pmu.num_counters + 2; ++ pmu->num_counters_fixed = x86_pmu.num_counters_fixed + 1; ++ } else { ++ pmu->num_counters = x86_pmu.num_counters; ++ pmu->num_counters_fixed = x86_pmu.num_counters_fixed; ++ } + pmu->max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, pmu->num_counters); + pmu->unconstrained = (struct event_constraint) + __EVENT_CONSTRAINT(0, (1ULL << pmu->num_counters) - 1, +diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h +index ad87cb36f7c81..2bf1c7ea2758d 100644 +--- a/arch/x86/events/perf_event.h ++++ b/arch/x86/events/perf_event.h +@@ -229,6 +229,7 @@ struct cpu_hw_events { + */ + struct perf_event *events[X86_PMC_IDX_MAX]; /* in counter order */ + unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; ++ unsigned long dirty[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; + int enabled; + + int n_events; /* the # of events in the below arrays */ +diff --git a/arch/x86/include/asm/idtentry.h b/arch/x86/include/asm/idtentry.h +index 73d45b0dfff2d..cd9f3e3049449 100644 +--- a/arch/x86/include/asm/idtentry.h ++++ b/arch/x86/include/asm/idtentry.h +@@ -312,8 +312,8 @@ static __always_inline void __##func(struct pt_regs *regs) + */ + #define DECLARE_IDTENTRY_VC(vector, func) \ + DECLARE_IDTENTRY_RAW_ERRORCODE(vector, func); \ +- __visible noinstr void ist_##func(struct pt_regs *regs, unsigned long error_code); \ +- __visible noinstr void safe_stack_##func(struct pt_regs *regs, unsigned long error_code) ++ __visible noinstr void kernel_##func(struct pt_regs *regs, unsigned long error_code); \ ++ __visible noinstr void user_##func(struct pt_regs *regs, unsigned long error_code) + + /** + * DEFINE_IDTENTRY_IST - Emit code for IST entry points +@@ -355,33 +355,24 @@ static __always_inline void __##func(struct pt_regs *regs) + DEFINE_IDTENTRY_RAW_ERRORCODE(func) + + /** +- * DEFINE_IDTENTRY_VC_SAFE_STACK - Emit code for VMM communication handler +- which runs on a safe stack. ++ * DEFINE_IDTENTRY_VC_KERNEL - Emit code for VMM communication handler ++ when raised from kernel mode + * @func: Function name of the entry point + * + * Maps to DEFINE_IDTENTRY_RAW_ERRORCODE + */ +-#define DEFINE_IDTENTRY_VC_SAFE_STACK(func) \ +- DEFINE_IDTENTRY_RAW_ERRORCODE(safe_stack_##func) ++#define DEFINE_IDTENTRY_VC_KERNEL(func) \ ++ DEFINE_IDTENTRY_RAW_ERRORCODE(kernel_##func) + + /** +- * DEFINE_IDTENTRY_VC_IST - Emit code for VMM communication handler +- which runs on the VC fall-back stack ++ * DEFINE_IDTENTRY_VC_USER - Emit code for VMM communication handler ++ when raised from user mode + * @func: Function name of the entry point + * + * Maps to DEFINE_IDTENTRY_RAW_ERRORCODE + */ +-#define DEFINE_IDTENTRY_VC_IST(func) \ +- DEFINE_IDTENTRY_RAW_ERRORCODE(ist_##func) +- +-/** +- * DEFINE_IDTENTRY_VC - Emit code for VMM communication handler +- * @func: Function name of the entry point +- * +- * Maps to DEFINE_IDTENTRY_RAW_ERRORCODE +- */ +-#define DEFINE_IDTENTRY_VC(func) \ +- DEFINE_IDTENTRY_RAW_ERRORCODE(func) ++#define DEFINE_IDTENTRY_VC_USER(func) \ ++ DEFINE_IDTENTRY_RAW_ERRORCODE(user_##func) + + #else /* CONFIG_X86_64 */ + +diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h +index 682e82956ea5a..fbd55c682d5e7 100644 +--- a/arch/x86/include/asm/kvm_host.h ++++ b/arch/x86/include/asm/kvm_host.h +@@ -85,7 +85,7 @@ + #define KVM_REQ_APICV_UPDATE \ + KVM_ARCH_REQ_FLAGS(25, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP) + #define KVM_REQ_TLB_FLUSH_CURRENT KVM_ARCH_REQ(26) +-#define KVM_REQ_HV_TLB_FLUSH \ ++#define KVM_REQ_TLB_FLUSH_GUEST \ + KVM_ARCH_REQ_FLAGS(27, KVM_REQUEST_NO_WAKEUP) + #define KVM_REQ_APF_READY KVM_ARCH_REQ(28) + #define KVM_REQ_MSR_FILTER_CHANGED KVM_ARCH_REQ(29) +@@ -1464,6 +1464,7 @@ int kvm_mmu_create(struct kvm_vcpu *vcpu); + void kvm_mmu_init_vm(struct kvm *kvm); + void kvm_mmu_uninit_vm(struct kvm *kvm); + ++void kvm_mmu_after_set_cpuid(struct kvm_vcpu *vcpu); + void kvm_mmu_reset_context(struct kvm_vcpu *vcpu); + void kvm_mmu_slot_remove_write_access(struct kvm *kvm, + struct kvm_memory_slot *memslot, +diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h +index 544f41a179fb6..8fc1b5003713f 100644 +--- a/arch/x86/include/asm/perf_event.h ++++ b/arch/x86/include/asm/perf_event.h +@@ -478,6 +478,7 @@ struct x86_pmu_lbr { + + extern void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap); + extern void perf_check_microcode(void); ++extern void perf_clear_dirty_counters(void); + extern int x86_perf_rdpmc_index(struct perf_event *event); + #else + static inline void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap) +diff --git a/arch/x86/include/asm/preempt.h b/arch/x86/include/asm/preempt.h +index f8cb8af4de5ce..fe5efbcba8240 100644 +--- a/arch/x86/include/asm/preempt.h ++++ b/arch/x86/include/asm/preempt.h +@@ -44,7 +44,7 @@ static __always_inline void preempt_count_set(int pc) + #define init_task_preempt_count(p) do { } while (0) + + #define init_idle_preempt_count(p, cpu) do { \ +- per_cpu(__preempt_count, (cpu)) = PREEMPT_ENABLED; \ ++ per_cpu(__preempt_count, (cpu)) = PREEMPT_DISABLED; \ + } while (0) + + /* +diff --git a/arch/x86/include/uapi/asm/hwcap2.h b/arch/x86/include/uapi/asm/hwcap2.h +index 5fdfcb47000f9..054604aba9f00 100644 +--- a/arch/x86/include/uapi/asm/hwcap2.h ++++ b/arch/x86/include/uapi/asm/hwcap2.h +@@ -2,10 +2,12 @@ + #ifndef _ASM_X86_HWCAP2_H + #define _ASM_X86_HWCAP2_H + ++#include ++ + /* MONITOR/MWAIT enabled in Ring 3 */ +-#define HWCAP2_RING3MWAIT (1 << 0) ++#define HWCAP2_RING3MWAIT _BITUL(0) + + /* Kernel allows FSGSBASE instructions available in Ring 3 */ +-#define HWCAP2_FSGSBASE BIT(1) ++#define HWCAP2_FSGSBASE _BITUL(1) + + #endif +diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c +index 22f13343b5da8..4fa0a42808951 100644 +--- a/arch/x86/kernel/cpu/mshyperv.c ++++ b/arch/x86/kernel/cpu/mshyperv.c +@@ -236,7 +236,7 @@ static void __init hv_smp_prepare_cpus(unsigned int max_cpus) + for_each_present_cpu(i) { + if (i == 0) + continue; +- ret = hv_call_add_logical_proc(numa_cpu_node(i), i, cpu_physical_id(i)); ++ ret = hv_call_add_logical_proc(numa_cpu_node(i), i, i); + BUG_ON(ret); + } + +diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c +index 6edd1e2ee8afa..058aacb423371 100644 +--- a/arch/x86/kernel/early-quirks.c ++++ b/arch/x86/kernel/early-quirks.c +@@ -549,6 +549,7 @@ static const struct pci_device_id intel_early_ids[] __initconst = { + INTEL_CNL_IDS(&gen9_early_ops), + INTEL_ICL_11_IDS(&gen11_early_ops), + INTEL_EHL_IDS(&gen11_early_ops), ++ INTEL_JSL_IDS(&gen11_early_ops), + INTEL_TGL_12_IDS(&gen11_early_ops), + INTEL_RKL_IDS(&gen11_early_ops), + INTEL_ADLS_IDS(&gen11_early_ops), +diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c +index 651b81cd648e5..d66a33d24f4f9 100644 +--- a/arch/x86/kernel/sev.c ++++ b/arch/x86/kernel/sev.c +@@ -7,12 +7,11 @@ + * Author: Joerg Roedel + */ + +-#define pr_fmt(fmt) "SEV-ES: " fmt ++#define pr_fmt(fmt) "SEV: " fmt + + #include /* For show_regs() */ + #include + #include +-#include + #include + #include + #include +@@ -192,11 +191,19 @@ void noinstr __sev_es_ist_exit(void) + this_cpu_write(cpu_tss_rw.x86_tss.ist[IST_INDEX_VC], *(unsigned long *)ist); + } + +-static __always_inline struct ghcb *sev_es_get_ghcb(struct ghcb_state *state) ++/* ++ * Nothing shall interrupt this code path while holding the per-CPU ++ * GHCB. The backup GHCB is only for NMIs interrupting this path. ++ * ++ * Callers must disable local interrupts around it. ++ */ ++static noinstr struct ghcb *__sev_get_ghcb(struct ghcb_state *state) + { + struct sev_es_runtime_data *data; + struct ghcb *ghcb; + ++ WARN_ON(!irqs_disabled()); ++ + data = this_cpu_read(runtime_data); + ghcb = &data->ghcb_page; + +@@ -213,7 +220,9 @@ static __always_inline struct ghcb *sev_es_get_ghcb(struct ghcb_state *state) + data->ghcb_active = false; + data->backup_ghcb_active = false; + ++ instrumentation_begin(); + panic("Unable to handle #VC exception! GHCB and Backup GHCB are already in use"); ++ instrumentation_end(); + } + + /* Mark backup_ghcb active before writing to it */ +@@ -479,11 +488,13 @@ static enum es_result vc_slow_virt_to_phys(struct ghcb *ghcb, struct es_em_ctxt + /* Include code shared with pre-decompression boot stage */ + #include "sev-shared.c" + +-static __always_inline void sev_es_put_ghcb(struct ghcb_state *state) ++static noinstr void __sev_put_ghcb(struct ghcb_state *state) + { + struct sev_es_runtime_data *data; + struct ghcb *ghcb; + ++ WARN_ON(!irqs_disabled()); ++ + data = this_cpu_read(runtime_data); + ghcb = &data->ghcb_page; + +@@ -507,7 +518,7 @@ void noinstr __sev_es_nmi_complete(void) + struct ghcb_state state; + struct ghcb *ghcb; + +- ghcb = sev_es_get_ghcb(&state); ++ ghcb = __sev_get_ghcb(&state); + + vc_ghcb_invalidate(ghcb); + ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_NMI_COMPLETE); +@@ -517,7 +528,7 @@ void noinstr __sev_es_nmi_complete(void) + sev_es_wr_ghcb_msr(__pa_nodebug(ghcb)); + VMGEXIT(); + +- sev_es_put_ghcb(&state); ++ __sev_put_ghcb(&state); + } + + static u64 get_jump_table_addr(void) +@@ -529,7 +540,7 @@ static u64 get_jump_table_addr(void) + + local_irq_save(flags); + +- ghcb = sev_es_get_ghcb(&state); ++ ghcb = __sev_get_ghcb(&state); + + vc_ghcb_invalidate(ghcb); + ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_AP_JUMP_TABLE); +@@ -543,7 +554,7 @@ static u64 get_jump_table_addr(void) + ghcb_sw_exit_info_2_is_valid(ghcb)) + ret = ghcb->save.sw_exit_info_2; + +- sev_es_put_ghcb(&state); ++ __sev_put_ghcb(&state); + + local_irq_restore(flags); + +@@ -668,7 +679,7 @@ static void sev_es_ap_hlt_loop(void) + struct ghcb_state state; + struct ghcb *ghcb; + +- ghcb = sev_es_get_ghcb(&state); ++ ghcb = __sev_get_ghcb(&state); + + while (true) { + vc_ghcb_invalidate(ghcb); +@@ -685,7 +696,7 @@ static void sev_es_ap_hlt_loop(void) + break; + } + +- sev_es_put_ghcb(&state); ++ __sev_put_ghcb(&state); + } + + /* +@@ -775,7 +786,7 @@ void __init sev_es_init_vc_handling(void) + sev_es_setup_play_dead(); + + /* Secondary CPUs use the runtime #VC handler */ +- initial_vc_handler = (unsigned long)safe_stack_exc_vmm_communication; ++ initial_vc_handler = (unsigned long)kernel_exc_vmm_communication; + } + + static void __init vc_early_forward_exception(struct es_em_ctxt *ctxt) +@@ -1213,14 +1224,6 @@ static enum es_result vc_handle_trap_ac(struct ghcb *ghcb, + return ES_EXCEPTION; + } + +-static __always_inline void vc_handle_trap_db(struct pt_regs *regs) +-{ +- if (user_mode(regs)) +- noist_exc_debug(regs); +- else +- exc_debug(regs); +-} +- + static enum es_result vc_handle_exitcode(struct es_em_ctxt *ctxt, + struct ghcb *ghcb, + unsigned long exit_code) +@@ -1316,44 +1319,15 @@ static __always_inline bool on_vc_fallback_stack(struct pt_regs *regs) + return (sp >= __this_cpu_ist_bottom_va(VC2) && sp < __this_cpu_ist_top_va(VC2)); + } + +-/* +- * Main #VC exception handler. It is called when the entry code was able to +- * switch off the IST to a safe kernel stack. +- * +- * With the current implementation it is always possible to switch to a safe +- * stack because #VC exceptions only happen at known places, like intercepted +- * instructions or accesses to MMIO areas/IO ports. They can also happen with +- * code instrumentation when the hypervisor intercepts #DB, but the critical +- * paths are forbidden to be instrumented, so #DB exceptions currently also +- * only happen in safe places. +- */ +-DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication) ++static bool vc_raw_handle_exception(struct pt_regs *regs, unsigned long error_code) + { +- irqentry_state_t irq_state; + struct ghcb_state state; + struct es_em_ctxt ctxt; + enum es_result result; + struct ghcb *ghcb; ++ bool ret = true; + +- /* +- * Handle #DB before calling into !noinstr code to avoid recursive #DB. +- */ +- if (error_code == SVM_EXIT_EXCP_BASE + X86_TRAP_DB) { +- vc_handle_trap_db(regs); +- return; +- } +- +- irq_state = irqentry_nmi_enter(regs); +- lockdep_assert_irqs_disabled(); +- instrumentation_begin(); +- +- /* +- * This is invoked through an interrupt gate, so IRQs are disabled. The +- * code below might walk page-tables for user or kernel addresses, so +- * keep the IRQs disabled to protect us against concurrent TLB flushes. +- */ +- +- ghcb = sev_es_get_ghcb(&state); ++ ghcb = __sev_get_ghcb(&state); + + vc_ghcb_invalidate(ghcb); + result = vc_init_em_ctxt(&ctxt, regs, error_code); +@@ -1361,7 +1335,7 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication) + if (result == ES_OK) + result = vc_handle_exitcode(&ctxt, ghcb, error_code); + +- sev_es_put_ghcb(&state); ++ __sev_put_ghcb(&state); + + /* Done - now check the result */ + switch (result) { +@@ -1371,15 +1345,18 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication) + case ES_UNSUPPORTED: + pr_err_ratelimited("Unsupported exit-code 0x%02lx in early #VC exception (IP: 0x%lx)\n", + error_code, regs->ip); +- goto fail; ++ ret = false; ++ break; + case ES_VMM_ERROR: + pr_err_ratelimited("Failure in communication with VMM (exit-code 0x%02lx IP: 0x%lx)\n", + error_code, regs->ip); +- goto fail; ++ ret = false; ++ break; + case ES_DECODE_FAILED: + pr_err_ratelimited("Failed to decode instruction (exit-code 0x%02lx IP: 0x%lx)\n", + error_code, regs->ip); +- goto fail; ++ ret = false; ++ break; + case ES_EXCEPTION: + vc_forward_exception(&ctxt); + break; +@@ -1395,24 +1372,52 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication) + BUG(); + } + +-out: +- instrumentation_end(); +- irqentry_nmi_exit(regs, irq_state); ++ return ret; ++} + +- return; ++static __always_inline bool vc_is_db(unsigned long error_code) ++{ ++ return error_code == SVM_EXIT_EXCP_BASE + X86_TRAP_DB; ++} + +-fail: +- if (user_mode(regs)) { +- /* +- * Do not kill the machine if user-space triggered the +- * exception. Send SIGBUS instead and let user-space deal with +- * it. +- */ +- force_sig_fault(SIGBUS, BUS_OBJERR, (void __user *)0); +- } else { +- pr_emerg("PANIC: Unhandled #VC exception in kernel space (result=%d)\n", +- result); ++/* ++ * Runtime #VC exception handler when raised from kernel mode. Runs in NMI mode ++ * and will panic when an error happens. ++ */ ++DEFINE_IDTENTRY_VC_KERNEL(exc_vmm_communication) ++{ ++ irqentry_state_t irq_state; + ++ /* ++ * With the current implementation it is always possible to switch to a ++ * safe stack because #VC exceptions only happen at known places, like ++ * intercepted instructions or accesses to MMIO areas/IO ports. They can ++ * also happen with code instrumentation when the hypervisor intercepts ++ * #DB, but the critical paths are forbidden to be instrumented, so #DB ++ * exceptions currently also only happen in safe places. ++ * ++ * But keep this here in case the noinstr annotations are violated due ++ * to bug elsewhere. ++ */ ++ if (unlikely(on_vc_fallback_stack(regs))) { ++ instrumentation_begin(); ++ panic("Can't handle #VC exception from unsupported context\n"); ++ instrumentation_end(); ++ } ++ ++ /* ++ * Handle #DB before calling into !noinstr code to avoid recursive #DB. ++ */ ++ if (vc_is_db(error_code)) { ++ exc_debug(regs); ++ return; ++ } ++ ++ irq_state = irqentry_nmi_enter(regs); ++ ++ instrumentation_begin(); ++ ++ if (!vc_raw_handle_exception(regs, error_code)) { + /* Show some debug info */ + show_regs(regs); + +@@ -1423,23 +1428,38 @@ fail: + panic("Returned from Terminate-Request to Hypervisor\n"); + } + +- goto out; ++ instrumentation_end(); ++ irqentry_nmi_exit(regs, irq_state); + } + +-/* This handler runs on the #VC fall-back stack. It can cause further #VC exceptions */ +-DEFINE_IDTENTRY_VC_IST(exc_vmm_communication) ++/* ++ * Runtime #VC exception handler when raised from user mode. Runs in IRQ mode ++ * and will kill the current task with SIGBUS when an error happens. ++ */ ++DEFINE_IDTENTRY_VC_USER(exc_vmm_communication) + { ++ /* ++ * Handle #DB before calling into !noinstr code to avoid recursive #DB. ++ */ ++ if (vc_is_db(error_code)) { ++ noist_exc_debug(regs); ++ return; ++ } ++ ++ irqentry_enter_from_user_mode(regs); + instrumentation_begin(); +- panic("Can't handle #VC exception from unsupported context\n"); +- instrumentation_end(); +-} + +-DEFINE_IDTENTRY_VC(exc_vmm_communication) +-{ +- if (likely(!on_vc_fallback_stack(regs))) +- safe_stack_exc_vmm_communication(regs, error_code); +- else +- ist_exc_vmm_communication(regs, error_code); ++ if (!vc_raw_handle_exception(regs, error_code)) { ++ /* ++ * Do not kill the machine if user-space triggered the ++ * exception. Send SIGBUS instead and let user-space deal with ++ * it. ++ */ ++ force_sig_fault(SIGBUS, BUS_OBJERR, (void __user *)0); ++ } ++ ++ instrumentation_end(); ++ irqentry_exit_to_user_mode(regs); + } + + bool __init handle_vc_boot_ghcb(struct pt_regs *regs) +diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c +index 7770245cc7fa7..ec2d64aa21631 100644 +--- a/arch/x86/kernel/smpboot.c ++++ b/arch/x86/kernel/smpboot.c +@@ -236,7 +236,6 @@ static void notrace start_secondary(void *unused) + cpu_init(); + rcu_cpu_starting(raw_smp_processor_id()); + x86_cpuinit.early_percpu_clock_init(); +- preempt_disable(); + smp_callin(); + + enable_start_cpu0 = 0; +diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c +index 57ec011921805..6eb1b097e97eb 100644 +--- a/arch/x86/kernel/tsc.c ++++ b/arch/x86/kernel/tsc.c +@@ -1152,7 +1152,8 @@ static struct clocksource clocksource_tsc = { + .mask = CLOCKSOURCE_MASK(64), + .flags = CLOCK_SOURCE_IS_CONTINUOUS | + CLOCK_SOURCE_VALID_FOR_HRES | +- CLOCK_SOURCE_MUST_VERIFY, ++ CLOCK_SOURCE_MUST_VERIFY | ++ CLOCK_SOURCE_VERIFY_PERCPU, + .vdso_clock_mode = VDSO_CLOCKMODE_TSC, + .enable = tsc_cs_enable, + .resume = tsc_resume, +diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c +index b4da665bb8923..c42613cfb5ba6 100644 +--- a/arch/x86/kvm/cpuid.c ++++ b/arch/x86/kvm/cpuid.c +@@ -202,10 +202,10 @@ static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) + static_call(kvm_x86_vcpu_after_set_cpuid)(vcpu); + + /* +- * Except for the MMU, which needs to be reset after any vendor +- * specific adjustments to the reserved GPA bits. ++ * Except for the MMU, which needs to do its thing any vendor specific ++ * adjustments to the reserved GPA bits. + */ +- kvm_mmu_reset_context(vcpu); ++ kvm_mmu_after_set_cpuid(vcpu); + } + + static int is_efer_nx(void) +diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c +index f00830e5202fe..fdd1eca717fd6 100644 +--- a/arch/x86/kvm/hyperv.c ++++ b/arch/x86/kvm/hyperv.c +@@ -1704,7 +1704,7 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, u64 ingpa, u16 rep_cnt, bool + * vcpu->arch.cr3 may not be up-to-date for running vCPUs so we can't + * analyze it here, flush TLB regardless of the specified address space. + */ +- kvm_make_vcpus_request_mask(kvm, KVM_REQ_HV_TLB_FLUSH, ++ kvm_make_vcpus_request_mask(kvm, KVM_REQ_TLB_FLUSH_GUEST, + NULL, vcpu_mask, &hv_vcpu->tlb_flush); + + ret_success: +diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c +index a54f72c31be90..99afc6f1eed02 100644 +--- a/arch/x86/kvm/mmu/mmu.c ++++ b/arch/x86/kvm/mmu/mmu.c +@@ -4168,7 +4168,15 @@ static inline u64 reserved_hpa_bits(void) + void + reset_shadow_zero_bits_mask(struct kvm_vcpu *vcpu, struct kvm_mmu *context) + { +- bool uses_nx = context->nx || ++ /* ++ * KVM uses NX when TDP is disabled to handle a variety of scenarios, ++ * notably for huge SPTEs if iTLB multi-hit mitigation is enabled and ++ * to generate correct permissions for CR0.WP=0/CR4.SMEP=1/EFER.NX=0. ++ * The iTLB multi-hit workaround can be toggled at any time, so assume ++ * NX can be used by any non-nested shadow MMU to avoid having to reset ++ * MMU contexts. Note, KVM forces EFER.NX=1 when TDP is disabled. ++ */ ++ bool uses_nx = context->nx || !tdp_enabled || + context->mmu_role.base.smep_andnot_wp; + struct rsvd_bits_validate *shadow_zero_check; + int i; +@@ -4851,6 +4859,18 @@ kvm_mmu_calc_root_page_role(struct kvm_vcpu *vcpu) + return role.base; + } + ++void kvm_mmu_after_set_cpuid(struct kvm_vcpu *vcpu) ++{ ++ /* ++ * Invalidate all MMU roles to force them to reinitialize as CPUID ++ * information is factored into reserved bit calculations. ++ */ ++ vcpu->arch.root_mmu.mmu_role.ext.valid = 0; ++ vcpu->arch.guest_mmu.mmu_role.ext.valid = 0; ++ vcpu->arch.nested_mmu.mmu_role.ext.valid = 0; ++ kvm_mmu_reset_context(vcpu); ++} ++ + void kvm_mmu_reset_context(struct kvm_vcpu *vcpu) + { + kvm_mmu_unload(vcpu); +diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h +index 823a5919f9fa0..52fffd68b5229 100644 +--- a/arch/x86/kvm/mmu/paging_tmpl.h ++++ b/arch/x86/kvm/mmu/paging_tmpl.h +@@ -471,8 +471,7 @@ retry_walk: + + error: + errcode |= write_fault | user_fault; +- if (fetch_fault && (mmu->nx || +- kvm_read_cr4_bits(vcpu, X86_CR4_SMEP))) ++ if (fetch_fault && (mmu->nx || mmu->mmu_role.ext.cr4_smep)) + errcode |= PFERR_FETCH_MASK; + + walker->fault.vector = PF_VECTOR; +diff --git a/arch/x86/kvm/mmu/spte.c b/arch/x86/kvm/mmu/spte.c +index 66d43cec0c31a..8e8e8da740a07 100644 +--- a/arch/x86/kvm/mmu/spte.c ++++ b/arch/x86/kvm/mmu/spte.c +@@ -102,13 +102,6 @@ int make_spte(struct kvm_vcpu *vcpu, unsigned int pte_access, int level, + else if (kvm_vcpu_ad_need_write_protect(vcpu)) + spte |= SPTE_TDP_AD_WRPROT_ONLY_MASK; + +- /* +- * Bits 62:52 of PAE SPTEs are reserved. WARN if said bits are set +- * if PAE paging may be employed (shadow paging or any 32-bit KVM). +- */ +- WARN_ON_ONCE((!tdp_enabled || !IS_ENABLED(CONFIG_X86_64)) && +- (spte & SPTE_TDP_AD_MASK)); +- + /* + * For the EPT case, shadow_present_mask is 0 if hardware + * supports exec-only page table entries. In that case, +diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c +index 237317b1eddda..8773bd5287da8 100644 +--- a/arch/x86/kvm/mmu/tdp_mmu.c ++++ b/arch/x86/kvm/mmu/tdp_mmu.c +@@ -912,7 +912,7 @@ static int tdp_mmu_map_handle_target_level(struct kvm_vcpu *vcpu, int write, + kvm_pfn_t pfn, bool prefault) + { + u64 new_spte; +- int ret = 0; ++ int ret = RET_PF_FIXED; + int make_spte_ret = 0; + + if (unlikely(is_noslot_pfn(pfn))) +@@ -949,7 +949,11 @@ static int tdp_mmu_map_handle_target_level(struct kvm_vcpu *vcpu, int write, + rcu_dereference(iter->sptep)); + } + +- if (!prefault) ++ /* ++ * Increase pf_fixed in both RET_PF_EMULATE and RET_PF_FIXED to be ++ * consistent with legacy MMU behavior. ++ */ ++ if (ret != RET_PF_SPURIOUS) + vcpu->stat.pf_fixed++; + + return ret; +diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c +index 6058a65a6ede6..2e63171864a74 100644 +--- a/arch/x86/kvm/vmx/nested.c ++++ b/arch/x86/kvm/vmx/nested.c +@@ -1127,12 +1127,19 @@ static int nested_vmx_load_cr3(struct kvm_vcpu *vcpu, unsigned long cr3, bool ne + + /* + * Unconditionally skip the TLB flush on fast CR3 switch, all TLB +- * flushes are handled by nested_vmx_transition_tlb_flush(). See +- * nested_vmx_transition_mmu_sync for details on skipping the MMU sync. ++ * flushes are handled by nested_vmx_transition_tlb_flush(). + */ +- if (!nested_ept) +- kvm_mmu_new_pgd(vcpu, cr3, true, +- !nested_vmx_transition_mmu_sync(vcpu)); ++ if (!nested_ept) { ++ kvm_mmu_new_pgd(vcpu, cr3, true, true); ++ ++ /* ++ * A TLB flush on VM-Enter/VM-Exit flushes all linear mappings ++ * across all PCIDs, i.e. all PGDs need to be synchronized. ++ * See nested_vmx_transition_mmu_sync() for more details. ++ */ ++ if (nested_vmx_transition_mmu_sync(vcpu)) ++ kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu); ++ } + + vcpu->arch.cr3 = cr3; + kvm_register_mark_available(vcpu, VCPU_EXREG_CR3); +@@ -3682,7 +3689,7 @@ void nested_mark_vmcs12_pages_dirty(struct kvm_vcpu *vcpu) + } + } + +-static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu) ++static int vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu) + { + struct vcpu_vmx *vmx = to_vmx(vcpu); + int max_irr; +@@ -3690,17 +3697,17 @@ static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu) + u16 status; + + if (!vmx->nested.pi_desc || !vmx->nested.pi_pending) +- return; ++ return 0; + + vmx->nested.pi_pending = false; + if (!pi_test_and_clear_on(vmx->nested.pi_desc)) +- return; ++ return 0; + + max_irr = find_last_bit((unsigned long *)vmx->nested.pi_desc->pir, 256); + if (max_irr != 256) { + vapic_page = vmx->nested.virtual_apic_map.hva; + if (!vapic_page) +- return; ++ return 0; + + __kvm_apic_update_irr(vmx->nested.pi_desc->pir, + vapic_page, &max_irr); +@@ -3713,6 +3720,7 @@ static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu) + } + + nested_mark_vmcs12_pages_dirty(vcpu); ++ return 0; + } + + static void nested_vmx_inject_exception_vmexit(struct kvm_vcpu *vcpu, +@@ -3887,8 +3895,7 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu) + } + + no_vmexit: +- vmx_complete_nested_posted_interrupt(vcpu); +- return 0; ++ return vmx_complete_nested_posted_interrupt(vcpu); + } + + static u32 vmx_get_preemption_timer_value(struct kvm_vcpu *vcpu) +@@ -5481,8 +5488,6 @@ static int nested_vmx_eptp_switching(struct kvm_vcpu *vcpu, + { + u32 index = kvm_rcx_read(vcpu); + u64 new_eptp; +- bool accessed_dirty; +- struct kvm_mmu *mmu = vcpu->arch.walk_mmu; + + if (!nested_cpu_has_eptp_switching(vmcs12) || + !nested_cpu_has_ept(vmcs12)) +@@ -5491,13 +5496,10 @@ static int nested_vmx_eptp_switching(struct kvm_vcpu *vcpu, + if (index >= VMFUNC_EPTP_ENTRIES) + return 1; + +- + if (kvm_vcpu_read_guest_page(vcpu, vmcs12->eptp_list_address >> PAGE_SHIFT, + &new_eptp, index * 8, 8)) + return 1; + +- accessed_dirty = !!(new_eptp & VMX_EPTP_AD_ENABLE_BIT); +- + /* + * If the (L2) guest does a vmfunc to the currently + * active ept pointer, we don't have to do anything else +@@ -5506,8 +5508,6 @@ static int nested_vmx_eptp_switching(struct kvm_vcpu *vcpu, + if (!nested_vmx_check_eptp(vcpu, new_eptp)) + return 1; + +- mmu->ept_ad = accessed_dirty; +- mmu->mmu_role.base.ad_disabled = !accessed_dirty; + vmcs12->ept_pointer = new_eptp; + + kvm_make_request(KVM_REQ_MMU_RELOAD, vcpu); +@@ -5533,7 +5533,7 @@ static int handle_vmfunc(struct kvm_vcpu *vcpu) + } + + vmcs12 = get_vmcs12(vcpu); +- if ((vmcs12->vm_function_control & (1 << function)) == 0) ++ if (!(vmcs12->vm_function_control & BIT_ULL(function))) + goto fail; + + switch (function) { +@@ -5806,6 +5806,9 @@ static bool nested_vmx_l0_wants_exit(struct kvm_vcpu *vcpu, + else if (is_breakpoint(intr_info) && + vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP) + return true; ++ else if (is_alignment_check(intr_info) && ++ !vmx_guest_inject_ac(vcpu)) ++ return true; + return false; + case EXIT_REASON_EXTERNAL_INTERRUPT: + return true; +diff --git a/arch/x86/kvm/vmx/vmcs.h b/arch/x86/kvm/vmx/vmcs.h +index 1472c6c376f74..571d9ad80a59e 100644 +--- a/arch/x86/kvm/vmx/vmcs.h ++++ b/arch/x86/kvm/vmx/vmcs.h +@@ -117,6 +117,11 @@ static inline bool is_gp_fault(u32 intr_info) + return is_exception_n(intr_info, GP_VECTOR); + } + ++static inline bool is_alignment_check(u32 intr_info) ++{ ++ return is_exception_n(intr_info, AC_VECTOR); ++} ++ + static inline bool is_machine_check(u32 intr_info) + { + return is_exception_n(intr_info, MC_VECTOR); +diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c +index c2a779b688e64..dcd4f43c23de5 100644 +--- a/arch/x86/kvm/vmx/vmx.c ++++ b/arch/x86/kvm/vmx/vmx.c +@@ -4829,7 +4829,7 @@ static int handle_machine_check(struct kvm_vcpu *vcpu) + * - Guest has #AC detection enabled in CR0 + * - Guest EFLAGS has AC bit set + */ +-static inline bool guest_inject_ac(struct kvm_vcpu *vcpu) ++bool vmx_guest_inject_ac(struct kvm_vcpu *vcpu) + { + if (!boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT)) + return true; +@@ -4937,7 +4937,7 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu) + kvm_run->debug.arch.exception = ex_no; + break; + case AC_VECTOR: +- if (guest_inject_ac(vcpu)) { ++ if (vmx_guest_inject_ac(vcpu)) { + kvm_queue_exception_e(vcpu, AC_VECTOR, error_code); + return 1; + } +diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h +index 16e4e457ba23c..d91869c8c1fc2 100644 +--- a/arch/x86/kvm/vmx/vmx.h ++++ b/arch/x86/kvm/vmx/vmx.h +@@ -387,6 +387,7 @@ void vmx_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); + void vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); + u64 construct_eptp(struct kvm_vcpu *vcpu, hpa_t root_hpa, int root_level); + ++bool vmx_guest_inject_ac(struct kvm_vcpu *vcpu); + void vmx_update_exception_bitmap(struct kvm_vcpu *vcpu); + void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu); + bool vmx_nmi_blocked(struct kvm_vcpu *vcpu); +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index e0f4a46649d75..dad282fe0dac2 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -9171,7 +9171,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) + } + if (kvm_check_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu)) + kvm_vcpu_flush_tlb_current(vcpu); +- if (kvm_check_request(KVM_REQ_HV_TLB_FLUSH, vcpu)) ++ if (kvm_check_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu)) + kvm_vcpu_flush_tlb_guest(vcpu); + + if (kvm_check_request(KVM_REQ_REPORT_TPR_ACCESS, vcpu)) { +@@ -10454,6 +10454,8 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) + + void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) + { ++ unsigned long old_cr0 = kvm_read_cr0(vcpu); ++ + kvm_lapic_reset(vcpu, init_event); + + vcpu->arch.hflags = 0; +@@ -10522,6 +10524,17 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) + vcpu->arch.ia32_xss = 0; + + static_call(kvm_x86_vcpu_reset)(vcpu, init_event); ++ ++ /* ++ * Reset the MMU context if paging was enabled prior to INIT (which is ++ * implied if CR0.PG=1 as CR0 will be '0' prior to RESET). Unlike the ++ * standard CR0/CR4/EFER modification paths, only CR0.PG needs to be ++ * checked because it is unconditionally cleared on INIT and all other ++ * paging related bits are ignored if paging is disabled, i.e. CR0.WP, ++ * CR4, and EFER changes are all irrelevant if CR0.PG was '0'. ++ */ ++ if (old_cr0 & X86_CR0_PG) ++ kvm_mmu_reset_context(vcpu); + } + + void kvm_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector) +diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c +index 78804680e9231..cfe6b1e85fa61 100644 +--- a/arch/x86/mm/tlb.c ++++ b/arch/x86/mm/tlb.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + + #include "mm_internal.h" + +@@ -404,9 +405,14 @@ static inline void cr4_update_pce_mm(struct mm_struct *mm) + { + if (static_branch_unlikely(&rdpmc_always_available_key) || + (!static_branch_unlikely(&rdpmc_never_available_key) && +- atomic_read(&mm->context.perf_rdpmc_allowed))) ++ atomic_read(&mm->context.perf_rdpmc_allowed))) { ++ /* ++ * Clear the existing dirty counters to ++ * prevent the leak for an RDPMC task. ++ */ ++ perf_clear_dirty_counters(); + cr4_set_bits_irqsoff(X86_CR4_PCE); +- else ++ } else + cr4_clear_bits_irqsoff(X86_CR4_PCE); + } + +diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c +index 2a2e290fa5d83..a3d867f221531 100644 +--- a/arch/x86/net/bpf_jit_comp.c ++++ b/arch/x86/net/bpf_jit_comp.c +@@ -1297,7 +1297,7 @@ st: if (is_imm8(insn->off)) + emit_ldx(&prog, BPF_SIZE(insn->code), dst_reg, src_reg, insn->off); + if (BPF_MODE(insn->code) == BPF_PROBE_MEM) { + struct exception_table_entry *ex; +- u8 *_insn = image + proglen; ++ u8 *_insn = image + proglen + (start_of_ldx - temp); + s64 delta; + + /* populate jmp_offset for JMP above */ +diff --git a/arch/xtensa/kernel/smp.c b/arch/xtensa/kernel/smp.c +index cd85a7a2722ba..1254da07ead1f 100644 +--- a/arch/xtensa/kernel/smp.c ++++ b/arch/xtensa/kernel/smp.c +@@ -145,7 +145,6 @@ void secondary_start_kernel(void) + cpumask_set_cpu(cpu, mm_cpumask(mm)); + enter_lazy_tlb(mm, current); + +- preempt_disable(); + trace_hardirqs_off(); + + calibrate_delay(); +diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c +index acd1f881273e0..eccbe2aed7c3f 100644 +--- a/block/bfq-iosched.c ++++ b/block/bfq-iosched.c +@@ -2695,9 +2695,15 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq, + * costly and complicated. + */ + if (unlikely(!bfqd->nonrot_with_queueing)) { +- if (bic->stable_merge_bfqq && ++ /* ++ * Make sure also that bfqq is sync, because ++ * bic->stable_merge_bfqq may point to some queue (for ++ * stable merging) also if bic is associated with a ++ * sync queue, but this bfqq is async ++ */ ++ if (bfq_bfqq_sync(bfqq) && bic->stable_merge_bfqq && + !bfq_bfqq_just_created(bfqq) && +- time_is_after_jiffies(bfqq->split_time + ++ time_is_before_jiffies(bfqq->split_time + + msecs_to_jiffies(200))) { + struct bfq_queue *stable_merge_bfqq = + bic->stable_merge_bfqq; +@@ -6129,11 +6135,13 @@ static void bfq_completed_request(struct bfq_queue *bfqq, struct bfq_data *bfqd) + * of other queues. But a false waker will unjustly steal + * bandwidth to its supposedly woken queue. So considering + * also shared queues in the waking mechanism may cause more +- * control troubles than throughput benefits. Then do not set +- * last_completed_rq_bfqq to bfqq if bfqq is a shared queue. ++ * control troubles than throughput benefits. Then reset ++ * last_completed_rq_bfqq if bfqq is a shared queue. + */ + if (!bfq_bfqq_coop(bfqq)) + bfqd->last_completed_rq_bfqq = bfqq; ++ else ++ bfqd->last_completed_rq_bfqq = NULL; + + /* + * If we are waiting to discover whether the request pattern +diff --git a/block/bio.c b/block/bio.c +index 44205dfb6b60a..1fab762e079be 100644 +--- a/block/bio.c ++++ b/block/bio.c +@@ -1375,8 +1375,7 @@ static inline bool bio_remaining_done(struct bio *bio) + * + * bio_endio() can be called several times on a bio that has been chained + * using bio_chain(). The ->bi_end_io() function will only be called the +- * last time. At this point the BLK_TA_COMPLETE tracing event will be +- * generated if BIO_TRACE_COMPLETION is set. ++ * last time. + **/ + void bio_endio(struct bio *bio) + { +@@ -1389,6 +1388,11 @@ again: + if (bio->bi_bdev) + rq_qos_done_bio(bio->bi_bdev->bd_disk->queue, bio); + ++ if (bio->bi_bdev && bio_flagged(bio, BIO_TRACE_COMPLETION)) { ++ trace_block_bio_complete(bio->bi_bdev->bd_disk->queue, bio); ++ bio_clear_flag(bio, BIO_TRACE_COMPLETION); ++ } ++ + /* + * Need to have a real endio function for chained bios, otherwise + * various corner cases will break (like stacking block devices that +@@ -1402,11 +1406,6 @@ again: + goto again; + } + +- if (bio->bi_bdev && bio_flagged(bio, BIO_TRACE_COMPLETION)) { +- trace_block_bio_complete(bio->bi_bdev->bd_disk->queue, bio); +- bio_clear_flag(bio, BIO_TRACE_COMPLETION); +- } +- + blk_throtl_bio_endio(bio); + /* release cgroup info */ + bio_uninit(bio); +diff --git a/block/blk-flush.c b/block/blk-flush.c +index 7942ca6ed3211..1002f6c581816 100644 +--- a/block/blk-flush.c ++++ b/block/blk-flush.c +@@ -219,8 +219,6 @@ static void flush_end_io(struct request *flush_rq, blk_status_t error) + unsigned long flags = 0; + struct blk_flush_queue *fq = blk_get_flush_queue(q, flush_rq->mq_ctx); + +- blk_account_io_flush(flush_rq); +- + /* release the tag's ownership to the req cloned from */ + spin_lock_irqsave(&fq->mq_flush_lock, flags); + +@@ -230,6 +228,7 @@ static void flush_end_io(struct request *flush_rq, blk_status_t error) + return; + } + ++ blk_account_io_flush(flush_rq); + /* + * Flush request has to be marked as IDLE when it is really ended + * because its .end_io() is called from timeout code path too for +diff --git a/block/blk-merge.c b/block/blk-merge.c +index 4d97fb6dd2267..bcdff1879c346 100644 +--- a/block/blk-merge.c ++++ b/block/blk-merge.c +@@ -559,10 +559,14 @@ static inline unsigned int blk_rq_get_max_segments(struct request *rq) + static inline int ll_new_hw_segment(struct request *req, struct bio *bio, + unsigned int nr_phys_segs) + { +- if (req->nr_phys_segments + nr_phys_segs > blk_rq_get_max_segments(req)) ++ if (blk_integrity_merge_bio(req->q, req, bio) == false) + goto no_merge; + +- if (blk_integrity_merge_bio(req->q, req, bio) == false) ++ /* discard request merge won't add new segment */ ++ if (req_op(req) == REQ_OP_DISCARD) ++ return 1; ++ ++ if (req->nr_phys_segments + nr_phys_segs > blk_rq_get_max_segments(req)) + goto no_merge; + + /* +diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c +index 2a37731e8244b..1671dae43030b 100644 +--- a/block/blk-mq-tag.c ++++ b/block/blk-mq-tag.c +@@ -199,6 +199,20 @@ struct bt_iter_data { + bool reserved; + }; + ++static struct request *blk_mq_find_and_get_req(struct blk_mq_tags *tags, ++ unsigned int bitnr) ++{ ++ struct request *rq; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&tags->lock, flags); ++ rq = tags->rqs[bitnr]; ++ if (!rq || !refcount_inc_not_zero(&rq->ref)) ++ rq = NULL; ++ spin_unlock_irqrestore(&tags->lock, flags); ++ return rq; ++} ++ + static bool bt_iter(struct sbitmap *bitmap, unsigned int bitnr, void *data) + { + struct bt_iter_data *iter_data = data; +@@ -206,18 +220,22 @@ static bool bt_iter(struct sbitmap *bitmap, unsigned int bitnr, void *data) + struct blk_mq_tags *tags = hctx->tags; + bool reserved = iter_data->reserved; + struct request *rq; ++ bool ret = true; + + if (!reserved) + bitnr += tags->nr_reserved_tags; +- rq = tags->rqs[bitnr]; +- + /* + * We can hit rq == NULL here, because the tagging functions + * test and set the bit before assigning ->rqs[]. + */ +- if (rq && rq->q == hctx->queue && rq->mq_hctx == hctx) +- return iter_data->fn(hctx, rq, iter_data->data, reserved); +- return true; ++ rq = blk_mq_find_and_get_req(tags, bitnr); ++ if (!rq) ++ return true; ++ ++ if (rq->q == hctx->queue && rq->mq_hctx == hctx) ++ ret = iter_data->fn(hctx, rq, iter_data->data, reserved); ++ blk_mq_put_rq_ref(rq); ++ return ret; + } + + /** +@@ -264,6 +282,8 @@ static bool bt_tags_iter(struct sbitmap *bitmap, unsigned int bitnr, void *data) + struct blk_mq_tags *tags = iter_data->tags; + bool reserved = iter_data->flags & BT_TAG_ITER_RESERVED; + struct request *rq; ++ bool ret = true; ++ bool iter_static_rqs = !!(iter_data->flags & BT_TAG_ITER_STATIC_RQS); + + if (!reserved) + bitnr += tags->nr_reserved_tags; +@@ -272,16 +292,19 @@ static bool bt_tags_iter(struct sbitmap *bitmap, unsigned int bitnr, void *data) + * We can hit rq == NULL here, because the tagging functions + * test and set the bit before assigning ->rqs[]. + */ +- if (iter_data->flags & BT_TAG_ITER_STATIC_RQS) ++ if (iter_static_rqs) + rq = tags->static_rqs[bitnr]; + else +- rq = tags->rqs[bitnr]; ++ rq = blk_mq_find_and_get_req(tags, bitnr); + if (!rq) + return true; +- if ((iter_data->flags & BT_TAG_ITER_STARTED) && +- !blk_mq_request_started(rq)) +- return true; +- return iter_data->fn(rq, iter_data->data, reserved); ++ ++ if (!(iter_data->flags & BT_TAG_ITER_STARTED) || ++ blk_mq_request_started(rq)) ++ ret = iter_data->fn(rq, iter_data->data, reserved); ++ if (!iter_static_rqs) ++ blk_mq_put_rq_ref(rq); ++ return ret; + } + + /** +@@ -348,6 +371,9 @@ void blk_mq_all_tag_iter(struct blk_mq_tags *tags, busy_tag_iter_fn *fn, + * indicates whether or not @rq is a reserved request. Return + * true to continue iterating tags, false to stop. + * @priv: Will be passed as second argument to @fn. ++ * ++ * We grab one request reference before calling @fn and release it after ++ * @fn returns. + */ + void blk_mq_tagset_busy_iter(struct blk_mq_tag_set *tagset, + busy_tag_iter_fn *fn, void *priv) +@@ -516,6 +542,7 @@ struct blk_mq_tags *blk_mq_init_tags(unsigned int total_tags, + + tags->nr_tags = total_tags; + tags->nr_reserved_tags = reserved_tags; ++ spin_lock_init(&tags->lock); + + if (blk_mq_is_sbitmap_shared(flags)) + return tags; +diff --git a/block/blk-mq-tag.h b/block/blk-mq-tag.h +index 7d3e6b333a4a9..f887988e5ef60 100644 +--- a/block/blk-mq-tag.h ++++ b/block/blk-mq-tag.h +@@ -20,6 +20,12 @@ struct blk_mq_tags { + struct request **rqs; + struct request **static_rqs; + struct list_head page_list; ++ ++ /* ++ * used to clear request reference in rqs[] before freeing one ++ * request pool ++ */ ++ spinlock_t lock; + }; + + extern struct blk_mq_tags *blk_mq_init_tags(unsigned int nr_tags, +diff --git a/block/blk-mq.c b/block/blk-mq.c +index c86c01bfecdbe..c732aa581124f 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -909,6 +909,14 @@ static bool blk_mq_req_expired(struct request *rq, unsigned long *next) + return false; + } + ++void blk_mq_put_rq_ref(struct request *rq) ++{ ++ if (is_flush_rq(rq, rq->mq_hctx)) ++ rq->end_io(rq, 0); ++ else if (refcount_dec_and_test(&rq->ref)) ++ __blk_mq_free_request(rq); ++} ++ + static bool blk_mq_check_expired(struct blk_mq_hw_ctx *hctx, + struct request *rq, void *priv, bool reserved) + { +@@ -942,11 +950,7 @@ static bool blk_mq_check_expired(struct blk_mq_hw_ctx *hctx, + if (blk_mq_req_expired(rq, next)) + blk_mq_rq_timed_out(rq, reserved); + +- if (is_flush_rq(rq, hctx)) +- rq->end_io(rq, 0); +- else if (refcount_dec_and_test(&rq->ref)) +- __blk_mq_free_request(rq); +- ++ blk_mq_put_rq_ref(rq); + return true; + } + +@@ -1220,9 +1224,6 @@ static void blk_mq_update_dispatch_busy(struct blk_mq_hw_ctx *hctx, bool busy) + { + unsigned int ewma; + +- if (hctx->queue->elevator) +- return; +- + ewma = hctx->dispatch_busy; + + if (!ewma && !busy) +@@ -2303,6 +2304,45 @@ queue_exit: + return BLK_QC_T_NONE; + } + ++static size_t order_to_size(unsigned int order) ++{ ++ return (size_t)PAGE_SIZE << order; ++} ++ ++/* called before freeing request pool in @tags */ ++static void blk_mq_clear_rq_mapping(struct blk_mq_tag_set *set, ++ struct blk_mq_tags *tags, unsigned int hctx_idx) ++{ ++ struct blk_mq_tags *drv_tags = set->tags[hctx_idx]; ++ struct page *page; ++ unsigned long flags; ++ ++ list_for_each_entry(page, &tags->page_list, lru) { ++ unsigned long start = (unsigned long)page_address(page); ++ unsigned long end = start + order_to_size(page->private); ++ int i; ++ ++ for (i = 0; i < set->queue_depth; i++) { ++ struct request *rq = drv_tags->rqs[i]; ++ unsigned long rq_addr = (unsigned long)rq; ++ ++ if (rq_addr >= start && rq_addr < end) { ++ WARN_ON_ONCE(refcount_read(&rq->ref) != 0); ++ cmpxchg(&drv_tags->rqs[i], rq, NULL); ++ } ++ } ++ } ++ ++ /* ++ * Wait until all pending iteration is done. ++ * ++ * Request reference is cleared and it is guaranteed to be observed ++ * after the ->lock is released. ++ */ ++ spin_lock_irqsave(&drv_tags->lock, flags); ++ spin_unlock_irqrestore(&drv_tags->lock, flags); ++} ++ + void blk_mq_free_rqs(struct blk_mq_tag_set *set, struct blk_mq_tags *tags, + unsigned int hctx_idx) + { +@@ -2321,6 +2361,8 @@ void blk_mq_free_rqs(struct blk_mq_tag_set *set, struct blk_mq_tags *tags, + } + } + ++ blk_mq_clear_rq_mapping(set, tags, hctx_idx); ++ + while (!list_empty(&tags->page_list)) { + page = list_first_entry(&tags->page_list, struct page, lru); + list_del_init(&page->lru); +@@ -2380,11 +2422,6 @@ struct blk_mq_tags *blk_mq_alloc_rq_map(struct blk_mq_tag_set *set, + return tags; + } + +-static size_t order_to_size(unsigned int order) +-{ +- return (size_t)PAGE_SIZE << order; +-} +- + static int blk_mq_init_request(struct blk_mq_tag_set *set, struct request *rq, + unsigned int hctx_idx, int node) + { +diff --git a/block/blk-mq.h b/block/blk-mq.h +index 9ce64bc4a6c8f..556368d2c5b69 100644 +--- a/block/blk-mq.h ++++ b/block/blk-mq.h +@@ -47,6 +47,7 @@ void blk_mq_add_to_requeue_list(struct request *rq, bool at_head, + void blk_mq_flush_busy_ctxs(struct blk_mq_hw_ctx *hctx, struct list_head *list); + struct request *blk_mq_dequeue_from_ctx(struct blk_mq_hw_ctx *hctx, + struct blk_mq_ctx *start); ++void blk_mq_put_rq_ref(struct request *rq); + + /* + * Internal helpers for allocating/freeing the request map +diff --git a/block/blk-rq-qos.h b/block/blk-rq-qos.h +index 2bc43e94f4c40..2bcb3495e376b 100644 +--- a/block/blk-rq-qos.h ++++ b/block/blk-rq-qos.h +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + + #include "blk-mq-debugfs.h" + +@@ -99,8 +100,21 @@ static inline void rq_wait_init(struct rq_wait *rq_wait) + + static inline void rq_qos_add(struct request_queue *q, struct rq_qos *rqos) + { ++ /* ++ * No IO can be in-flight when adding rqos, so freeze queue, which ++ * is fine since we only support rq_qos for blk-mq queue. ++ * ++ * Reuse ->queue_lock for protecting against other concurrent ++ * rq_qos adding/deleting ++ */ ++ blk_mq_freeze_queue(q); ++ ++ spin_lock_irq(&q->queue_lock); + rqos->next = q->rq_qos; + q->rq_qos = rqos; ++ spin_unlock_irq(&q->queue_lock); ++ ++ blk_mq_unfreeze_queue(q); + + if (rqos->ops->debugfs_attrs) + blk_mq_debugfs_register_rqos(rqos); +@@ -110,12 +124,22 @@ static inline void rq_qos_del(struct request_queue *q, struct rq_qos *rqos) + { + struct rq_qos **cur; + ++ /* ++ * See comment in rq_qos_add() about freezing queue & using ++ * ->queue_lock. ++ */ ++ blk_mq_freeze_queue(q); ++ ++ spin_lock_irq(&q->queue_lock); + for (cur = &q->rq_qos; *cur; cur = &(*cur)->next) { + if (*cur == rqos) { + *cur = rqos->next; + break; + } + } ++ spin_unlock_irq(&q->queue_lock); ++ ++ blk_mq_unfreeze_queue(q); + + blk_mq_debugfs_unregister_rqos(rqos); + } +diff --git a/block/blk-wbt.c b/block/blk-wbt.c +index 42aed0160f86a..f5e5ac915bf7c 100644 +--- a/block/blk-wbt.c ++++ b/block/blk-wbt.c +@@ -77,7 +77,8 @@ enum { + + static inline bool rwb_enabled(struct rq_wb *rwb) + { +- return rwb && rwb->wb_normal != 0; ++ return rwb && rwb->enable_state != WBT_STATE_OFF_DEFAULT && ++ rwb->wb_normal != 0; + } + + static void wb_timestamp(struct rq_wb *rwb, unsigned long *var) +@@ -636,9 +637,13 @@ void wbt_set_write_cache(struct request_queue *q, bool write_cache_on) + void wbt_enable_default(struct request_queue *q) + { + struct rq_qos *rqos = wbt_rq_qos(q); ++ + /* Throttling already enabled? */ +- if (rqos) ++ if (rqos) { ++ if (RQWB(rqos)->enable_state == WBT_STATE_OFF_DEFAULT) ++ RQWB(rqos)->enable_state = WBT_STATE_ON_DEFAULT; + return; ++ } + + /* Queue not registered? Maybe shutting down... */ + if (!blk_queue_registered(q)) +@@ -702,7 +707,7 @@ void wbt_disable_default(struct request_queue *q) + rwb = RQWB(rqos); + if (rwb->enable_state == WBT_STATE_ON_DEFAULT) { + blk_stat_deactivate(rwb->cb); +- rwb->wb_normal = 0; ++ rwb->enable_state = WBT_STATE_OFF_DEFAULT; + } + } + EXPORT_SYMBOL_GPL(wbt_disable_default); +diff --git a/block/blk-wbt.h b/block/blk-wbt.h +index 16bdc85b8df92..2eb01becde8c4 100644 +--- a/block/blk-wbt.h ++++ b/block/blk-wbt.h +@@ -34,6 +34,7 @@ enum { + enum { + WBT_STATE_ON_DEFAULT = 1, + WBT_STATE_ON_MANUAL = 2, ++ WBT_STATE_OFF_DEFAULT + }; + + struct rq_wb { +diff --git a/crypto/ecdh.c b/crypto/ecdh.c +index 04a427b8c9564..e2c4808590244 100644 +--- a/crypto/ecdh.c ++++ b/crypto/ecdh.c +@@ -179,10 +179,20 @@ static int ecdh_init(void) + { + int ret; + ++ /* NIST p192 will fail to register in FIPS mode */ + ret = crypto_register_kpp(&ecdh_nist_p192); + ecdh_nist_p192_registered = ret == 0; + +- return crypto_register_kpp(&ecdh_nist_p256); ++ ret = crypto_register_kpp(&ecdh_nist_p256); ++ if (ret) ++ goto nist_p256_error; ++ ++ return 0; ++ ++nist_p256_error: ++ if (ecdh_nist_p192_registered) ++ crypto_unregister_kpp(&ecdh_nist_p192); ++ return ret; + } + + static void ecdh_exit(void) +diff --git a/crypto/shash.c b/crypto/shash.c +index 2e3433ad97629..0a0a50cb694f0 100644 +--- a/crypto/shash.c ++++ b/crypto/shash.c +@@ -20,12 +20,24 @@ + + static const struct crypto_type crypto_shash_type; + +-int shash_no_setkey(struct crypto_shash *tfm, const u8 *key, +- unsigned int keylen) ++static int shash_no_setkey(struct crypto_shash *tfm, const u8 *key, ++ unsigned int keylen) + { + return -ENOSYS; + } +-EXPORT_SYMBOL_GPL(shash_no_setkey); ++ ++/* ++ * Check whether an shash algorithm has a setkey function. ++ * ++ * For CFI compatibility, this must not be an inline function. This is because ++ * when CFI is enabled, modules won't get the same address for shash_no_setkey ++ * (if it were exported, which inlining would require) as the core kernel will. ++ */ ++bool crypto_shash_alg_has_setkey(struct shash_alg *alg) ++{ ++ return alg->setkey != shash_no_setkey; ++} ++EXPORT_SYMBOL_GPL(crypto_shash_alg_has_setkey); + + static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key, + unsigned int keylen) +diff --git a/crypto/sm2.c b/crypto/sm2.c +index b21addc3ac06a..db8a4a265669d 100644 +--- a/crypto/sm2.c ++++ b/crypto/sm2.c +@@ -79,10 +79,17 @@ static int sm2_ec_ctx_init(struct mpi_ec_ctx *ec) + goto free; + + rc = -ENOMEM; ++ ++ ec->Q = mpi_point_new(0); ++ if (!ec->Q) ++ goto free; ++ + /* mpi_ec_setup_elliptic_curve */ + ec->G = mpi_point_new(0); +- if (!ec->G) ++ if (!ec->G) { ++ mpi_point_release(ec->Q); + goto free; ++ } + + mpi_set(ec->G->x, x); + mpi_set(ec->G->y, y); +@@ -91,6 +98,7 @@ static int sm2_ec_ctx_init(struct mpi_ec_ctx *ec) + rc = -EINVAL; + ec->n = mpi_scanval(ecp->n); + if (!ec->n) { ++ mpi_point_release(ec->Q); + mpi_point_release(ec->G); + goto free; + } +@@ -386,27 +394,15 @@ static int sm2_set_pub_key(struct crypto_akcipher *tfm, + MPI a; + int rc; + +- ec->Q = mpi_point_new(0); +- if (!ec->Q) +- return -ENOMEM; +- + /* include the uncompressed flag '0x04' */ +- rc = -ENOMEM; + a = mpi_read_raw_data(key, keylen); + if (!a) +- goto error; ++ return -ENOMEM; + + mpi_normalize(a); + rc = sm2_ecc_os2ec(ec->Q, a); + mpi_free(a); +- if (rc) +- goto error; +- +- return 0; + +-error: +- mpi_point_release(ec->Q); +- ec->Q = NULL; + return rc; + } + +diff --git a/crypto/testmgr.c b/crypto/testmgr.c +index 10c5b3b01ec47..26e40dba9ad29 100644 +--- a/crypto/testmgr.c ++++ b/crypto/testmgr.c +@@ -4899,15 +4899,12 @@ static const struct alg_test_desc alg_test_descs[] = { + } + }, { + #endif +-#ifndef CONFIG_CRYPTO_FIPS + .alg = "ecdh-nist-p192", + .test = alg_test_kpp, +- .fips_allowed = 1, + .suite = { + .kpp = __VECS(ecdh_p192_tv_template) + } + }, { +-#endif + .alg = "ecdh-nist-p256", + .test = alg_test_kpp, + .fips_allowed = 1, +diff --git a/crypto/testmgr.h b/crypto/testmgr.h +index 34e4a3db39917..b9cf5b815532a 100644 +--- a/crypto/testmgr.h ++++ b/crypto/testmgr.h +@@ -2685,7 +2685,6 @@ static const struct kpp_testvec curve25519_tv_template[] = { + } + }; + +-#ifndef CONFIG_CRYPTO_FIPS + static const struct kpp_testvec ecdh_p192_tv_template[] = { + { + .secret = +@@ -2719,13 +2718,12 @@ static const struct kpp_testvec ecdh_p192_tv_template[] = { + "\xf4\x57\xcc\x4f\x1f\x4e\x31\xcc" + "\xe3\x40\x60\xc8\x06\x93\xc6\x2e" + "\x99\x80\x81\x28\xaf\xc5\x51\x74", +- .secret_size = 32, ++ .secret_size = 30, + .b_public_size = 48, + .expected_a_public_size = 48, + .expected_ss_size = 24 + } + }; +-#endif + + static const struct kpp_testvec ecdh_p256_tv_template[] = { + { +@@ -2766,7 +2764,7 @@ static const struct kpp_testvec ecdh_p256_tv_template[] = { + "\x9f\x4a\x38\xcc\xc0\x2c\x49\x2f" + "\xb1\x32\xbb\xaf\x22\x61\xda\xcb" + "\x6f\xdb\xa9\xaa\xfc\x77\x81\xf3", +- .secret_size = 40, ++ .secret_size = 38, + .b_public_size = 64, + .expected_a_public_size = 64, + .expected_ss_size = 32 +@@ -2804,8 +2802,8 @@ static const struct kpp_testvec ecdh_p256_tv_template[] = { + "\x37\x08\xcc\x40\x5e\x7a\xfd\x6a" + "\x6a\x02\x6e\x41\x87\x68\x38\x77" + "\xfa\xa9\x44\x43\x2d\xef\x09\xdf", +- .secret_size = 8, +- .b_secret_size = 40, ++ .secret_size = 6, ++ .b_secret_size = 38, + .b_public_size = 64, + .expected_a_public_size = 64, + .expected_ss_size = 32, +diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile +index 700b41adf2db6..9aa82d5272720 100644 +--- a/drivers/acpi/Makefile ++++ b/drivers/acpi/Makefile +@@ -8,6 +8,11 @@ ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT + # + # ACPI Boot-Time Table Parsing + # ++ifeq ($(CONFIG_ACPI_CUSTOM_DSDT),y) ++tables.o: $(src)/../../include/$(subst $\",,$(CONFIG_ACPI_CUSTOM_DSDT_FILE)) ; ++ ++endif ++ + obj-$(CONFIG_ACPI) += tables.o + obj-$(CONFIG_X86) += blacklist.o + +diff --git a/drivers/acpi/acpi_fpdt.c b/drivers/acpi/acpi_fpdt.c +index a89a806a7a2a9..4ee2ad234e3d6 100644 +--- a/drivers/acpi/acpi_fpdt.c ++++ b/drivers/acpi/acpi_fpdt.c +@@ -240,8 +240,10 @@ static int __init acpi_init_fpdt(void) + return 0; + + fpdt_kobj = kobject_create_and_add("fpdt", acpi_kobj); +- if (!fpdt_kobj) ++ if (!fpdt_kobj) { ++ acpi_put_table(header); + return -ENOMEM; ++ } + + while (offset < header->length) { + subtable = (void *)header + offset; +diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c +index 14b71b41e8453..38e10ab976e67 100644 +--- a/drivers/acpi/acpica/nsrepair2.c ++++ b/drivers/acpi/acpica/nsrepair2.c +@@ -379,6 +379,13 @@ acpi_ns_repair_CID(struct acpi_evaluate_info *info, + + (*element_ptr)->common.reference_count = + original_ref_count; ++ ++ /* ++ * The original_element holds a reference from the package object ++ * that represents _HID. Since a new element was created by _HID, ++ * remove the reference from the _CID package. ++ */ ++ acpi_ut_remove_reference(original_element); + } + + element_ptr++; +diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c +index fce7ade2aba92..0c8330ed1ffd5 100644 +--- a/drivers/acpi/apei/ghes.c ++++ b/drivers/acpi/apei/ghes.c +@@ -441,28 +441,35 @@ static void ghes_kick_task_work(struct callback_head *head) + gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node, node_len); + } + +-static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, +- int sev) ++static bool ghes_do_memory_failure(u64 physical_addr, int flags) + { + unsigned long pfn; +- int flags = -1; +- int sec_sev = ghes_severity(gdata->error_severity); +- struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata); + + if (!IS_ENABLED(CONFIG_ACPI_APEI_MEMORY_FAILURE)) + return false; + +- if (!(mem_err->validation_bits & CPER_MEM_VALID_PA)) +- return false; +- +- pfn = mem_err->physical_addr >> PAGE_SHIFT; ++ pfn = PHYS_PFN(physical_addr); + if (!pfn_valid(pfn)) { + pr_warn_ratelimited(FW_WARN GHES_PFX + "Invalid address in generic error data: %#llx\n", +- mem_err->physical_addr); ++ physical_addr); + return false; + } + ++ memory_failure_queue(pfn, flags); ++ return true; ++} ++ ++static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, ++ int sev) ++{ ++ int flags = -1; ++ int sec_sev = ghes_severity(gdata->error_severity); ++ struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata); ++ ++ if (!(mem_err->validation_bits & CPER_MEM_VALID_PA)) ++ return false; ++ + /* iff following two events can be handled properly by now */ + if (sec_sev == GHES_SEV_CORRECTED && + (gdata->flags & CPER_SEC_ERROR_THRESHOLD_EXCEEDED)) +@@ -470,14 +477,56 @@ static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, + if (sev == GHES_SEV_RECOVERABLE && sec_sev == GHES_SEV_RECOVERABLE) + flags = 0; + +- if (flags != -1) { +- memory_failure_queue(pfn, flags); +- return true; +- } ++ if (flags != -1) ++ return ghes_do_memory_failure(mem_err->physical_addr, flags); + + return false; + } + ++static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, int sev) ++{ ++ struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata); ++ bool queued = false; ++ int sec_sev, i; ++ char *p; ++ ++ log_arm_hw_error(err); ++ ++ sec_sev = ghes_severity(gdata->error_severity); ++ if (sev != GHES_SEV_RECOVERABLE || sec_sev != GHES_SEV_RECOVERABLE) ++ return false; ++ ++ p = (char *)(err + 1); ++ for (i = 0; i < err->err_info_num; i++) { ++ struct cper_arm_err_info *err_info = (struct cper_arm_err_info *)p; ++ bool is_cache = (err_info->type == CPER_ARM_CACHE_ERROR); ++ bool has_pa = (err_info->validation_bits & CPER_ARM_INFO_VALID_PHYSICAL_ADDR); ++ const char *error_type = "unknown error"; ++ ++ /* ++ * The field (err_info->error_info & BIT(26)) is fixed to set to ++ * 1 in some old firmware of HiSilicon Kunpeng920. We assume that ++ * firmware won't mix corrected errors in an uncorrected section, ++ * and don't filter out 'corrected' error here. ++ */ ++ if (is_cache && has_pa) { ++ queued = ghes_do_memory_failure(err_info->physical_fault_addr, 0); ++ p += err_info->length; ++ continue; ++ } ++ ++ if (err_info->type < ARRAY_SIZE(cper_proc_error_type_strs)) ++ error_type = cper_proc_error_type_strs[err_info->type]; ++ ++ pr_warn_ratelimited(FW_WARN GHES_PFX ++ "Unhandled processor error type: %s\n", ++ error_type); ++ p += err_info->length; ++ } ++ ++ return queued; ++} ++ + /* + * PCIe AER errors need to be sent to the AER driver for reporting and + * recovery. The GHES severities map to the following AER severities and +@@ -605,9 +654,7 @@ static bool ghes_do_proc(struct ghes *ghes, + ghes_handle_aer(gdata); + } + else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) { +- struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata); +- +- log_arm_hw_error(err); ++ queued = ghes_handle_arm_hw_error(gdata, sev); + } else { + void *err = acpi_hest_get_payload(gdata); + +diff --git a/drivers/acpi/bgrt.c b/drivers/acpi/bgrt.c +index 19bb7f870204c..e0d14017706ea 100644 +--- a/drivers/acpi/bgrt.c ++++ b/drivers/acpi/bgrt.c +@@ -15,40 +15,19 @@ + static void *bgrt_image; + static struct kobject *bgrt_kobj; + +-static ssize_t version_show(struct device *dev, +- struct device_attribute *attr, char *buf) +-{ +- return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.version); +-} +-static DEVICE_ATTR_RO(version); +- +-static ssize_t status_show(struct device *dev, +- struct device_attribute *attr, char *buf) +-{ +- return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.status); +-} +-static DEVICE_ATTR_RO(status); +- +-static ssize_t type_show(struct device *dev, +- struct device_attribute *attr, char *buf) +-{ +- return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_type); +-} +-static DEVICE_ATTR_RO(type); +- +-static ssize_t xoffset_show(struct device *dev, +- struct device_attribute *attr, char *buf) +-{ +- return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_offset_x); +-} +-static DEVICE_ATTR_RO(xoffset); +- +-static ssize_t yoffset_show(struct device *dev, +- struct device_attribute *attr, char *buf) +-{ +- return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_offset_y); +-} +-static DEVICE_ATTR_RO(yoffset); ++#define BGRT_SHOW(_name, _member) \ ++ static ssize_t _name##_show(struct kobject *kobj, \ ++ struct kobj_attribute *attr, char *buf) \ ++ { \ ++ return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab._member); \ ++ } \ ++ struct kobj_attribute bgrt_attr_##_name = __ATTR_RO(_name) ++ ++BGRT_SHOW(version, version); ++BGRT_SHOW(status, status); ++BGRT_SHOW(type, image_type); ++BGRT_SHOW(xoffset, image_offset_x); ++BGRT_SHOW(yoffset, image_offset_y); + + static ssize_t image_read(struct file *file, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) +@@ -60,11 +39,11 @@ static ssize_t image_read(struct file *file, struct kobject *kobj, + static BIN_ATTR_RO(image, 0); /* size gets filled in later */ + + static struct attribute *bgrt_attributes[] = { +- &dev_attr_version.attr, +- &dev_attr_status.attr, +- &dev_attr_type.attr, +- &dev_attr_xoffset.attr, +- &dev_attr_yoffset.attr, ++ &bgrt_attr_version.attr, ++ &bgrt_attr_status.attr, ++ &bgrt_attr_type.attr, ++ &bgrt_attr_xoffset.attr, ++ &bgrt_attr_yoffset.attr, + NULL, + }; + +diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c +index a4bd673934c0a..44b4f02e2c6d7 100644 +--- a/drivers/acpi/bus.c ++++ b/drivers/acpi/bus.c +@@ -1321,6 +1321,7 @@ static int __init acpi_init(void) + + result = acpi_bus_init(); + if (result) { ++ kobject_put(acpi_kobj); + disable_acpi(); + return result; + } +diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c +index d260bc1f3e6e7..9d2d3b9bb8b59 100644 +--- a/drivers/acpi/device_pm.c ++++ b/drivers/acpi/device_pm.c +@@ -20,6 +20,7 @@ + #include + #include + ++#include "fan.h" + #include "internal.h" + + /** +@@ -1310,10 +1311,7 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on) + * with the generic ACPI PM domain. + */ + static const struct acpi_device_id special_pm_ids[] = { +- {"PNP0C0B", }, /* Generic ACPI fan */ +- {"INT3404", }, /* Fan */ +- {"INTC1044", }, /* Fan for Tiger Lake generation */ +- {"INTC1048", }, /* Fan for Alder Lake generation */ ++ ACPI_FAN_DEVICE_IDS, + {} + }; + struct acpi_device *adev = ACPI_COMPANION(dev); +diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c +index fa2c1c93072cf..a393e0e09381d 100644 +--- a/drivers/acpi/device_sysfs.c ++++ b/drivers/acpi/device_sysfs.c +@@ -448,7 +448,7 @@ static ssize_t description_show(struct device *dev, + (wchar_t *)acpi_dev->pnp.str_obj->buffer.pointer, + acpi_dev->pnp.str_obj->buffer.length, + UTF16_LITTLE_ENDIAN, buf, +- PAGE_SIZE); ++ PAGE_SIZE - 1); + + buf[result++] = '\n'; + +diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c +index 13565629ce0a8..87c3b4a099b94 100644 +--- a/drivers/acpi/ec.c ++++ b/drivers/acpi/ec.c +@@ -183,6 +183,7 @@ static struct workqueue_struct *ec_query_wq; + + static int EC_FLAGS_CORRECT_ECDT; /* Needs ECDT port address correction */ + static int EC_FLAGS_IGNORE_DSDT_GPE; /* Needs ECDT GPE as correction setting */ ++static int EC_FLAGS_TRUST_DSDT_GPE; /* Needs DSDT GPE as correction setting */ + static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */ + + /* -------------------------------------------------------------------------- +@@ -1593,7 +1594,8 @@ static int acpi_ec_add(struct acpi_device *device) + } + + if (boot_ec && ec->command_addr == boot_ec->command_addr && +- ec->data_addr == boot_ec->data_addr) { ++ ec->data_addr == boot_ec->data_addr && ++ !EC_FLAGS_TRUST_DSDT_GPE) { + /* + * Trust PNP0C09 namespace location rather than + * ECDT ID. But trust ECDT GPE rather than _GPE +@@ -1816,6 +1818,18 @@ static int ec_correct_ecdt(const struct dmi_system_id *id) + return 0; + } + ++/* ++ * Some ECDTs contain wrong GPE setting, but they share the same port addresses ++ * with DSDT EC, don't duplicate the DSDT EC with ECDT EC in this case. ++ * https://bugzilla.kernel.org/show_bug.cgi?id=209989 ++ */ ++static int ec_honor_dsdt_gpe(const struct dmi_system_id *id) ++{ ++ pr_debug("Detected system needing DSDT GPE setting.\n"); ++ EC_FLAGS_TRUST_DSDT_GPE = 1; ++ return 0; ++} ++ + /* + * Some DSDTs contain wrong GPE setting. + * Asus FX502VD/VE, GL702VMK, X550VXK, X580VD +@@ -1846,6 +1860,22 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "GL702VMK"),}, NULL}, + { ++ ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X505BA", { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "X505BA"),}, NULL}, ++ { ++ ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X505BP", { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "X505BP"),}, NULL}, ++ { ++ ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X542BA", { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "X542BA"),}, NULL}, ++ { ++ ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X542BP", { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "X542BP"),}, NULL}, ++ { + ec_honor_ecdt_gpe, "ASUS X550VXK", { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X550VXK"),}, NULL}, +@@ -1854,6 +1884,11 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X580VD"),}, NULL}, + { ++ /* https://bugzilla.kernel.org/show_bug.cgi?id=209989 */ ++ ec_honor_dsdt_gpe, "HP Pavilion Gaming Laptop 15-cx0xxx", { ++ DMI_MATCH(DMI_SYS_VENDOR, "HP"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Gaming Laptop 15-cx0xxx"),}, NULL}, ++ { + ec_clear_on_resume, "Samsung hardware", { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL}, + {}, +diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c +index 66c3983f0ccca..5cd0ceb50bc8a 100644 +--- a/drivers/acpi/fan.c ++++ b/drivers/acpi/fan.c +@@ -16,6 +16,8 @@ + #include + #include + ++#include "fan.h" ++ + MODULE_AUTHOR("Paul Diefenbaugh"); + MODULE_DESCRIPTION("ACPI Fan Driver"); + MODULE_LICENSE("GPL"); +@@ -24,10 +26,7 @@ static int acpi_fan_probe(struct platform_device *pdev); + static int acpi_fan_remove(struct platform_device *pdev); + + static const struct acpi_device_id fan_device_ids[] = { +- {"PNP0C0B", 0}, +- {"INT3404", 0}, +- {"INTC1044", 0}, +- {"INTC1048", 0}, ++ ACPI_FAN_DEVICE_IDS, + {"", 0}, + }; + MODULE_DEVICE_TABLE(acpi, fan_device_ids); +diff --git a/drivers/acpi/fan.h b/drivers/acpi/fan.h +new file mode 100644 +index 0000000000000..dc9a6efa514b0 +--- /dev/null ++++ b/drivers/acpi/fan.h +@@ -0,0 +1,13 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++/* ++ * ACPI fan device IDs are shared between the fan driver and the device power ++ * management code. ++ * ++ * Add new device IDs before the generic ACPI fan one. ++ */ ++#define ACPI_FAN_DEVICE_IDS \ ++ {"INT3404", }, /* Fan */ \ ++ {"INTC1044", }, /* Fan for Tiger Lake generation */ \ ++ {"INTC1048", }, /* Fan for Alder Lake generation */ \ ++ {"PNP0C0B", } /* Generic ACPI fan */ +diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c +index 45a019619e4a5..095c8aca141eb 100644 +--- a/drivers/acpi/processor_idle.c ++++ b/drivers/acpi/processor_idle.c +@@ -16,6 +16,7 @@ + #include + #include + #include /* need_resched() */ ++#include + #include + #include + #include +@@ -384,10 +385,37 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, + return; + } + ++static int acpi_cst_latency_cmp(const void *a, const void *b) ++{ ++ const struct acpi_processor_cx *x = a, *y = b; ++ ++ if (!(x->valid && y->valid)) ++ return 0; ++ if (x->latency > y->latency) ++ return 1; ++ if (x->latency < y->latency) ++ return -1; ++ return 0; ++} ++static void acpi_cst_latency_swap(void *a, void *b, int n) ++{ ++ struct acpi_processor_cx *x = a, *y = b; ++ u32 tmp; ++ ++ if (!(x->valid && y->valid)) ++ return; ++ tmp = x->latency; ++ x->latency = y->latency; ++ y->latency = tmp; ++} ++ + static int acpi_processor_power_verify(struct acpi_processor *pr) + { + unsigned int i; + unsigned int working = 0; ++ unsigned int last_latency = 0; ++ unsigned int last_type = 0; ++ bool buggy_latency = false; + + pr->power.timer_broadcast_on_state = INT_MAX; + +@@ -411,12 +439,24 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) + } + if (!cx->valid) + continue; ++ if (cx->type >= last_type && cx->latency < last_latency) ++ buggy_latency = true; ++ last_latency = cx->latency; ++ last_type = cx->type; + + lapic_timer_check_state(i, pr, cx); + tsc_check_state(cx->type); + working++; + } + ++ if (buggy_latency) { ++ pr_notice("FW issue: working around C-state latencies out of order\n"); ++ sort(&pr->power.states[1], max_cstate, ++ sizeof(struct acpi_processor_cx), ++ acpi_cst_latency_cmp, ++ acpi_cst_latency_swap); ++ } ++ + lapic_timer_propagate_broadcast(pr); + + return (working); +diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c +index ee78a210c6068..dc01fb550b28d 100644 +--- a/drivers/acpi/resource.c ++++ b/drivers/acpi/resource.c +@@ -423,6 +423,13 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, + } + } + ++static bool irq_is_legacy(struct acpi_resource_irq *irq) ++{ ++ return irq->triggering == ACPI_EDGE_SENSITIVE && ++ irq->polarity == ACPI_ACTIVE_HIGH && ++ irq->shareable == ACPI_EXCLUSIVE; ++} ++ + /** + * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information. + * @ares: Input ACPI resource object. +@@ -461,7 +468,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index, + } + acpi_dev_get_irqresource(res, irq->interrupts[index], + irq->triggering, irq->polarity, +- irq->shareable, true); ++ irq->shareable, irq_is_legacy(irq)); + break; + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: + ext_irq = &ares->data.extended_irq; +diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c +index e10d38ac7cf28..438df8da6d122 100644 +--- a/drivers/acpi/scan.c ++++ b/drivers/acpi/scan.c +@@ -1671,8 +1671,20 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, + device_initialize(&device->dev); + dev_set_uevent_suppress(&device->dev, true); + acpi_init_coherency(device); +- /* Assume there are unmet deps to start with. */ +- device->dep_unmet = 1; ++} ++ ++static void acpi_scan_dep_init(struct acpi_device *adev) ++{ ++ struct acpi_dep_data *dep; ++ ++ mutex_lock(&acpi_dep_list_lock); ++ ++ list_for_each_entry(dep, &acpi_dep_list, node) { ++ if (dep->consumer == adev->handle) ++ adev->dep_unmet++; ++ } ++ ++ mutex_unlock(&acpi_dep_list_lock); + } + + void acpi_device_add_finalize(struct acpi_device *device) +@@ -1688,7 +1700,7 @@ static void acpi_scan_init_status(struct acpi_device *adev) + } + + static int acpi_add_single_object(struct acpi_device **child, +- acpi_handle handle, int type) ++ acpi_handle handle, int type, bool dep_init) + { + struct acpi_device *device; + int result; +@@ -1703,8 +1715,12 @@ static int acpi_add_single_object(struct acpi_device **child, + * acpi_bus_get_status() and use its quirk handling. Note that + * this must be done before the get power-/wakeup_dev-flags calls. + */ +- if (type == ACPI_BUS_TYPE_DEVICE || type == ACPI_BUS_TYPE_PROCESSOR) ++ if (type == ACPI_BUS_TYPE_DEVICE || type == ACPI_BUS_TYPE_PROCESSOR) { ++ if (dep_init) ++ acpi_scan_dep_init(device); ++ + acpi_scan_init_status(device); ++ } + + acpi_bus_get_power_flags(device); + acpi_bus_get_wakeup_device_flags(device); +@@ -1886,22 +1902,6 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep) + return count; + } + +-static void acpi_scan_dep_init(struct acpi_device *adev) +-{ +- struct acpi_dep_data *dep; +- +- adev->dep_unmet = 0; +- +- mutex_lock(&acpi_dep_list_lock); +- +- list_for_each_entry(dep, &acpi_dep_list, node) { +- if (dep->consumer == adev->handle) +- adev->dep_unmet++; +- } +- +- mutex_unlock(&acpi_dep_list_lock); +-} +- + static bool acpi_bus_scan_second_pass; + + static acpi_status acpi_bus_check_add(acpi_handle handle, bool check_dep, +@@ -1949,19 +1949,15 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, bool check_dep, + return AE_OK; + } + +- acpi_add_single_object(&device, handle, type); +- if (!device) +- return AE_CTRL_DEPTH; +- +- acpi_scan_init_hotplug(device); + /* + * If check_dep is true at this point, the device has no dependencies, + * or the creation of the device object would have been postponed above. + */ +- if (check_dep) +- device->dep_unmet = 0; +- else +- acpi_scan_dep_init(device); ++ acpi_add_single_object(&device, handle, type, !check_dep); ++ if (!device) ++ return AE_CTRL_DEPTH; ++ ++ acpi_scan_init_hotplug(device); + + out: + if (!*adev_p) +@@ -2223,7 +2219,7 @@ int acpi_bus_register_early_device(int type) + struct acpi_device *device = NULL; + int result; + +- result = acpi_add_single_object(&device, NULL, type); ++ result = acpi_add_single_object(&device, NULL, type, false); + if (result) + return result; + +@@ -2243,7 +2239,7 @@ static int acpi_bus_scan_fixed(void) + struct acpi_device *device = NULL; + + result = acpi_add_single_object(&device, NULL, +- ACPI_BUS_TYPE_POWER_BUTTON); ++ ACPI_BUS_TYPE_POWER_BUTTON, false); + if (result) + return result; + +@@ -2259,7 +2255,7 @@ static int acpi_bus_scan_fixed(void) + struct acpi_device *device = NULL; + + result = acpi_add_single_object(&device, NULL, +- ACPI_BUS_TYPE_SLEEP_BUTTON); ++ ACPI_BUS_TYPE_SLEEP_BUTTON, false); + if (result) + return result; + +diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c +index 2b69536cdccba..2d7ddb8a8cb65 100644 +--- a/drivers/acpi/x86/s2idle.c ++++ b/drivers/acpi/x86/s2idle.c +@@ -42,6 +42,8 @@ static const struct acpi_device_id lps0_device_ids[] = { + + /* AMD */ + #define ACPI_LPS0_DSM_UUID_AMD "e3f32452-febc-43ce-9039-932122d37721" ++#define ACPI_LPS0_ENTRY_AMD 2 ++#define ACPI_LPS0_EXIT_AMD 3 + #define ACPI_LPS0_SCREEN_OFF_AMD 4 + #define ACPI_LPS0_SCREEN_ON_AMD 5 + +@@ -408,6 +410,7 @@ int acpi_s2idle_prepare_late(void) + + if (acpi_s2idle_vendor_amd()) { + acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF_AMD); ++ acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY_AMD); + } else { + acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF); + acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY); +@@ -422,6 +425,7 @@ void acpi_s2idle_restore_early(void) + return; + + if (acpi_s2idle_vendor_amd()) { ++ acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT_AMD); + acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON_AMD); + } else { + acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT); +diff --git a/drivers/ata/pata_ep93xx.c b/drivers/ata/pata_ep93xx.c +index badab67088935..46208ececbb6a 100644 +--- a/drivers/ata/pata_ep93xx.c ++++ b/drivers/ata/pata_ep93xx.c +@@ -928,7 +928,7 @@ static int ep93xx_pata_probe(struct platform_device *pdev) + /* INT[3] (IRQ_EP93XX_EXT3) line connected as pull down */ + irq = platform_get_irq(pdev, 0); + if (irq < 0) { +- err = -ENXIO; ++ err = irq; + goto err_rel_gpio; + } + +diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c +index bd87476ab4813..b5a3f710d76de 100644 +--- a/drivers/ata/pata_octeon_cf.c ++++ b/drivers/ata/pata_octeon_cf.c +@@ -898,10 +898,11 @@ static int octeon_cf_probe(struct platform_device *pdev) + return -EINVAL; + } + +- irq_handler = octeon_cf_interrupt; + i = platform_get_irq(dma_dev, 0); +- if (i > 0) ++ if (i > 0) { + irq = i; ++ irq_handler = octeon_cf_interrupt; ++ } + } + of_node_put(dma_node); + } +diff --git a/drivers/ata/pata_rb532_cf.c b/drivers/ata/pata_rb532_cf.c +index 479c4b29b8562..303f8c375b3af 100644 +--- a/drivers/ata/pata_rb532_cf.c ++++ b/drivers/ata/pata_rb532_cf.c +@@ -115,10 +115,12 @@ static int rb532_pata_driver_probe(struct platform_device *pdev) + } + + irq = platform_get_irq(pdev, 0); +- if (irq <= 0) { ++ if (irq < 0) { + dev_err(&pdev->dev, "no IRQ resource found\n"); +- return -ENOENT; ++ return irq; + } ++ if (!irq) ++ return -EINVAL; + + gpiod = devm_gpiod_get(&pdev->dev, NULL, GPIOD_IN); + if (IS_ERR(gpiod)) { +diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c +index 64b2ef15ec191..8440203e835ed 100644 +--- a/drivers/ata/sata_highbank.c ++++ b/drivers/ata/sata_highbank.c +@@ -469,10 +469,12 @@ static int ahci_highbank_probe(struct platform_device *pdev) + } + + irq = platform_get_irq(pdev, 0); +- if (irq <= 0) { ++ if (irq < 0) { + dev_err(dev, "no irq\n"); +- return -EINVAL; ++ return irq; + } ++ if (!irq) ++ return -EINVAL; + + hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); + if (!hpriv) { +diff --git a/drivers/block/loop.c b/drivers/block/loop.c +index 76e12f3482a91..8271df1251535 100644 +--- a/drivers/block/loop.c ++++ b/drivers/block/loop.c +@@ -1154,6 +1154,7 @@ static int loop_configure(struct loop_device *lo, fmode_t mode, + blk_queue_physical_block_size(lo->lo_queue, bsize); + blk_queue_io_min(lo->lo_queue, bsize); + ++ loop_config_discard(lo); + loop_update_rotational(lo); + loop_update_dio(lo); + loop_sysfs_init(lo); +diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c +index 25114f0d13199..bd71dfc9c9748 100644 +--- a/drivers/bluetooth/btqca.c ++++ b/drivers/bluetooth/btqca.c +@@ -183,7 +183,7 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev) + EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd); + + static void qca_tlv_check_data(struct qca_fw_config *config, +- const struct firmware *fw, enum qca_btsoc_type soc_type) ++ u8 *fw_data, enum qca_btsoc_type soc_type) + { + const u8 *data; + u32 type_len; +@@ -194,7 +194,7 @@ static void qca_tlv_check_data(struct qca_fw_config *config, + struct tlv_type_nvm *tlv_nvm; + uint8_t nvm_baud_rate = config->user_baud_rate; + +- tlv = (struct tlv_type_hdr *)fw->data; ++ tlv = (struct tlv_type_hdr *)fw_data; + + type_len = le32_to_cpu(tlv->type_len); + length = (type_len >> 8) & 0x00ffffff; +@@ -390,8 +390,9 @@ static int qca_download_firmware(struct hci_dev *hdev, + enum qca_btsoc_type soc_type) + { + const struct firmware *fw; ++ u8 *data; + const u8 *segment; +- int ret, remain, i = 0; ++ int ret, size, remain, i = 0; + + bt_dev_info(hdev, "QCA Downloading %s", config->fwname); + +@@ -402,10 +403,22 @@ static int qca_download_firmware(struct hci_dev *hdev, + return ret; + } + +- qca_tlv_check_data(config, fw, soc_type); ++ size = fw->size; ++ data = vmalloc(fw->size); ++ if (!data) { ++ bt_dev_err(hdev, "QCA Failed to allocate memory for file: %s", ++ config->fwname); ++ release_firmware(fw); ++ return -ENOMEM; ++ } ++ ++ memcpy(data, fw->data, size); ++ release_firmware(fw); ++ ++ qca_tlv_check_data(config, data, soc_type); + +- segment = fw->data; +- remain = fw->size; ++ segment = data; ++ remain = size; + while (remain > 0) { + int segsize = min(MAX_SIZE_PER_TLV_SEGMENT, remain); + +@@ -435,7 +448,7 @@ static int qca_download_firmware(struct hci_dev *hdev, + ret = qca_inject_cmd_complete_event(hdev); + + out: +- release_firmware(fw); ++ vfree(data); + + return ret; + } +diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c +index 0a0056912d51e..dc6551d65912f 100644 +--- a/drivers/bluetooth/hci_qca.c ++++ b/drivers/bluetooth/hci_qca.c +@@ -1835,8 +1835,6 @@ static void qca_power_shutdown(struct hci_uart *hu) + unsigned long flags; + enum qca_btsoc_type soc_type = qca_soc_type(hu); + +- qcadev = serdev_device_get_drvdata(hu->serdev); +- + /* From this point we go into power off state. But serial port is + * still open, stop queueing the IBS data and flush all the buffered + * data in skb's. +@@ -1852,6 +1850,8 @@ static void qca_power_shutdown(struct hci_uart *hu) + if (!hu->serdev) + return; + ++ qcadev = serdev_device_get_drvdata(hu->serdev); ++ + if (qca_is_wcn399x(soc_type)) { + host_set_baudrate(hu, 2400); + qca_send_power_pulse(hu, false); +diff --git a/drivers/bluetooth/virtio_bt.c b/drivers/bluetooth/virtio_bt.c +index c804db7e90f8f..57908ce4fae85 100644 +--- a/drivers/bluetooth/virtio_bt.c ++++ b/drivers/bluetooth/virtio_bt.c +@@ -34,6 +34,9 @@ static int virtbt_add_inbuf(struct virtio_bluetooth *vbt) + int err; + + skb = alloc_skb(1000, GFP_KERNEL); ++ if (!skb) ++ return -ENOMEM; ++ + sg_init_one(sg, skb->data, 1000); + + err = virtqueue_add_inbuf(vq, sg, 1, skb, GFP_KERNEL); +diff --git a/drivers/bus/mhi/core/pm.c b/drivers/bus/mhi/core/pm.c +index e2e59a341fef6..bbf6cd04861eb 100644 +--- a/drivers/bus/mhi/core/pm.c ++++ b/drivers/bus/mhi/core/pm.c +@@ -465,23 +465,15 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl) + + /* Trigger MHI RESET so that the device will not access host memory */ + if (!MHI_PM_IN_FATAL_STATE(mhi_cntrl->pm_state)) { +- u32 in_reset = -1; +- unsigned long timeout = msecs_to_jiffies(mhi_cntrl->timeout_ms); +- + dev_dbg(dev, "Triggering MHI Reset in device\n"); + mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET); + + /* Wait for the reset bit to be cleared by the device */ +- ret = wait_event_timeout(mhi_cntrl->state_event, +- mhi_read_reg_field(mhi_cntrl, +- mhi_cntrl->regs, +- MHICTRL, +- MHICTRL_RESET_MASK, +- MHICTRL_RESET_SHIFT, +- &in_reset) || +- !in_reset, timeout); +- if (!ret || in_reset) +- dev_err(dev, "Device failed to exit MHI Reset state\n"); ++ ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, ++ MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, 0, ++ 25000); ++ if (ret) ++ dev_err(dev, "Device failed to clear MHI Reset\n"); + + /* + * Device will clear BHI_INTVEC as a part of RESET processing, +@@ -934,6 +926,7 @@ int mhi_pm_resume(struct mhi_controller *mhi_cntrl) + + ret = wait_event_timeout(mhi_cntrl->state_event, + mhi_cntrl->dev_state == MHI_STATE_M0 || ++ mhi_cntrl->dev_state == MHI_STATE_M2 || + MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state), + msecs_to_jiffies(mhi_cntrl->timeout_ms)); + +diff --git a/drivers/bus/mhi/pci_generic.c b/drivers/bus/mhi/pci_generic.c +index b3357a8a2fdbc..ca3bc40427f85 100644 +--- a/drivers/bus/mhi/pci_generic.c ++++ b/drivers/bus/mhi/pci_generic.c +@@ -665,7 +665,7 @@ static int mhi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) + + err = mhi_register_controller(mhi_cntrl, mhi_cntrl_config); + if (err) +- return err; ++ goto err_disable_reporting; + + /* MHI bus does not power up the controller by default */ + err = mhi_prepare_for_power_up(mhi_cntrl); +@@ -699,6 +699,8 @@ err_unprepare: + mhi_unprepare_after_power_down(mhi_cntrl); + err_unregister: + mhi_unregister_controller(mhi_cntrl); ++err_disable_reporting: ++ pci_disable_pcie_error_reporting(pdev); + + return err; + } +@@ -721,6 +723,7 @@ static void mhi_pci_remove(struct pci_dev *pdev) + pm_runtime_get_noresume(&pdev->dev); + + mhi_unregister_controller(mhi_cntrl); ++ pci_disable_pcie_error_reporting(pdev); + } + + static void mhi_pci_shutdown(struct pci_dev *pdev) +diff --git a/drivers/char/hw_random/exynos-trng.c b/drivers/char/hw_random/exynos-trng.c +index 8e1fe3f8dd2df..c8db62bc5ff72 100644 +--- a/drivers/char/hw_random/exynos-trng.c ++++ b/drivers/char/hw_random/exynos-trng.c +@@ -132,7 +132,7 @@ static int exynos_trng_probe(struct platform_device *pdev) + return PTR_ERR(trng->mem); + + pm_runtime_enable(&pdev->dev); +- ret = pm_runtime_get_sync(&pdev->dev); ++ ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret < 0) { + dev_err(&pdev->dev, "Could not get runtime PM.\n"); + goto err_pm_get; +@@ -165,7 +165,7 @@ err_register: + clk_disable_unprepare(trng->clk); + + err_clock: +- pm_runtime_put_sync(&pdev->dev); ++ pm_runtime_put_noidle(&pdev->dev); + + err_pm_get: + pm_runtime_disable(&pdev->dev); +diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c +index 89681f07bc787..9468e9520cee0 100644 +--- a/drivers/char/pcmcia/cm4000_cs.c ++++ b/drivers/char/pcmcia/cm4000_cs.c +@@ -544,6 +544,10 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq) + io_read_num_rec_bytes(iobase, &num_bytes_read); + if (num_bytes_read >= 4) { + DEBUGP(2, dev, "NumRecBytes = %i\n", num_bytes_read); ++ if (num_bytes_read > 4) { ++ rc = -EIO; ++ goto exit_setprotocol; ++ } + break; + } + usleep_range(10000, 11000); +diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c +index 55b9d3965ae1b..69579efb247b3 100644 +--- a/drivers/char/tpm/tpm_tis_core.c ++++ b/drivers/char/tpm/tpm_tis_core.c +@@ -196,13 +196,24 @@ static u8 tpm_tis_status(struct tpm_chip *chip) + return 0; + + if (unlikely((status & TPM_STS_READ_ZERO) != 0)) { +- /* +- * If this trips, the chances are the read is +- * returning 0xff because the locality hasn't been +- * acquired. Usually because tpm_try_get_ops() hasn't +- * been called before doing a TPM operation. +- */ +- WARN_ONCE(1, "TPM returned invalid status\n"); ++ if (!test_and_set_bit(TPM_TIS_INVALID_STATUS, &priv->flags)) { ++ /* ++ * If this trips, the chances are the read is ++ * returning 0xff because the locality hasn't been ++ * acquired. Usually because tpm_try_get_ops() hasn't ++ * been called before doing a TPM operation. ++ */ ++ dev_err(&chip->dev, "invalid TPM_STS.x 0x%02x, dumping stack for forensics\n", ++ status); ++ ++ /* ++ * Dump stack for forensics, as invalid TPM_STS.x could be ++ * potentially triggered by impaired tpm_try_get_ops() or ++ * tpm_find_get_ops(). ++ */ ++ dump_stack(); ++ } ++ + return 0; + } + +diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h +index 9b2d32a59f670..b2a3c6c72882d 100644 +--- a/drivers/char/tpm/tpm_tis_core.h ++++ b/drivers/char/tpm/tpm_tis_core.h +@@ -83,6 +83,7 @@ enum tis_defaults { + + enum tpm_tis_flags { + TPM_TIS_ITPM_WORKAROUND = BIT(0), ++ TPM_TIS_INVALID_STATUS = BIT(1), + }; + + struct tpm_tis_data { +@@ -90,7 +91,7 @@ struct tpm_tis_data { + int locality; + int irq; + bool irq_tested; +- unsigned int flags; ++ unsigned long flags; + void __iomem *ilb_base_addr; + u16 clkrun_enabled; + wait_queue_head_t int_queue; +diff --git a/drivers/char/tpm/tpm_tis_spi_main.c b/drivers/char/tpm/tpm_tis_spi_main.c +index 3856f6ebcb34f..de4209003a448 100644 +--- a/drivers/char/tpm/tpm_tis_spi_main.c ++++ b/drivers/char/tpm/tpm_tis_spi_main.c +@@ -260,6 +260,8 @@ static int tpm_tis_spi_remove(struct spi_device *dev) + } + + static const struct spi_device_id tpm_tis_spi_id[] = { ++ { "st33htpm-spi", (unsigned long)tpm_tis_spi_probe }, ++ { "slb9670", (unsigned long)tpm_tis_spi_probe }, + { "tpm_tis_spi", (unsigned long)tpm_tis_spi_probe }, + { "cr50", (unsigned long)cr50_spi_probe }, + {} +diff --git a/drivers/clk/actions/owl-s500.c b/drivers/clk/actions/owl-s500.c +index 61bb224f63309..cbeb51c804eb5 100644 +--- a/drivers/clk/actions/owl-s500.c ++++ b/drivers/clk/actions/owl-s500.c +@@ -127,8 +127,7 @@ static struct clk_factor_table sd_factor_table[] = { + { 12, 1, 13 }, { 13, 1, 14 }, { 14, 1, 15 }, { 15, 1, 16 }, + { 16, 1, 17 }, { 17, 1, 18 }, { 18, 1, 19 }, { 19, 1, 20 }, + { 20, 1, 21 }, { 21, 1, 22 }, { 22, 1, 23 }, { 23, 1, 24 }, +- { 24, 1, 25 }, { 25, 1, 26 }, { 26, 1, 27 }, { 27, 1, 28 }, +- { 28, 1, 29 }, { 29, 1, 30 }, { 30, 1, 31 }, { 31, 1, 32 }, ++ { 24, 1, 25 }, + + /* bit8: /128 */ + { 256, 1, 1 * 128 }, { 257, 1, 2 * 128 }, { 258, 1, 3 * 128 }, { 259, 1, 4 * 128 }, +@@ -137,19 +136,20 @@ static struct clk_factor_table sd_factor_table[] = { + { 268, 1, 13 * 128 }, { 269, 1, 14 * 128 }, { 270, 1, 15 * 128 }, { 271, 1, 16 * 128 }, + { 272, 1, 17 * 128 }, { 273, 1, 18 * 128 }, { 274, 1, 19 * 128 }, { 275, 1, 20 * 128 }, + { 276, 1, 21 * 128 }, { 277, 1, 22 * 128 }, { 278, 1, 23 * 128 }, { 279, 1, 24 * 128 }, +- { 280, 1, 25 * 128 }, { 281, 1, 26 * 128 }, { 282, 1, 27 * 128 }, { 283, 1, 28 * 128 }, +- { 284, 1, 29 * 128 }, { 285, 1, 30 * 128 }, { 286, 1, 31 * 128 }, { 287, 1, 32 * 128 }, ++ { 280, 1, 25 * 128 }, + { 0, 0, 0 }, + }; + +-static struct clk_factor_table bisp_factor_table[] = { +- { 0, 1, 1 }, { 1, 1, 2 }, { 2, 1, 3 }, { 3, 1, 4 }, +- { 4, 1, 5 }, { 5, 1, 6 }, { 6, 1, 7 }, { 7, 1, 8 }, ++static struct clk_factor_table de_factor_table[] = { ++ { 0, 1, 1 }, { 1, 2, 3 }, { 2, 1, 2 }, { 3, 2, 5 }, ++ { 4, 1, 3 }, { 5, 1, 4 }, { 6, 1, 6 }, { 7, 1, 8 }, ++ { 8, 1, 12 }, + { 0, 0, 0 }, + }; + +-static struct clk_factor_table ahb_factor_table[] = { +- { 1, 1, 2 }, { 2, 1, 3 }, ++static struct clk_factor_table hde_factor_table[] = { ++ { 0, 1, 1 }, { 1, 2, 3 }, { 2, 1, 2 }, { 3, 2, 5 }, ++ { 4, 1, 3 }, { 5, 1, 4 }, { 6, 1, 6 }, { 7, 1, 8 }, + { 0, 0, 0 }, + }; + +@@ -158,6 +158,13 @@ static struct clk_div_table rmii_ref_div_table[] = { + { 0, 0 }, + }; + ++static struct clk_div_table std12rate_div_table[] = { ++ { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, ++ { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 }, ++ { 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 }, ++ { 0, 0 }, ++}; ++ + static struct clk_div_table i2s_div_table[] = { + { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, + { 4, 6 }, { 5, 8 }, { 6, 12 }, { 7, 16 }, +@@ -174,7 +181,6 @@ static struct clk_div_table nand_div_table[] = { + + /* mux clock */ + static OWL_MUX(dev_clk, "dev_clk", dev_clk_mux_p, CMU_DEVPLL, 12, 1, CLK_SET_RATE_PARENT); +-static OWL_MUX(ahbprediv_clk, "ahbprediv_clk", ahbprediv_clk_mux_p, CMU_BUSCLK1, 8, 3, CLK_SET_RATE_PARENT); + + /* gate clocks */ + static OWL_GATE(gpio_clk, "gpio_clk", "apb_clk", CMU_DEVCLKEN0, 18, 0, 0); +@@ -187,45 +193,54 @@ static OWL_GATE(timer_clk, "timer_clk", "hosc", CMU_DEVCLKEN1, 27, 0, 0); + static OWL_GATE(hdmi_clk, "hdmi_clk", "hosc", CMU_DEVCLKEN1, 3, 0, 0); + + /* divider clocks */ +-static OWL_DIVIDER(h_clk, "h_clk", "ahbprediv_clk", CMU_BUSCLK1, 12, 2, NULL, 0, 0); ++static OWL_DIVIDER(h_clk, "h_clk", "ahbprediv_clk", CMU_BUSCLK1, 2, 2, NULL, 0, 0); + static OWL_DIVIDER(apb_clk, "apb_clk", "ahb_clk", CMU_BUSCLK1, 14, 2, NULL, 0, 0); + static OWL_DIVIDER(rmii_ref_clk, "rmii_ref_clk", "ethernet_pll_clk", CMU_ETHERNETPLL, 1, 1, rmii_ref_div_table, 0, 0); + + /* factor clocks */ +-static OWL_FACTOR(ahb_clk, "ahb_clk", "h_clk", CMU_BUSCLK1, 2, 2, ahb_factor_table, 0, 0); +-static OWL_FACTOR(de1_clk, "de_clk1", "de_clk", CMU_DECLK, 0, 3, bisp_factor_table, 0, 0); +-static OWL_FACTOR(de2_clk, "de_clk2", "de_clk", CMU_DECLK, 4, 3, bisp_factor_table, 0, 0); ++static OWL_FACTOR(de1_clk, "de_clk1", "de_clk", CMU_DECLK, 0, 4, de_factor_table, 0, 0); ++static OWL_FACTOR(de2_clk, "de_clk2", "de_clk", CMU_DECLK, 4, 4, de_factor_table, 0, 0); + + /* composite clocks */ ++static OWL_COMP_DIV(ahbprediv_clk, "ahbprediv_clk", ahbprediv_clk_mux_p, ++ OWL_MUX_HW(CMU_BUSCLK1, 8, 3), ++ { 0 }, ++ OWL_DIVIDER_HW(CMU_BUSCLK1, 12, 2, 0, NULL), ++ CLK_SET_RATE_PARENT); ++ ++static OWL_COMP_FIXED_FACTOR(ahb_clk, "ahb_clk", "h_clk", ++ { 0 }, ++ 1, 1, 0); ++ + static OWL_COMP_FACTOR(vce_clk, "vce_clk", hde_clk_mux_p, + OWL_MUX_HW(CMU_VCECLK, 4, 2), + OWL_GATE_HW(CMU_DEVCLKEN0, 26, 0), +- OWL_FACTOR_HW(CMU_VCECLK, 0, 3, 0, bisp_factor_table), ++ OWL_FACTOR_HW(CMU_VCECLK, 0, 3, 0, hde_factor_table), + 0); + + static OWL_COMP_FACTOR(vde_clk, "vde_clk", hde_clk_mux_p, + OWL_MUX_HW(CMU_VDECLK, 4, 2), + OWL_GATE_HW(CMU_DEVCLKEN0, 25, 0), +- OWL_FACTOR_HW(CMU_VDECLK, 0, 3, 0, bisp_factor_table), ++ OWL_FACTOR_HW(CMU_VDECLK, 0, 3, 0, hde_factor_table), + 0); + +-static OWL_COMP_FACTOR(bisp_clk, "bisp_clk", bisp_clk_mux_p, ++static OWL_COMP_DIV(bisp_clk, "bisp_clk", bisp_clk_mux_p, + OWL_MUX_HW(CMU_BISPCLK, 4, 1), + OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0), +- OWL_FACTOR_HW(CMU_BISPCLK, 0, 3, 0, bisp_factor_table), ++ OWL_DIVIDER_HW(CMU_BISPCLK, 0, 4, 0, std12rate_div_table), + 0); + +-static OWL_COMP_FACTOR(sensor0_clk, "sensor0_clk", sensor_clk_mux_p, ++static OWL_COMP_DIV(sensor0_clk, "sensor0_clk", sensor_clk_mux_p, + OWL_MUX_HW(CMU_SENSORCLK, 4, 1), + OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0), +- OWL_FACTOR_HW(CMU_SENSORCLK, 0, 3, 0, bisp_factor_table), +- CLK_IGNORE_UNUSED); ++ OWL_DIVIDER_HW(CMU_SENSORCLK, 0, 4, 0, std12rate_div_table), ++ 0); + +-static OWL_COMP_FACTOR(sensor1_clk, "sensor1_clk", sensor_clk_mux_p, ++static OWL_COMP_DIV(sensor1_clk, "sensor1_clk", sensor_clk_mux_p, + OWL_MUX_HW(CMU_SENSORCLK, 4, 1), + OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0), +- OWL_FACTOR_HW(CMU_SENSORCLK, 8, 3, 0, bisp_factor_table), +- CLK_IGNORE_UNUSED); ++ OWL_DIVIDER_HW(CMU_SENSORCLK, 8, 4, 0, std12rate_div_table), ++ 0); + + static OWL_COMP_FACTOR(sd0_clk, "sd0_clk", sd_clk_mux_p, + OWL_MUX_HW(CMU_SD0CLK, 9, 1), +@@ -305,7 +320,7 @@ static OWL_COMP_FIXED_FACTOR(i2c3_clk, "i2c3_clk", "ethernet_pll_clk", + static OWL_COMP_DIV(uart0_clk, "uart0_clk", uart_clk_mux_p, + OWL_MUX_HW(CMU_UART0CLK, 16, 1), + OWL_GATE_HW(CMU_DEVCLKEN1, 6, 0), +- OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), ++ OWL_DIVIDER_HW(CMU_UART0CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + CLK_IGNORE_UNUSED); + + static OWL_COMP_DIV(uart1_clk, "uart1_clk", uart_clk_mux_p, +@@ -317,31 +332,31 @@ static OWL_COMP_DIV(uart1_clk, "uart1_clk", uart_clk_mux_p, + static OWL_COMP_DIV(uart2_clk, "uart2_clk", uart_clk_mux_p, + OWL_MUX_HW(CMU_UART2CLK, 16, 1), + OWL_GATE_HW(CMU_DEVCLKEN1, 8, 0), +- OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), ++ OWL_DIVIDER_HW(CMU_UART2CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + CLK_IGNORE_UNUSED); + + static OWL_COMP_DIV(uart3_clk, "uart3_clk", uart_clk_mux_p, + OWL_MUX_HW(CMU_UART3CLK, 16, 1), + OWL_GATE_HW(CMU_DEVCLKEN1, 19, 0), +- OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), ++ OWL_DIVIDER_HW(CMU_UART3CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + CLK_IGNORE_UNUSED); + + static OWL_COMP_DIV(uart4_clk, "uart4_clk", uart_clk_mux_p, + OWL_MUX_HW(CMU_UART4CLK, 16, 1), + OWL_GATE_HW(CMU_DEVCLKEN1, 20, 0), +- OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), ++ OWL_DIVIDER_HW(CMU_UART4CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + CLK_IGNORE_UNUSED); + + static OWL_COMP_DIV(uart5_clk, "uart5_clk", uart_clk_mux_p, + OWL_MUX_HW(CMU_UART5CLK, 16, 1), + OWL_GATE_HW(CMU_DEVCLKEN1, 21, 0), +- OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), ++ OWL_DIVIDER_HW(CMU_UART5CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + CLK_IGNORE_UNUSED); + + static OWL_COMP_DIV(uart6_clk, "uart6_clk", uart_clk_mux_p, + OWL_MUX_HW(CMU_UART6CLK, 16, 1), + OWL_GATE_HW(CMU_DEVCLKEN1, 18, 0), +- OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), ++ OWL_DIVIDER_HW(CMU_UART6CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + CLK_IGNORE_UNUSED); + + static OWL_COMP_DIV(i2srx_clk, "i2srx_clk", i2s_clk_mux_p, +diff --git a/drivers/clk/clk-k210.c b/drivers/clk/clk-k210.c +index 6c84abf5b2e36..67a7cb3503c36 100644 +--- a/drivers/clk/clk-k210.c ++++ b/drivers/clk/clk-k210.c +@@ -722,6 +722,7 @@ static int k210_clk_set_parent(struct clk_hw *hw, u8 index) + reg |= BIT(cfg->mux_bit); + else + reg &= ~BIT(cfg->mux_bit); ++ writel(reg, ksc->regs + cfg->mux_reg); + spin_unlock_irqrestore(&ksc->clk_lock, flags); + + return 0; +diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c +index e0446e66fa645..eb22f4fdbc6b4 100644 +--- a/drivers/clk/clk-si5341.c ++++ b/drivers/clk/clk-si5341.c +@@ -92,12 +92,22 @@ struct clk_si5341_output_config { + #define SI5341_PN_BASE 0x0002 + #define SI5341_DEVICE_REV 0x0005 + #define SI5341_STATUS 0x000C ++#define SI5341_LOS 0x000D ++#define SI5341_STATUS_STICKY 0x0011 ++#define SI5341_LOS_STICKY 0x0012 + #define SI5341_SOFT_RST 0x001C + #define SI5341_IN_SEL 0x0021 ++#define SI5341_DEVICE_READY 0x00FE + #define SI5341_XAXB_CFG 0x090E + #define SI5341_IN_EN 0x0949 + #define SI5341_INX_TO_PFD_EN 0x094A + ++/* Status bits */ ++#define SI5341_STATUS_SYSINCAL BIT(0) ++#define SI5341_STATUS_LOSXAXB BIT(1) ++#define SI5341_STATUS_LOSREF BIT(2) ++#define SI5341_STATUS_LOL BIT(3) ++ + /* Input selection */ + #define SI5341_IN_SEL_MASK 0x06 + #define SI5341_IN_SEL_SHIFT 1 +@@ -340,6 +350,8 @@ static const struct si5341_reg_default si5341_reg_defaults[] = { + { 0x094A, 0x00 }, /* INx_TO_PFD_EN (disabled) */ + { 0x0A02, 0x00 }, /* Not in datasheet */ + { 0x0B44, 0x0F }, /* PDIV_ENB (datasheet does not mention what it is) */ ++ { 0x0B57, 0x10 }, /* VCO_RESET_CALCODE (not described in datasheet) */ ++ { 0x0B58, 0x05 }, /* VCO_RESET_CALCODE (not described in datasheet) */ + }; + + /* Read and interpret a 44-bit followed by a 32-bit value in the regmap */ +@@ -623,6 +635,9 @@ static unsigned long si5341_synth_clk_recalc_rate(struct clk_hw *hw, + SI5341_SYNTH_N_NUM(synth->index), &n_num, &n_den); + if (err < 0) + return err; ++ /* Check for bogus/uninitialized settings */ ++ if (!n_num || !n_den) ++ return 0; + + /* + * n_num and n_den are shifted left as much as possible, so to prevent +@@ -806,6 +821,9 @@ static long si5341_output_clk_round_rate(struct clk_hw *hw, unsigned long rate, + { + unsigned long r; + ++ if (!rate) ++ return 0; ++ + r = *parent_rate >> 1; + + /* If rate is an even divisor, no changes to parent required */ +@@ -834,11 +852,16 @@ static int si5341_output_clk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) + { + struct clk_si5341_output *output = to_clk_si5341_output(hw); +- /* Frequency divider is (r_div + 1) * 2 */ +- u32 r_div = (parent_rate / rate) >> 1; ++ u32 r_div; + int err; + u8 r[3]; + ++ if (!rate) ++ return -EINVAL; ++ ++ /* Frequency divider is (r_div + 1) * 2 */ ++ r_div = (parent_rate / rate) >> 1; ++ + if (r_div <= 1) + r_div = 0; + else if (r_div >= BIT(24)) +@@ -1083,7 +1106,7 @@ static const struct si5341_reg_default si5341_preamble[] = { + { 0x0B25, 0x00 }, + { 0x0502, 0x01 }, + { 0x0505, 0x03 }, +- { 0x0957, 0x1F }, ++ { 0x0957, 0x17 }, + { 0x0B4E, 0x1A }, + }; + +@@ -1189,6 +1212,32 @@ static const struct regmap_range_cfg si5341_regmap_ranges[] = { + }, + }; + ++static int si5341_wait_device_ready(struct i2c_client *client) ++{ ++ int count; ++ ++ /* Datasheet warns: Any attempt to read or write any register other ++ * than DEVICE_READY before DEVICE_READY reads as 0x0F may corrupt the ++ * NVM programming and may corrupt the register contents, as they are ++ * read from NVM. Note that this includes accesses to the PAGE register. ++ * Also: DEVICE_READY is available on every register page, so no page ++ * change is needed to read it. ++ * Do this outside regmap to avoid automatic PAGE register access. ++ * May take up to 300ms to complete. ++ */ ++ for (count = 0; count < 15; ++count) { ++ s32 result = i2c_smbus_read_byte_data(client, ++ SI5341_DEVICE_READY); ++ if (result < 0) ++ return result; ++ if (result == 0x0F) ++ return 0; ++ msleep(20); ++ } ++ dev_err(&client->dev, "timeout waiting for DEVICE_READY\n"); ++ return -EIO; ++} ++ + static const struct regmap_config si5341_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +@@ -1378,6 +1427,7 @@ static int si5341_probe(struct i2c_client *client, + unsigned int i; + struct clk_si5341_output_config config[SI5341_MAX_NUM_OUTPUTS]; + bool initialization_required; ++ u32 status; + + data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); + if (!data) +@@ -1385,6 +1435,11 @@ static int si5341_probe(struct i2c_client *client, + + data->i2c_client = client; + ++ /* Must be done before otherwise touching hardware */ ++ err = si5341_wait_device_ready(client); ++ if (err) ++ return err; ++ + for (i = 0; i < SI5341_NUM_INPUTS; ++i) { + input = devm_clk_get(&client->dev, si5341_input_clock_names[i]); + if (IS_ERR(input)) { +@@ -1540,6 +1595,22 @@ static int si5341_probe(struct i2c_client *client, + return err; + } + ++ /* wait for device to report input clock present and PLL lock */ ++ err = regmap_read_poll_timeout(data->regmap, SI5341_STATUS, status, ++ !(status & (SI5341_STATUS_LOSREF | SI5341_STATUS_LOL)), ++ 10000, 250000); ++ if (err) { ++ dev_err(&client->dev, "Error waiting for input clock or PLL lock\n"); ++ return err; ++ } ++ ++ /* clear sticky alarm bits from initialization */ ++ err = regmap_write(data->regmap, SI5341_STATUS_STICKY, 0); ++ if (err) { ++ dev_err(&client->dev, "unable to clear sticky status\n"); ++ return err; ++ } ++ + /* Free the names, clk framework makes copies */ + for (i = 0; i < data->num_synth; ++i) + devm_kfree(&client->dev, (void *)synth_clock_names[i]); +diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c +index 344cd6c611887..3c737742c2a92 100644 +--- a/drivers/clk/clk-versaclock5.c ++++ b/drivers/clk/clk-versaclock5.c +@@ -69,7 +69,10 @@ + #define VC5_FEEDBACK_FRAC_DIV(n) (0x19 + (n)) + #define VC5_RC_CONTROL0 0x1e + #define VC5_RC_CONTROL1 0x1f +-/* Register 0x20 is factory reserved */ ++ ++/* These registers are named "Unused Factory Reserved Registers" */ ++#define VC5_RESERVED_X0(idx) (0x20 + ((idx) * 0x10)) ++#define VC5_RESERVED_X0_BYPASS_SYNC BIT(7) /* bypass_sync bit */ + + /* Output divider control for divider 1,2,3,4 */ + #define VC5_OUT_DIV_CONTROL(idx) (0x21 + ((idx) * 0x10)) +@@ -87,7 +90,6 @@ + #define VC5_OUT_DIV_SKEW_INT(idx, n) (0x2b + ((idx) * 0x10) + (n)) + #define VC5_OUT_DIV_INT(idx, n) (0x2d + ((idx) * 0x10) + (n)) + #define VC5_OUT_DIV_SKEW_FRAC(idx) (0x2f + ((idx) * 0x10)) +-/* Registers 0x30, 0x40, 0x50 are factory reserved */ + + /* Clock control register for clock 1,2 */ + #define VC5_CLK_OUTPUT_CFG(idx, n) (0x60 + ((idx) * 0x2) + (n)) +@@ -140,6 +142,8 @@ + #define VC5_HAS_INTERNAL_XTAL BIT(0) + /* chip has PFD requency doubler */ + #define VC5_HAS_PFD_FREQ_DBL BIT(1) ++/* chip has bits to disable FOD sync */ ++#define VC5_HAS_BYPASS_SYNC_BIT BIT(2) + + /* Supported IDT VC5 models. */ + enum vc5_model { +@@ -581,6 +585,23 @@ static int vc5_clk_out_prepare(struct clk_hw *hw) + unsigned int src; + int ret; + ++ /* ++ * When enabling a FOD, all currently enabled FODs are briefly ++ * stopped in order to synchronize all of them. This causes a clock ++ * disruption to any unrelated chips that might be already using ++ * other clock outputs. Bypass the sync feature to avoid the issue, ++ * which is possible on the VersaClock 6E family via reserved ++ * registers. ++ */ ++ if (vc5->chip_info->flags & VC5_HAS_BYPASS_SYNC_BIT) { ++ ret = regmap_update_bits(vc5->regmap, ++ VC5_RESERVED_X0(hwdata->num), ++ VC5_RESERVED_X0_BYPASS_SYNC, ++ VC5_RESERVED_X0_BYPASS_SYNC); ++ if (ret) ++ return ret; ++ } ++ + /* + * If the input mux is disabled, enable it first and + * select source from matching FOD. +@@ -1166,7 +1187,7 @@ static const struct vc5_chip_info idt_5p49v6965_info = { + .model = IDT_VC6_5P49V6965, + .clk_fod_cnt = 4, + .clk_out_cnt = 5, +- .flags = 0, ++ .flags = VC5_HAS_BYPASS_SYNC_BIT, + }; + + static const struct i2c_device_id vc5_id[] = { +diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c +index b08019e1faf99..c491bc9c61ce7 100644 +--- a/drivers/clk/imx/clk-imx8mq.c ++++ b/drivers/clk/imx/clk-imx8mq.c +@@ -358,46 +358,26 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) + hws[IMX8MQ_VIDEO2_PLL_OUT] = imx_clk_hw_sscg_pll("video2_pll_out", video2_pll_out_sels, ARRAY_SIZE(video2_pll_out_sels), 0, 0, 0, base + 0x54, 0); + + /* SYS PLL1 fixed output */ +- hws[IMX8MQ_SYS1_PLL_40M_CG] = imx_clk_hw_gate("sys1_pll_40m_cg", "sys1_pll_out", base + 0x30, 9); +- hws[IMX8MQ_SYS1_PLL_80M_CG] = imx_clk_hw_gate("sys1_pll_80m_cg", "sys1_pll_out", base + 0x30, 11); +- hws[IMX8MQ_SYS1_PLL_100M_CG] = imx_clk_hw_gate("sys1_pll_100m_cg", "sys1_pll_out", base + 0x30, 13); +- hws[IMX8MQ_SYS1_PLL_133M_CG] = imx_clk_hw_gate("sys1_pll_133m_cg", "sys1_pll_out", base + 0x30, 15); +- hws[IMX8MQ_SYS1_PLL_160M_CG] = imx_clk_hw_gate("sys1_pll_160m_cg", "sys1_pll_out", base + 0x30, 17); +- hws[IMX8MQ_SYS1_PLL_200M_CG] = imx_clk_hw_gate("sys1_pll_200m_cg", "sys1_pll_out", base + 0x30, 19); +- hws[IMX8MQ_SYS1_PLL_266M_CG] = imx_clk_hw_gate("sys1_pll_266m_cg", "sys1_pll_out", base + 0x30, 21); +- hws[IMX8MQ_SYS1_PLL_400M_CG] = imx_clk_hw_gate("sys1_pll_400m_cg", "sys1_pll_out", base + 0x30, 23); +- hws[IMX8MQ_SYS1_PLL_800M_CG] = imx_clk_hw_gate("sys1_pll_800m_cg", "sys1_pll_out", base + 0x30, 25); +- +- hws[IMX8MQ_SYS1_PLL_40M] = imx_clk_hw_fixed_factor("sys1_pll_40m", "sys1_pll_40m_cg", 1, 20); +- hws[IMX8MQ_SYS1_PLL_80M] = imx_clk_hw_fixed_factor("sys1_pll_80m", "sys1_pll_80m_cg", 1, 10); +- hws[IMX8MQ_SYS1_PLL_100M] = imx_clk_hw_fixed_factor("sys1_pll_100m", "sys1_pll_100m_cg", 1, 8); +- hws[IMX8MQ_SYS1_PLL_133M] = imx_clk_hw_fixed_factor("sys1_pll_133m", "sys1_pll_133m_cg", 1, 6); +- hws[IMX8MQ_SYS1_PLL_160M] = imx_clk_hw_fixed_factor("sys1_pll_160m", "sys1_pll_160m_cg", 1, 5); +- hws[IMX8MQ_SYS1_PLL_200M] = imx_clk_hw_fixed_factor("sys1_pll_200m", "sys1_pll_200m_cg", 1, 4); +- hws[IMX8MQ_SYS1_PLL_266M] = imx_clk_hw_fixed_factor("sys1_pll_266m", "sys1_pll_266m_cg", 1, 3); +- hws[IMX8MQ_SYS1_PLL_400M] = imx_clk_hw_fixed_factor("sys1_pll_400m", "sys1_pll_400m_cg", 1, 2); +- hws[IMX8MQ_SYS1_PLL_800M] = imx_clk_hw_fixed_factor("sys1_pll_800m", "sys1_pll_800m_cg", 1, 1); ++ hws[IMX8MQ_SYS1_PLL_40M] = imx_clk_hw_fixed_factor("sys1_pll_40m", "sys1_pll_out", 1, 20); ++ hws[IMX8MQ_SYS1_PLL_80M] = imx_clk_hw_fixed_factor("sys1_pll_80m", "sys1_pll_out", 1, 10); ++ hws[IMX8MQ_SYS1_PLL_100M] = imx_clk_hw_fixed_factor("sys1_pll_100m", "sys1_pll_out", 1, 8); ++ hws[IMX8MQ_SYS1_PLL_133M] = imx_clk_hw_fixed_factor("sys1_pll_133m", "sys1_pll_out", 1, 6); ++ hws[IMX8MQ_SYS1_PLL_160M] = imx_clk_hw_fixed_factor("sys1_pll_160m", "sys1_pll_out", 1, 5); ++ hws[IMX8MQ_SYS1_PLL_200M] = imx_clk_hw_fixed_factor("sys1_pll_200m", "sys1_pll_out", 1, 4); ++ hws[IMX8MQ_SYS1_PLL_266M] = imx_clk_hw_fixed_factor("sys1_pll_266m", "sys1_pll_out", 1, 3); ++ hws[IMX8MQ_SYS1_PLL_400M] = imx_clk_hw_fixed_factor("sys1_pll_400m", "sys1_pll_out", 1, 2); ++ hws[IMX8MQ_SYS1_PLL_800M] = imx_clk_hw_fixed_factor("sys1_pll_800m", "sys1_pll_out", 1, 1); + + /* SYS PLL2 fixed output */ +- hws[IMX8MQ_SYS2_PLL_50M_CG] = imx_clk_hw_gate("sys2_pll_50m_cg", "sys2_pll_out", base + 0x3c, 9); +- hws[IMX8MQ_SYS2_PLL_100M_CG] = imx_clk_hw_gate("sys2_pll_100m_cg", "sys2_pll_out", base + 0x3c, 11); +- hws[IMX8MQ_SYS2_PLL_125M_CG] = imx_clk_hw_gate("sys2_pll_125m_cg", "sys2_pll_out", base + 0x3c, 13); +- hws[IMX8MQ_SYS2_PLL_166M_CG] = imx_clk_hw_gate("sys2_pll_166m_cg", "sys2_pll_out", base + 0x3c, 15); +- hws[IMX8MQ_SYS2_PLL_200M_CG] = imx_clk_hw_gate("sys2_pll_200m_cg", "sys2_pll_out", base + 0x3c, 17); +- hws[IMX8MQ_SYS2_PLL_250M_CG] = imx_clk_hw_gate("sys2_pll_250m_cg", "sys2_pll_out", base + 0x3c, 19); +- hws[IMX8MQ_SYS2_PLL_333M_CG] = imx_clk_hw_gate("sys2_pll_333m_cg", "sys2_pll_out", base + 0x3c, 21); +- hws[IMX8MQ_SYS2_PLL_500M_CG] = imx_clk_hw_gate("sys2_pll_500m_cg", "sys2_pll_out", base + 0x3c, 23); +- hws[IMX8MQ_SYS2_PLL_1000M_CG] = imx_clk_hw_gate("sys2_pll_1000m_cg", "sys2_pll_out", base + 0x3c, 25); +- +- hws[IMX8MQ_SYS2_PLL_50M] = imx_clk_hw_fixed_factor("sys2_pll_50m", "sys2_pll_50m_cg", 1, 20); +- hws[IMX8MQ_SYS2_PLL_100M] = imx_clk_hw_fixed_factor("sys2_pll_100m", "sys2_pll_100m_cg", 1, 10); +- hws[IMX8MQ_SYS2_PLL_125M] = imx_clk_hw_fixed_factor("sys2_pll_125m", "sys2_pll_125m_cg", 1, 8); +- hws[IMX8MQ_SYS2_PLL_166M] = imx_clk_hw_fixed_factor("sys2_pll_166m", "sys2_pll_166m_cg", 1, 6); +- hws[IMX8MQ_SYS2_PLL_200M] = imx_clk_hw_fixed_factor("sys2_pll_200m", "sys2_pll_200m_cg", 1, 5); +- hws[IMX8MQ_SYS2_PLL_250M] = imx_clk_hw_fixed_factor("sys2_pll_250m", "sys2_pll_250m_cg", 1, 4); +- hws[IMX8MQ_SYS2_PLL_333M] = imx_clk_hw_fixed_factor("sys2_pll_333m", "sys2_pll_333m_cg", 1, 3); +- hws[IMX8MQ_SYS2_PLL_500M] = imx_clk_hw_fixed_factor("sys2_pll_500m", "sys2_pll_500m_cg", 1, 2); +- hws[IMX8MQ_SYS2_PLL_1000M] = imx_clk_hw_fixed_factor("sys2_pll_1000m", "sys2_pll_1000m_cg", 1, 1); ++ hws[IMX8MQ_SYS2_PLL_50M] = imx_clk_hw_fixed_factor("sys2_pll_50m", "sys2_pll_out", 1, 20); ++ hws[IMX8MQ_SYS2_PLL_100M] = imx_clk_hw_fixed_factor("sys2_pll_100m", "sys2_pll_out", 1, 10); ++ hws[IMX8MQ_SYS2_PLL_125M] = imx_clk_hw_fixed_factor("sys2_pll_125m", "sys2_pll_out", 1, 8); ++ hws[IMX8MQ_SYS2_PLL_166M] = imx_clk_hw_fixed_factor("sys2_pll_166m", "sys2_pll_out", 1, 6); ++ hws[IMX8MQ_SYS2_PLL_200M] = imx_clk_hw_fixed_factor("sys2_pll_200m", "sys2_pll_out", 1, 5); ++ hws[IMX8MQ_SYS2_PLL_250M] = imx_clk_hw_fixed_factor("sys2_pll_250m", "sys2_pll_out", 1, 4); ++ hws[IMX8MQ_SYS2_PLL_333M] = imx_clk_hw_fixed_factor("sys2_pll_333m", "sys2_pll_out", 1, 3); ++ hws[IMX8MQ_SYS2_PLL_500M] = imx_clk_hw_fixed_factor("sys2_pll_500m", "sys2_pll_out", 1, 2); ++ hws[IMX8MQ_SYS2_PLL_1000M] = imx_clk_hw_fixed_factor("sys2_pll_1000m", "sys2_pll_out", 1, 1); + + hws[IMX8MQ_CLK_MON_AUDIO_PLL1_DIV] = imx_clk_hw_divider("audio_pll1_out_monitor", "audio_pll1_bypass", base + 0x78, 0, 3); + hws[IMX8MQ_CLK_MON_AUDIO_PLL2_DIV] = imx_clk_hw_divider("audio_pll2_out_monitor", "audio_pll2_bypass", base + 0x78, 4, 3); +diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c +index b080359b4645e..a805bac93c113 100644 +--- a/drivers/clk/meson/g12a.c ++++ b/drivers/clk/meson/g12a.c +@@ -1603,7 +1603,7 @@ static struct clk_regmap g12b_cpub_clk_trace = { + }; + + static const struct pll_mult_range g12a_gp0_pll_mult_range = { +- .min = 55, ++ .min = 125, + .max = 255, + }; + +diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c +index c6eb99169ddc7..6f8f0bbc5ab5b 100644 +--- a/drivers/clk/qcom/clk-alpha-pll.c ++++ b/drivers/clk/qcom/clk-alpha-pll.c +@@ -1234,7 +1234,7 @@ static int alpha_pll_fabia_prepare(struct clk_hw *hw) + return ret; + + /* Setup PLL for calibration frequency */ +- regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), cal_l); ++ regmap_write(pll->clkr.regmap, PLL_CAL_L_VAL(pll), cal_l); + + /* Bringup the PLL at calibration frequency */ + ret = clk_alpha_pll_enable(hw); +diff --git a/drivers/clk/qcom/gcc-sc7280.c b/drivers/clk/qcom/gcc-sc7280.c +index ef734db316df8..6cefcdc869905 100644 +--- a/drivers/clk/qcom/gcc-sc7280.c ++++ b/drivers/clk/qcom/gcc-sc7280.c +@@ -716,6 +716,7 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s2_clk_src[] = { + F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25), ++ F(52174000, P_GCC_GPLL0_OUT_MAIN, 1, 2, 23), + F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15), +diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c +index 946ea2f45bf3b..75ca855e720df 100644 +--- a/drivers/clk/rockchip/clk-rk3568.c ++++ b/drivers/clk/rockchip/clk-rk3568.c +@@ -454,17 +454,17 @@ static struct rockchip_clk_branch rk3568_clk_branches[] __initdata = { + COMPOSITE_NOMUX(CPLL_125M, "cpll_125m", "cpll", CLK_IGNORE_UNUSED, + RK3568_CLKSEL_CON(80), 0, 5, DFLAGS, + RK3568_CLKGATE_CON(35), 10, GFLAGS), ++ COMPOSITE_NOMUX(CPLL_100M, "cpll_100m", "cpll", CLK_IGNORE_UNUSED, ++ RK3568_CLKSEL_CON(82), 0, 5, DFLAGS, ++ RK3568_CLKGATE_CON(35), 11, GFLAGS), + COMPOSITE_NOMUX(CPLL_62P5M, "cpll_62p5", "cpll", CLK_IGNORE_UNUSED, + RK3568_CLKSEL_CON(80), 8, 5, DFLAGS, +- RK3568_CLKGATE_CON(35), 11, GFLAGS), ++ RK3568_CLKGATE_CON(35), 12, GFLAGS), + COMPOSITE_NOMUX(CPLL_50M, "cpll_50m", "cpll", CLK_IGNORE_UNUSED, + RK3568_CLKSEL_CON(81), 0, 5, DFLAGS, +- RK3568_CLKGATE_CON(35), 12, GFLAGS), ++ RK3568_CLKGATE_CON(35), 13, GFLAGS), + COMPOSITE_NOMUX(CPLL_25M, "cpll_25m", "cpll", CLK_IGNORE_UNUSED, + RK3568_CLKSEL_CON(81), 8, 6, DFLAGS, +- RK3568_CLKGATE_CON(35), 13, GFLAGS), +- COMPOSITE_NOMUX(CPLL_100M, "cpll_100m", "cpll", CLK_IGNORE_UNUSED, +- RK3568_CLKSEL_CON(82), 0, 5, DFLAGS, + RK3568_CLKGATE_CON(35), 14, GFLAGS), + COMPOSITE_NOMUX(0, "clk_osc0_div_750k", "xin24m", CLK_IGNORE_UNUSED, + RK3568_CLKSEL_CON(82), 8, 6, DFLAGS, +diff --git a/drivers/clk/socfpga/clk-agilex.c b/drivers/clk/socfpga/clk-agilex.c +index 92a6d740a799d..1cb21ea79c640 100644 +--- a/drivers/clk/socfpga/clk-agilex.c ++++ b/drivers/clk/socfpga/clk-agilex.c +@@ -177,6 +177,8 @@ static const struct clk_parent_data emac_mux[] = { + .name = "emaca_free_clk", }, + { .fw_name = "emacb_free_clk", + .name = "emacb_free_clk", }, ++ { .fw_name = "boot_clk", ++ .name = "boot_clk", }, + }; + + static const struct clk_parent_data noc_mux[] = { +@@ -186,6 +188,41 @@ static const struct clk_parent_data noc_mux[] = { + .name = "boot_clk", }, + }; + ++static const struct clk_parent_data sdmmc_mux[] = { ++ { .fw_name = "sdmmc_free_clk", ++ .name = "sdmmc_free_clk", }, ++ { .fw_name = "boot_clk", ++ .name = "boot_clk", }, ++}; ++ ++static const struct clk_parent_data s2f_user1_mux[] = { ++ { .fw_name = "s2f_user1_free_clk", ++ .name = "s2f_user1_free_clk", }, ++ { .fw_name = "boot_clk", ++ .name = "boot_clk", }, ++}; ++ ++static const struct clk_parent_data psi_mux[] = { ++ { .fw_name = "psi_ref_free_clk", ++ .name = "psi_ref_free_clk", }, ++ { .fw_name = "boot_clk", ++ .name = "boot_clk", }, ++}; ++ ++static const struct clk_parent_data gpio_db_mux[] = { ++ { .fw_name = "gpio_db_free_clk", ++ .name = "gpio_db_free_clk", }, ++ { .fw_name = "boot_clk", ++ .name = "boot_clk", }, ++}; ++ ++static const struct clk_parent_data emac_ptp_mux[] = { ++ { .fw_name = "emac_ptp_free_clk", ++ .name = "emac_ptp_free_clk", }, ++ { .fw_name = "boot_clk", ++ .name = "boot_clk", }, ++}; ++ + /* clocks in AO (always on) controller */ + static const struct stratix10_pll_clock agilex_pll_clks[] = { + { AGILEX_BOOT_CLK, "boot_clk", boot_mux, ARRAY_SIZE(boot_mux), 0, +@@ -222,11 +259,9 @@ static const struct stratix10_perip_cnt_clock agilex_main_perip_cnt_clks[] = { + { AGILEX_MPU_FREE_CLK, "mpu_free_clk", NULL, mpu_free_mux, ARRAY_SIZE(mpu_free_mux), + 0, 0x3C, 0, 0, 0}, + { AGILEX_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux, ARRAY_SIZE(noc_free_mux), +- 0, 0x40, 0, 0, 1}, +- { AGILEX_L4_SYS_FREE_CLK, "l4_sys_free_clk", "noc_free_clk", NULL, 1, 0, +- 0, 4, 0, 0}, +- { AGILEX_NOC_CLK, "noc_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), +- 0, 0, 0, 0x30, 1}, ++ 0, 0x40, 0, 0, 0}, ++ { AGILEX_L4_SYS_FREE_CLK, "l4_sys_free_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, ++ 0, 4, 0x30, 1}, + { AGILEX_EMAC_A_FREE_CLK, "emaca_free_clk", NULL, emaca_free_mux, ARRAY_SIZE(emaca_free_mux), + 0, 0xD4, 0, 0x88, 0}, + { AGILEX_EMAC_B_FREE_CLK, "emacb_free_clk", NULL, emacb_free_mux, ARRAY_SIZE(emacb_free_mux), +@@ -236,7 +271,7 @@ static const struct stratix10_perip_cnt_clock agilex_main_perip_cnt_clks[] = { + { AGILEX_GPIO_DB_FREE_CLK, "gpio_db_free_clk", NULL, gpio_db_free_mux, + ARRAY_SIZE(gpio_db_free_mux), 0, 0xE0, 0, 0x88, 3}, + { AGILEX_SDMMC_FREE_CLK, "sdmmc_free_clk", NULL, sdmmc_free_mux, +- ARRAY_SIZE(sdmmc_free_mux), 0, 0xE4, 0, 0x88, 4}, ++ ARRAY_SIZE(sdmmc_free_mux), 0, 0xE4, 0, 0, 0}, + { AGILEX_S2F_USER0_FREE_CLK, "s2f_user0_free_clk", NULL, s2f_usr0_free_mux, + ARRAY_SIZE(s2f_usr0_free_mux), 0, 0xE8, 0, 0, 0}, + { AGILEX_S2F_USER1_FREE_CLK, "s2f_user1_free_clk", NULL, s2f_usr1_free_mux, +@@ -252,24 +287,24 @@ static const struct stratix10_gate_clock agilex_gate_clks[] = { + 0, 0, 0, 0, 0, 0, 4}, + { AGILEX_MPU_CCU_CLK, "mpu_ccu_clk", "mpu_clk", NULL, 1, 0, 0x24, + 0, 0, 0, 0, 0, 0, 2}, +- { AGILEX_L4_MAIN_CLK, "l4_main_clk", "noc_clk", NULL, 1, 0, 0x24, +- 1, 0x44, 0, 2, 0, 0, 0}, +- { AGILEX_L4_MP_CLK, "l4_mp_clk", "noc_clk", NULL, 1, 0, 0x24, +- 2, 0x44, 8, 2, 0, 0, 0}, ++ { AGILEX_L4_MAIN_CLK, "l4_main_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24, ++ 1, 0x44, 0, 2, 0x30, 1, 0}, ++ { AGILEX_L4_MP_CLK, "l4_mp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24, ++ 2, 0x44, 8, 2, 0x30, 1, 0}, + /* + * The l4_sp_clk feeds a 100 MHz clock to various peripherals, one of them + * being the SP timers, thus cannot get gated. + */ +- { AGILEX_L4_SP_CLK, "l4_sp_clk", "noc_clk", NULL, 1, CLK_IS_CRITICAL, 0x24, +- 3, 0x44, 16, 2, 0, 0, 0}, +- { AGILEX_CS_AT_CLK, "cs_at_clk", "noc_clk", NULL, 1, 0, 0x24, +- 4, 0x44, 24, 2, 0, 0, 0}, +- { AGILEX_CS_TRACE_CLK, "cs_trace_clk", "noc_clk", NULL, 1, 0, 0x24, +- 4, 0x44, 26, 2, 0, 0, 0}, ++ { AGILEX_L4_SP_CLK, "l4_sp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), CLK_IS_CRITICAL, 0x24, ++ 3, 0x44, 16, 2, 0x30, 1, 0}, ++ { AGILEX_CS_AT_CLK, "cs_at_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24, ++ 4, 0x44, 24, 2, 0x30, 1, 0}, ++ { AGILEX_CS_TRACE_CLK, "cs_trace_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24, ++ 4, 0x44, 26, 2, 0x30, 1, 0}, + { AGILEX_CS_PDBG_CLK, "cs_pdbg_clk", "cs_at_clk", NULL, 1, 0, 0x24, + 4, 0x44, 28, 1, 0, 0, 0}, +- { AGILEX_CS_TIMER_CLK, "cs_timer_clk", "noc_clk", NULL, 1, 0, 0x24, +- 5, 0, 0, 0, 0, 0, 0}, ++ { AGILEX_CS_TIMER_CLK, "cs_timer_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24, ++ 5, 0, 0, 0, 0x30, 1, 0}, + { AGILEX_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_usr0_mux, ARRAY_SIZE(s2f_usr0_mux), 0, 0x24, + 6, 0, 0, 0, 0, 0, 0}, + { AGILEX_EMAC0_CLK, "emac0_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C, +@@ -278,16 +313,16 @@ static const struct stratix10_gate_clock agilex_gate_clks[] = { + 1, 0, 0, 0, 0x94, 27, 0}, + { AGILEX_EMAC2_CLK, "emac2_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C, + 2, 0, 0, 0, 0x94, 28, 0}, +- { AGILEX_EMAC_PTP_CLK, "emac_ptp_clk", "emac_ptp_free_clk", NULL, 1, 0, 0x7C, +- 3, 0, 0, 0, 0, 0, 0}, +- { AGILEX_GPIO_DB_CLK, "gpio_db_clk", "gpio_db_free_clk", NULL, 1, 0, 0x7C, +- 4, 0x98, 0, 16, 0, 0, 0}, +- { AGILEX_SDMMC_CLK, "sdmmc_clk", "sdmmc_free_clk", NULL, 1, 0, 0x7C, +- 5, 0, 0, 0, 0, 0, 4}, +- { AGILEX_S2F_USER1_CLK, "s2f_user1_clk", "s2f_user1_free_clk", NULL, 1, 0, 0x7C, +- 6, 0, 0, 0, 0, 0, 0}, +- { AGILEX_PSI_REF_CLK, "psi_ref_clk", "psi_ref_free_clk", NULL, 1, 0, 0x7C, +- 7, 0, 0, 0, 0, 0, 0}, ++ { AGILEX_EMAC_PTP_CLK, "emac_ptp_clk", NULL, emac_ptp_mux, ARRAY_SIZE(emac_ptp_mux), 0, 0x7C, ++ 3, 0, 0, 0, 0x88, 2, 0}, ++ { AGILEX_GPIO_DB_CLK, "gpio_db_clk", NULL, gpio_db_mux, ARRAY_SIZE(gpio_db_mux), 0, 0x7C, ++ 4, 0x98, 0, 16, 0x88, 3, 0}, ++ { AGILEX_SDMMC_CLK, "sdmmc_clk", NULL, sdmmc_mux, ARRAY_SIZE(sdmmc_mux), 0, 0x7C, ++ 5, 0, 0, 0, 0x88, 4, 4}, ++ { AGILEX_S2F_USER1_CLK, "s2f_user1_clk", NULL, s2f_user1_mux, ARRAY_SIZE(s2f_user1_mux), 0, 0x7C, ++ 6, 0, 0, 0, 0x88, 5, 0}, ++ { AGILEX_PSI_REF_CLK, "psi_ref_clk", NULL, psi_mux, ARRAY_SIZE(psi_mux), 0, 0x7C, ++ 7, 0, 0, 0, 0x88, 6, 0}, + { AGILEX_USB_CLK, "usb_clk", "l4_mp_clk", NULL, 1, 0, 0x7C, + 8, 0, 0, 0, 0, 0, 0}, + { AGILEX_SPI_M_CLK, "spi_m_clk", "l4_mp_clk", NULL, 1, 0, 0x7C, +@@ -366,7 +401,7 @@ static int agilex_clk_register_gate(const struct stratix10_gate_clock *clks, + int i; + + for (i = 0; i < nums; i++) { +- hw_clk = s10_register_gate(&clks[i], base); ++ hw_clk = agilex_register_gate(&clks[i], base); + if (IS_ERR(hw_clk)) { + pr_err("%s: failed to register clock %s\n", + __func__, clks[i].name); +diff --git a/drivers/clk/socfpga/clk-gate-s10.c b/drivers/clk/socfpga/clk-gate-s10.c +index b84f2627551e1..32567795765fb 100644 +--- a/drivers/clk/socfpga/clk-gate-s10.c ++++ b/drivers/clk/socfpga/clk-gate-s10.c +@@ -11,6 +11,13 @@ + #define SOCFPGA_CS_PDBG_CLK "cs_pdbg_clk" + #define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, hw.hw) + ++#define SOCFPGA_EMAC0_CLK "emac0_clk" ++#define SOCFPGA_EMAC1_CLK "emac1_clk" ++#define SOCFPGA_EMAC2_CLK "emac2_clk" ++#define AGILEX_BYPASS_OFFSET 0xC ++#define STRATIX10_BYPASS_OFFSET 0x2C ++#define BOOTCLK_BYPASS 2 ++ + static unsigned long socfpga_gate_clk_recalc_rate(struct clk_hw *hwclk, + unsigned long parent_rate) + { +@@ -44,14 +51,61 @@ static unsigned long socfpga_dbg_clk_recalc_rate(struct clk_hw *hwclk, + static u8 socfpga_gate_get_parent(struct clk_hw *hwclk) + { + struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk); +- u32 mask; ++ u32 mask, second_bypass; ++ u8 parent = 0; ++ const char *name = clk_hw_get_name(hwclk); ++ ++ if (socfpgaclk->bypass_reg) { ++ mask = (0x1 << socfpgaclk->bypass_shift); ++ parent = ((readl(socfpgaclk->bypass_reg) & mask) >> ++ socfpgaclk->bypass_shift); ++ } ++ ++ if (streq(name, SOCFPGA_EMAC0_CLK) || ++ streq(name, SOCFPGA_EMAC1_CLK) || ++ streq(name, SOCFPGA_EMAC2_CLK)) { ++ second_bypass = readl(socfpgaclk->bypass_reg - ++ STRATIX10_BYPASS_OFFSET); ++ /* EMACA bypass to bootclk @0xB0 offset */ ++ if (second_bypass & 0x1) ++ if (parent == 0) /* only applicable if parent is maca */ ++ parent = BOOTCLK_BYPASS; ++ ++ if (second_bypass & 0x2) ++ if (parent == 1) /* only applicable if parent is macb */ ++ parent = BOOTCLK_BYPASS; ++ } ++ return parent; ++} ++ ++static u8 socfpga_agilex_gate_get_parent(struct clk_hw *hwclk) ++{ ++ struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk); ++ u32 mask, second_bypass; + u8 parent = 0; ++ const char *name = clk_hw_get_name(hwclk); + + if (socfpgaclk->bypass_reg) { + mask = (0x1 << socfpgaclk->bypass_shift); + parent = ((readl(socfpgaclk->bypass_reg) & mask) >> + socfpgaclk->bypass_shift); + } ++ ++ if (streq(name, SOCFPGA_EMAC0_CLK) || ++ streq(name, SOCFPGA_EMAC1_CLK) || ++ streq(name, SOCFPGA_EMAC2_CLK)) { ++ second_bypass = readl(socfpgaclk->bypass_reg - ++ AGILEX_BYPASS_OFFSET); ++ /* EMACA bypass to bootclk @0x88 offset */ ++ if (second_bypass & 0x1) ++ if (parent == 0) /* only applicable if parent is maca */ ++ parent = BOOTCLK_BYPASS; ++ ++ if (second_bypass & 0x2) ++ if (parent == 1) /* only applicable if parent is macb */ ++ parent = BOOTCLK_BYPASS; ++ } ++ + return parent; + } + +@@ -60,6 +114,11 @@ static struct clk_ops gateclk_ops = { + .get_parent = socfpga_gate_get_parent, + }; + ++static const struct clk_ops agilex_gateclk_ops = { ++ .recalc_rate = socfpga_gate_clk_recalc_rate, ++ .get_parent = socfpga_agilex_gate_get_parent, ++}; ++ + static const struct clk_ops dbgclk_ops = { + .recalc_rate = socfpga_dbg_clk_recalc_rate, + .get_parent = socfpga_gate_get_parent, +@@ -122,3 +181,61 @@ struct clk_hw *s10_register_gate(const struct stratix10_gate_clock *clks, void _ + } + return hw_clk; + } ++ ++struct clk_hw *agilex_register_gate(const struct stratix10_gate_clock *clks, void __iomem *regbase) ++{ ++ struct clk_hw *hw_clk; ++ struct socfpga_gate_clk *socfpga_clk; ++ struct clk_init_data init; ++ const char *parent_name = clks->parent_name; ++ int ret; ++ ++ socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL); ++ if (!socfpga_clk) ++ return NULL; ++ ++ socfpga_clk->hw.reg = regbase + clks->gate_reg; ++ socfpga_clk->hw.bit_idx = clks->gate_idx; ++ ++ gateclk_ops.enable = clk_gate_ops.enable; ++ gateclk_ops.disable = clk_gate_ops.disable; ++ ++ socfpga_clk->fixed_div = clks->fixed_div; ++ ++ if (clks->div_reg) ++ socfpga_clk->div_reg = regbase + clks->div_reg; ++ else ++ socfpga_clk->div_reg = NULL; ++ ++ socfpga_clk->width = clks->div_width; ++ socfpga_clk->shift = clks->div_offset; ++ ++ if (clks->bypass_reg) ++ socfpga_clk->bypass_reg = regbase + clks->bypass_reg; ++ else ++ socfpga_clk->bypass_reg = NULL; ++ socfpga_clk->bypass_shift = clks->bypass_shift; ++ ++ if (streq(clks->name, "cs_pdbg_clk")) ++ init.ops = &dbgclk_ops; ++ else ++ init.ops = &agilex_gateclk_ops; ++ ++ init.name = clks->name; ++ init.flags = clks->flags; ++ ++ init.num_parents = clks->num_parents; ++ init.parent_names = parent_name ? &parent_name : NULL; ++ if (init.parent_names == NULL) ++ init.parent_data = clks->parent_data; ++ socfpga_clk->hw.hw.init = &init; ++ ++ hw_clk = &socfpga_clk->hw.hw; ++ ++ ret = clk_hw_register(NULL, &socfpga_clk->hw.hw); ++ if (ret) { ++ kfree(socfpga_clk); ++ return ERR_PTR(ret); ++ } ++ return hw_clk; ++} +diff --git a/drivers/clk/socfpga/clk-periph-s10.c b/drivers/clk/socfpga/clk-periph-s10.c +index e5a5fef76df70..cbabde2b476bf 100644 +--- a/drivers/clk/socfpga/clk-periph-s10.c ++++ b/drivers/clk/socfpga/clk-periph-s10.c +@@ -64,16 +64,21 @@ static u8 clk_periclk_get_parent(struct clk_hw *hwclk) + { + struct socfpga_periph_clk *socfpgaclk = to_periph_clk(hwclk); + u32 clk_src, mask; +- u8 parent; ++ u8 parent = 0; + ++ /* handle the bypass first */ + if (socfpgaclk->bypass_reg) { + mask = (0x1 << socfpgaclk->bypass_shift); + parent = ((readl(socfpgaclk->bypass_reg) & mask) >> + socfpgaclk->bypass_shift); +- } else { ++ if (parent) ++ return parent; ++ } ++ ++ if (socfpgaclk->hw.reg) { + clk_src = readl(socfpgaclk->hw.reg); + parent = (clk_src >> CLK_MGR_FREE_SHIFT) & +- CLK_MGR_FREE_MASK; ++ CLK_MGR_FREE_MASK; + } + return parent; + } +diff --git a/drivers/clk/socfpga/clk-s10.c b/drivers/clk/socfpga/clk-s10.c +index f0bd77138ecb4..b532d51faaee5 100644 +--- a/drivers/clk/socfpga/clk-s10.c ++++ b/drivers/clk/socfpga/clk-s10.c +@@ -144,6 +144,41 @@ static const struct clk_parent_data mpu_free_mux[] = { + .name = "f2s-free-clk", }, + }; + ++static const struct clk_parent_data sdmmc_mux[] = { ++ { .fw_name = "sdmmc_free_clk", ++ .name = "sdmmc_free_clk", }, ++ { .fw_name = "boot_clk", ++ .name = "boot_clk", }, ++}; ++ ++static const struct clk_parent_data s2f_user1_mux[] = { ++ { .fw_name = "s2f_user1_free_clk", ++ .name = "s2f_user1_free_clk", }, ++ { .fw_name = "boot_clk", ++ .name = "boot_clk", }, ++}; ++ ++static const struct clk_parent_data psi_mux[] = { ++ { .fw_name = "psi_ref_free_clk", ++ .name = "psi_ref_free_clk", }, ++ { .fw_name = "boot_clk", ++ .name = "boot_clk", }, ++}; ++ ++static const struct clk_parent_data gpio_db_mux[] = { ++ { .fw_name = "gpio_db_free_clk", ++ .name = "gpio_db_free_clk", }, ++ { .fw_name = "boot_clk", ++ .name = "boot_clk", }, ++}; ++ ++static const struct clk_parent_data emac_ptp_mux[] = { ++ { .fw_name = "emac_ptp_free_clk", ++ .name = "emac_ptp_free_clk", }, ++ { .fw_name = "boot_clk", ++ .name = "boot_clk", }, ++}; ++ + /* clocks in AO (always on) controller */ + static const struct stratix10_pll_clock s10_pll_clks[] = { + { STRATIX10_BOOT_CLK, "boot_clk", boot_mux, ARRAY_SIZE(boot_mux), 0, +@@ -167,7 +202,7 @@ static const struct stratix10_perip_cnt_clock s10_main_perip_cnt_clks[] = { + { STRATIX10_MPU_FREE_CLK, "mpu_free_clk", NULL, mpu_free_mux, ARRAY_SIZE(mpu_free_mux), + 0, 0x48, 0, 0, 0}, + { STRATIX10_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux, ARRAY_SIZE(noc_free_mux), +- 0, 0x4C, 0, 0, 0}, ++ 0, 0x4C, 0, 0x3C, 1}, + { STRATIX10_MAIN_EMACA_CLK, "main_emaca_clk", "main_noc_base_clk", NULL, 1, 0, + 0x50, 0, 0, 0}, + { STRATIX10_MAIN_EMACB_CLK, "main_emacb_clk", "main_noc_base_clk", NULL, 1, 0, +@@ -200,10 +235,8 @@ static const struct stratix10_perip_cnt_clock s10_main_perip_cnt_clks[] = { + 0, 0xD4, 0, 0, 0}, + { STRATIX10_PERI_PSI_REF_CLK, "peri_psi_ref_clk", "peri_noc_base_clk", NULL, 1, 0, + 0xD8, 0, 0, 0}, +- { STRATIX10_L4_SYS_FREE_CLK, "l4_sys_free_clk", "noc_free_clk", NULL, 1, 0, +- 0, 4, 0, 0}, +- { STRATIX10_NOC_CLK, "noc_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), +- 0, 0, 0, 0x3C, 1}, ++ { STRATIX10_L4_SYS_FREE_CLK, "l4_sys_free_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, ++ 0, 4, 0x3C, 1}, + { STRATIX10_EMAC_A_FREE_CLK, "emaca_free_clk", NULL, emaca_free_mux, ARRAY_SIZE(emaca_free_mux), + 0, 0, 2, 0xB0, 0}, + { STRATIX10_EMAC_B_FREE_CLK, "emacb_free_clk", NULL, emacb_free_mux, ARRAY_SIZE(emacb_free_mux), +@@ -227,20 +260,20 @@ static const struct stratix10_gate_clock s10_gate_clks[] = { + 0, 0, 0, 0, 0, 0, 4}, + { STRATIX10_MPU_L2RAM_CLK, "mpu_l2ram_clk", "mpu_clk", NULL, 1, 0, 0x30, + 0, 0, 0, 0, 0, 0, 2}, +- { STRATIX10_L4_MAIN_CLK, "l4_main_clk", "noc_clk", NULL, 1, 0, 0x30, +- 1, 0x70, 0, 2, 0, 0, 0}, +- { STRATIX10_L4_MP_CLK, "l4_mp_clk", "noc_clk", NULL, 1, 0, 0x30, +- 2, 0x70, 8, 2, 0, 0, 0}, +- { STRATIX10_L4_SP_CLK, "l4_sp_clk", "noc_clk", NULL, 1, CLK_IS_CRITICAL, 0x30, +- 3, 0x70, 16, 2, 0, 0, 0}, +- { STRATIX10_CS_AT_CLK, "cs_at_clk", "noc_clk", NULL, 1, 0, 0x30, +- 4, 0x70, 24, 2, 0, 0, 0}, +- { STRATIX10_CS_TRACE_CLK, "cs_trace_clk", "noc_clk", NULL, 1, 0, 0x30, +- 4, 0x70, 26, 2, 0, 0, 0}, ++ { STRATIX10_L4_MAIN_CLK, "l4_main_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30, ++ 1, 0x70, 0, 2, 0x3C, 1, 0}, ++ { STRATIX10_L4_MP_CLK, "l4_mp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30, ++ 2, 0x70, 8, 2, 0x3C, 1, 0}, ++ { STRATIX10_L4_SP_CLK, "l4_sp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), CLK_IS_CRITICAL, 0x30, ++ 3, 0x70, 16, 2, 0x3C, 1, 0}, ++ { STRATIX10_CS_AT_CLK, "cs_at_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30, ++ 4, 0x70, 24, 2, 0x3C, 1, 0}, ++ { STRATIX10_CS_TRACE_CLK, "cs_trace_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30, ++ 4, 0x70, 26, 2, 0x3C, 1, 0}, + { STRATIX10_CS_PDBG_CLK, "cs_pdbg_clk", "cs_at_clk", NULL, 1, 0, 0x30, + 4, 0x70, 28, 1, 0, 0, 0}, +- { STRATIX10_CS_TIMER_CLK, "cs_timer_clk", "noc_clk", NULL, 1, 0, 0x30, +- 5, 0, 0, 0, 0, 0, 0}, ++ { STRATIX10_CS_TIMER_CLK, "cs_timer_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30, ++ 5, 0, 0, 0, 0x3C, 1, 0}, + { STRATIX10_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_usr0_mux, ARRAY_SIZE(s2f_usr0_mux), 0, 0x30, + 6, 0, 0, 0, 0, 0, 0}, + { STRATIX10_EMAC0_CLK, "emac0_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0xA4, +@@ -249,16 +282,16 @@ static const struct stratix10_gate_clock s10_gate_clks[] = { + 1, 0, 0, 0, 0xDC, 27, 0}, + { STRATIX10_EMAC2_CLK, "emac2_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0xA4, + 2, 0, 0, 0, 0xDC, 28, 0}, +- { STRATIX10_EMAC_PTP_CLK, "emac_ptp_clk", "emac_ptp_free_clk", NULL, 1, 0, 0xA4, +- 3, 0, 0, 0, 0, 0, 0}, +- { STRATIX10_GPIO_DB_CLK, "gpio_db_clk", "gpio_db_free_clk", NULL, 1, 0, 0xA4, +- 4, 0xE0, 0, 16, 0, 0, 0}, +- { STRATIX10_SDMMC_CLK, "sdmmc_clk", "sdmmc_free_clk", NULL, 1, 0, 0xA4, +- 5, 0, 0, 0, 0, 0, 4}, +- { STRATIX10_S2F_USER1_CLK, "s2f_user1_clk", "s2f_user1_free_clk", NULL, 1, 0, 0xA4, +- 6, 0, 0, 0, 0, 0, 0}, +- { STRATIX10_PSI_REF_CLK, "psi_ref_clk", "psi_ref_free_clk", NULL, 1, 0, 0xA4, +- 7, 0, 0, 0, 0, 0, 0}, ++ { STRATIX10_EMAC_PTP_CLK, "emac_ptp_clk", NULL, emac_ptp_mux, ARRAY_SIZE(emac_ptp_mux), 0, 0xA4, ++ 3, 0, 0, 0, 0xB0, 2, 0}, ++ { STRATIX10_GPIO_DB_CLK, "gpio_db_clk", NULL, gpio_db_mux, ARRAY_SIZE(gpio_db_mux), 0, 0xA4, ++ 4, 0xE0, 0, 16, 0xB0, 3, 0}, ++ { STRATIX10_SDMMC_CLK, "sdmmc_clk", NULL, sdmmc_mux, ARRAY_SIZE(sdmmc_mux), 0, 0xA4, ++ 5, 0, 0, 0, 0xB0, 4, 4}, ++ { STRATIX10_S2F_USER1_CLK, "s2f_user1_clk", NULL, s2f_user1_mux, ARRAY_SIZE(s2f_user1_mux), 0, 0xA4, ++ 6, 0, 0, 0, 0xB0, 5, 0}, ++ { STRATIX10_PSI_REF_CLK, "psi_ref_clk", NULL, psi_mux, ARRAY_SIZE(psi_mux), 0, 0xA4, ++ 7, 0, 0, 0, 0xB0, 6, 0}, + { STRATIX10_USB_CLK, "usb_clk", "l4_mp_clk", NULL, 1, 0, 0xA4, + 8, 0, 0, 0, 0, 0, 0}, + { STRATIX10_SPI_M_CLK, "spi_m_clk", "l4_mp_clk", NULL, 1, 0, 0xA4, +diff --git a/drivers/clk/socfpga/stratix10-clk.h b/drivers/clk/socfpga/stratix10-clk.h +index 61eaf3a41fbb8..75234e0783e1c 100644 +--- a/drivers/clk/socfpga/stratix10-clk.h ++++ b/drivers/clk/socfpga/stratix10-clk.h +@@ -85,4 +85,6 @@ struct clk_hw *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *c + void __iomem *reg); + struct clk_hw *s10_register_gate(const struct stratix10_gate_clock *clks, + void __iomem *reg); ++struct clk_hw *agilex_register_gate(const struct stratix10_gate_clock *clks, ++ void __iomem *reg); + #endif /* __STRATIX10_CLK_H */ +diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c +index a774942cb153a..f49724a22540e 100644 +--- a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c ++++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c +@@ -817,10 +817,10 @@ static void __init sun8i_v3_v3s_ccu_init(struct device_node *node, + return; + } + +- /* Force the PLL-Audio-1x divider to 4 */ ++ /* Force the PLL-Audio-1x divider to 1 */ + val = readl(reg + SUN8I_V3S_PLL_AUDIO_REG); + val &= ~GENMASK(19, 16); +- writel(val | (3 << 16), reg + SUN8I_V3S_PLL_AUDIO_REG); ++ writel(val, reg + SUN8I_V3S_PLL_AUDIO_REG); + + sunxi_ccu_probe(node, reg, ccu_desc); + } +diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c +index 16dbf83d2f62a..a33688b2359e5 100644 +--- a/drivers/clk/tegra/clk-tegra30.c ++++ b/drivers/clk/tegra/clk-tegra30.c +@@ -1245,7 +1245,7 @@ static struct tegra_clk_init_table init_table[] __initdata = { + { TEGRA30_CLK_GR3D, TEGRA30_CLK_PLL_C, 300000000, 0 }, + { TEGRA30_CLK_GR3D2, TEGRA30_CLK_PLL_C, 300000000, 0 }, + { TEGRA30_CLK_PLL_U, TEGRA30_CLK_CLK_MAX, 480000000, 0 }, +- { TEGRA30_CLK_VDE, TEGRA30_CLK_PLL_C, 600000000, 0 }, ++ { TEGRA30_CLK_VDE, TEGRA30_CLK_PLL_C, 300000000, 0 }, + { TEGRA30_CLK_SPDIF_IN_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, + { TEGRA30_CLK_I2S0_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, + { TEGRA30_CLK_I2S1_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, +diff --git a/drivers/clk/zynqmp/clk-mux-zynqmp.c b/drivers/clk/zynqmp/clk-mux-zynqmp.c +index 06194149be831..d576c900dee06 100644 +--- a/drivers/clk/zynqmp/clk-mux-zynqmp.c ++++ b/drivers/clk/zynqmp/clk-mux-zynqmp.c +@@ -38,7 +38,7 @@ struct zynqmp_clk_mux { + * zynqmp_clk_mux_get_parent() - Get parent of clock + * @hw: handle between common and hardware-specific interfaces + * +- * Return: Parent index ++ * Return: Parent index on success or number of parents in case of error + */ + static u8 zynqmp_clk_mux_get_parent(struct clk_hw *hw) + { +@@ -50,9 +50,15 @@ static u8 zynqmp_clk_mux_get_parent(struct clk_hw *hw) + + ret = zynqmp_pm_clock_getparent(clk_id, &val); + +- if (ret) ++ if (ret) { + pr_warn_once("%s() getparent failed for clock: %s, ret = %d\n", + __func__, clk_name, ret); ++ /* ++ * clk_core_get_parent_by_index() takes num_parents as incorrect ++ * index which is exactly what I want to return here ++ */ ++ return clk_hw_get_num_parents(hw); ++ } + + return val; + } +diff --git a/drivers/clk/zynqmp/pll.c b/drivers/clk/zynqmp/pll.c +index abe6afbf3407b..e025581f0d54a 100644 +--- a/drivers/clk/zynqmp/pll.c ++++ b/drivers/clk/zynqmp/pll.c +@@ -31,8 +31,9 @@ struct zynqmp_pll { + #define PS_PLL_VCO_MAX 3000000000UL + + enum pll_mode { +- PLL_MODE_INT, +- PLL_MODE_FRAC, ++ PLL_MODE_INT = 0, ++ PLL_MODE_FRAC = 1, ++ PLL_MODE_ERROR = 2, + }; + + #define FRAC_OFFSET 0x8 +@@ -54,9 +55,11 @@ static inline enum pll_mode zynqmp_pll_get_mode(struct clk_hw *hw) + int ret; + + ret = zynqmp_pm_get_pll_frac_mode(clk_id, ret_payload); +- if (ret) ++ if (ret) { + pr_warn_once("%s() PLL get frac mode failed for %s, ret = %d\n", + __func__, clk_name, ret); ++ return PLL_MODE_ERROR; ++ } + + return ret_payload[1]; + } +@@ -126,7 +129,7 @@ static long zynqmp_pll_round_rate(struct clk_hw *hw, unsigned long rate, + * @hw: Handle between common and hardware-specific interfaces + * @parent_rate: Clock frequency of parent clock + * +- * Return: Current clock frequency ++ * Return: Current clock frequency or 0 in case of error + */ + static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +@@ -138,14 +141,21 @@ static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw, + unsigned long rate, frac; + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; ++ enum pll_mode mode; + + ret = zynqmp_pm_clock_getdivider(clk_id, &fbdiv); +- if (ret) ++ if (ret) { + pr_warn_once("%s() get divider failed for %s, ret = %d\n", + __func__, clk_name, ret); ++ return 0ul; ++ } ++ ++ mode = zynqmp_pll_get_mode(hw); ++ if (mode == PLL_MODE_ERROR) ++ return 0ul; + + rate = parent_rate * fbdiv; +- if (zynqmp_pll_get_mode(hw) == PLL_MODE_FRAC) { ++ if (mode == PLL_MODE_FRAC) { + zynqmp_pm_get_pll_frac_data(clk_id, ret_payload); + data = ret_payload[1]; + frac = (parent_rate * data) / FRAC_DIV; +diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c +index 33eeabf9c3d12..e5c631f1b5cbe 100644 +--- a/drivers/clocksource/timer-ti-dm.c ++++ b/drivers/clocksource/timer-ti-dm.c +@@ -78,6 +78,9 @@ static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg, + + static void omap_timer_restore_context(struct omap_dm_timer *timer) + { ++ __omap_dm_timer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET, ++ timer->context.ocp_cfg, 0); ++ + omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, + timer->context.twer); + omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, +@@ -95,6 +98,9 @@ static void omap_timer_restore_context(struct omap_dm_timer *timer) + + static void omap_timer_save_context(struct omap_dm_timer *timer) + { ++ timer->context.ocp_cfg = ++ __omap_dm_timer_read(timer, OMAP_TIMER_OCP_CFG_OFFSET, 0); ++ + timer->context.tclr = + omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); + timer->context.twer = +diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c +index 802abc925b2ae..cbab834c37a03 100644 +--- a/drivers/cpufreq/cpufreq.c ++++ b/drivers/cpufreq/cpufreq.c +@@ -1367,9 +1367,14 @@ static int cpufreq_online(unsigned int cpu) + goto out_free_policy; + } + ++ /* ++ * The initialization has succeeded and the policy is online. ++ * If there is a problem with its frequency table, take it ++ * offline and drop it. ++ */ + ret = cpufreq_table_validate_and_sort(policy); + if (ret) +- goto out_exit_policy; ++ goto out_offline_policy; + + /* related_cpus should at least include policy->cpus. */ + cpumask_copy(policy->related_cpus, policy->cpus); +@@ -1515,6 +1520,10 @@ out_destroy_policy: + + up_write(&policy->rwsem); + ++out_offline_policy: ++ if (cpufreq_driver->offline) ++ cpufreq_driver->offline(policy); ++ + out_exit_policy: + if (cpufreq_driver->exit) + cpufreq_driver->exit(policy); +diff --git a/drivers/crypto/cavium/nitrox/nitrox_isr.c b/drivers/crypto/cavium/nitrox/nitrox_isr.c +index c288c4b51783d..f19e520da6d0c 100644 +--- a/drivers/crypto/cavium/nitrox/nitrox_isr.c ++++ b/drivers/crypto/cavium/nitrox/nitrox_isr.c +@@ -307,6 +307,10 @@ int nitrox_register_interrupts(struct nitrox_device *ndev) + * Entry 192: NPS_CORE_INT_ACTIVE + */ + nr_vecs = pci_msix_vec_count(pdev); ++ if (nr_vecs < 0) { ++ dev_err(DEV(ndev), "Error in getting vec count %d\n", nr_vecs); ++ return nr_vecs; ++ } + + /* Enable MSI-X */ + ret = pci_alloc_irq_vectors(pdev, nr_vecs, nr_vecs, PCI_IRQ_MSIX); +diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c +index 3506b2050fb86..91808402e0bf2 100644 +--- a/drivers/crypto/ccp/sev-dev.c ++++ b/drivers/crypto/ccp/sev-dev.c +@@ -43,6 +43,10 @@ static int psp_probe_timeout = 5; + module_param(psp_probe_timeout, int, 0644); + MODULE_PARM_DESC(psp_probe_timeout, " default timeout value, in seconds, during PSP device probe"); + ++MODULE_FIRMWARE("amd/amd_sev_fam17h_model0xh.sbin"); /* 1st gen EPYC */ ++MODULE_FIRMWARE("amd/amd_sev_fam17h_model3xh.sbin"); /* 2nd gen EPYC */ ++MODULE_FIRMWARE("amd/amd_sev_fam19h_model0xh.sbin"); /* 3rd gen EPYC */ ++ + static bool psp_dead; + static int psp_timeout; + +diff --git a/drivers/crypto/ccp/sp-pci.c b/drivers/crypto/ccp/sp-pci.c +index f468594ef8afa..6fb6ba35f89d4 100644 +--- a/drivers/crypto/ccp/sp-pci.c ++++ b/drivers/crypto/ccp/sp-pci.c +@@ -222,7 +222,7 @@ static int sp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) + if (ret) { + dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n", + ret); +- goto e_err; ++ goto free_irqs; + } + } + +@@ -230,10 +230,12 @@ static int sp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) + + ret = sp_init(sp); + if (ret) +- goto e_err; ++ goto free_irqs; + + return 0; + ++free_irqs: ++ sp_free_irqs(sp); + e_err: + dev_notice(dev, "initialization failed\n"); + return ret; +diff --git a/drivers/crypto/hisilicon/hpre/hpre_crypto.c b/drivers/crypto/hisilicon/hpre/hpre_crypto.c +index a380087c83f77..782ddffa5d904 100644 +--- a/drivers/crypto/hisilicon/hpre/hpre_crypto.c ++++ b/drivers/crypto/hisilicon/hpre/hpre_crypto.c +@@ -298,6 +298,8 @@ static void hpre_hw_data_clr_all(struct hpre_ctx *ctx, + dma_addr_t tmp; + + tmp = le64_to_cpu(sqe->in); ++ if (unlikely(dma_mapping_error(dev, tmp))) ++ return; + + if (src) { + if (req->src) +@@ -307,6 +309,8 @@ static void hpre_hw_data_clr_all(struct hpre_ctx *ctx, + } + + tmp = le64_to_cpu(sqe->out); ++ if (unlikely(dma_mapping_error(dev, tmp))) ++ return; + + if (req->dst) { + if (dst) +@@ -524,6 +528,8 @@ static int hpre_msg_request_set(struct hpre_ctx *ctx, void *req, bool is_rsa) + msg->key = cpu_to_le64(ctx->dh.dma_xa_p); + } + ++ msg->in = cpu_to_le64(DMA_MAPPING_ERROR); ++ msg->out = cpu_to_le64(DMA_MAPPING_ERROR); + msg->dw0 |= cpu_to_le32(0x1 << HPRE_SQE_DONE_SHIFT); + msg->task_len1 = (ctx->key_sz >> HPRE_BITS_2_BYTES_SHIFT) - 1; + h_req->ctx = ctx; +@@ -1372,11 +1378,15 @@ static void hpre_ecdh_hw_data_clr_all(struct hpre_ctx *ctx, + dma_addr_t dma; + + dma = le64_to_cpu(sqe->in); ++ if (unlikely(dma_mapping_error(dev, dma))) ++ return; + + if (src && req->src) + dma_free_coherent(dev, ctx->key_sz << 2, req->src, dma); + + dma = le64_to_cpu(sqe->out); ++ if (unlikely(dma_mapping_error(dev, dma))) ++ return; + + if (req->dst) + dma_free_coherent(dev, ctx->key_sz << 1, req->dst, dma); +@@ -1431,6 +1441,8 @@ static int hpre_ecdh_msg_request_set(struct hpre_ctx *ctx, + h_req->areq.ecdh = req; + msg = &h_req->req; + memset(msg, 0, sizeof(*msg)); ++ msg->in = cpu_to_le64(DMA_MAPPING_ERROR); ++ msg->out = cpu_to_le64(DMA_MAPPING_ERROR); + msg->key = cpu_to_le64(ctx->ecdh.dma_p); + + msg->dw0 |= cpu_to_le32(0x1U << HPRE_SQE_DONE_SHIFT); +@@ -1667,11 +1679,15 @@ static void hpre_curve25519_hw_data_clr_all(struct hpre_ctx *ctx, + dma_addr_t dma; + + dma = le64_to_cpu(sqe->in); ++ if (unlikely(dma_mapping_error(dev, dma))) ++ return; + + if (src && req->src) + dma_free_coherent(dev, ctx->key_sz, req->src, dma); + + dma = le64_to_cpu(sqe->out); ++ if (unlikely(dma_mapping_error(dev, dma))) ++ return; + + if (req->dst) + dma_free_coherent(dev, ctx->key_sz, req->dst, dma); +@@ -1722,6 +1738,8 @@ static int hpre_curve25519_msg_request_set(struct hpre_ctx *ctx, + h_req->areq.curve25519 = req; + msg = &h_req->req; + memset(msg, 0, sizeof(*msg)); ++ msg->in = cpu_to_le64(DMA_MAPPING_ERROR); ++ msg->out = cpu_to_le64(DMA_MAPPING_ERROR); + msg->key = cpu_to_le64(ctx->curve25519.dma_p); + + msg->dw0 |= cpu_to_le32(0x1U << HPRE_SQE_DONE_SHIFT); +diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c +index 133aede8bf078..b43fad8b9e8d4 100644 +--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c ++++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c +@@ -1541,11 +1541,11 @@ static struct skcipher_alg sec_skciphers[] = { + AES_BLOCK_SIZE, AES_BLOCK_SIZE) + + SEC_SKCIPHER_ALG("ecb(des3_ede)", sec_setkey_3des_ecb, +- SEC_DES3_2KEY_SIZE, SEC_DES3_3KEY_SIZE, ++ SEC_DES3_3KEY_SIZE, SEC_DES3_3KEY_SIZE, + DES3_EDE_BLOCK_SIZE, 0) + + SEC_SKCIPHER_ALG("cbc(des3_ede)", sec_setkey_3des_cbc, +- SEC_DES3_2KEY_SIZE, SEC_DES3_3KEY_SIZE, ++ SEC_DES3_3KEY_SIZE, SEC_DES3_3KEY_SIZE, + DES3_EDE_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE) + + SEC_SKCIPHER_ALG("xts(sm4)", sec_setkey_sm4_xts, +diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c +index 0616e369522e9..f577ee4afd06f 100644 +--- a/drivers/crypto/ixp4xx_crypto.c ++++ b/drivers/crypto/ixp4xx_crypto.c +@@ -149,6 +149,8 @@ struct crypt_ctl { + struct ablk_ctx { + struct buffer_desc *src; + struct buffer_desc *dst; ++ u8 iv[MAX_IVLEN]; ++ bool encrypt; + }; + + struct aead_ctx { +@@ -330,7 +332,7 @@ static void free_buf_chain(struct device *dev, struct buffer_desc *buf, + + buf1 = buf->next; + phys1 = buf->phys_next; +- dma_unmap_single(dev, buf->phys_next, buf->buf_len, buf->dir); ++ dma_unmap_single(dev, buf->phys_addr, buf->buf_len, buf->dir); + dma_pool_free(buffer_pool, buf, phys); + buf = buf1; + phys = phys1; +@@ -381,6 +383,20 @@ static void one_packet(dma_addr_t phys) + case CTL_FLAG_PERFORM_ABLK: { + struct skcipher_request *req = crypt->data.ablk_req; + struct ablk_ctx *req_ctx = skcipher_request_ctx(req); ++ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); ++ unsigned int ivsize = crypto_skcipher_ivsize(tfm); ++ unsigned int offset; ++ ++ if (ivsize > 0) { ++ offset = req->cryptlen - ivsize; ++ if (req_ctx->encrypt) { ++ scatterwalk_map_and_copy(req->iv, req->dst, ++ offset, ivsize, 0); ++ } else { ++ memcpy(req->iv, req_ctx->iv, ivsize); ++ memzero_explicit(req_ctx->iv, ivsize); ++ } ++ } + + if (req_ctx->dst) { + free_buf_chain(dev, req_ctx->dst, crypt->dst_buf); +@@ -876,6 +892,7 @@ static int ablk_perform(struct skcipher_request *req, int encrypt) + struct ablk_ctx *req_ctx = skcipher_request_ctx(req); + struct buffer_desc src_hook; + struct device *dev = &pdev->dev; ++ unsigned int offset; + gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? + GFP_KERNEL : GFP_ATOMIC; + +@@ -885,6 +902,7 @@ static int ablk_perform(struct skcipher_request *req, int encrypt) + return -EAGAIN; + + dir = encrypt ? &ctx->encrypt : &ctx->decrypt; ++ req_ctx->encrypt = encrypt; + + crypt = get_crypt_desc(); + if (!crypt) +@@ -900,6 +918,10 @@ static int ablk_perform(struct skcipher_request *req, int encrypt) + + BUG_ON(ivsize && !req->iv); + memcpy(crypt->iv, req->iv, ivsize); ++ if (ivsize > 0 && !encrypt) { ++ offset = req->cryptlen - ivsize; ++ scatterwalk_map_and_copy(req_ctx->iv, req->src, offset, ivsize, 0); ++ } + if (req->src != req->dst) { + struct buffer_desc dst_hook; + crypt->mode |= NPE_OP_NOT_IN_PLACE; +diff --git a/drivers/crypto/nx/nx-842-pseries.c b/drivers/crypto/nx/nx-842-pseries.c +index cc8dd3072b8b7..9b2417ebc95a0 100644 +--- a/drivers/crypto/nx/nx-842-pseries.c ++++ b/drivers/crypto/nx/nx-842-pseries.c +@@ -538,13 +538,15 @@ static int nx842_OF_set_defaults(struct nx842_devdata *devdata) + * The status field indicates if the device is enabled when the status + * is 'okay'. Otherwise the device driver will be disabled. + * +- * @prop - struct property point containing the maxsyncop for the update ++ * @devdata: struct nx842_devdata to use for dev_info ++ * @prop: struct property point containing the maxsyncop for the update + * + * Returns: + * 0 - Device is available + * -ENODEV - Device is not available + */ +-static int nx842_OF_upd_status(struct property *prop) ++static int nx842_OF_upd_status(struct nx842_devdata *devdata, ++ struct property *prop) + { + const char *status = (const char *)prop->value; + +@@ -758,7 +760,7 @@ static int nx842_OF_upd(struct property *new_prop) + goto out; + + /* Perform property updates */ +- ret = nx842_OF_upd_status(status); ++ ret = nx842_OF_upd_status(new_devdata, status); + if (ret) + goto error_out; + +@@ -1069,6 +1071,7 @@ static const struct vio_device_id nx842_vio_driver_ids[] = { + {"ibm,compression-v1", "ibm,compression"}, + {"", ""}, + }; ++MODULE_DEVICE_TABLE(vio, nx842_vio_driver_ids); + + static struct vio_driver nx842_vio_driver = { + .name = KBUILD_MODNAME, +diff --git a/drivers/crypto/nx/nx-aes-ctr.c b/drivers/crypto/nx/nx-aes-ctr.c +index 13f518802343d..6120e350ff71d 100644 +--- a/drivers/crypto/nx/nx-aes-ctr.c ++++ b/drivers/crypto/nx/nx-aes-ctr.c +@@ -118,7 +118,7 @@ static int ctr3686_aes_nx_crypt(struct skcipher_request *req) + struct nx_crypto_ctx *nx_ctx = crypto_skcipher_ctx(tfm); + u8 iv[16]; + +- memcpy(iv, nx_ctx->priv.ctr.nonce, CTR_RFC3686_IV_SIZE); ++ memcpy(iv, nx_ctx->priv.ctr.nonce, CTR_RFC3686_NONCE_SIZE); + memcpy(iv + CTR_RFC3686_NONCE_SIZE, req->iv, CTR_RFC3686_IV_SIZE); + iv[12] = iv[13] = iv[14] = 0; + iv[15] = 1; +diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c +index ae0d320d3c60d..dd53ad9987b0d 100644 +--- a/drivers/crypto/omap-sham.c ++++ b/drivers/crypto/omap-sham.c +@@ -372,7 +372,7 @@ static int omap_sham_hw_init(struct omap_sham_dev *dd) + { + int err; + +- err = pm_runtime_get_sync(dd->dev); ++ err = pm_runtime_resume_and_get(dd->dev); + if (err < 0) { + dev_err(dd->dev, "failed to get sync: %d\n", err); + return err; +@@ -2244,7 +2244,7 @@ static int omap_sham_suspend(struct device *dev) + + static int omap_sham_resume(struct device *dev) + { +- int err = pm_runtime_get_sync(dev); ++ int err = pm_runtime_resume_and_get(dev); + if (err < 0) { + dev_err(dev, "failed to get sync: %d\n", err); + return err; +diff --git a/drivers/crypto/qat/qat_common/qat_hal.c b/drivers/crypto/qat/qat_common/qat_hal.c +index bd3028126cbe6..069f51621f0e8 100644 +--- a/drivers/crypto/qat/qat_common/qat_hal.c ++++ b/drivers/crypto/qat/qat_common/qat_hal.c +@@ -1417,7 +1417,11 @@ static int qat_hal_put_rel_wr_xfer(struct icp_qat_fw_loader_handle *handle, + pr_err("QAT: bad xfrAddr=0x%x\n", xfr_addr); + return -EINVAL; + } +- qat_hal_rd_rel_reg(handle, ae, ctx, ICP_GPB_REL, gprnum, &gprval); ++ status = qat_hal_rd_rel_reg(handle, ae, ctx, ICP_GPB_REL, gprnum, &gprval); ++ if (status) { ++ pr_err("QAT: failed to read register"); ++ return status; ++ } + gpr_addr = qat_hal_get_reg_addr(ICP_GPB_REL, gprnum); + data16low = 0xffff & data; + data16hi = 0xffff & (data >> 0x10); +diff --git a/drivers/crypto/qat/qat_common/qat_uclo.c b/drivers/crypto/qat/qat_common/qat_uclo.c +index 1fb5fc852f6b8..6d95160e451e5 100644 +--- a/drivers/crypto/qat/qat_common/qat_uclo.c ++++ b/drivers/crypto/qat/qat_common/qat_uclo.c +@@ -342,7 +342,6 @@ static int qat_uclo_init_umem_seg(struct icp_qat_fw_loader_handle *handle, + return 0; + } + +-#define ICP_DH895XCC_PESRAM_BAR_SIZE 0x80000 + static int qat_uclo_init_ae_memory(struct icp_qat_fw_loader_handle *handle, + struct icp_qat_uof_initmem *init_mem) + { +diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c +index c0a0d8c4fce19..8ff10928f581d 100644 +--- a/drivers/crypto/qce/skcipher.c ++++ b/drivers/crypto/qce/skcipher.c +@@ -72,7 +72,7 @@ qce_skcipher_async_req_handle(struct crypto_async_request *async_req) + struct scatterlist *sg; + bool diff_dst; + gfp_t gfp; +- int ret; ++ int dst_nents, src_nents, ret; + + rctx->iv = req->iv; + rctx->ivsize = crypto_skcipher_ivsize(skcipher); +@@ -123,21 +123,26 @@ qce_skcipher_async_req_handle(struct crypto_async_request *async_req) + sg_mark_end(sg); + rctx->dst_sg = rctx->dst_tbl.sgl; + +- ret = dma_map_sg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst); +- if (ret < 0) ++ dst_nents = dma_map_sg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst); ++ if (dst_nents < 0) { ++ ret = dst_nents; + goto error_free; ++ } + + if (diff_dst) { +- ret = dma_map_sg(qce->dev, req->src, rctx->src_nents, dir_src); +- if (ret < 0) ++ src_nents = dma_map_sg(qce->dev, req->src, rctx->src_nents, dir_src); ++ if (src_nents < 0) { ++ ret = src_nents; + goto error_unmap_dst; ++ } + rctx->src_sg = req->src; + } else { + rctx->src_sg = rctx->dst_sg; ++ src_nents = dst_nents - 1; + } + +- ret = qce_dma_prep_sgs(&qce->dma, rctx->src_sg, rctx->src_nents, +- rctx->dst_sg, rctx->dst_nents, ++ ret = qce_dma_prep_sgs(&qce->dma, rctx->src_sg, src_nents, ++ rctx->dst_sg, dst_nents, + qce_skcipher_done, async_req); + if (ret) + goto error_unmap_src; +diff --git a/drivers/crypto/sa2ul.c b/drivers/crypto/sa2ul.c +index 1c6929fb3a131..9f077ec9dbb7f 100644 +--- a/drivers/crypto/sa2ul.c ++++ b/drivers/crypto/sa2ul.c +@@ -2300,9 +2300,9 @@ static int sa_dma_init(struct sa_crypto_data *dd) + + dd->dma_rx2 = dma_request_chan(dd->dev, "rx2"); + if (IS_ERR(dd->dma_rx2)) { +- dma_release_channel(dd->dma_rx1); +- return dev_err_probe(dd->dev, PTR_ERR(dd->dma_rx2), +- "Unable to request rx2 DMA channel\n"); ++ ret = dev_err_probe(dd->dev, PTR_ERR(dd->dma_rx2), ++ "Unable to request rx2 DMA channel\n"); ++ goto err_dma_rx2; + } + + dd->dma_tx = dma_request_chan(dd->dev, "tx"); +@@ -2323,28 +2323,31 @@ static int sa_dma_init(struct sa_crypto_data *dd) + if (ret) { + dev_err(dd->dev, "can't configure IN dmaengine slave: %d\n", + ret); +- return ret; ++ goto err_dma_config; + } + + ret = dmaengine_slave_config(dd->dma_rx2, &cfg); + if (ret) { + dev_err(dd->dev, "can't configure IN dmaengine slave: %d\n", + ret); +- return ret; ++ goto err_dma_config; + } + + ret = dmaengine_slave_config(dd->dma_tx, &cfg); + if (ret) { + dev_err(dd->dev, "can't configure OUT dmaengine slave: %d\n", + ret); +- return ret; ++ goto err_dma_config; + } + + return 0; + ++err_dma_config: ++ dma_release_channel(dd->dma_tx); + err_dma_tx: +- dma_release_channel(dd->dma_rx1); + dma_release_channel(dd->dma_rx2); ++err_dma_rx2: ++ dma_release_channel(dd->dma_rx1); + + return ret; + } +@@ -2385,7 +2388,6 @@ MODULE_DEVICE_TABLE(of, of_match); + + static int sa_ul_probe(struct platform_device *pdev) + { +- const struct of_device_id *match; + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; + struct resource *res; +@@ -2397,6 +2399,10 @@ static int sa_ul_probe(struct platform_device *pdev) + if (!dev_data) + return -ENOMEM; + ++ dev_data->match_data = of_device_get_match_data(dev); ++ if (!dev_data->match_data) ++ return -ENODEV; ++ + sa_k3_dev = dev; + dev_data->dev = dev; + dev_data->pdev = pdev; +@@ -2408,20 +2414,14 @@ static int sa_ul_probe(struct platform_device *pdev) + if (ret < 0) { + dev_err(&pdev->dev, "%s: failed to get sync: %d\n", __func__, + ret); ++ pm_runtime_disable(dev); + return ret; + } + + sa_init_mem(dev_data); + ret = sa_dma_init(dev_data); + if (ret) +- goto disable_pm_runtime; +- +- match = of_match_node(of_match, dev->of_node); +- if (!match) { +- dev_err(dev, "No compatible match found\n"); +- return -ENODEV; +- } +- dev_data->match_data = match->data; ++ goto destroy_dma_pool; + + spin_lock_init(&dev_data->scid_lock); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +@@ -2454,9 +2454,9 @@ release_dma: + dma_release_channel(dev_data->dma_rx1); + dma_release_channel(dev_data->dma_tx); + ++destroy_dma_pool: + dma_pool_destroy(dev_data->sc_pool); + +-disable_pm_runtime: + pm_runtime_put_sync(&pdev->dev); + pm_runtime_disable(&pdev->dev); + +diff --git a/drivers/crypto/ux500/hash/hash_core.c b/drivers/crypto/ux500/hash/hash_core.c +index ecb7412e84e3e..51a6e1a424349 100644 +--- a/drivers/crypto/ux500/hash/hash_core.c ++++ b/drivers/crypto/ux500/hash/hash_core.c +@@ -1011,6 +1011,7 @@ static int hash_hw_final(struct ahash_request *req) + goto out; + } + } else if (req->nbytes == 0 && ctx->keylen > 0) { ++ ret = -EPERM; + dev_err(device_data->dev, "%s: Empty message with keylength > 0, NOT supported\n", + __func__); + goto out; +diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c +index fe08c46642f7c..28f3e0ba6cdd9 100644 +--- a/drivers/devfreq/devfreq.c ++++ b/drivers/devfreq/devfreq.c +@@ -823,6 +823,7 @@ struct devfreq *devfreq_add_device(struct device *dev, + if (devfreq->profile->timer < 0 + || devfreq->profile->timer >= DEVFREQ_TIMER_NUM) { + mutex_unlock(&devfreq->lock); ++ err = -EINVAL; + goto err_dev; + } + +diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c +index b094132bd20b3..fc09324a03e03 100644 +--- a/drivers/devfreq/governor_passive.c ++++ b/drivers/devfreq/governor_passive.c +@@ -65,7 +65,7 @@ static int devfreq_passive_get_target_freq(struct devfreq *devfreq, + dev_pm_opp_put(p_opp); + + if (IS_ERR(opp)) +- return PTR_ERR(opp); ++ goto no_required_opp; + + *freq = dev_pm_opp_get_freq(opp); + dev_pm_opp_put(opp); +@@ -73,6 +73,7 @@ static int devfreq_passive_get_target_freq(struct devfreq *devfreq, + return 0; + } + ++no_required_opp: + /* + * Get the OPP table's index of decided frequency by governor + * of parent device. +diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig +index 1e836e320edd9..91164c5f0757d 100644 +--- a/drivers/edac/Kconfig ++++ b/drivers/edac/Kconfig +@@ -270,7 +270,8 @@ config EDAC_PND2 + + config EDAC_IGEN6 + tristate "Intel client SoC Integrated MC" +- depends on PCI && X86_64 && PCI_MMCONFIG && ARCH_HAVE_NMI_SAFE_CMPXCHG ++ depends on PCI && PCI_MMCONFIG && ARCH_HAVE_NMI_SAFE_CMPXCHG ++ depends on X64_64 && X86_MCE_INTEL + help + Support for error detection and correction on the Intel + client SoC Integrated Memory Controller using In-Band ECC IP. +diff --git a/drivers/edac/aspeed_edac.c b/drivers/edac/aspeed_edac.c +index a46da56d6d544..6bd5f88159193 100644 +--- a/drivers/edac/aspeed_edac.c ++++ b/drivers/edac/aspeed_edac.c +@@ -254,8 +254,8 @@ static int init_csrows(struct mem_ctl_info *mci) + return rc; + } + +- dev_dbg(mci->pdev, "dt: /memory node resources: first page r.start=0x%x, resource_size=0x%x, PAGE_SHIFT macro=0x%x\n", +- r.start, resource_size(&r), PAGE_SHIFT); ++ dev_dbg(mci->pdev, "dt: /memory node resources: first page %pR, PAGE_SHIFT macro=0x%x\n", ++ &r, PAGE_SHIFT); + + csrow->first_page = r.start >> PAGE_SHIFT; + nr_pages = resource_size(&r) >> PAGE_SHIFT; +diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c +index 238a4ad1e526e..37b4e875420e4 100644 +--- a/drivers/edac/i10nm_base.c ++++ b/drivers/edac/i10nm_base.c +@@ -278,6 +278,9 @@ static int __init i10nm_init(void) + if (owner && strncmp(owner, EDAC_MOD_STR, sizeof(EDAC_MOD_STR))) + return -EBUSY; + ++ if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) ++ return -ENODEV; ++ + id = x86_match_cpu(i10nm_cpuids); + if (!id) + return -ENODEV; +diff --git a/drivers/edac/pnd2_edac.c b/drivers/edac/pnd2_edac.c +index 928f63a374c78..c94ca1f790c43 100644 +--- a/drivers/edac/pnd2_edac.c ++++ b/drivers/edac/pnd2_edac.c +@@ -1554,6 +1554,9 @@ static int __init pnd2_init(void) + if (owner && strncmp(owner, EDAC_MOD_STR, sizeof(EDAC_MOD_STR))) + return -EBUSY; + ++ if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) ++ return -ENODEV; ++ + id = x86_match_cpu(pnd2_cpuids); + if (!id) + return -ENODEV; +diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c +index 93daa4297f2e0..4c626fcd4dcbb 100644 +--- a/drivers/edac/sb_edac.c ++++ b/drivers/edac/sb_edac.c +@@ -3510,6 +3510,9 @@ static int __init sbridge_init(void) + if (owner && strncmp(owner, EDAC_MOD_STR, sizeof(EDAC_MOD_STR))) + return -EBUSY; + ++ if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) ++ return -ENODEV; ++ + id = x86_match_cpu(sbridge_cpuids); + if (!id) + return -ENODEV; +diff --git a/drivers/edac/skx_base.c b/drivers/edac/skx_base.c +index 6a4f0b27c6545..4dbd46575bfb4 100644 +--- a/drivers/edac/skx_base.c ++++ b/drivers/edac/skx_base.c +@@ -656,6 +656,9 @@ static int __init skx_init(void) + if (owner && strncmp(owner, EDAC_MOD_STR, sizeof(EDAC_MOD_STR))) + return -EBUSY; + ++ if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) ++ return -ENODEV; ++ + id = x86_match_cpu(skx_cpuids); + if (!id) + return -ENODEV; +diff --git a/drivers/edac/ti_edac.c b/drivers/edac/ti_edac.c +index e7eae20f83d1d..169f96e51c293 100644 +--- a/drivers/edac/ti_edac.c ++++ b/drivers/edac/ti_edac.c +@@ -197,6 +197,7 @@ static const struct of_device_id ti_edac_of_match[] = { + { .compatible = "ti,emif-dra7xx", .data = (void *)EMIF_TYPE_DRA7 }, + {}, + }; ++MODULE_DEVICE_TABLE(of, ti_edac_of_match); + + static int _emif_get_id(struct device_node *node) + { +diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c +index e1408075ef7d6..5c3cdb725514d 100644 +--- a/drivers/extcon/extcon-max8997.c ++++ b/drivers/extcon/extcon-max8997.c +@@ -733,7 +733,7 @@ static int max8997_muic_probe(struct platform_device *pdev) + 2, info->status); + if (ret) { + dev_err(info->dev, "failed to read MUIC register\n"); +- return ret; ++ goto err_irq; + } + cable_type = max8997_muic_get_cable_type(info, + MAX8997_CABLE_GROUP_ADC, &attached); +@@ -788,3 +788,4 @@ module_platform_driver(max8997_muic_driver); + MODULE_DESCRIPTION("Maxim MAX8997 Extcon driver"); + MODULE_AUTHOR("Donggeun Kim "); + MODULE_LICENSE("GPL"); ++MODULE_ALIAS("platform:max8997-muic"); +diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c +index db41d1c58efd5..c3e4b220e66fa 100644 +--- a/drivers/extcon/extcon-sm5502.c ++++ b/drivers/extcon/extcon-sm5502.c +@@ -88,7 +88,6 @@ static struct reg_data sm5502_reg_data[] = { + | SM5502_REG_INTM2_MHL_MASK, + .invert = true, + }, +- { } + }; + + /* List of detectable cables */ +diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c +index 3aa489dba30a7..2a7687911c097 100644 +--- a/drivers/firmware/stratix10-svc.c ++++ b/drivers/firmware/stratix10-svc.c +@@ -1034,24 +1034,32 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev) + + /* add svc client device(s) */ + svc = devm_kzalloc(dev, sizeof(*svc), GFP_KERNEL); +- if (!svc) +- return -ENOMEM; ++ if (!svc) { ++ ret = -ENOMEM; ++ goto err_free_kfifo; ++ } + + svc->stratix10_svc_rsu = platform_device_alloc(STRATIX10_RSU, 0); + if (!svc->stratix10_svc_rsu) { + dev_err(dev, "failed to allocate %s device\n", STRATIX10_RSU); +- return -ENOMEM; ++ ret = -ENOMEM; ++ goto err_free_kfifo; + } + + ret = platform_device_add(svc->stratix10_svc_rsu); +- if (ret) { +- platform_device_put(svc->stratix10_svc_rsu); +- return ret; +- } ++ if (ret) ++ goto err_put_device; ++ + dev_set_drvdata(dev, svc); + + pr_info("Intel Service Layer Driver Initialized\n"); + ++ return 0; ++ ++err_put_device: ++ platform_device_put(svc->stratix10_svc_rsu); ++err_free_kfifo: ++ kfifo_free(&controller->svc_fifo); + return ret; + } + +diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c +index 4e60e84cd17a5..59ddc9fd5bca4 100644 +--- a/drivers/fsi/fsi-core.c ++++ b/drivers/fsi/fsi-core.c +@@ -724,7 +724,7 @@ static ssize_t cfam_read(struct file *filep, char __user *buf, size_t count, + rc = count; + fail: + *offset = off; +- return count; ++ return rc; + } + + static ssize_t cfam_write(struct file *filep, const char __user *buf, +@@ -761,7 +761,7 @@ static ssize_t cfam_write(struct file *filep, const char __user *buf, + rc = count; + fail: + *offset = off; +- return count; ++ return rc; + } + + static loff_t cfam_llseek(struct file *file, loff_t offset, int whence) +diff --git a/drivers/fsi/fsi-occ.c b/drivers/fsi/fsi-occ.c +index 10ca2e290655b..cb05b6dacc9d5 100644 +--- a/drivers/fsi/fsi-occ.c ++++ b/drivers/fsi/fsi-occ.c +@@ -495,6 +495,7 @@ int fsi_occ_submit(struct device *dev, const void *request, size_t req_len, + goto done; + + if (resp->return_status == OCC_RESP_CMD_IN_PRG || ++ resp->return_status == OCC_RESP_CRIT_INIT || + resp->seq_no != seq_no) { + rc = -ETIMEDOUT; + +diff --git a/drivers/fsi/fsi-sbefifo.c b/drivers/fsi/fsi-sbefifo.c +index bfd5e5da80209..84cb965bfed5c 100644 +--- a/drivers/fsi/fsi-sbefifo.c ++++ b/drivers/fsi/fsi-sbefifo.c +@@ -325,7 +325,8 @@ static int sbefifo_up_write(struct sbefifo *sbefifo, __be32 word) + static int sbefifo_request_reset(struct sbefifo *sbefifo) + { + struct device *dev = &sbefifo->fsi_dev->dev; +- u32 status, timeout; ++ unsigned long end_time; ++ u32 status; + int rc; + + dev_dbg(dev, "Requesting FIFO reset\n"); +@@ -341,7 +342,8 @@ static int sbefifo_request_reset(struct sbefifo *sbefifo) + } + + /* Wait for it to complete */ +- for (timeout = 0; timeout < SBEFIFO_RESET_TIMEOUT; timeout++) { ++ end_time = jiffies + msecs_to_jiffies(SBEFIFO_RESET_TIMEOUT); ++ while (!time_after(jiffies, end_time)) { + rc = sbefifo_regr(sbefifo, SBEFIFO_UP | SBEFIFO_STS, &status); + if (rc) { + dev_err(dev, "Failed to read UP fifo status during reset" +@@ -355,7 +357,7 @@ static int sbefifo_request_reset(struct sbefifo *sbefifo) + return 0; + } + +- msleep(1); ++ cond_resched(); + } + dev_err(dev, "FIFO reset timed out\n"); + +@@ -400,7 +402,7 @@ static int sbefifo_cleanup_hw(struct sbefifo *sbefifo) + /* The FIFO already contains a reset request from the SBE ? */ + if (down_status & SBEFIFO_STS_RESET_REQ) { + dev_info(dev, "Cleanup: FIFO reset request set, resetting\n"); +- rc = sbefifo_regw(sbefifo, SBEFIFO_UP, SBEFIFO_PERFORM_RESET); ++ rc = sbefifo_regw(sbefifo, SBEFIFO_DOWN, SBEFIFO_PERFORM_RESET); + if (rc) { + sbefifo->broken = true; + dev_err(dev, "Cleanup: Reset reg write failed, rc=%d\n", rc); +diff --git a/drivers/fsi/fsi-scom.c b/drivers/fsi/fsi-scom.c +index b45bfab7b7f55..75d1389e2626d 100644 +--- a/drivers/fsi/fsi-scom.c ++++ b/drivers/fsi/fsi-scom.c +@@ -38,9 +38,10 @@ + #define SCOM_STATUS_PIB_RESP_MASK 0x00007000 + #define SCOM_STATUS_PIB_RESP_SHIFT 12 + +-#define SCOM_STATUS_ANY_ERR (SCOM_STATUS_PROTECTION | \ +- SCOM_STATUS_PARITY | \ +- SCOM_STATUS_PIB_ABORT | \ ++#define SCOM_STATUS_FSI2PIB_ERROR (SCOM_STATUS_PROTECTION | \ ++ SCOM_STATUS_PARITY | \ ++ SCOM_STATUS_PIB_ABORT) ++#define SCOM_STATUS_ANY_ERR (SCOM_STATUS_FSI2PIB_ERROR | \ + SCOM_STATUS_PIB_RESP_MASK) + /* SCOM address encodings */ + #define XSCOM_ADDR_IND_FLAG BIT_ULL(63) +@@ -240,13 +241,14 @@ static int handle_fsi2pib_status(struct scom_device *scom, uint32_t status) + { + uint32_t dummy = -1; + +- if (status & SCOM_STATUS_PROTECTION) +- return -EPERM; +- if (status & SCOM_STATUS_PARITY) { ++ if (status & SCOM_STATUS_FSI2PIB_ERROR) + fsi_device_write(scom->fsi_dev, SCOM_FSI2PIB_RESET_REG, &dummy, + sizeof(uint32_t)); ++ ++ if (status & SCOM_STATUS_PROTECTION) ++ return -EPERM; ++ if (status & SCOM_STATUS_PARITY) + return -EIO; +- } + /* Return -EBUSY on PIB abort to force a retry */ + if (status & SCOM_STATUS_PIB_ABORT) + return -EBUSY; +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index 652cc1a0e450f..2b2d7b9f26f16 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -28,6 +28,7 @@ + + #include "dm_services_types.h" + #include "dc.h" ++#include "dc_link_dp.h" + #include "dc/inc/core_types.h" + #include "dal_asic_id.h" + #include "dmub/dmub_srv.h" +@@ -2696,6 +2697,7 @@ static void handle_hpd_rx_irq(void *param) + enum dc_connection_type new_connection_type = dc_connection_none; + struct amdgpu_device *adev = drm_to_adev(dev); + union hpd_irq_data hpd_irq_data; ++ bool lock_flag = 0; + + memset(&hpd_irq_data, 0, sizeof(hpd_irq_data)); + +@@ -2726,13 +2728,28 @@ static void handle_hpd_rx_irq(void *param) + } + } + +- mutex_lock(&adev->dm.dc_lock); ++ /* ++ * TODO: We need the lock to avoid touching DC state while it's being ++ * modified during automated compliance testing, or when link loss ++ * happens. While this should be split into subhandlers and proper ++ * interfaces to avoid having to conditionally lock like this in the ++ * outer layer, we need this workaround temporarily to allow MST ++ * lightup in some scenarios to avoid timeout. ++ */ ++ if (!amdgpu_in_reset(adev) && ++ (hpd_rx_irq_check_link_loss_status(dc_link, &hpd_irq_data) || ++ hpd_irq_data.bytes.device_service_irq.bits.AUTOMATED_TEST)) { ++ mutex_lock(&adev->dm.dc_lock); ++ lock_flag = 1; ++ } ++ + #ifdef CONFIG_DRM_AMD_DC_HDCP + result = dc_link_handle_hpd_rx_irq(dc_link, &hpd_irq_data, NULL); + #else + result = dc_link_handle_hpd_rx_irq(dc_link, NULL, NULL); + #endif +- mutex_unlock(&adev->dm.dc_lock); ++ if (!amdgpu_in_reset(adev) && lock_flag) ++ mutex_unlock(&adev->dm.dc_lock); + + out: + if (result && !is_mst_root_connector) { +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +index 9b221db526dc9..d62460b69d954 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +@@ -278,6 +278,9 @@ dm_dp_mst_detect(struct drm_connector *connector, + struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); + struct amdgpu_dm_connector *master = aconnector->mst_port; + ++ if (drm_connector_is_unregistered(connector)) ++ return connector_status_disconnected; ++ + return drm_dp_mst_detect_port(connector, ctx, &master->mst_mgr, + aconnector->port); + } +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +index 3ff3d9e909837..72bd7bc681a81 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +@@ -1976,7 +1976,7 @@ enum dc_status read_hpd_rx_irq_data( + return retval; + } + +-static bool hpd_rx_irq_check_link_loss_status( ++bool hpd_rx_irq_check_link_loss_status( + struct dc_link *link, + union hpd_irq_data *hpd_irq_dpcd_data) + { +diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h +index 3ae05c96d5572..a9c0c7f7a55dc 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h +@@ -67,6 +67,10 @@ bool perform_link_training_with_retries( + struct pipe_ctx *pipe_ctx, + enum signal_type signal); + ++bool hpd_rx_irq_check_link_loss_status( ++ struct dc_link *link, ++ union hpd_irq_data *hpd_irq_dpcd_data); ++ + bool is_mst_supported(struct dc_link *link); + + bool detect_dp_sink_caps(struct dc_link *link); +diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c +index 0ac3c2039c4b1..c29cc7f19863a 100644 +--- a/drivers/gpu/drm/ast/ast_main.c ++++ b/drivers/gpu/drm/ast/ast_main.c +@@ -413,7 +413,7 @@ struct ast_private *ast_device_create(const struct drm_driver *drv, + + pci_set_drvdata(pdev, dev); + +- ast->regs = pci_iomap(pdev, 1, 0); ++ ast->regs = pcim_iomap(pdev, 1, 0); + if (!ast->regs) + return ERR_PTR(-EIO); + +@@ -429,7 +429,7 @@ struct ast_private *ast_device_create(const struct drm_driver *drv, + + /* "map" IO regs if the above hasn't done so already */ + if (!ast->ioregs) { +- ast->ioregs = pci_iomap(pdev, 2, 0); ++ ast->ioregs = pcim_iomap(pdev, 2, 0); + if (!ast->ioregs) + return ERR_PTR(-EIO); + } +diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig +index 400193e38d298..9ce8438fb58b9 100644 +--- a/drivers/gpu/drm/bridge/Kconfig ++++ b/drivers/gpu/drm/bridge/Kconfig +@@ -68,6 +68,7 @@ config DRM_LONTIUM_LT8912B + select DRM_KMS_HELPER + select DRM_MIPI_DSI + select REGMAP_I2C ++ select VIDEOMODE_HELPERS + help + Driver for Lontium LT8912B DSI to HDMI bridge + chip driver. +@@ -172,7 +173,7 @@ config DRM_SIL_SII8620 + tristate "Silicon Image SII8620 HDMI/MHL bridge" + depends on OF + select DRM_KMS_HELPER +- imply EXTCON ++ select EXTCON + depends on RC_CORE || !RC_CORE + help + Silicon Image SII8620 HDMI/MHL bridge chip driver. +diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c +index 23283ba0c4f93..b4e349ca38fe3 100644 +--- a/drivers/gpu/drm/bridge/analogix/anx7625.c ++++ b/drivers/gpu/drm/bridge/analogix/anx7625.c +@@ -893,7 +893,7 @@ static void anx7625_power_on(struct anx7625_data *ctx) + usleep_range(2000, 2100); + } + +- usleep_range(4000, 4100); ++ usleep_range(11000, 12000); + + /* Power on pin enable */ + gpiod_set_value(ctx->pdata.gpio_p_on, 1); +diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c +index 64f0effb52ac1..044acd07c1538 100644 +--- a/drivers/gpu/drm/drm_bridge.c ++++ b/drivers/gpu/drm/drm_bridge.c +@@ -522,6 +522,9 @@ void drm_bridge_chain_pre_enable(struct drm_bridge *bridge) + list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { + if (iter->funcs->pre_enable) + iter->funcs->pre_enable(iter); ++ ++ if (iter == bridge) ++ break; + } + } + EXPORT_SYMBOL(drm_bridge_chain_pre_enable); +diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c +index 7ffd7b570b54d..538682f882b16 100644 +--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c ++++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c +@@ -1082,7 +1082,6 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, + struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + const struct drm_framebuffer *fb = plane_state->hw.fb; + unsigned int rotation = plane_state->hw.rotation; +- struct drm_format_name_buf format_name; + + if (!fb) + return 0; +@@ -1130,9 +1129,8 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, + case DRM_FORMAT_XVYU12_16161616: + case DRM_FORMAT_XVYU16161616: + drm_dbg_kms(&dev_priv->drm, +- "Unsupported pixel format %s for 90/270!\n", +- drm_get_format_name(fb->format->format, +- &format_name)); ++ "Unsupported pixel format %p4cc for 90/270!\n", ++ &fb->format->format); + return -EINVAL; + default: + break; +diff --git a/drivers/gpu/drm/i915/gt/selftest_execlists.c b/drivers/gpu/drm/i915/gt/selftest_execlists.c +index 1081cd36a2bd3..1e5d59a776b81 100644 +--- a/drivers/gpu/drm/i915/gt/selftest_execlists.c ++++ b/drivers/gpu/drm/i915/gt/selftest_execlists.c +@@ -551,6 +551,32 @@ static int live_pin_rewind(void *arg) + return err; + } + ++static int engine_lock_reset_tasklet(struct intel_engine_cs *engine) ++{ ++ tasklet_disable(&engine->execlists.tasklet); ++ local_bh_disable(); ++ ++ if (test_and_set_bit(I915_RESET_ENGINE + engine->id, ++ &engine->gt->reset.flags)) { ++ local_bh_enable(); ++ tasklet_enable(&engine->execlists.tasklet); ++ ++ intel_gt_set_wedged(engine->gt); ++ return -EBUSY; ++ } ++ ++ return 0; ++} ++ ++static void engine_unlock_reset_tasklet(struct intel_engine_cs *engine) ++{ ++ clear_and_wake_up_bit(I915_RESET_ENGINE + engine->id, ++ &engine->gt->reset.flags); ++ ++ local_bh_enable(); ++ tasklet_enable(&engine->execlists.tasklet); ++} ++ + static int live_hold_reset(void *arg) + { + struct intel_gt *gt = arg; +@@ -598,15 +624,9 @@ static int live_hold_reset(void *arg) + + /* We have our request executing, now remove it and reset */ + +- local_bh_disable(); +- if (test_and_set_bit(I915_RESET_ENGINE + id, +- >->reset.flags)) { +- local_bh_enable(); +- intel_gt_set_wedged(gt); +- err = -EBUSY; ++ err = engine_lock_reset_tasklet(engine); ++ if (err) + goto out; +- } +- tasklet_disable(&engine->execlists.tasklet); + + engine->execlists.tasklet.callback(&engine->execlists.tasklet); + GEM_BUG_ON(execlists_active(&engine->execlists) != rq); +@@ -618,10 +638,7 @@ static int live_hold_reset(void *arg) + __intel_engine_reset_bh(engine, NULL); + GEM_BUG_ON(rq->fence.error != -EIO); + +- tasklet_enable(&engine->execlists.tasklet); +- clear_and_wake_up_bit(I915_RESET_ENGINE + id, +- >->reset.flags); +- local_bh_enable(); ++ engine_unlock_reset_tasklet(engine); + + /* Check that we do not resubmit the held request */ + if (!i915_request_wait(rq, 0, HZ / 5)) { +@@ -4585,15 +4602,9 @@ static int reset_virtual_engine(struct intel_gt *gt, + GEM_BUG_ON(engine == ve->engine); + + /* Take ownership of the reset and tasklet */ +- local_bh_disable(); +- if (test_and_set_bit(I915_RESET_ENGINE + engine->id, +- >->reset.flags)) { +- local_bh_enable(); +- intel_gt_set_wedged(gt); +- err = -EBUSY; ++ err = engine_lock_reset_tasklet(engine); ++ if (err) + goto out_heartbeat; +- } +- tasklet_disable(&engine->execlists.tasklet); + + engine->execlists.tasklet.callback(&engine->execlists.tasklet); + GEM_BUG_ON(execlists_active(&engine->execlists) != rq); +@@ -4612,9 +4623,7 @@ static int reset_virtual_engine(struct intel_gt *gt, + GEM_BUG_ON(rq->fence.error != -EIO); + + /* Release our grasp on the engine, letting CS flow again */ +- tasklet_enable(&engine->execlists.tasklet); +- clear_and_wake_up_bit(I915_RESET_ENGINE + engine->id, >->reset.flags); +- local_bh_enable(); ++ engine_unlock_reset_tasklet(engine); + + /* Check that we do not resubmit the held request */ + i915_request_get(rq); +diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c +index fa5009705365e..233310712deb0 100644 +--- a/drivers/gpu/drm/imx/ipuv3-plane.c ++++ b/drivers/gpu/drm/imx/ipuv3-plane.c +@@ -35,7 +35,7 @@ static inline struct ipu_plane *to_ipu_plane(struct drm_plane *p) + return container_of(p, struct ipu_plane, base); + } + +-static const uint32_t ipu_plane_formats[] = { ++static const uint32_t ipu_plane_all_formats[] = { + DRM_FORMAT_ARGB1555, + DRM_FORMAT_XRGB1555, + DRM_FORMAT_ABGR1555, +@@ -72,6 +72,31 @@ static const uint32_t ipu_plane_formats[] = { + DRM_FORMAT_BGRX8888_A8, + }; + ++static const uint32_t ipu_plane_rgb_formats[] = { ++ DRM_FORMAT_ARGB1555, ++ DRM_FORMAT_XRGB1555, ++ DRM_FORMAT_ABGR1555, ++ DRM_FORMAT_XBGR1555, ++ DRM_FORMAT_RGBA5551, ++ DRM_FORMAT_BGRA5551, ++ DRM_FORMAT_ARGB4444, ++ DRM_FORMAT_ARGB8888, ++ DRM_FORMAT_XRGB8888, ++ DRM_FORMAT_ABGR8888, ++ DRM_FORMAT_XBGR8888, ++ DRM_FORMAT_RGBA8888, ++ DRM_FORMAT_RGBX8888, ++ DRM_FORMAT_BGRA8888, ++ DRM_FORMAT_BGRX8888, ++ DRM_FORMAT_RGB565, ++ DRM_FORMAT_RGB565_A8, ++ DRM_FORMAT_BGR565_A8, ++ DRM_FORMAT_RGB888_A8, ++ DRM_FORMAT_BGR888_A8, ++ DRM_FORMAT_RGBX8888_A8, ++ DRM_FORMAT_BGRX8888_A8, ++}; ++ + static const uint64_t ipu_format_modifiers[] = { + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +@@ -320,10 +345,11 @@ static bool ipu_plane_format_mod_supported(struct drm_plane *plane, + if (modifier == DRM_FORMAT_MOD_LINEAR) + return true; + +- /* without a PRG there are no supported modifiers */ +- if (!ipu_prg_present(ipu)) +- return false; +- ++ /* ++ * Without a PRG the possible modifiers list only includes the linear ++ * modifier, so we always take the early return from this function and ++ * only end up here if the PRG is present. ++ */ + return ipu_prg_format_supported(ipu, format, modifier); + } + +@@ -830,16 +856,28 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu, + struct ipu_plane *ipu_plane; + const uint64_t *modifiers = ipu_format_modifiers; + unsigned int zpos = (type == DRM_PLANE_TYPE_PRIMARY) ? 0 : 1; ++ unsigned int format_count; ++ const uint32_t *formats; + int ret; + + DRM_DEBUG_KMS("channel %d, dp flow %d, possible_crtcs=0x%x\n", + dma, dp, possible_crtcs); + ++ if (dp == IPU_DP_FLOW_SYNC_BG || dp == IPU_DP_FLOW_SYNC_FG) { ++ formats = ipu_plane_all_formats; ++ format_count = ARRAY_SIZE(ipu_plane_all_formats); ++ } else { ++ formats = ipu_plane_rgb_formats; ++ format_count = ARRAY_SIZE(ipu_plane_rgb_formats); ++ } ++ ++ if (ipu_prg_present(ipu)) ++ modifiers = pre_format_modifiers; ++ + ipu_plane = drmm_universal_plane_alloc(dev, struct ipu_plane, base, + possible_crtcs, &ipu_plane_funcs, +- ipu_plane_formats, +- ARRAY_SIZE(ipu_plane_formats), +- modifiers, type, NULL); ++ formats, format_count, modifiers, ++ type, NULL); + if (IS_ERR(ipu_plane)) { + DRM_ERROR("failed to allocate and initialize %s plane\n", + zpos ? "overlay" : "primary"); +@@ -850,9 +888,6 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu, + ipu_plane->dma = dma; + ipu_plane->dp_flow = dp; + +- if (ipu_prg_present(ipu)) +- modifiers = pre_format_modifiers; +- + drm_plane_helper_add(&ipu_plane->base, &ipu_plane_helper_funcs); + + if (dp == IPU_DP_FLOW_SYNC_BG || dp == IPU_DP_FLOW_SYNC_FG) +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +index 18bc76b7f1a33..4523d6ba891b5 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +@@ -407,9 +407,6 @@ static void dpu_crtc_frame_event_work(struct kthread_work *work) + fevent->event); + } + +- if (fevent->event & DPU_ENCODER_FRAME_EVENT_DONE) +- dpu_core_perf_crtc_update(crtc, 0, false); +- + if (fevent->event & (DPU_ENCODER_FRAME_EVENT_DONE + | DPU_ENCODER_FRAME_EVENT_ERROR)) + frame_done = true; +@@ -477,6 +474,7 @@ static void dpu_crtc_frame_event_cb(void *data, u32 event) + void dpu_crtc_complete_commit(struct drm_crtc *crtc) + { + trace_dpu_crtc_complete_commit(DRMID(crtc)); ++ dpu_core_perf_crtc_update(crtc, 0, false); + _dpu_crtc_complete_flip(crtc); + } + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c +index 06b56fec04e04..6b0a7bc87eb75 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c +@@ -225,7 +225,7 @@ int dpu_mdss_init(struct drm_device *dev) + struct msm_drm_private *priv = dev->dev_private; + struct dpu_mdss *dpu_mdss; + struct dss_module_power *mp; +- int ret = 0; ++ int ret; + int irq; + + dpu_mdss = devm_kzalloc(dev->dev, sizeof(*dpu_mdss), GFP_KERNEL); +@@ -253,8 +253,10 @@ int dpu_mdss_init(struct drm_device *dev) + goto irq_domain_error; + + irq = platform_get_irq(pdev, 0); +- if (irq < 0) ++ if (irq < 0) { ++ ret = irq; + goto irq_error; ++ } + + irq_set_chained_handler_and_data(irq, dpu_mdss_irq, + dpu_mdss); +@@ -263,7 +265,7 @@ int dpu_mdss_init(struct drm_device *dev) + + pm_runtime_enable(dev->dev); + +- return ret; ++ return 0; + + irq_error: + _dpu_mdss_irq_domain_fini(dpu_mdss); +diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c +index b1a9b1b98f5f6..f4f53f23e331e 100644 +--- a/drivers/gpu/drm/msm/dp/dp_catalog.c ++++ b/drivers/gpu/drm/msm/dp/dp_catalog.c +@@ -582,10 +582,9 @@ void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog) + + u32 reftimer = dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER); + +- /* enable HPD interrupts */ ++ /* enable HPD plug and unplug interrupts */ + dp_catalog_hpd_config_intr(dp_catalog, +- DP_DP_HPD_PLUG_INT_MASK | DP_DP_IRQ_HPD_INT_MASK +- | DP_DP_HPD_UNPLUG_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, true); ++ DP_DP_HPD_PLUG_INT_MASK | DP_DP_HPD_UNPLUG_INT_MASK, true); + + /* Configure REFTIMER and enable it */ + reftimer |= DP_DP_HPD_REFTIMER_ENABLE; +diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c +index 1390f3547fde4..2a8955ca70d1a 100644 +--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c ++++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c +@@ -1809,6 +1809,61 @@ end: + return ret; + } + ++int dp_ctrl_off_link_stream(struct dp_ctrl *dp_ctrl) ++{ ++ struct dp_ctrl_private *ctrl; ++ struct dp_io *dp_io; ++ struct phy *phy; ++ int ret; ++ ++ ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); ++ dp_io = &ctrl->parser->io; ++ phy = dp_io->phy; ++ ++ /* set dongle to D3 (power off) mode */ ++ dp_link_psm_config(ctrl->link, &ctrl->panel->link_info, true); ++ ++ dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, false); ++ ++ ret = dp_power_clk_enable(ctrl->power, DP_STREAM_PM, false); ++ if (ret) { ++ DRM_ERROR("Failed to disable pixel clocks. ret=%d\n", ret); ++ return ret; ++ } ++ ++ ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, false); ++ if (ret) { ++ DRM_ERROR("Failed to disable link clocks. ret=%d\n", ret); ++ return ret; ++ } ++ ++ phy_power_off(phy); ++ ++ /* aux channel down, reinit phy */ ++ phy_exit(phy); ++ phy_init(phy); ++ ++ DRM_DEBUG_DP("DP off link/stream done\n"); ++ return ret; ++} ++ ++void dp_ctrl_off_phy(struct dp_ctrl *dp_ctrl) ++{ ++ struct dp_ctrl_private *ctrl; ++ struct dp_io *dp_io; ++ struct phy *phy; ++ ++ ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); ++ dp_io = &ctrl->parser->io; ++ phy = dp_io->phy; ++ ++ dp_catalog_ctrl_reset(ctrl->catalog); ++ ++ phy_exit(phy); ++ ++ DRM_DEBUG_DP("DP off phy done\n"); ++} ++ + int dp_ctrl_off(struct dp_ctrl *dp_ctrl) + { + struct dp_ctrl_private *ctrl; +diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.h b/drivers/gpu/drm/msm/dp/dp_ctrl.h +index a836bd358447c..25e4f75122522 100644 +--- a/drivers/gpu/drm/msm/dp/dp_ctrl.h ++++ b/drivers/gpu/drm/msm/dp/dp_ctrl.h +@@ -23,6 +23,8 @@ int dp_ctrl_host_init(struct dp_ctrl *dp_ctrl, bool flip, bool reset); + void dp_ctrl_host_deinit(struct dp_ctrl *dp_ctrl); + int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl); + int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl); ++int dp_ctrl_off_link_stream(struct dp_ctrl *dp_ctrl); ++void dp_ctrl_off_phy(struct dp_ctrl *dp_ctrl); + int dp_ctrl_off(struct dp_ctrl *dp_ctrl); + void dp_ctrl_push_idle(struct dp_ctrl *dp_ctrl); + void dp_ctrl_isr(struct dp_ctrl *dp_ctrl); +diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c +index 1784e119269b7..cdec0a367a2cb 100644 +--- a/drivers/gpu/drm/msm/dp/dp_display.c ++++ b/drivers/gpu/drm/msm/dp/dp_display.c +@@ -346,6 +346,12 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp) + dp->dp_display.max_pclk_khz = DP_MAX_PIXEL_CLK_KHZ; + dp->dp_display.max_dp_lanes = dp->parser->max_dp_lanes; + ++ /* ++ * set sink to normal operation mode -- D0 ++ * before dpcd read ++ */ ++ dp_link_psm_config(dp->link, &dp->panel->link_info, false); ++ + dp_link_reset_phy_params_vx_px(dp->link); + rc = dp_ctrl_on_link(dp->ctrl); + if (rc) { +@@ -414,11 +420,6 @@ static int dp_display_usbpd_configure_cb(struct device *dev) + + dp_display_host_init(dp, false); + +- /* +- * set sink to normal operation mode -- D0 +- * before dpcd read +- */ +- dp_link_psm_config(dp->link, &dp->panel->link_info, false); + rc = dp_display_process_hpd_high(dp); + end: + return rc; +@@ -579,6 +580,10 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data) + dp_add_event(dp, EV_CONNECT_PENDING_TIMEOUT, 0, tout); + } + ++ /* enable HDP irq_hpd/replug interrupt */ ++ dp_catalog_hpd_config_intr(dp->catalog, ++ DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, true); ++ + mutex_unlock(&dp->event_mutex); + + /* uevent will complete connection part */ +@@ -628,7 +633,26 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data) + mutex_lock(&dp->event_mutex); + + state = dp->hpd_state; +- if (state == ST_DISCONNECT_PENDING || state == ST_DISCONNECTED) { ++ ++ /* disable irq_hpd/replug interrupts */ ++ dp_catalog_hpd_config_intr(dp->catalog, ++ DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, false); ++ ++ /* unplugged, no more irq_hpd handle */ ++ dp_del_event(dp, EV_IRQ_HPD_INT); ++ ++ if (state == ST_DISCONNECTED) { ++ /* triggered by irq_hdp with sink_count = 0 */ ++ if (dp->link->sink_count == 0) { ++ dp_ctrl_off_phy(dp->ctrl); ++ hpd->hpd_high = 0; ++ dp->core_initialized = false; ++ } ++ mutex_unlock(&dp->event_mutex); ++ return 0; ++ } ++ ++ if (state == ST_DISCONNECT_PENDING) { + mutex_unlock(&dp->event_mutex); + return 0; + } +@@ -642,9 +666,8 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data) + + dp->hpd_state = ST_DISCONNECT_PENDING; + +- /* disable HPD plug interrupt until disconnect is done */ +- dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK +- | DP_DP_IRQ_HPD_INT_MASK, false); ++ /* disable HPD plug interrupts */ ++ dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, false); + + hpd->hpd_high = 0; + +@@ -660,8 +683,8 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data) + /* signal the disconnect event early to ensure proper teardown */ + dp_display_handle_plugged_change(g_dp_display, false); + +- dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK | +- DP_DP_IRQ_HPD_INT_MASK, true); ++ /* enable HDP plug interrupt to prepare for next plugin */ ++ dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, true); + + /* uevent will complete disconnection part */ + mutex_unlock(&dp->event_mutex); +@@ -692,7 +715,7 @@ static int dp_irq_hpd_handle(struct dp_display_private *dp, u32 data) + + /* irq_hpd can happen at either connected or disconnected state */ + state = dp->hpd_state; +- if (state == ST_DISPLAY_OFF) { ++ if (state == ST_DISPLAY_OFF || state == ST_SUSPENDED) { + mutex_unlock(&dp->event_mutex); + return 0; + } +@@ -910,9 +933,13 @@ static int dp_display_disable(struct dp_display_private *dp, u32 data) + + dp_display->audio_enabled = false; + +- dp_ctrl_off(dp->ctrl); +- +- dp->core_initialized = false; ++ /* triggered by irq_hpd with sink_count = 0 */ ++ if (dp->link->sink_count == 0) { ++ dp_ctrl_off_link_stream(dp->ctrl); ++ } else { ++ dp_ctrl_off(dp->ctrl); ++ dp->core_initialized = false; ++ } + + dp_display->power_on = false; + +diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c +index fe7d17cd35ecd..afd555b0c105e 100644 +--- a/drivers/gpu/drm/msm/msm_drv.c ++++ b/drivers/gpu/drm/msm/msm_drv.c +@@ -523,6 +523,7 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv) + priv->event_thread[i].worker = kthread_create_worker(0, + "crtc_event:%d", priv->event_thread[i].crtc_id); + if (IS_ERR(priv->event_thread[i].worker)) { ++ ret = PTR_ERR(priv->event_thread[i].worker); + DRM_DEV_ERROR(dev, "failed to create crtc_event kthread\n"); + goto err_msm_uninit; + } +diff --git a/drivers/gpu/drm/pl111/Kconfig b/drivers/gpu/drm/pl111/Kconfig +index 80f6748055e36..3aae387a96af2 100644 +--- a/drivers/gpu/drm/pl111/Kconfig ++++ b/drivers/gpu/drm/pl111/Kconfig +@@ -3,6 +3,7 @@ config DRM_PL111 + tristate "DRM Support for PL111 CLCD Controller" + depends on DRM + depends on ARM || ARM64 || COMPILE_TEST ++ depends on VEXPRESS_CONFIG || VEXPRESS_CONFIG=n + depends on COMMON_CLK + select DRM_KMS_HELPER + select DRM_KMS_CMA_HELPER +diff --git a/drivers/gpu/drm/qxl/qxl_dumb.c b/drivers/gpu/drm/qxl/qxl_dumb.c +index 48a58ba1db965..686485b19d0f2 100644 +--- a/drivers/gpu/drm/qxl/qxl_dumb.c ++++ b/drivers/gpu/drm/qxl/qxl_dumb.c +@@ -58,6 +58,8 @@ int qxl_mode_dumb_create(struct drm_file *file_priv, + surf.height = args->height; + surf.stride = pitch; + surf.format = format; ++ surf.data = 0; ++ + r = qxl_gem_object_create_with_handle(qdev, file_priv, + QXL_GEM_DOMAIN_CPU, + args->size, &surf, &qobj, +diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c +index a4a45daf93f2b..6802d9b65f828 100644 +--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c ++++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c +@@ -73,6 +73,7 @@ static int cdn_dp_grf_write(struct cdn_dp_device *dp, + ret = regmap_write(dp->grf, reg, val); + if (ret) { + DRM_DEV_ERROR(dp->dev, "Could not write to GRF: %d\n", ret); ++ clk_disable_unprepare(dp->grf_clk); + return ret; + } + +diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.c b/drivers/gpu/drm/rockchip/cdn-dp-reg.c +index 9d2163ef4d6e2..33fb4d05c5065 100644 +--- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c ++++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.c +@@ -658,7 +658,7 @@ int cdn_dp_config_video(struct cdn_dp_device *dp) + */ + do { + tu_size_reg += 2; +- symbol = tu_size_reg * mode->clock * bit_per_pix; ++ symbol = (u64)tu_size_reg * mode->clock * bit_per_pix; + do_div(symbol, dp->max_lanes * link_rate * 8); + rem = do_div(symbol, 1000); + if (tu_size_reg > 64) { +diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c +index 24a71091759cc..d8c47ee3cad37 100644 +--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c +@@ -692,13 +692,8 @@ static const struct dw_mipi_dsi_phy_ops dw_mipi_dsi_rockchip_phy_ops = { + .get_timing = dw_mipi_dsi_phy_get_timing, + }; + +-static void dw_mipi_dsi_rockchip_config(struct dw_mipi_dsi_rockchip *dsi, +- int mux) ++static void dw_mipi_dsi_rockchip_config(struct dw_mipi_dsi_rockchip *dsi) + { +- if (dsi->cdata->lcdsel_grf_reg) +- regmap_write(dsi->grf_regmap, dsi->cdata->lcdsel_grf_reg, +- mux ? dsi->cdata->lcdsel_lit : dsi->cdata->lcdsel_big); +- + if (dsi->cdata->lanecfg1_grf_reg) + regmap_write(dsi->grf_regmap, dsi->cdata->lanecfg1_grf_reg, + dsi->cdata->lanecfg1); +@@ -712,6 +707,13 @@ static void dw_mipi_dsi_rockchip_config(struct dw_mipi_dsi_rockchip *dsi, + dsi->cdata->enable); + } + ++static void dw_mipi_dsi_rockchip_set_lcdsel(struct dw_mipi_dsi_rockchip *dsi, ++ int mux) ++{ ++ regmap_write(dsi->grf_regmap, dsi->cdata->lcdsel_grf_reg, ++ mux ? dsi->cdata->lcdsel_lit : dsi->cdata->lcdsel_big); ++} ++ + static int + dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder, + struct drm_crtc_state *crtc_state, +@@ -767,9 +769,9 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder) + return; + } + +- dw_mipi_dsi_rockchip_config(dsi, mux); ++ dw_mipi_dsi_rockchip_set_lcdsel(dsi, mux); + if (dsi->slave) +- dw_mipi_dsi_rockchip_config(dsi->slave, mux); ++ dw_mipi_dsi_rockchip_set_lcdsel(dsi->slave, mux); + + clk_disable_unprepare(dsi->grf_clk); + } +@@ -923,6 +925,24 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev, + return ret; + } + ++ /* ++ * With the GRF clock running, write lane and dual-mode configurations ++ * that won't change immediately. If we waited until enable() to do ++ * this, things like panel preparation would not be able to send ++ * commands over DSI. ++ */ ++ ret = clk_prepare_enable(dsi->grf_clk); ++ if (ret) { ++ DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n", ret); ++ return ret; ++ } ++ ++ dw_mipi_dsi_rockchip_config(dsi); ++ if (dsi->slave) ++ dw_mipi_dsi_rockchip_config(dsi->slave); ++ ++ clk_disable_unprepare(dsi->grf_clk); ++ + ret = rockchip_dsi_drm_create_encoder(dsi, drm_dev); + if (ret) { + DRM_DEV_ERROR(dev, "Failed to create drm encoder\n"); +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +index 64469439ddf2f..f5b9028a16a38 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -1022,6 +1022,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, + VOP_WIN_SET(vop, win, alpha_en, 1); + } else { + VOP_WIN_SET(vop, win, src_alpha_ctl, SRC_ALPHA_EN(0)); ++ VOP_WIN_SET(vop, win, alpha_en, 0); + } + + VOP_WIN_SET(vop, win, enable, 1); +diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c +index bd5ba10822c24..489d63c05c0d9 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_lvds.c ++++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c +@@ -499,11 +499,11 @@ static int px30_lvds_probe(struct platform_device *pdev, + if (IS_ERR(lvds->dphy)) + return PTR_ERR(lvds->dphy); + +- phy_init(lvds->dphy); ++ ret = phy_init(lvds->dphy); + if (ret) + return ret; + +- phy_set_mode(lvds->dphy, PHY_MODE_LVDS); ++ ret = phy_set_mode(lvds->dphy, PHY_MODE_LVDS); + if (ret) + return ret; + +diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c +index 76657dcdf9b00..1f36b67cd6ce9 100644 +--- a/drivers/gpu/drm/vc4/vc4_crtc.c ++++ b/drivers/gpu/drm/vc4/vc4_crtc.c +@@ -279,14 +279,22 @@ static u32 vc4_crtc_get_fifo_full_level_bits(struct vc4_crtc *vc4_crtc, + * allows drivers to push pixels to more than one encoder from the + * same CRTC. + */ +-static struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc) ++static struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc, ++ struct drm_atomic_state *state, ++ struct drm_connector_state *(*get_state)(struct drm_atomic_state *state, ++ struct drm_connector *connector)) + { + struct drm_connector *connector; + struct drm_connector_list_iter conn_iter; + + drm_connector_list_iter_begin(crtc->dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { +- if (connector->state->crtc == crtc) { ++ struct drm_connector_state *conn_state = get_state(state, connector); ++ ++ if (!conn_state) ++ continue; ++ ++ if (conn_state->crtc == crtc) { + drm_connector_list_iter_end(&conn_iter); + return connector->encoder; + } +@@ -305,16 +313,17 @@ static void vc4_crtc_pixelvalve_reset(struct drm_crtc *crtc) + CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_FIFO_CLR); + } + +-static void vc4_crtc_config_pv(struct drm_crtc *crtc) ++static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_atomic_state *state) + { + struct drm_device *dev = crtc->dev; + struct vc4_dev *vc4 = to_vc4_dev(dev); +- struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc); ++ struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, state, ++ drm_atomic_get_new_connector_state); + struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder); + struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); + const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc); +- struct drm_crtc_state *state = crtc->state; +- struct drm_display_mode *mode = &state->adjusted_mode; ++ struct drm_crtc_state *crtc_state = crtc->state; ++ struct drm_display_mode *mode = &crtc_state->adjusted_mode; + bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE; + u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1; + bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 || +@@ -421,10 +430,10 @@ static void require_hvs_enabled(struct drm_device *dev) + } + + static int vc4_crtc_disable(struct drm_crtc *crtc, ++ struct drm_encoder *encoder, + struct drm_atomic_state *state, + unsigned int channel) + { +- struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc); + struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder); + struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); + struct drm_device *dev = crtc->dev; +@@ -465,10 +474,29 @@ static int vc4_crtc_disable(struct drm_crtc *crtc, + return 0; + } + ++static struct drm_encoder *vc4_crtc_get_encoder_by_type(struct drm_crtc *crtc, ++ enum vc4_encoder_type type) ++{ ++ struct drm_encoder *encoder; ++ ++ drm_for_each_encoder(encoder, crtc->dev) { ++ struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder); ++ ++ if (vc4_encoder->type == type) ++ return encoder; ++ } ++ ++ return NULL; ++} ++ + int vc4_crtc_disable_at_boot(struct drm_crtc *crtc) + { + struct drm_device *drm = crtc->dev; + struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); ++ enum vc4_encoder_type encoder_type; ++ const struct vc4_pv_data *pv_data; ++ struct drm_encoder *encoder; ++ unsigned encoder_sel; + int channel; + + if (!(of_device_is_compatible(vc4_crtc->pdev->dev.of_node, +@@ -487,7 +515,17 @@ int vc4_crtc_disable_at_boot(struct drm_crtc *crtc) + if (channel < 0) + return 0; + +- return vc4_crtc_disable(crtc, NULL, channel); ++ encoder_sel = VC4_GET_FIELD(CRTC_READ(PV_CONTROL), PV_CONTROL_CLK_SELECT); ++ if (WARN_ON(encoder_sel != 0)) ++ return 0; ++ ++ pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc); ++ encoder_type = pv_data->encoder_types[encoder_sel]; ++ encoder = vc4_crtc_get_encoder_by_type(crtc, encoder_type); ++ if (WARN_ON(!encoder)) ++ return 0; ++ ++ return vc4_crtc_disable(crtc, encoder, NULL, channel); + } + + static void vc4_crtc_atomic_disable(struct drm_crtc *crtc, +@@ -496,6 +534,8 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc, + struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, + crtc); + struct vc4_crtc_state *old_vc4_state = to_vc4_crtc_state(old_state); ++ struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, state, ++ drm_atomic_get_old_connector_state); + struct drm_device *dev = crtc->dev; + + require_hvs_enabled(dev); +@@ -503,7 +543,7 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc, + /* Disable vblank irq handling before crtc is disabled. */ + drm_crtc_vblank_off(crtc); + +- vc4_crtc_disable(crtc, state, old_vc4_state->assigned_channel); ++ vc4_crtc_disable(crtc, encoder, state, old_vc4_state->assigned_channel); + + /* + * Make sure we issue a vblank event after disabling the CRTC if +@@ -524,7 +564,8 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc, + { + struct drm_device *dev = crtc->dev; + struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); +- struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc); ++ struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, state, ++ drm_atomic_get_new_connector_state); + struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder); + + require_hvs_enabled(dev); +@@ -539,7 +580,7 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc, + if (vc4_encoder->pre_crtc_configure) + vc4_encoder->pre_crtc_configure(encoder, state); + +- vc4_crtc_config_pv(crtc); ++ vc4_crtc_config_pv(crtc, state); + + CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN); + +diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c +index 8106b5634fe10..e94730beb15b7 100644 +--- a/drivers/gpu/drm/vc4/vc4_hdmi.c ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c +@@ -2000,7 +2000,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) + &hpd_gpio_flags); + if (vc4_hdmi->hpd_gpio < 0) { + ret = vc4_hdmi->hpd_gpio; +- goto err_unprepare_hsm; ++ goto err_put_ddc; + } + + vc4_hdmi->hpd_active_low = hpd_gpio_flags & OF_GPIO_ACTIVE_LOW; +@@ -2041,8 +2041,8 @@ err_destroy_conn: + vc4_hdmi_connector_destroy(&vc4_hdmi->connector); + err_destroy_encoder: + drm_encoder_cleanup(encoder); +-err_unprepare_hsm: + pm_runtime_disable(dev); ++err_put_ddc: + put_device(&vc4_hdmi->ddc->dev); + + return ret; +diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h b/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h +index 4db25bd9fa22d..127eaf0a0a580 100644 +--- a/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h ++++ b/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h +@@ -1467,6 +1467,7 @@ struct svga3dsurface_cache { + + /** + * struct svga3dsurface_loc - Surface location ++ * @sheet: The multisample sheet. + * @sub_resource: Surface subresource. Defined as layer * num_mip_levels + + * mip_level. + * @x: X coordinate. +@@ -1474,6 +1475,7 @@ struct svga3dsurface_cache { + * @z: Z coordinate. + */ + struct svga3dsurface_loc { ++ u32 sheet; + u32 sub_resource; + u32 x, y, z; + }; +@@ -1566,8 +1568,8 @@ svga3dsurface_get_loc(const struct svga3dsurface_cache *cache, + u32 layer; + int i; + +- if (offset >= cache->sheet_bytes) +- offset %= cache->sheet_bytes; ++ loc->sheet = offset / cache->sheet_bytes; ++ offset -= loc->sheet * cache->sheet_bytes; + + layer = offset / cache->mip_chain_bytes; + offset -= layer * cache->mip_chain_bytes; +@@ -1631,6 +1633,7 @@ svga3dsurface_min_loc(const struct svga3dsurface_cache *cache, + u32 sub_resource, + struct svga3dsurface_loc *loc) + { ++ loc->sheet = 0; + loc->sub_resource = sub_resource; + loc->x = loc->y = loc->z = 0; + } +@@ -1652,6 +1655,7 @@ svga3dsurface_max_loc(const struct svga3dsurface_cache *cache, + const struct drm_vmw_size *size; + u32 mip; + ++ loc->sheet = 0; + loc->sub_resource = sub_resource + 1; + mip = sub_resource % cache->num_mip_levels; + size = &cache->mip[mip].size; +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +index 7a24196f92c38..d6a6d8a3387a9 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +@@ -2763,12 +2763,24 @@ static int vmw_cmd_dx_genmips(struct vmw_private *dev_priv, + { + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXGenMips) = + container_of(header, typeof(*cmd), header); +- struct vmw_resource *ret; ++ struct vmw_resource *view; ++ struct vmw_res_cache_entry *rcache; + +- ret = vmw_view_id_val_add(sw_context, vmw_view_sr, +- cmd->body.shaderResourceViewId); ++ view = vmw_view_id_val_add(sw_context, vmw_view_sr, ++ cmd->body.shaderResourceViewId); ++ if (IS_ERR(view)) ++ return PTR_ERR(view); + +- return PTR_ERR_OR_ZERO(ret); ++ /* ++ * Normally the shader-resource view is not gpu-dirtying, but for ++ * this particular command it is... ++ * So mark the last looked-up surface, which is the surface ++ * the view points to, gpu-dirty. ++ */ ++ rcache = &sw_context->res_cache[vmw_res_surface]; ++ vmw_validation_res_set_dirty(sw_context->ctx, rcache->private, ++ VMW_RES_DIRTY_SET); ++ return 0; + } + + /** +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +index c3e55c1376eb8..beab3e19d8e21 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +@@ -1804,6 +1804,19 @@ static void vmw_surface_tex_dirty_range_add(struct vmw_resource *res, + svga3dsurface_get_loc(cache, &loc2, end - 1); + svga3dsurface_inc_loc(cache, &loc2); + ++ if (loc1.sheet != loc2.sheet) { ++ u32 sub_res; ++ ++ /* ++ * Multiple multisample sheets. To do this in an optimized ++ * fashion, compute the dirty region for each sheet and the ++ * resulting union. Since this is not a common case, just dirty ++ * the whole surface. ++ */ ++ for (sub_res = 0; sub_res < dirty->num_subres; ++sub_res) ++ vmw_subres_dirty_full(dirty, sub_res); ++ return; ++ } + if (loc1.sub_resource + 1 == loc2.sub_resource) { + /* Dirty range covers a single sub-resource */ + vmw_subres_dirty_add(dirty, &loc1, &loc2); +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 0de2788b9814c..7db332139f7d5 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -2306,12 +2306,8 @@ static int hid_device_remove(struct device *dev) + { + struct hid_device *hdev = to_hid_device(dev); + struct hid_driver *hdrv; +- int ret = 0; + +- if (down_interruptible(&hdev->driver_input_lock)) { +- ret = -EINTR; +- goto end; +- } ++ down(&hdev->driver_input_lock); + hdev->io_started = false; + + hdrv = hdev->driver; +@@ -2326,8 +2322,8 @@ static int hid_device_remove(struct device *dev) + + if (!hdev->io_started) + up(&hdev->driver_input_lock); +-end: +- return ret; ++ ++ return 0; + } + + static ssize_t modalias_show(struct device *dev, struct device_attribute *a, +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index b84a0a11e05bf..63ca5959dc679 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -396,6 +396,7 @@ + #define USB_DEVICE_ID_HP_X2_10_COVER 0x0755 + #define I2C_DEVICE_ID_HP_SPECTRE_X360_15 0x2817 + #define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706 ++#define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN 0x261A + + #define USB_VENDOR_ID_ELECOM 0x056e + #define USB_DEVICE_ID_ELECOM_BM084 0x0061 +diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c +index abbfa91e73e43..68c8644234a4a 100644 +--- a/drivers/hid/hid-input.c ++++ b/drivers/hid/hid-input.c +@@ -326,6 +326,8 @@ static const struct hid_device_id hid_battery_quirks[] = { + HID_BATTERY_QUIRK_IGNORE }, + { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_15), + HID_BATTERY_QUIRK_IGNORE }, ++ { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN), ++ HID_BATTERY_QUIRK_IGNORE }, + {} + }; + +diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c +index 8319b0ce385a5..b3722c51ec78a 100644 +--- a/drivers/hid/hid-sony.c ++++ b/drivers/hid/hid-sony.c +@@ -597,9 +597,8 @@ struct sony_sc { + /* DS4 calibration data */ + struct ds4_calibration_data ds4_calib_data[6]; + /* GH Live */ ++ struct urb *ghl_urb; + struct timer_list ghl_poke_timer; +- struct usb_ctrlrequest *ghl_cr; +- u8 *ghl_databuf; + }; + + static void sony_set_leds(struct sony_sc *sc); +@@ -625,66 +624,54 @@ static inline void sony_schedule_work(struct sony_sc *sc, + + static void ghl_magic_poke_cb(struct urb *urb) + { +- if (urb) { +- /* Free sc->ghl_cr and sc->ghl_databuf allocated in +- * ghl_magic_poke() +- */ +- kfree(urb->setup_packet); +- kfree(urb->transfer_buffer); +- } ++ struct sony_sc *sc = urb->context; ++ ++ if (urb->status < 0) ++ hid_err(sc->hdev, "URB transfer failed : %d", urb->status); ++ ++ mod_timer(&sc->ghl_poke_timer, jiffies + GHL_GUITAR_POKE_INTERVAL*HZ); + } + + static void ghl_magic_poke(struct timer_list *t) + { ++ int ret; + struct sony_sc *sc = from_timer(sc, t, ghl_poke_timer); + +- int ret; ++ ret = usb_submit_urb(sc->ghl_urb, GFP_ATOMIC); ++ if (ret < 0) ++ hid_err(sc->hdev, "usb_submit_urb failed: %d", ret); ++} ++ ++static int ghl_init_urb(struct sony_sc *sc, struct usb_device *usbdev) ++{ ++ struct usb_ctrlrequest *cr; ++ u16 poke_size; ++ u8 *databuf; + unsigned int pipe; +- struct urb *urb; +- struct usb_device *usbdev = to_usb_device(sc->hdev->dev.parent->parent); +- const u16 poke_size = +- ARRAY_SIZE(ghl_ps3wiiu_magic_data); + ++ poke_size = ARRAY_SIZE(ghl_ps3wiiu_magic_data); + pipe = usb_sndctrlpipe(usbdev, 0); + +- if (!sc->ghl_cr) { +- sc->ghl_cr = kzalloc(sizeof(*sc->ghl_cr), GFP_ATOMIC); +- if (!sc->ghl_cr) +- goto resched; +- } +- +- if (!sc->ghl_databuf) { +- sc->ghl_databuf = kzalloc(poke_size, GFP_ATOMIC); +- if (!sc->ghl_databuf) +- goto resched; +- } ++ cr = devm_kzalloc(&sc->hdev->dev, sizeof(*cr), GFP_ATOMIC); ++ if (cr == NULL) ++ return -ENOMEM; + +- urb = usb_alloc_urb(0, GFP_ATOMIC); +- if (!urb) +- goto resched; ++ databuf = devm_kzalloc(&sc->hdev->dev, poke_size, GFP_ATOMIC); ++ if (databuf == NULL) ++ return -ENOMEM; + +- sc->ghl_cr->bRequestType = ++ cr->bRequestType = + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT; +- sc->ghl_cr->bRequest = USB_REQ_SET_CONFIGURATION; +- sc->ghl_cr->wValue = cpu_to_le16(ghl_ps3wiiu_magic_value); +- sc->ghl_cr->wIndex = 0; +- sc->ghl_cr->wLength = cpu_to_le16(poke_size); +- memcpy(sc->ghl_databuf, ghl_ps3wiiu_magic_data, poke_size); +- ++ cr->bRequest = USB_REQ_SET_CONFIGURATION; ++ cr->wValue = cpu_to_le16(ghl_ps3wiiu_magic_value); ++ cr->wIndex = 0; ++ cr->wLength = cpu_to_le16(poke_size); ++ memcpy(databuf, ghl_ps3wiiu_magic_data, poke_size); + usb_fill_control_urb( +- urb, usbdev, pipe, +- (unsigned char *) sc->ghl_cr, sc->ghl_databuf, +- poke_size, ghl_magic_poke_cb, NULL); +- ret = usb_submit_urb(urb, GFP_ATOMIC); +- if (ret < 0) { +- kfree(sc->ghl_databuf); +- kfree(sc->ghl_cr); +- } +- usb_free_urb(urb); +- +-resched: +- /* Reschedule for next time */ +- mod_timer(&sc->ghl_poke_timer, jiffies + GHL_GUITAR_POKE_INTERVAL*HZ); ++ sc->ghl_urb, usbdev, pipe, ++ (unsigned char *) cr, databuf, poke_size, ++ ghl_magic_poke_cb, sc); ++ return 0; + } + + static int guitar_mapping(struct hid_device *hdev, struct hid_input *hi, +@@ -2981,6 +2968,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) + int ret; + unsigned long quirks = id->driver_data; + struct sony_sc *sc; ++ struct usb_device *usbdev; + unsigned int connect_mask = HID_CONNECT_DEFAULT; + + if (!strcmp(hdev->name, "FutureMax Dance Mat")) +@@ -3000,6 +2988,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) + sc->quirks = quirks; + hid_set_drvdata(hdev, sc); + sc->hdev = hdev; ++ usbdev = to_usb_device(sc->hdev->dev.parent->parent); + + ret = hid_parse(hdev); + if (ret) { +@@ -3042,6 +3031,15 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) + } + + if (sc->quirks & GHL_GUITAR_PS3WIIU) { ++ sc->ghl_urb = usb_alloc_urb(0, GFP_ATOMIC); ++ if (!sc->ghl_urb) ++ return -ENOMEM; ++ ret = ghl_init_urb(sc, usbdev); ++ if (ret) { ++ hid_err(hdev, "error preparing URB\n"); ++ return ret; ++ } ++ + timer_setup(&sc->ghl_poke_timer, ghl_magic_poke, 0); + mod_timer(&sc->ghl_poke_timer, + jiffies + GHL_GUITAR_POKE_INTERVAL*HZ); +@@ -3054,8 +3052,10 @@ static void sony_remove(struct hid_device *hdev) + { + struct sony_sc *sc = hid_get_drvdata(hdev); + +- if (sc->quirks & GHL_GUITAR_PS3WIIU) ++ if (sc->quirks & GHL_GUITAR_PS3WIIU) { + del_timer_sync(&sc->ghl_poke_timer); ++ usb_free_urb(sc->ghl_urb); ++ } + + hid_hw_close(hdev); + +diff --git a/drivers/hid/surface-hid/surface_hid.c b/drivers/hid/surface-hid/surface_hid.c +index 3477b31611ae1..a3a70e4f3f6c9 100644 +--- a/drivers/hid/surface-hid/surface_hid.c ++++ b/drivers/hid/surface-hid/surface_hid.c +@@ -143,7 +143,7 @@ static int ssam_hid_get_raw_report(struct surface_hid_device *shid, u8 rprt_id, + rqst.target_id = shid->uid.target; + rqst.instance_id = shid->uid.instance; + rqst.command_id = SURFACE_HID_CID_GET_FEATURE_REPORT; +- rqst.flags = 0; ++ rqst.flags = SSAM_REQUEST_HAS_RESPONSE; + rqst.length = sizeof(rprt_id); + rqst.payload = &rprt_id; + +diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h +index 71c886245dbf2..8f16654eca098 100644 +--- a/drivers/hid/wacom_wac.h ++++ b/drivers/hid/wacom_wac.h +@@ -122,7 +122,7 @@ + #define WACOM_HID_WD_TOUCHONOFF (WACOM_HID_UP_WACOMDIGITIZER | 0x0454) + #define WACOM_HID_WD_BATTERY_LEVEL (WACOM_HID_UP_WACOMDIGITIZER | 0x043b) + #define WACOM_HID_WD_EXPRESSKEY00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0910) +-#define WACOM_HID_WD_EXPRESSKEYCAP00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0950) ++#define WACOM_HID_WD_EXPRESSKEYCAP00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0940) + #define WACOM_HID_WD_MODE_CHANGE (WACOM_HID_UP_WACOMDIGITIZER | 0x0980) + #define WACOM_HID_WD_MUTE_DEVICE (WACOM_HID_UP_WACOMDIGITIZER | 0x0981) + #define WACOM_HID_WD_CONTROLPANEL (WACOM_HID_UP_WACOMDIGITIZER | 0x0982) +diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c +index 311cd005b3be6..5e479d54918cf 100644 +--- a/drivers/hv/connection.c ++++ b/drivers/hv/connection.c +@@ -232,8 +232,10 @@ int vmbus_connect(void) + */ + + for (i = 0; ; i++) { +- if (i == ARRAY_SIZE(vmbus_versions)) ++ if (i == ARRAY_SIZE(vmbus_versions)) { ++ ret = -EDOM; + goto cleanup; ++ } + + version = vmbus_versions[i]; + if (version > max_version) +diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c +index e4aefeb330daf..136576cba26f5 100644 +--- a/drivers/hv/hv_util.c ++++ b/drivers/hv/hv_util.c +@@ -750,8 +750,8 @@ static int hv_timesync_init(struct hv_util_service *srv) + */ + hv_ptp_clock = ptp_clock_register(&ptp_hyperv_info, NULL); + if (IS_ERR_OR_NULL(hv_ptp_clock)) { +- pr_err("cannot register PTP clock: %ld\n", +- PTR_ERR(hv_ptp_clock)); ++ pr_err("cannot register PTP clock: %d\n", ++ PTR_ERR_OR_ZERO(hv_ptp_clock)); + hv_ptp_clock = NULL; + } + +diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c +index 40eab3349904b..6b884ea009877 100644 +--- a/drivers/hwmon/lm70.c ++++ b/drivers/hwmon/lm70.c +@@ -22,10 +22,10 @@ + #include + #include + #include ++#include + #include + #include + #include +-#include + + #define DRVNAME "lm70" + +@@ -148,29 +148,6 @@ static const struct of_device_id lm70_of_ids[] = { + MODULE_DEVICE_TABLE(of, lm70_of_ids); + #endif + +-#ifdef CONFIG_ACPI +-static const struct acpi_device_id lm70_acpi_ids[] = { +- { +- .id = "LM000070", +- .driver_data = LM70_CHIP_LM70, +- }, +- { +- .id = "TMP00121", +- .driver_data = LM70_CHIP_TMP121, +- }, +- { +- .id = "LM000071", +- .driver_data = LM70_CHIP_LM71, +- }, +- { +- .id = "LM000074", +- .driver_data = LM70_CHIP_LM74, +- }, +- {}, +-}; +-MODULE_DEVICE_TABLE(acpi, lm70_acpi_ids); +-#endif +- + static int lm70_probe(struct spi_device *spi) + { + struct device *hwmon_dev; +@@ -217,7 +194,6 @@ static struct spi_driver lm70_driver = { + .driver = { + .name = "lm70", + .of_match_table = of_match_ptr(lm70_of_ids), +- .acpi_match_table = ACPI_PTR(lm70_acpi_ids), + }, + .id_table = lm70_ids, + .probe = lm70_probe, +diff --git a/drivers/hwmon/max31722.c b/drivers/hwmon/max31722.c +index 062eceb7be0db..613338cbcb170 100644 +--- a/drivers/hwmon/max31722.c ++++ b/drivers/hwmon/max31722.c +@@ -6,7 +6,6 @@ + * Copyright (c) 2016, Intel Corporation. + */ + +-#include + #include + #include + #include +@@ -133,20 +132,12 @@ static const struct spi_device_id max31722_spi_id[] = { + {"max31723", 0}, + {} + }; +- +-static const struct acpi_device_id __maybe_unused max31722_acpi_id[] = { +- {"MAX31722", 0}, +- {"MAX31723", 0}, +- {} +-}; +- + MODULE_DEVICE_TABLE(spi, max31722_spi_id); + + static struct spi_driver max31722_driver = { + .driver = { + .name = "max31722", + .pm = &max31722_pm_ops, +- .acpi_match_table = ACPI_PTR(max31722_acpi_id), + }, + .probe = max31722_probe, + .remove = max31722_remove, +diff --git a/drivers/hwmon/max31790.c b/drivers/hwmon/max31790.c +index 86e6c71db685c..67677c4377687 100644 +--- a/drivers/hwmon/max31790.c ++++ b/drivers/hwmon/max31790.c +@@ -27,6 +27,7 @@ + + /* Fan Config register bits */ + #define MAX31790_FAN_CFG_RPM_MODE 0x80 ++#define MAX31790_FAN_CFG_CTRL_MON 0x10 + #define MAX31790_FAN_CFG_TACH_INPUT_EN 0x08 + #define MAX31790_FAN_CFG_TACH_INPUT 0x01 + +@@ -104,7 +105,7 @@ static struct max31790_data *max31790_update_device(struct device *dev) + data->tach[NR_CHANNEL + i] = rv; + } else { + rv = i2c_smbus_read_word_swapped(client, +- MAX31790_REG_PWMOUT(i)); ++ MAX31790_REG_PWM_DUTY_CYCLE(i)); + if (rv < 0) + goto abort; + data->pwm[i] = rv; +@@ -170,7 +171,7 @@ static int max31790_read_fan(struct device *dev, u32 attr, int channel, + + switch (attr) { + case hwmon_fan_input: +- sr = get_tach_period(data->fan_dynamics[channel]); ++ sr = get_tach_period(data->fan_dynamics[channel % NR_CHANNEL]); + rpm = RPM_FROM_REG(data->tach[channel], sr); + *val = rpm; + return 0; +@@ -271,12 +272,12 @@ static int max31790_read_pwm(struct device *dev, u32 attr, int channel, + *val = data->pwm[channel] >> 8; + return 0; + case hwmon_pwm_enable: +- if (fan_config & MAX31790_FAN_CFG_RPM_MODE) ++ if (fan_config & MAX31790_FAN_CFG_CTRL_MON) ++ *val = 0; ++ else if (fan_config & MAX31790_FAN_CFG_RPM_MODE) + *val = 2; +- else if (fan_config & MAX31790_FAN_CFG_TACH_INPUT_EN) +- *val = 1; + else +- *val = 0; ++ *val = 1; + return 0; + default: + return -EOPNOTSUPP; +@@ -299,31 +300,41 @@ static int max31790_write_pwm(struct device *dev, u32 attr, int channel, + err = -EINVAL; + break; + } +- data->pwm[channel] = val << 8; ++ data->valid = false; + err = i2c_smbus_write_word_swapped(client, + MAX31790_REG_PWMOUT(channel), +- data->pwm[channel]); ++ val << 8); + break; + case hwmon_pwm_enable: + fan_config = data->fan_config[channel]; + if (val == 0) { +- fan_config &= ~(MAX31790_FAN_CFG_TACH_INPUT_EN | +- MAX31790_FAN_CFG_RPM_MODE); ++ fan_config |= MAX31790_FAN_CFG_CTRL_MON; ++ /* ++ * Disable RPM mode; otherwise disabling fan speed ++ * monitoring is not possible. ++ */ ++ fan_config &= ~MAX31790_FAN_CFG_RPM_MODE; + } else if (val == 1) { +- fan_config = (fan_config | +- MAX31790_FAN_CFG_TACH_INPUT_EN) & +- ~MAX31790_FAN_CFG_RPM_MODE; ++ fan_config &= ~(MAX31790_FAN_CFG_CTRL_MON | MAX31790_FAN_CFG_RPM_MODE); + } else if (val == 2) { +- fan_config |= MAX31790_FAN_CFG_TACH_INPUT_EN | +- MAX31790_FAN_CFG_RPM_MODE; ++ fan_config &= ~MAX31790_FAN_CFG_CTRL_MON; ++ /* ++ * The chip sets MAX31790_FAN_CFG_TACH_INPUT_EN on its ++ * own if MAX31790_FAN_CFG_RPM_MODE is set. ++ * Do it here as well to reflect the actual register ++ * value in the cache. ++ */ ++ fan_config |= (MAX31790_FAN_CFG_RPM_MODE | MAX31790_FAN_CFG_TACH_INPUT_EN); + } else { + err = -EINVAL; + break; + } +- data->fan_config[channel] = fan_config; +- err = i2c_smbus_write_byte_data(client, +- MAX31790_REG_FAN_CONFIG(channel), +- fan_config); ++ if (fan_config != data->fan_config[channel]) { ++ err = i2c_smbus_write_byte_data(client, MAX31790_REG_FAN_CONFIG(channel), ++ fan_config); ++ if (!err) ++ data->fan_config[channel] = fan_config; ++ } + break; + default: + err = -EOPNOTSUPP; +diff --git a/drivers/hwmon/pmbus/bpa-rs600.c b/drivers/hwmon/pmbus/bpa-rs600.c +index f6558ee9dec36..2be69fedfa361 100644 +--- a/drivers/hwmon/pmbus/bpa-rs600.c ++++ b/drivers/hwmon/pmbus/bpa-rs600.c +@@ -46,6 +46,32 @@ static int bpa_rs600_read_byte_data(struct i2c_client *client, int page, int reg + return ret; + } + ++/* ++ * The BPA-RS600 violates the PMBus spec. Specifically it treats the ++ * mantissa as unsigned. Deal with this here to allow the PMBus core ++ * to work with correctly encoded data. ++ */ ++static int bpa_rs600_read_vin(struct i2c_client *client) ++{ ++ int ret, exponent, mantissa; ++ ++ ret = pmbus_read_word_data(client, 0, 0xff, PMBUS_READ_VIN); ++ if (ret < 0) ++ return ret; ++ ++ if (ret & BIT(10)) { ++ exponent = ret >> 11; ++ mantissa = ret & 0x7ff; ++ ++ exponent++; ++ mantissa >>= 1; ++ ++ ret = (exponent << 11) | mantissa; ++ } ++ ++ return ret; ++} ++ + static int bpa_rs600_read_word_data(struct i2c_client *client, int page, int phase, int reg) + { + int ret; +@@ -85,6 +111,9 @@ static int bpa_rs600_read_word_data(struct i2c_client *client, int page, int pha + /* These commands return data but it is invalid/un-documented */ + ret = -ENXIO; + break; ++ case PMBUS_READ_VIN: ++ ret = bpa_rs600_read_vin(client); ++ break; + default: + if (reg >= PMBUS_VIRT_BASE) + ret = -ENXIO; +diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c +index 6c68d34d956e8..4ddf3d2338443 100644 +--- a/drivers/hwtracing/coresight/coresight-core.c ++++ b/drivers/hwtracing/coresight/coresight-core.c +@@ -608,7 +608,7 @@ static struct coresight_device * + coresight_find_enabled_sink(struct coresight_device *csdev) + { + int i; +- struct coresight_device *sink; ++ struct coresight_device *sink = NULL; + + if ((csdev->type == CORESIGHT_DEV_TYPE_SINK || + csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) && +diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c +index dcca9c2396db1..6d5014ebaab5e 100644 +--- a/drivers/i2c/busses/i2c-mpc.c ++++ b/drivers/i2c/busses/i2c-mpc.c +@@ -635,6 +635,8 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id) + + status = readb(i2c->base + MPC_I2C_SR); + if (status & CSR_MIF) { ++ /* Read again to allow register to stabilise */ ++ status = readb(i2c->base + MPC_I2C_SR); + writeb(0, i2c->base + MPC_I2C_SR); + mpc_i2c_do_intr(i2c, status); + return IRQ_HANDLED; +diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c +index b8a7469cdae41..b8cea42fca1a1 100644 +--- a/drivers/iio/accel/bma180.c ++++ b/drivers/iio/accel/bma180.c +@@ -55,7 +55,7 @@ struct bma180_part_info { + + u8 int_reset_reg, int_reset_mask; + u8 sleep_reg, sleep_mask; +- u8 bw_reg, bw_mask; ++ u8 bw_reg, bw_mask, bw_offset; + u8 scale_reg, scale_mask; + u8 power_reg, power_mask, lowpower_val; + u8 int_enable_reg, int_enable_mask; +@@ -127,6 +127,7 @@ struct bma180_part_info { + + #define BMA250_RANGE_MASK GENMASK(3, 0) /* Range of accel values */ + #define BMA250_BW_MASK GENMASK(4, 0) /* Accel bandwidth */ ++#define BMA250_BW_OFFSET 8 + #define BMA250_SUSPEND_MASK BIT(7) /* chip will sleep */ + #define BMA250_LOWPOWER_MASK BIT(6) + #define BMA250_DATA_INTEN_MASK BIT(4) +@@ -143,6 +144,7 @@ struct bma180_part_info { + + #define BMA254_RANGE_MASK GENMASK(3, 0) /* Range of accel values */ + #define BMA254_BW_MASK GENMASK(4, 0) /* Accel bandwidth */ ++#define BMA254_BW_OFFSET 8 + #define BMA254_SUSPEND_MASK BIT(7) /* chip will sleep */ + #define BMA254_LOWPOWER_MASK BIT(6) + #define BMA254_DATA_INTEN_MASK BIT(4) +@@ -162,7 +164,11 @@ struct bma180_data { + int scale; + int bw; + bool pmode; +- u8 buff[16]; /* 3x 16-bit + 8-bit + padding + timestamp */ ++ /* Ensure timestamp is naturally aligned */ ++ struct { ++ s16 chan[4]; ++ s64 timestamp __aligned(8); ++ } scan; + }; + + enum bma180_chan { +@@ -283,7 +289,8 @@ static int bma180_set_bw(struct bma180_data *data, int val) + for (i = 0; i < data->part_info->num_bw; ++i) { + if (data->part_info->bw_table[i] == val) { + ret = bma180_set_bits(data, data->part_info->bw_reg, +- data->part_info->bw_mask, i); ++ data->part_info->bw_mask, ++ i + data->part_info->bw_offset); + if (ret) { + dev_err(&data->client->dev, + "failed to set bandwidth\n"); +@@ -876,6 +883,7 @@ static const struct bma180_part_info bma180_part_info[] = { + .sleep_mask = BMA250_SUSPEND_MASK, + .bw_reg = BMA250_BW_REG, + .bw_mask = BMA250_BW_MASK, ++ .bw_offset = BMA250_BW_OFFSET, + .scale_reg = BMA250_RANGE_REG, + .scale_mask = BMA250_RANGE_MASK, + .power_reg = BMA250_POWER_REG, +@@ -905,6 +913,7 @@ static const struct bma180_part_info bma180_part_info[] = { + .sleep_mask = BMA254_SUSPEND_MASK, + .bw_reg = BMA254_BW_REG, + .bw_mask = BMA254_BW_MASK, ++ .bw_offset = BMA254_BW_OFFSET, + .scale_reg = BMA254_RANGE_REG, + .scale_mask = BMA254_RANGE_MASK, + .power_reg = BMA254_POWER_REG, +@@ -938,12 +947,12 @@ static irqreturn_t bma180_trigger_handler(int irq, void *p) + mutex_unlock(&data->mutex); + goto err; + } +- ((s16 *)data->buff)[i++] = ret; ++ data->scan.chan[i++] = ret; + } + + mutex_unlock(&data->mutex); + +- iio_push_to_buffers_with_timestamp(indio_dev, data->buff, time_ns); ++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, time_ns); + err: + iio_trigger_notify_done(indio_dev->trig); + +diff --git a/drivers/iio/accel/bma220_spi.c b/drivers/iio/accel/bma220_spi.c +index 36fc9876dbcaf..0622c79364994 100644 +--- a/drivers/iio/accel/bma220_spi.c ++++ b/drivers/iio/accel/bma220_spi.c +@@ -63,7 +63,11 @@ static const int bma220_scale_table[][2] = { + struct bma220_data { + struct spi_device *spi_device; + struct mutex lock; +- s8 buffer[16]; /* 3x8-bit channels + 5x8 padding + 8x8 timestamp */ ++ struct { ++ s8 chans[3]; ++ /* Ensure timestamp is naturally aligned. */ ++ s64 timestamp __aligned(8); ++ } scan; + u8 tx_buf[2] ____cacheline_aligned; + }; + +@@ -94,12 +98,12 @@ static irqreturn_t bma220_trigger_handler(int irq, void *p) + + mutex_lock(&data->lock); + data->tx_buf[0] = BMA220_REG_ACCEL_X | BMA220_READ_MASK; +- ret = spi_write_then_read(spi, data->tx_buf, 1, data->buffer, ++ ret = spi_write_then_read(spi, data->tx_buf, 1, &data->scan.chans, + ARRAY_SIZE(bma220_channels) - 1); + if (ret < 0) + goto err; + +- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, ++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, + pf->timestamp); + err: + mutex_unlock(&data->lock); +diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c +index 04d85ce34e9f5..5d58b5533cb82 100644 +--- a/drivers/iio/accel/bmc150-accel-core.c ++++ b/drivers/iio/accel/bmc150-accel-core.c +@@ -1177,11 +1177,12 @@ static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = { + /* + * The datasheet page 17 says: + * 15.6, 31.3, 62.5 and 125 mg per LSB. ++ * IIO unit is m/s^2 so multiply by g = 9.80665 m/s^2. + */ +- .scale_table = { {156000, BMC150_ACCEL_DEF_RANGE_2G}, +- {313000, BMC150_ACCEL_DEF_RANGE_4G}, +- {625000, BMC150_ACCEL_DEF_RANGE_8G}, +- {1250000, BMC150_ACCEL_DEF_RANGE_16G} }, ++ .scale_table = { {152984, BMC150_ACCEL_DEF_RANGE_2G}, ++ {306948, BMC150_ACCEL_DEF_RANGE_4G}, ++ {612916, BMC150_ACCEL_DEF_RANGE_8G}, ++ {1225831, BMC150_ACCEL_DEF_RANGE_16G} }, + }, + [bma222e] = { + .name = "BMA222E", +@@ -1809,21 +1810,17 @@ EXPORT_SYMBOL_GPL(bmc150_accel_core_probe); + + struct i2c_client *bmc150_get_second_device(struct i2c_client *client) + { +- struct bmc150_accel_data *data = i2c_get_clientdata(client); +- +- if (!data) +- return NULL; ++ struct bmc150_accel_data *data = iio_priv(i2c_get_clientdata(client)); + + return data->second_device; + } + EXPORT_SYMBOL_GPL(bmc150_get_second_device); + +-void bmc150_set_second_device(struct i2c_client *client) ++void bmc150_set_second_device(struct i2c_client *client, struct i2c_client *second_dev) + { +- struct bmc150_accel_data *data = i2c_get_clientdata(client); ++ struct bmc150_accel_data *data = iio_priv(i2c_get_clientdata(client)); + +- if (data) +- data->second_device = client; ++ data->second_device = second_dev; + } + EXPORT_SYMBOL_GPL(bmc150_set_second_device); + +diff --git a/drivers/iio/accel/bmc150-accel-i2c.c b/drivers/iio/accel/bmc150-accel-i2c.c +index 69f709319484f..2afaae0294eef 100644 +--- a/drivers/iio/accel/bmc150-accel-i2c.c ++++ b/drivers/iio/accel/bmc150-accel-i2c.c +@@ -70,7 +70,7 @@ static int bmc150_accel_probe(struct i2c_client *client, + + second_dev = i2c_acpi_new_device(&client->dev, 1, &board_info); + if (!IS_ERR(second_dev)) +- bmc150_set_second_device(second_dev); ++ bmc150_set_second_device(client, second_dev); + } + #endif + +diff --git a/drivers/iio/accel/bmc150-accel.h b/drivers/iio/accel/bmc150-accel.h +index 6024f15b97004..e30c1698f6fbd 100644 +--- a/drivers/iio/accel/bmc150-accel.h ++++ b/drivers/iio/accel/bmc150-accel.h +@@ -18,7 +18,7 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq, + const char *name, bool block_supported); + int bmc150_accel_core_remove(struct device *dev); + struct i2c_client *bmc150_get_second_device(struct i2c_client *second_device); +-void bmc150_set_second_device(struct i2c_client *second_device); ++void bmc150_set_second_device(struct i2c_client *client, struct i2c_client *second_dev); + extern const struct dev_pm_ops bmc150_accel_pm_ops; + extern const struct regmap_config bmc150_regmap_conf; + +diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c +index 2f9465cb382ff..27f47e1c251e9 100644 +--- a/drivers/iio/accel/hid-sensor-accel-3d.c ++++ b/drivers/iio/accel/hid-sensor-accel-3d.c +@@ -28,8 +28,11 @@ struct accel_3d_state { + struct hid_sensor_hub_callbacks callbacks; + struct hid_sensor_common common_attributes; + struct hid_sensor_hub_attribute_info accel[ACCEL_3D_CHANNEL_MAX]; +- /* Reserve for 3 channels + padding + timestamp */ +- u32 accel_val[ACCEL_3D_CHANNEL_MAX + 3]; ++ /* Ensure timestamp is naturally aligned */ ++ struct { ++ u32 accel_val[3]; ++ s64 timestamp __aligned(8); ++ } scan; + int scale_pre_decml; + int scale_post_decml; + int scale_precision; +@@ -245,8 +248,8 @@ static int accel_3d_proc_event(struct hid_sensor_hub_device *hsdev, + accel_state->timestamp = iio_get_time_ns(indio_dev); + + hid_sensor_push_data(indio_dev, +- accel_state->accel_val, +- sizeof(accel_state->accel_val), ++ &accel_state->scan, ++ sizeof(accel_state->scan), + accel_state->timestamp); + + accel_state->timestamp = 0; +@@ -271,7 +274,7 @@ static int accel_3d_capture_sample(struct hid_sensor_hub_device *hsdev, + case HID_USAGE_SENSOR_ACCEL_Y_AXIS: + case HID_USAGE_SENSOR_ACCEL_Z_AXIS: + offset = usage_id - HID_USAGE_SENSOR_ACCEL_X_AXIS; +- accel_state->accel_val[CHANNEL_SCAN_INDEX_X + offset] = ++ accel_state->scan.accel_val[CHANNEL_SCAN_INDEX_X + offset] = + *(u32 *)raw_data; + ret = 0; + break; +diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c +index ff724bc17a458..f6720dbba0aa3 100644 +--- a/drivers/iio/accel/kxcjk-1013.c ++++ b/drivers/iio/accel/kxcjk-1013.c +@@ -133,6 +133,13 @@ enum kx_acpi_type { + ACPI_KIOX010A, + }; + ++enum kxcjk1013_axis { ++ AXIS_X, ++ AXIS_Y, ++ AXIS_Z, ++ AXIS_MAX ++}; ++ + struct kxcjk1013_data { + struct regulator_bulk_data regulators[2]; + struct i2c_client *client; +@@ -140,7 +147,11 @@ struct kxcjk1013_data { + struct iio_trigger *motion_trig; + struct iio_mount_matrix orientation; + struct mutex mutex; +- s16 buffer[8]; ++ /* Ensure timestamp naturally aligned */ ++ struct { ++ s16 chans[AXIS_MAX]; ++ s64 timestamp __aligned(8); ++ } scan; + u8 odr_bits; + u8 range; + int wake_thres; +@@ -154,13 +165,6 @@ struct kxcjk1013_data { + enum kx_acpi_type acpi_type; + }; + +-enum kxcjk1013_axis { +- AXIS_X, +- AXIS_Y, +- AXIS_Z, +- AXIS_MAX, +-}; +- + enum kxcjk1013_mode { + STANDBY, + OPERATION, +@@ -1094,12 +1098,12 @@ static irqreturn_t kxcjk1013_trigger_handler(int irq, void *p) + ret = i2c_smbus_read_i2c_block_data_or_emulated(data->client, + KXCJK1013_REG_XOUT_L, + AXIS_MAX * 2, +- (u8 *)data->buffer); ++ (u8 *)data->scan.chans); + mutex_unlock(&data->mutex); + if (ret < 0) + goto err; + +- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, ++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, + data->timestamp); + err: + iio_trigger_notify_done(indio_dev->trig); +diff --git a/drivers/iio/accel/mxc4005.c b/drivers/iio/accel/mxc4005.c +index fb3cbaa62bd87..0f90e6ec01e17 100644 +--- a/drivers/iio/accel/mxc4005.c ++++ b/drivers/iio/accel/mxc4005.c +@@ -56,7 +56,11 @@ struct mxc4005_data { + struct mutex mutex; + struct regmap *regmap; + struct iio_trigger *dready_trig; +- __be16 buffer[8]; ++ /* Ensure timestamp is naturally aligned */ ++ struct { ++ __be16 chans[3]; ++ s64 timestamp __aligned(8); ++ } scan; + bool trigger_enabled; + }; + +@@ -135,7 +139,7 @@ static int mxc4005_read_xyz(struct mxc4005_data *data) + int ret; + + ret = regmap_bulk_read(data->regmap, MXC4005_REG_XOUT_UPPER, +- data->buffer, sizeof(data->buffer)); ++ data->scan.chans, sizeof(data->scan.chans)); + if (ret < 0) { + dev_err(data->dev, "failed to read axes\n"); + return ret; +@@ -301,7 +305,7 @@ static irqreturn_t mxc4005_trigger_handler(int irq, void *private) + if (ret < 0) + goto err; + +- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, ++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, + pf->timestamp); + + err: +diff --git a/drivers/iio/accel/stk8312.c b/drivers/iio/accel/stk8312.c +index 157d8faefb9e4..ba571f0f5c985 100644 +--- a/drivers/iio/accel/stk8312.c ++++ b/drivers/iio/accel/stk8312.c +@@ -103,7 +103,11 @@ struct stk8312_data { + u8 mode; + struct iio_trigger *dready_trig; + bool dready_trigger_on; +- s8 buffer[16]; /* 3x8-bit channels + 5x8 padding + 64-bit timestamp */ ++ /* Ensure timestamp is naturally aligned */ ++ struct { ++ s8 chans[3]; ++ s64 timestamp __aligned(8); ++ } scan; + }; + + static IIO_CONST_ATTR(in_accel_scale_available, STK8312_SCALE_AVAIL); +@@ -438,7 +442,7 @@ static irqreturn_t stk8312_trigger_handler(int irq, void *p) + ret = i2c_smbus_read_i2c_block_data(data->client, + STK8312_REG_XOUT, + STK8312_ALL_CHANNEL_SIZE, +- data->buffer); ++ data->scan.chans); + if (ret < STK8312_ALL_CHANNEL_SIZE) { + dev_err(&data->client->dev, "register read failed\n"); + mutex_unlock(&data->lock); +@@ -452,12 +456,12 @@ static irqreturn_t stk8312_trigger_handler(int irq, void *p) + mutex_unlock(&data->lock); + goto err; + } +- data->buffer[i++] = ret; ++ data->scan.chans[i++] = ret; + } + } + mutex_unlock(&data->lock); + +- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, ++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, + pf->timestamp); + err: + iio_trigger_notify_done(indio_dev->trig); +diff --git a/drivers/iio/accel/stk8ba50.c b/drivers/iio/accel/stk8ba50.c +index 7cf9cb7e86667..eb9daa4e623a8 100644 +--- a/drivers/iio/accel/stk8ba50.c ++++ b/drivers/iio/accel/stk8ba50.c +@@ -91,12 +91,11 @@ struct stk8ba50_data { + u8 sample_rate_idx; + struct iio_trigger *dready_trig; + bool dready_trigger_on; +- /* +- * 3 x 16-bit channels (10-bit data, 6-bit padding) + +- * 1 x 16 padding + +- * 4 x 16 64-bit timestamp +- */ +- s16 buffer[8]; ++ /* Ensure timestamp is naturally aligned */ ++ struct { ++ s16 chans[3]; ++ s64 timetamp __aligned(8); ++ } scan; + }; + + #define STK8BA50_ACCEL_CHANNEL(index, reg, axis) { \ +@@ -324,7 +323,7 @@ static irqreturn_t stk8ba50_trigger_handler(int irq, void *p) + ret = i2c_smbus_read_i2c_block_data(data->client, + STK8BA50_REG_XOUT, + STK8BA50_ALL_CHANNEL_SIZE, +- (u8 *)data->buffer); ++ (u8 *)data->scan.chans); + if (ret < STK8BA50_ALL_CHANNEL_SIZE) { + dev_err(&data->client->dev, "register read failed\n"); + goto err; +@@ -337,10 +336,10 @@ static irqreturn_t stk8ba50_trigger_handler(int irq, void *p) + if (ret < 0) + goto err; + +- data->buffer[i++] = ret; ++ data->scan.chans[i++] = ret; + } + } +- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, ++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, + pf->timestamp); + err: + mutex_unlock(&data->lock); +diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c +index a7826f097b95c..d356b515df090 100644 +--- a/drivers/iio/adc/at91-sama5d2_adc.c ++++ b/drivers/iio/adc/at91-sama5d2_adc.c +@@ -403,7 +403,8 @@ struct at91_adc_state { + struct at91_adc_dma dma_st; + struct at91_adc_touch touch_st; + struct iio_dev *indio_dev; +- u16 buffer[AT91_BUFFER_MAX_HWORDS]; ++ /* Ensure naturally aligned timestamp */ ++ u16 buffer[AT91_BUFFER_MAX_HWORDS] __aligned(8); + /* + * lock to prevent concurrent 'single conversion' requests through + * sysfs. +diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c +index 6a173531d355b..f7ee856a6b8b6 100644 +--- a/drivers/iio/adc/hx711.c ++++ b/drivers/iio/adc/hx711.c +@@ -86,9 +86,9 @@ struct hx711_data { + struct mutex lock; + /* + * triggered buffer +- * 2x32-bit channel + 64-bit timestamp ++ * 2x32-bit channel + 64-bit naturally aligned timestamp + */ +- u32 buffer[4]; ++ u32 buffer[4] __aligned(8); + /* + * delay after a rising edge on SCK until the data is ready DOUT + * this is dependent on the hx711 where the datasheet tells a +diff --git a/drivers/iio/adc/mxs-lradc-adc.c b/drivers/iio/adc/mxs-lradc-adc.c +index 30e29f44ebd2e..c480cb489c1a3 100644 +--- a/drivers/iio/adc/mxs-lradc-adc.c ++++ b/drivers/iio/adc/mxs-lradc-adc.c +@@ -115,7 +115,8 @@ struct mxs_lradc_adc { + struct device *dev; + + void __iomem *base; +- u32 buffer[10]; ++ /* Maximum of 8 channels + 8 byte ts */ ++ u32 buffer[10] __aligned(8); + struct iio_trigger *trig; + struct completion completion; + spinlock_t lock; +diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c +index 9fef39bcf997b..5b828428be77c 100644 +--- a/drivers/iio/adc/ti-ads1015.c ++++ b/drivers/iio/adc/ti-ads1015.c +@@ -395,10 +395,14 @@ static irqreturn_t ads1015_trigger_handler(int irq, void *p) + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct ads1015_data *data = iio_priv(indio_dev); +- s16 buf[8]; /* 1x s16 ADC val + 3x s16 padding + 4x s16 timestamp */ ++ /* Ensure natural alignment of timestamp */ ++ struct { ++ s16 chan; ++ s64 timestamp __aligned(8); ++ } scan; + int chan, ret, res; + +- memset(buf, 0, sizeof(buf)); ++ memset(&scan, 0, sizeof(scan)); + + mutex_lock(&data->lock); + chan = find_first_bit(indio_dev->active_scan_mask, +@@ -409,10 +413,10 @@ static irqreturn_t ads1015_trigger_handler(int irq, void *p) + goto err; + } + +- buf[0] = res; ++ scan.chan = res; + mutex_unlock(&data->lock); + +- iio_push_to_buffers_with_timestamp(indio_dev, buf, ++ iio_push_to_buffers_with_timestamp(indio_dev, &scan, + iio_get_time_ns(indio_dev)); + + err: +diff --git a/drivers/iio/adc/ti-ads8688.c b/drivers/iio/adc/ti-ads8688.c +index 16bcb37eebb72..79c803537dc42 100644 +--- a/drivers/iio/adc/ti-ads8688.c ++++ b/drivers/iio/adc/ti-ads8688.c +@@ -383,7 +383,8 @@ static irqreturn_t ads8688_trigger_handler(int irq, void *p) + { + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; +- u16 buffer[ADS8688_MAX_CHANNELS + sizeof(s64)/sizeof(u16)]; ++ /* Ensure naturally aligned timestamp */ ++ u16 buffer[ADS8688_MAX_CHANNELS + sizeof(s64)/sizeof(u16)] __aligned(8); + int i, j = 0; + + for (i = 0; i < indio_dev->masklength; i++) { +diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c +index 1d794cf3e3f13..fd57fc43e8e5c 100644 +--- a/drivers/iio/adc/vf610_adc.c ++++ b/drivers/iio/adc/vf610_adc.c +@@ -167,7 +167,11 @@ struct vf610_adc { + u32 sample_freq_avail[5]; + + struct completion completion; +- u16 buffer[8]; ++ /* Ensure the timestamp is naturally aligned */ ++ struct { ++ u16 chan; ++ s64 timestamp __aligned(8); ++ } scan; + }; + + static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 }; +@@ -579,9 +583,9 @@ static irqreturn_t vf610_adc_isr(int irq, void *dev_id) + if (coco & VF610_ADC_HS_COCO0) { + info->value = vf610_adc_read_data(info); + if (iio_buffer_enabled(indio_dev)) { +- info->buffer[0] = info->value; ++ info->scan.chan = info->value; + iio_push_to_buffers_with_timestamp(indio_dev, +- info->buffer, ++ &info->scan, + iio_get_time_ns(indio_dev)); + iio_trigger_notify_done(indio_dev->trig); + } else +diff --git a/drivers/iio/chemical/atlas-sensor.c b/drivers/iio/chemical/atlas-sensor.c +index 56ba6c82b501f..6795722c68b25 100644 +--- a/drivers/iio/chemical/atlas-sensor.c ++++ b/drivers/iio/chemical/atlas-sensor.c +@@ -91,8 +91,8 @@ struct atlas_data { + struct regmap *regmap; + struct irq_work work; + unsigned int interrupt_enabled; +- +- __be32 buffer[6]; /* 96-bit data + 32-bit pad + 64-bit timestamp */ ++ /* 96-bit data + 32-bit pad + 64-bit timestamp */ ++ __be32 buffer[6] __aligned(8); + }; + + static const struct regmap_config atlas_regmap_config = { +diff --git a/drivers/iio/dummy/Kconfig b/drivers/iio/dummy/Kconfig +index 5c5c2f8c55f36..1f46cb9e51b74 100644 +--- a/drivers/iio/dummy/Kconfig ++++ b/drivers/iio/dummy/Kconfig +@@ -34,6 +34,7 @@ config IIO_SIMPLE_DUMMY_BUFFER + select IIO_BUFFER + select IIO_TRIGGER + select IIO_KFIFO_BUF ++ select IIO_TRIGGERED_BUFFER + help + Add buffered data capture to the simple dummy driver. + +diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c +index 1462a6a5bc6da..3d9eba716b691 100644 +--- a/drivers/iio/frequency/adf4350.c ++++ b/drivers/iio/frequency/adf4350.c +@@ -563,8 +563,10 @@ static int adf4350_probe(struct spi_device *spi) + + st->lock_detect_gpiod = devm_gpiod_get_optional(&spi->dev, NULL, + GPIOD_IN); +- if (IS_ERR(st->lock_detect_gpiod)) +- return PTR_ERR(st->lock_detect_gpiod); ++ if (IS_ERR(st->lock_detect_gpiod)) { ++ ret = PTR_ERR(st->lock_detect_gpiod); ++ goto error_disable_reg; ++ } + + if (pdata->power_up_frequency) { + ret = adf4350_set_freq(st, pdata->power_up_frequency); +diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c +index b11ebd9bb7a41..7bc13ff2c3ac0 100644 +--- a/drivers/iio/gyro/bmg160_core.c ++++ b/drivers/iio/gyro/bmg160_core.c +@@ -98,7 +98,11 @@ struct bmg160_data { + struct iio_trigger *motion_trig; + struct iio_mount_matrix orientation; + struct mutex mutex; +- s16 buffer[8]; ++ /* Ensure naturally aligned timestamp */ ++ struct { ++ s16 chans[3]; ++ s64 timestamp __aligned(8); ++ } scan; + u32 dps_range; + int ev_enable_state; + int slope_thres; +@@ -882,12 +886,12 @@ static irqreturn_t bmg160_trigger_handler(int irq, void *p) + + mutex_lock(&data->mutex); + ret = regmap_bulk_read(data->regmap, BMG160_REG_XOUT_L, +- data->buffer, AXIS_MAX * 2); ++ data->scan.chans, AXIS_MAX * 2); + mutex_unlock(&data->mutex); + if (ret < 0) + goto err; + +- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, ++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, + pf->timestamp); + err: + iio_trigger_notify_done(indio_dev->trig); +diff --git a/drivers/iio/humidity/am2315.c b/drivers/iio/humidity/am2315.c +index 23bc9c784ef4b..248d0f262d601 100644 +--- a/drivers/iio/humidity/am2315.c ++++ b/drivers/iio/humidity/am2315.c +@@ -33,7 +33,11 @@ + struct am2315_data { + struct i2c_client *client; + struct mutex lock; +- s16 buffer[8]; /* 2x16-bit channels + 2x16 padding + 4x16 timestamp */ ++ /* Ensure timestamp is naturally aligned */ ++ struct { ++ s16 chans[2]; ++ s64 timestamp __aligned(8); ++ } scan; + }; + + struct am2315_sensor_data { +@@ -167,20 +171,20 @@ static irqreturn_t am2315_trigger_handler(int irq, void *p) + + mutex_lock(&data->lock); + if (*(indio_dev->active_scan_mask) == AM2315_ALL_CHANNEL_MASK) { +- data->buffer[0] = sensor_data.hum_data; +- data->buffer[1] = sensor_data.temp_data; ++ data->scan.chans[0] = sensor_data.hum_data; ++ data->scan.chans[1] = sensor_data.temp_data; + } else { + i = 0; + for_each_set_bit(bit, indio_dev->active_scan_mask, + indio_dev->masklength) { +- data->buffer[i] = (bit ? sensor_data.temp_data : +- sensor_data.hum_data); ++ data->scan.chans[i] = (bit ? sensor_data.temp_data : ++ sensor_data.hum_data); + i++; + } + } + mutex_unlock(&data->lock); + +- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, ++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, + pf->timestamp); + err: + iio_trigger_notify_done(indio_dev->trig); +diff --git a/drivers/iio/imu/adis16400.c b/drivers/iio/imu/adis16400.c +index 768aa493a1a60..b2f92b55b910c 100644 +--- a/drivers/iio/imu/adis16400.c ++++ b/drivers/iio/imu/adis16400.c +@@ -645,9 +645,6 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p) + void *buffer; + int ret; + +- if (!adis->buffer) +- return -ENOMEM; +- + if (!(st->variant->flags & ADIS16400_NO_BURST) && + st->adis.spi->max_speed_hz > ADIS16400_SPI_BURST) { + st->adis.spi->max_speed_hz = ADIS16400_SPI_BURST; +diff --git a/drivers/iio/imu/adis16475.c b/drivers/iio/imu/adis16475.c +index 1de62fc79e0fc..51b76444db0b9 100644 +--- a/drivers/iio/imu/adis16475.c ++++ b/drivers/iio/imu/adis16475.c +@@ -1068,7 +1068,7 @@ static irqreturn_t adis16475_trigger_handler(int irq, void *p) + + ret = spi_sync(adis->spi, &adis->msg); + if (ret) +- return ret; ++ goto check_burst32; + + adis->spi->max_speed_hz = cached_spi_speed_hz; + buffer = adis->buffer; +diff --git a/drivers/iio/imu/adis_buffer.c b/drivers/iio/imu/adis_buffer.c +index ac354321f63a3..175af154e4437 100644 +--- a/drivers/iio/imu/adis_buffer.c ++++ b/drivers/iio/imu/adis_buffer.c +@@ -129,9 +129,6 @@ static irqreturn_t adis_trigger_handler(int irq, void *p) + struct adis *adis = iio_device_get_drvdata(indio_dev); + int ret; + +- if (!adis->buffer) +- return -ENOMEM; +- + if (adis->data->has_paging) { + mutex_lock(&adis->state_lock); + if (adis->current_page != 0) { +diff --git a/drivers/iio/light/isl29125.c b/drivers/iio/light/isl29125.c +index b93b85dbc3a6a..ba53b50d711a1 100644 +--- a/drivers/iio/light/isl29125.c ++++ b/drivers/iio/light/isl29125.c +@@ -51,7 +51,11 @@ + struct isl29125_data { + struct i2c_client *client; + u8 conf1; +- u16 buffer[8]; /* 3x 16-bit, padding, 8 bytes timestamp */ ++ /* Ensure timestamp is naturally aligned */ ++ struct { ++ u16 chans[3]; ++ s64 timestamp __aligned(8); ++ } scan; + }; + + #define ISL29125_CHANNEL(_color, _si) { \ +@@ -184,10 +188,10 @@ static irqreturn_t isl29125_trigger_handler(int irq, void *p) + if (ret < 0) + goto done; + +- data->buffer[j++] = ret; ++ data->scan.chans[j++] = ret; + } + +- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, ++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, + iio_get_time_ns(indio_dev)); + + done: +diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c +index b4323d2db0b19..74ed2d88a3ed3 100644 +--- a/drivers/iio/light/ltr501.c ++++ b/drivers/iio/light/ltr501.c +@@ -32,9 +32,12 @@ + #define LTR501_PART_ID 0x86 + #define LTR501_MANUFAC_ID 0x87 + #define LTR501_ALS_DATA1 0x88 /* 16-bit, little endian */ ++#define LTR501_ALS_DATA1_UPPER 0x89 /* upper 8 bits of LTR501_ALS_DATA1 */ + #define LTR501_ALS_DATA0 0x8a /* 16-bit, little endian */ ++#define LTR501_ALS_DATA0_UPPER 0x8b /* upper 8 bits of LTR501_ALS_DATA0 */ + #define LTR501_ALS_PS_STATUS 0x8c + #define LTR501_PS_DATA 0x8d /* 16-bit, little endian */ ++#define LTR501_PS_DATA_UPPER 0x8e /* upper 8 bits of LTR501_PS_DATA */ + #define LTR501_INTR 0x8f /* output mode, polarity, mode */ + #define LTR501_PS_THRESH_UP 0x90 /* 11 bit, ps upper threshold */ + #define LTR501_PS_THRESH_LOW 0x92 /* 11 bit, ps lower threshold */ +@@ -406,18 +409,19 @@ static int ltr501_read_als(const struct ltr501_data *data, __le16 buf[2]) + + static int ltr501_read_ps(const struct ltr501_data *data) + { +- int ret, status; ++ __le16 status; ++ int ret; + + ret = ltr501_drdy(data, LTR501_STATUS_PS_RDY); + if (ret < 0) + return ret; + + ret = regmap_bulk_read(data->regmap, LTR501_PS_DATA, +- &status, 2); ++ &status, sizeof(status)); + if (ret < 0) + return ret; + +- return status; ++ return le16_to_cpu(status); + } + + static int ltr501_read_intr_prst(const struct ltr501_data *data, +@@ -1205,7 +1209,7 @@ static struct ltr501_chip_info ltr501_chip_info_tbl[] = { + .als_gain_tbl_size = ARRAY_SIZE(ltr559_als_gain_tbl), + .ps_gain = ltr559_ps_gain_tbl, + .ps_gain_tbl_size = ARRAY_SIZE(ltr559_ps_gain_tbl), +- .als_mode_active = BIT(1), ++ .als_mode_active = BIT(0), + .als_gain_mask = BIT(2) | BIT(3) | BIT(4), + .als_gain_shift = 2, + .info = <r501_info, +@@ -1354,9 +1358,12 @@ static bool ltr501_is_volatile_reg(struct device *dev, unsigned int reg) + { + switch (reg) { + case LTR501_ALS_DATA1: ++ case LTR501_ALS_DATA1_UPPER: + case LTR501_ALS_DATA0: ++ case LTR501_ALS_DATA0_UPPER: + case LTR501_ALS_PS_STATUS: + case LTR501_PS_DATA: ++ case LTR501_PS_DATA_UPPER: + return true; + default: + return false; +diff --git a/drivers/iio/light/tcs3414.c b/drivers/iio/light/tcs3414.c +index 6fe5d46f80d40..0593abd600ec2 100644 +--- a/drivers/iio/light/tcs3414.c ++++ b/drivers/iio/light/tcs3414.c +@@ -53,7 +53,11 @@ struct tcs3414_data { + u8 control; + u8 gain; + u8 timing; +- u16 buffer[8]; /* 4x 16-bit + 8 bytes timestamp */ ++ /* Ensure timestamp is naturally aligned */ ++ struct { ++ u16 chans[4]; ++ s64 timestamp __aligned(8); ++ } scan; + }; + + #define TCS3414_CHANNEL(_color, _si, _addr) { \ +@@ -209,10 +213,10 @@ static irqreturn_t tcs3414_trigger_handler(int irq, void *p) + if (ret < 0) + goto done; + +- data->buffer[j++] = ret; ++ data->scan.chans[j++] = ret; + } + +- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, ++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, + iio_get_time_ns(indio_dev)); + + done: +diff --git a/drivers/iio/light/tcs3472.c b/drivers/iio/light/tcs3472.c +index a0dc447aeb68b..371c6a39a1654 100644 +--- a/drivers/iio/light/tcs3472.c ++++ b/drivers/iio/light/tcs3472.c +@@ -64,7 +64,11 @@ struct tcs3472_data { + u8 control; + u8 atime; + u8 apers; +- u16 buffer[8]; /* 4 16-bit channels + 64-bit timestamp */ ++ /* Ensure timestamp is naturally aligned */ ++ struct { ++ u16 chans[4]; ++ s64 timestamp __aligned(8); ++ } scan; + }; + + static const struct iio_event_spec tcs3472_events[] = { +@@ -386,10 +390,10 @@ static irqreturn_t tcs3472_trigger_handler(int irq, void *p) + if (ret < 0) + goto done; + +- data->buffer[j++] = ret; ++ data->scan.chans[j++] = ret; + } + +- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, ++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, + iio_get_time_ns(indio_dev)); + + done: +@@ -531,7 +535,8 @@ static int tcs3472_probe(struct i2c_client *client, + return 0; + + free_irq: +- free_irq(client->irq, indio_dev); ++ if (client->irq) ++ free_irq(client->irq, indio_dev); + buffer_cleanup: + iio_triggered_buffer_cleanup(indio_dev); + return ret; +@@ -559,7 +564,8 @@ static int tcs3472_remove(struct i2c_client *client) + struct iio_dev *indio_dev = i2c_get_clientdata(client); + + iio_device_unregister(indio_dev); +- free_irq(client->irq, indio_dev); ++ if (client->irq) ++ free_irq(client->irq, indio_dev); + iio_triggered_buffer_cleanup(indio_dev); + tcs3472_powerdown(iio_priv(indio_dev)); + +diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c +index 2f7916f95689e..3b5e27053ef29 100644 +--- a/drivers/iio/light/vcnl4000.c ++++ b/drivers/iio/light/vcnl4000.c +@@ -910,7 +910,7 @@ static irqreturn_t vcnl4010_trigger_handler(int irq, void *p) + struct iio_dev *indio_dev = pf->indio_dev; + struct vcnl4000_data *data = iio_priv(indio_dev); + const unsigned long *active_scan_mask = indio_dev->active_scan_mask; +- u16 buffer[8] = {0}; /* 1x16-bit + ts */ ++ u16 buffer[8] __aligned(8) = {0}; /* 1x16-bit + naturally aligned ts */ + bool data_read = false; + unsigned long isr; + int val = 0; +diff --git a/drivers/iio/light/vcnl4035.c b/drivers/iio/light/vcnl4035.c +index ae87740d9cef2..bc07774117124 100644 +--- a/drivers/iio/light/vcnl4035.c ++++ b/drivers/iio/light/vcnl4035.c +@@ -102,7 +102,8 @@ static irqreturn_t vcnl4035_trigger_consumer_handler(int irq, void *p) + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct vcnl4035_data *data = iio_priv(indio_dev); +- u8 buffer[ALIGN(sizeof(u16), sizeof(s64)) + sizeof(s64)]; ++ /* Ensure naturally aligned timestamp */ ++ u8 buffer[ALIGN(sizeof(u16), sizeof(s64)) + sizeof(s64)] __aligned(8); + int ret; + + ret = regmap_read(data->regmap, VCNL4035_ALS_DATA, (int *)buffer); +diff --git a/drivers/iio/magnetometer/bmc150_magn.c b/drivers/iio/magnetometer/bmc150_magn.c +index 00f9766bad5c5..d534f4f3909eb 100644 +--- a/drivers/iio/magnetometer/bmc150_magn.c ++++ b/drivers/iio/magnetometer/bmc150_magn.c +@@ -138,8 +138,11 @@ struct bmc150_magn_data { + struct regmap *regmap; + struct regulator_bulk_data regulators[2]; + struct iio_mount_matrix orientation; +- /* 4 x 32 bits for x, y z, 4 bytes align, 64 bits timestamp */ +- s32 buffer[6]; ++ /* Ensure timestamp is naturally aligned */ ++ struct { ++ s32 chans[3]; ++ s64 timestamp __aligned(8); ++ } scan; + struct iio_trigger *dready_trig; + bool dready_trigger_on; + int max_odr; +@@ -675,11 +678,11 @@ static irqreturn_t bmc150_magn_trigger_handler(int irq, void *p) + int ret; + + mutex_lock(&data->mutex); +- ret = bmc150_magn_read_xyz(data, data->buffer); ++ ret = bmc150_magn_read_xyz(data, data->scan.chans); + if (ret < 0) + goto err; + +- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, ++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, + pf->timestamp); + + err: +diff --git a/drivers/iio/magnetometer/hmc5843.h b/drivers/iio/magnetometer/hmc5843.h +index 3f6c0b6629415..242f742f2643a 100644 +--- a/drivers/iio/magnetometer/hmc5843.h ++++ b/drivers/iio/magnetometer/hmc5843.h +@@ -33,7 +33,8 @@ enum hmc5843_ids { + * @lock: update and read regmap data + * @regmap: hardware access register maps + * @variant: describe chip variants +- * @buffer: 3x 16-bit channels + padding + 64-bit timestamp ++ * @scan: buffer to pack data for passing to ++ * iio_push_to_buffers_with_timestamp() + */ + struct hmc5843_data { + struct device *dev; +@@ -41,7 +42,10 @@ struct hmc5843_data { + struct regmap *regmap; + const struct hmc5843_chip_info *variant; + struct iio_mount_matrix orientation; +- __be16 buffer[8]; ++ struct { ++ __be16 chans[3]; ++ s64 timestamp __aligned(8); ++ } scan; + }; + + int hmc5843_common_probe(struct device *dev, struct regmap *regmap, +diff --git a/drivers/iio/magnetometer/hmc5843_core.c b/drivers/iio/magnetometer/hmc5843_core.c +index 780faea61d82e..221563e0c18fd 100644 +--- a/drivers/iio/magnetometer/hmc5843_core.c ++++ b/drivers/iio/magnetometer/hmc5843_core.c +@@ -446,13 +446,13 @@ static irqreturn_t hmc5843_trigger_handler(int irq, void *p) + } + + ret = regmap_bulk_read(data->regmap, HMC5843_DATA_OUT_MSB_REGS, +- data->buffer, 3 * sizeof(__be16)); ++ data->scan.chans, sizeof(data->scan.chans)); + + mutex_unlock(&data->lock); + if (ret < 0) + goto done; + +- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, ++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, + iio_get_time_ns(indio_dev)); + + done: +diff --git a/drivers/iio/magnetometer/rm3100-core.c b/drivers/iio/magnetometer/rm3100-core.c +index dd811da9cb6db..934da20781bba 100644 +--- a/drivers/iio/magnetometer/rm3100-core.c ++++ b/drivers/iio/magnetometer/rm3100-core.c +@@ -78,7 +78,8 @@ struct rm3100_data { + bool use_interrupt; + int conversion_time; + int scale; +- u8 buffer[RM3100_SCAN_BYTES]; ++ /* Ensure naturally aligned timestamp */ ++ u8 buffer[RM3100_SCAN_BYTES] __aligned(8); + struct iio_trigger *drdy_trig; + + /* +diff --git a/drivers/iio/potentiostat/lmp91000.c b/drivers/iio/potentiostat/lmp91000.c +index 8a9c576616ee5..ff39ba975da70 100644 +--- a/drivers/iio/potentiostat/lmp91000.c ++++ b/drivers/iio/potentiostat/lmp91000.c +@@ -71,8 +71,8 @@ struct lmp91000_data { + + struct completion completion; + u8 chan_select; +- +- u32 buffer[4]; /* 64-bit data + 64-bit timestamp */ ++ /* 64-bit data + 64-bit naturally aligned timestamp */ ++ u32 buffer[4] __aligned(8); + }; + + static const struct iio_chan_spec lmp91000_channels[] = { +diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c +index edc4a35ae66d1..1d5ace2bde44d 100644 +--- a/drivers/iio/proximity/as3935.c ++++ b/drivers/iio/proximity/as3935.c +@@ -59,7 +59,11 @@ struct as3935_state { + unsigned long noise_tripped; + u32 tune_cap; + u32 nflwdth_reg; +- u8 buffer[16]; /* 8-bit data + 56-bit padding + 64-bit timestamp */ ++ /* Ensure timestamp is naturally aligned */ ++ struct { ++ u8 chan; ++ s64 timestamp __aligned(8); ++ } scan; + u8 buf[2] ____cacheline_aligned; + }; + +@@ -225,8 +229,8 @@ static irqreturn_t as3935_trigger_handler(int irq, void *private) + if (ret) + goto err_read; + +- st->buffer[0] = val & AS3935_DATA_MASK; +- iio_push_to_buffers_with_timestamp(indio_dev, &st->buffer, ++ st->scan.chan = val & AS3935_DATA_MASK; ++ iio_push_to_buffers_with_timestamp(indio_dev, &st->scan, + iio_get_time_ns(indio_dev)); + err_read: + iio_trigger_notify_done(indio_dev->trig); +diff --git a/drivers/iio/proximity/isl29501.c b/drivers/iio/proximity/isl29501.c +index 90e76451c972a..5b6ea783795d9 100644 +--- a/drivers/iio/proximity/isl29501.c ++++ b/drivers/iio/proximity/isl29501.c +@@ -938,7 +938,7 @@ static irqreturn_t isl29501_trigger_handler(int irq, void *p) + struct iio_dev *indio_dev = pf->indio_dev; + struct isl29501_private *isl29501 = iio_priv(indio_dev); + const unsigned long *active_mask = indio_dev->active_scan_mask; +- u32 buffer[4] = {}; /* 1x16-bit + ts */ ++ u32 buffer[4] __aligned(8) = {}; /* 1x16-bit + naturally aligned ts */ + + if (test_bit(ISL29501_DISTANCE_SCAN_INDEX, active_mask)) + isl29501_register_read(isl29501, REG_DISTANCE, buffer); +diff --git a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c +index cc206bfa09c78..d854b8d5fbbaf 100644 +--- a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c ++++ b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c +@@ -44,7 +44,11 @@ struct lidar_data { + int (*xfer)(struct lidar_data *data, u8 reg, u8 *val, int len); + int i2c_enabled; + +- u16 buffer[8]; /* 2 byte distance + 8 byte timestamp */ ++ /* Ensure timestamp is naturally aligned */ ++ struct { ++ u16 chan; ++ s64 timestamp __aligned(8); ++ } scan; + }; + + static const struct iio_chan_spec lidar_channels[] = { +@@ -230,9 +234,9 @@ static irqreturn_t lidar_trigger_handler(int irq, void *private) + struct lidar_data *data = iio_priv(indio_dev); + int ret; + +- ret = lidar_get_measurement(data, data->buffer); ++ ret = lidar_get_measurement(data, &data->scan.chan); + if (!ret) { +- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, ++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, + iio_get_time_ns(indio_dev)); + } else if (ret != -EINVAL) { + dev_err(&data->client->dev, "cannot read LIDAR measurement"); +diff --git a/drivers/iio/proximity/srf08.c b/drivers/iio/proximity/srf08.c +index 70beac5c9c1df..9b0886760f76d 100644 +--- a/drivers/iio/proximity/srf08.c ++++ b/drivers/iio/proximity/srf08.c +@@ -63,11 +63,11 @@ struct srf08_data { + int range_mm; + struct mutex lock; + +- /* +- * triggered buffer +- * 1x16-bit channel + 3x16 padding + 4x16 timestamp +- */ +- s16 buffer[8]; ++ /* Ensure timestamp is naturally aligned */ ++ struct { ++ s16 chan; ++ s64 timestamp __aligned(8); ++ } scan; + + /* Sensor-Type */ + enum srf08_sensor_type sensor_type; +@@ -190,9 +190,9 @@ static irqreturn_t srf08_trigger_handler(int irq, void *p) + + mutex_lock(&data->lock); + +- data->buffer[0] = sensor_data; ++ data->scan.chan = sensor_data; + iio_push_to_buffers_with_timestamp(indio_dev, +- data->buffer, pf->timestamp); ++ &data->scan, pf->timestamp); + + mutex_unlock(&data->lock); + err: +diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c +index 0ead0d2231540..81d832646d27a 100644 +--- a/drivers/infiniband/core/cm.c ++++ b/drivers/infiniband/core/cm.c +@@ -121,8 +121,6 @@ static struct ib_cm { + __be32 random_id_operand; + struct list_head timewait_list; + struct workqueue_struct *wq; +- /* Sync on cm change port state */ +- spinlock_t state_lock; + } cm; + + /* Counter indexes ordered by attribute ID */ +@@ -203,8 +201,6 @@ struct cm_port { + struct cm_device *cm_dev; + struct ib_mad_agent *mad_agent; + u32 port_num; +- struct list_head cm_priv_prim_list; +- struct list_head cm_priv_altr_list; + struct cm_counter_group counter_group[CM_COUNTER_GROUPS]; + }; + +@@ -285,12 +281,6 @@ struct cm_id_private { + u8 service_timeout; + u8 target_ack_delay; + +- struct list_head prim_list; +- struct list_head altr_list; +- /* Indicates that the send port mad is registered and av is set */ +- int prim_send_port_not_ready; +- int altr_send_port_not_ready; +- + struct list_head work_list; + atomic_t work_count; + +@@ -305,53 +295,25 @@ static inline void cm_deref_id(struct cm_id_private *cm_id_priv) + complete(&cm_id_priv->comp); + } + +-static int cm_alloc_msg(struct cm_id_private *cm_id_priv, +- struct ib_mad_send_buf **msg) ++static struct ib_mad_send_buf *cm_alloc_msg(struct cm_id_private *cm_id_priv) + { + struct ib_mad_agent *mad_agent; + struct ib_mad_send_buf *m; + struct ib_ah *ah; +- struct cm_av *av; +- unsigned long flags, flags2; +- int ret = 0; + +- /* don't let the port to be released till the agent is down */ +- spin_lock_irqsave(&cm.state_lock, flags2); +- spin_lock_irqsave(&cm.lock, flags); +- if (!cm_id_priv->prim_send_port_not_ready) +- av = &cm_id_priv->av; +- else if (!cm_id_priv->altr_send_port_not_ready && +- (cm_id_priv->alt_av.port)) +- av = &cm_id_priv->alt_av; +- else { +- pr_info("%s: not valid CM id\n", __func__); +- ret = -ENODEV; +- spin_unlock_irqrestore(&cm.lock, flags); +- goto out; +- } +- spin_unlock_irqrestore(&cm.lock, flags); +- /* Make sure the port haven't released the mad yet */ + mad_agent = cm_id_priv->av.port->mad_agent; +- if (!mad_agent) { +- pr_info("%s: not a valid MAD agent\n", __func__); +- ret = -ENODEV; +- goto out; +- } +- ah = rdma_create_ah(mad_agent->qp->pd, &av->ah_attr, 0); +- if (IS_ERR(ah)) { +- ret = PTR_ERR(ah); +- goto out; +- } ++ ah = rdma_create_ah(mad_agent->qp->pd, &cm_id_priv->av.ah_attr, 0); ++ if (IS_ERR(ah)) ++ return (void *)ah; + + m = ib_create_send_mad(mad_agent, cm_id_priv->id.remote_cm_qpn, +- av->pkey_index, ++ cm_id_priv->av.pkey_index, + 0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA, + GFP_ATOMIC, + IB_MGMT_BASE_VERSION); + if (IS_ERR(m)) { + rdma_destroy_ah(ah, 0); +- ret = PTR_ERR(m); +- goto out; ++ return m; + } + + /* Timeout set by caller if response is expected. */ +@@ -360,11 +322,36 @@ static int cm_alloc_msg(struct cm_id_private *cm_id_priv, + + refcount_inc(&cm_id_priv->refcount); + m->context[0] = cm_id_priv; +- *msg = m; ++ return m; ++} + +-out: +- spin_unlock_irqrestore(&cm.state_lock, flags2); +- return ret; ++static struct ib_mad_send_buf * ++cm_alloc_priv_msg(struct cm_id_private *cm_id_priv) ++{ ++ struct ib_mad_send_buf *msg; ++ ++ lockdep_assert_held(&cm_id_priv->lock); ++ ++ msg = cm_alloc_msg(cm_id_priv); ++ if (IS_ERR(msg)) ++ return msg; ++ cm_id_priv->msg = msg; ++ return msg; ++} ++ ++static void cm_free_priv_msg(struct ib_mad_send_buf *msg) ++{ ++ struct cm_id_private *cm_id_priv = msg->context[0]; ++ ++ lockdep_assert_held(&cm_id_priv->lock); ++ ++ if (!WARN_ON(cm_id_priv->msg != msg)) ++ cm_id_priv->msg = NULL; ++ ++ if (msg->ah) ++ rdma_destroy_ah(msg->ah, 0); ++ cm_deref_id(cm_id_priv); ++ ib_free_send_mad(msg); + } + + static struct ib_mad_send_buf *cm_alloc_response_msg_no_ah(struct cm_port *port, +@@ -413,7 +400,7 @@ static int cm_alloc_response_msg(struct cm_port *port, + + ret = cm_create_response_msg_ah(port, mad_recv_wc, m); + if (ret) { +- cm_free_msg(m); ++ ib_free_send_mad(m); + return ret; + } + +@@ -421,6 +408,13 @@ static int cm_alloc_response_msg(struct cm_port *port, + return 0; + } + ++static void cm_free_response_msg(struct ib_mad_send_buf *msg) ++{ ++ if (msg->ah) ++ rdma_destroy_ah(msg->ah, 0); ++ ib_free_send_mad(msg); ++} ++ + static void *cm_copy_private_data(const void *private_data, u8 private_data_len) + { + void *data; +@@ -445,30 +439,12 @@ static void cm_set_private_data(struct cm_id_private *cm_id_priv, + cm_id_priv->private_data_len = private_data_len; + } + +-static int cm_init_av_for_lap(struct cm_port *port, struct ib_wc *wc, +- struct ib_grh *grh, struct cm_av *av) ++static void cm_init_av_for_lap(struct cm_port *port, struct ib_wc *wc, ++ struct rdma_ah_attr *ah_attr, struct cm_av *av) + { +- struct rdma_ah_attr new_ah_attr; +- int ret; +- + av->port = port; + av->pkey_index = wc->pkey_index; +- +- /* +- * av->ah_attr might be initialized based on past wc during incoming +- * connect request or while sending out connect request. So initialize +- * a new ah_attr on stack. If initialization fails, old ah_attr is +- * used for sending any responses. If initialization is successful, +- * than new ah_attr is used by overwriting old one. +- */ +- ret = ib_init_ah_attr_from_wc(port->cm_dev->ib_device, +- port->port_num, wc, +- grh, &new_ah_attr); +- if (ret) +- return ret; +- +- rdma_move_ah_attr(&av->ah_attr, &new_ah_attr); +- return 0; ++ rdma_move_ah_attr(&av->ah_attr, ah_attr); + } + + static int cm_init_av_for_response(struct cm_port *port, struct ib_wc *wc, +@@ -481,21 +457,6 @@ static int cm_init_av_for_response(struct cm_port *port, struct ib_wc *wc, + grh, &av->ah_attr); + } + +-static void add_cm_id_to_port_list(struct cm_id_private *cm_id_priv, +- struct cm_av *av, struct cm_port *port) +-{ +- unsigned long flags; +- +- spin_lock_irqsave(&cm.lock, flags); +- if (&cm_id_priv->av == av) +- list_add_tail(&cm_id_priv->prim_list, &port->cm_priv_prim_list); +- else if (&cm_id_priv->alt_av == av) +- list_add_tail(&cm_id_priv->altr_list, &port->cm_priv_altr_list); +- else +- WARN_ON(true); +- spin_unlock_irqrestore(&cm.lock, flags); +-} +- + static struct cm_port * + get_cm_port_from_path(struct sa_path_rec *path, const struct ib_gid_attr *attr) + { +@@ -539,8 +500,7 @@ get_cm_port_from_path(struct sa_path_rec *path, const struct ib_gid_attr *attr) + + static int cm_init_av_by_path(struct sa_path_rec *path, + const struct ib_gid_attr *sgid_attr, +- struct cm_av *av, +- struct cm_id_private *cm_id_priv) ++ struct cm_av *av) + { + struct rdma_ah_attr new_ah_attr; + struct cm_device *cm_dev; +@@ -574,11 +534,24 @@ static int cm_init_av_by_path(struct sa_path_rec *path, + return ret; + + av->timeout = path->packet_life_time + 1; +- add_cm_id_to_port_list(cm_id_priv, av, port); + rdma_move_ah_attr(&av->ah_attr, &new_ah_attr); + return 0; + } + ++/* Move av created by cm_init_av_by_path(), so av.dgid is not moved */ ++static void cm_move_av_from_path(struct cm_av *dest, struct cm_av *src) ++{ ++ dest->port = src->port; ++ dest->pkey_index = src->pkey_index; ++ rdma_move_ah_attr(&dest->ah_attr, &src->ah_attr); ++ dest->timeout = src->timeout; ++} ++ ++static void cm_destroy_av(struct cm_av *av) ++{ ++ rdma_destroy_ah_attr(&av->ah_attr); ++} ++ + static u32 cm_local_id(__be32 local_id) + { + return (__force u32) (local_id ^ cm.random_id_operand); +@@ -854,8 +827,6 @@ static struct cm_id_private *cm_alloc_id_priv(struct ib_device *device, + spin_lock_init(&cm_id_priv->lock); + init_completion(&cm_id_priv->comp); + INIT_LIST_HEAD(&cm_id_priv->work_list); +- INIT_LIST_HEAD(&cm_id_priv->prim_list); +- INIT_LIST_HEAD(&cm_id_priv->altr_list); + atomic_set(&cm_id_priv->work_count, -1); + refcount_set(&cm_id_priv->refcount, 1); + +@@ -1156,12 +1127,7 @@ retest: + kfree(cm_id_priv->timewait_info); + cm_id_priv->timewait_info = NULL; + } +- if (!list_empty(&cm_id_priv->altr_list) && +- (!cm_id_priv->altr_send_port_not_ready)) +- list_del(&cm_id_priv->altr_list); +- if (!list_empty(&cm_id_priv->prim_list) && +- (!cm_id_priv->prim_send_port_not_ready)) +- list_del(&cm_id_priv->prim_list); ++ + WARN_ON(cm_id_priv->listen_sharecount); + WARN_ON(!RB_EMPTY_NODE(&cm_id_priv->service_node)); + if (!RB_EMPTY_NODE(&cm_id_priv->sidr_id_node)) +@@ -1175,8 +1141,8 @@ retest: + while ((work = cm_dequeue_work(cm_id_priv)) != NULL) + cm_free_work(work); + +- rdma_destroy_ah_attr(&cm_id_priv->av.ah_attr); +- rdma_destroy_ah_attr(&cm_id_priv->alt_av.ah_attr); ++ cm_destroy_av(&cm_id_priv->av); ++ cm_destroy_av(&cm_id_priv->alt_av); + kfree(cm_id_priv->private_data); + kfree_rcu(cm_id_priv, rcu); + } +@@ -1500,7 +1466,9 @@ static int cm_validate_req_param(struct ib_cm_req_param *param) + int ib_send_cm_req(struct ib_cm_id *cm_id, + struct ib_cm_req_param *param) + { ++ struct cm_av av = {}, alt_av = {}; + struct cm_id_private *cm_id_priv; ++ struct ib_mad_send_buf *msg; + struct cm_req_msg *req_msg; + unsigned long flags; + int ret; +@@ -1514,8 +1482,7 @@ int ib_send_cm_req(struct ib_cm_id *cm_id, + spin_lock_irqsave(&cm_id_priv->lock, flags); + if (cm_id->state != IB_CM_IDLE || WARN_ON(cm_id_priv->timewait_info)) { + spin_unlock_irqrestore(&cm_id_priv->lock, flags); +- ret = -EINVAL; +- goto out; ++ return -EINVAL; + } + spin_unlock_irqrestore(&cm_id_priv->lock, flags); + +@@ -1524,19 +1491,20 @@ int ib_send_cm_req(struct ib_cm_id *cm_id, + if (IS_ERR(cm_id_priv->timewait_info)) { + ret = PTR_ERR(cm_id_priv->timewait_info); + cm_id_priv->timewait_info = NULL; +- goto out; ++ return ret; + } + + ret = cm_init_av_by_path(param->primary_path, +- param->ppath_sgid_attr, &cm_id_priv->av, +- cm_id_priv); ++ param->ppath_sgid_attr, &av); + if (ret) +- goto out; ++ return ret; + if (param->alternate_path) { + ret = cm_init_av_by_path(param->alternate_path, NULL, +- &cm_id_priv->alt_av, cm_id_priv); +- if (ret) +- goto out; ++ &alt_av); ++ if (ret) { ++ cm_destroy_av(&av); ++ return ret; ++ } + } + cm_id->service_id = param->service_id; + cm_id->service_mask = ~cpu_to_be64(0); +@@ -1552,33 +1520,40 @@ int ib_send_cm_req(struct ib_cm_id *cm_id, + cm_id_priv->pkey = param->primary_path->pkey; + cm_id_priv->qp_type = param->qp_type; + +- ret = cm_alloc_msg(cm_id_priv, &cm_id_priv->msg); +- if (ret) +- goto out; ++ spin_lock_irqsave(&cm_id_priv->lock, flags); ++ ++ cm_move_av_from_path(&cm_id_priv->av, &av); ++ if (param->alternate_path) ++ cm_move_av_from_path(&cm_id_priv->alt_av, &alt_av); ++ ++ msg = cm_alloc_priv_msg(cm_id_priv); ++ if (IS_ERR(msg)) { ++ ret = PTR_ERR(msg); ++ goto out_unlock; ++ } + +- req_msg = (struct cm_req_msg *) cm_id_priv->msg->mad; ++ req_msg = (struct cm_req_msg *)msg->mad; + cm_format_req(req_msg, cm_id_priv, param); + cm_id_priv->tid = req_msg->hdr.tid; +- cm_id_priv->msg->timeout_ms = cm_id_priv->timeout_ms; +- cm_id_priv->msg->context[1] = (void *) (unsigned long) IB_CM_REQ_SENT; ++ msg->timeout_ms = cm_id_priv->timeout_ms; ++ msg->context[1] = (void *)(unsigned long)IB_CM_REQ_SENT; + + cm_id_priv->local_qpn = cpu_to_be32(IBA_GET(CM_REQ_LOCAL_QPN, req_msg)); + cm_id_priv->rq_psn = cpu_to_be32(IBA_GET(CM_REQ_STARTING_PSN, req_msg)); + + trace_icm_send_req(&cm_id_priv->id); +- spin_lock_irqsave(&cm_id_priv->lock, flags); +- ret = ib_post_send_mad(cm_id_priv->msg, NULL); +- if (ret) { +- spin_unlock_irqrestore(&cm_id_priv->lock, flags); +- goto error2; +- } ++ ret = ib_post_send_mad(msg, NULL); ++ if (ret) ++ goto out_free; + BUG_ON(cm_id->state != IB_CM_IDLE); + cm_id->state = IB_CM_REQ_SENT; + spin_unlock_irqrestore(&cm_id_priv->lock, flags); + return 0; +- +-error2: cm_free_msg(cm_id_priv->msg); +-out: return ret; ++out_free: ++ cm_free_priv_msg(msg); ++out_unlock: ++ spin_unlock_irqrestore(&cm_id_priv->lock, flags); ++ return ret; + } + EXPORT_SYMBOL(ib_send_cm_req); + +@@ -1618,7 +1593,7 @@ static int cm_issue_rej(struct cm_port *port, + IBA_GET(CM_REJ_REMOTE_COMM_ID, rcv_msg)); + ret = ib_post_send_mad(msg, NULL); + if (ret) +- cm_free_msg(msg); ++ cm_free_response_msg(msg); + + return ret; + } +@@ -1974,7 +1949,7 @@ static void cm_dup_req_handler(struct cm_work *work, + return; + + unlock: spin_unlock_irq(&cm_id_priv->lock); +-free: cm_free_msg(msg); ++free: cm_free_response_msg(msg); + } + + static struct cm_id_private *cm_match_req(struct cm_work *work, +@@ -2163,8 +2138,7 @@ static int cm_req_handler(struct cm_work *work) + sa_path_set_dmac(&work->path[0], + cm_id_priv->av.ah_attr.roce.dmac); + work->path[0].hop_limit = grh->hop_limit; +- ret = cm_init_av_by_path(&work->path[0], gid_attr, &cm_id_priv->av, +- cm_id_priv); ++ ret = cm_init_av_by_path(&work->path[0], gid_attr, &cm_id_priv->av); + if (ret) { + int err; + +@@ -2183,7 +2157,7 @@ static int cm_req_handler(struct cm_work *work) + } + if (cm_req_has_alt_path(req_msg)) { + ret = cm_init_av_by_path(&work->path[1], NULL, +- &cm_id_priv->alt_av, cm_id_priv); ++ &cm_id_priv->alt_av); + if (ret) { + ib_send_cm_rej(&cm_id_priv->id, + IB_CM_REJ_INVALID_ALT_GID, +@@ -2283,9 +2257,11 @@ int ib_send_cm_rep(struct ib_cm_id *cm_id, + goto out; + } + +- ret = cm_alloc_msg(cm_id_priv, &msg); +- if (ret) ++ msg = cm_alloc_priv_msg(cm_id_priv); ++ if (IS_ERR(msg)) { ++ ret = PTR_ERR(msg); + goto out; ++ } + + rep_msg = (struct cm_rep_msg *) msg->mad; + cm_format_rep(rep_msg, cm_id_priv, param); +@@ -2294,14 +2270,10 @@ int ib_send_cm_rep(struct ib_cm_id *cm_id, + + trace_icm_send_rep(cm_id); + ret = ib_post_send_mad(msg, NULL); +- if (ret) { +- spin_unlock_irqrestore(&cm_id_priv->lock, flags); +- cm_free_msg(msg); +- return ret; +- } ++ if (ret) ++ goto out_free; + + cm_id->state = IB_CM_REP_SENT; +- cm_id_priv->msg = msg; + cm_id_priv->initiator_depth = param->initiator_depth; + cm_id_priv->responder_resources = param->responder_resources; + cm_id_priv->rq_psn = cpu_to_be32(IBA_GET(CM_REP_STARTING_PSN, rep_msg)); +@@ -2309,8 +2281,13 @@ int ib_send_cm_rep(struct ib_cm_id *cm_id, + "IBTA declares QPN to be 24 bits, but it is 0x%X\n", + param->qp_num); + cm_id_priv->local_qpn = cpu_to_be32(param->qp_num & 0xFFFFFF); ++ spin_unlock_irqrestore(&cm_id_priv->lock, flags); ++ return 0; + +-out: spin_unlock_irqrestore(&cm_id_priv->lock, flags); ++out_free: ++ cm_free_priv_msg(msg); ++out: ++ spin_unlock_irqrestore(&cm_id_priv->lock, flags); + return ret; + } + EXPORT_SYMBOL(ib_send_cm_rep); +@@ -2357,9 +2334,11 @@ int ib_send_cm_rtu(struct ib_cm_id *cm_id, + goto error; + } + +- ret = cm_alloc_msg(cm_id_priv, &msg); +- if (ret) ++ msg = cm_alloc_msg(cm_id_priv); ++ if (IS_ERR(msg)) { ++ ret = PTR_ERR(msg); + goto error; ++ } + + cm_format_rtu((struct cm_rtu_msg *) msg->mad, cm_id_priv, + private_data, private_data_len); +@@ -2453,7 +2432,7 @@ static void cm_dup_rep_handler(struct cm_work *work) + goto deref; + + unlock: spin_unlock_irq(&cm_id_priv->lock); +-free: cm_free_msg(msg); ++free: cm_free_response_msg(msg); + deref: cm_deref_id(cm_id_priv); + } + +@@ -2657,10 +2636,10 @@ static int cm_send_dreq_locked(struct cm_id_private *cm_id_priv, + cm_id_priv->id.lap_state == IB_CM_MRA_LAP_RCVD) + ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); + +- ret = cm_alloc_msg(cm_id_priv, &msg); +- if (ret) { ++ msg = cm_alloc_priv_msg(cm_id_priv); ++ if (IS_ERR(msg)) { + cm_enter_timewait(cm_id_priv); +- return ret; ++ return PTR_ERR(msg); + } + + cm_format_dreq((struct cm_dreq_msg *) msg->mad, cm_id_priv, +@@ -2672,12 +2651,11 @@ static int cm_send_dreq_locked(struct cm_id_private *cm_id_priv, + ret = ib_post_send_mad(msg, NULL); + if (ret) { + cm_enter_timewait(cm_id_priv); +- cm_free_msg(msg); ++ cm_free_priv_msg(msg); + return ret; + } + + cm_id_priv->id.state = IB_CM_DREQ_SENT; +- cm_id_priv->msg = msg; + return 0; + } + +@@ -2732,9 +2710,9 @@ static int cm_send_drep_locked(struct cm_id_private *cm_id_priv, + cm_set_private_data(cm_id_priv, private_data, private_data_len); + cm_enter_timewait(cm_id_priv); + +- ret = cm_alloc_msg(cm_id_priv, &msg); +- if (ret) +- return ret; ++ msg = cm_alloc_msg(cm_id_priv); ++ if (IS_ERR(msg)) ++ return PTR_ERR(msg); + + cm_format_drep((struct cm_drep_msg *) msg->mad, cm_id_priv, + private_data, private_data_len); +@@ -2794,7 +2772,7 @@ static int cm_issue_drep(struct cm_port *port, + IBA_GET(CM_DREQ_REMOTE_COMM_ID, dreq_msg)); + ret = ib_post_send_mad(msg, NULL); + if (ret) +- cm_free_msg(msg); ++ cm_free_response_msg(msg); + + return ret; + } +@@ -2853,7 +2831,7 @@ static int cm_dreq_handler(struct cm_work *work) + + if (cm_create_response_msg_ah(work->port, work->mad_recv_wc, msg) || + ib_post_send_mad(msg, NULL)) +- cm_free_msg(msg); ++ cm_free_response_msg(msg); + goto deref; + case IB_CM_DREQ_RCVD: + atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES]. +@@ -2927,9 +2905,9 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv, + case IB_CM_REP_RCVD: + case IB_CM_MRA_REP_SENT: + cm_reset_to_idle(cm_id_priv); +- ret = cm_alloc_msg(cm_id_priv, &msg); +- if (ret) +- return ret; ++ msg = cm_alloc_msg(cm_id_priv); ++ if (IS_ERR(msg)) ++ return PTR_ERR(msg); + cm_format_rej((struct cm_rej_msg *)msg->mad, cm_id_priv, reason, + ari, ari_length, private_data, private_data_len, + state); +@@ -2937,9 +2915,9 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv, + case IB_CM_REP_SENT: + case IB_CM_MRA_REP_RCVD: + cm_enter_timewait(cm_id_priv); +- ret = cm_alloc_msg(cm_id_priv, &msg); +- if (ret) +- return ret; ++ msg = cm_alloc_msg(cm_id_priv); ++ if (IS_ERR(msg)) ++ return PTR_ERR(msg); + cm_format_rej((struct cm_rej_msg *)msg->mad, cm_id_priv, reason, + ari, ari_length, private_data, private_data_len, + state); +@@ -3117,13 +3095,15 @@ int ib_send_cm_mra(struct ib_cm_id *cm_id, + default: + trace_icm_send_mra_unknown_err(&cm_id_priv->id); + ret = -EINVAL; +- goto error1; ++ goto error_unlock; + } + + if (!(service_timeout & IB_CM_MRA_FLAG_DELAY)) { +- ret = cm_alloc_msg(cm_id_priv, &msg); +- if (ret) +- goto error1; ++ msg = cm_alloc_msg(cm_id_priv); ++ if (IS_ERR(msg)) { ++ ret = PTR_ERR(msg); ++ goto error_unlock; ++ } + + cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv, + msg_response, service_timeout, +@@ -3131,7 +3111,7 @@ int ib_send_cm_mra(struct ib_cm_id *cm_id, + trace_icm_send_mra(cm_id); + ret = ib_post_send_mad(msg, NULL); + if (ret) +- goto error2; ++ goto error_free_msg; + } + + cm_id->state = cm_state; +@@ -3141,13 +3121,11 @@ int ib_send_cm_mra(struct ib_cm_id *cm_id, + spin_unlock_irqrestore(&cm_id_priv->lock, flags); + return 0; + +-error1: spin_unlock_irqrestore(&cm_id_priv->lock, flags); +- kfree(data); +- return ret; +- +-error2: spin_unlock_irqrestore(&cm_id_priv->lock, flags); +- kfree(data); ++error_free_msg: + cm_free_msg(msg); ++error_unlock: ++ spin_unlock_irqrestore(&cm_id_priv->lock, flags); ++ kfree(data); + return ret; + } + EXPORT_SYMBOL(ib_send_cm_mra); +@@ -3291,6 +3269,8 @@ static int cm_lap_handler(struct cm_work *work) + struct cm_lap_msg *lap_msg; + struct ib_cm_lap_event_param *param; + struct ib_mad_send_buf *msg = NULL; ++ struct rdma_ah_attr ah_attr; ++ struct cm_av alt_av = {}; + int ret; + + /* Currently Alternate path messages are not supported for +@@ -3319,7 +3299,25 @@ static int cm_lap_handler(struct cm_work *work) + work->cm_event.private_data = + IBA_GET_MEM_PTR(CM_LAP_PRIVATE_DATA, lap_msg); + ++ ret = ib_init_ah_attr_from_wc(work->port->cm_dev->ib_device, ++ work->port->port_num, ++ work->mad_recv_wc->wc, ++ work->mad_recv_wc->recv_buf.grh, ++ &ah_attr); ++ if (ret) ++ goto deref; ++ ++ ret = cm_init_av_by_path(param->alternate_path, NULL, &alt_av); ++ if (ret) { ++ rdma_destroy_ah_attr(&ah_attr); ++ return -EINVAL; ++ } ++ + spin_lock_irq(&cm_id_priv->lock); ++ cm_init_av_for_lap(work->port, work->mad_recv_wc->wc, ++ &ah_attr, &cm_id_priv->av); ++ cm_move_av_from_path(&cm_id_priv->alt_av, &alt_av); ++ + if (cm_id_priv->id.state != IB_CM_ESTABLISHED) + goto unlock; + +@@ -3343,7 +3341,7 @@ static int cm_lap_handler(struct cm_work *work) + + if (cm_create_response_msg_ah(work->port, work->mad_recv_wc, msg) || + ib_post_send_mad(msg, NULL)) +- cm_free_msg(msg); ++ cm_free_response_msg(msg); + goto deref; + case IB_CM_LAP_RCVD: + atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES]. +@@ -3353,17 +3351,6 @@ static int cm_lap_handler(struct cm_work *work) + goto unlock; + } + +- ret = cm_init_av_for_lap(work->port, work->mad_recv_wc->wc, +- work->mad_recv_wc->recv_buf.grh, +- &cm_id_priv->av); +- if (ret) +- goto unlock; +- +- ret = cm_init_av_by_path(param->alternate_path, NULL, +- &cm_id_priv->alt_av, cm_id_priv); +- if (ret) +- goto unlock; +- + cm_id_priv->id.lap_state = IB_CM_LAP_RCVD; + cm_id_priv->tid = lap_msg->hdr.tid; + cm_queue_work_unlock(cm_id_priv, work); +@@ -3471,6 +3458,7 @@ int ib_send_cm_sidr_req(struct ib_cm_id *cm_id, + { + struct cm_id_private *cm_id_priv; + struct ib_mad_send_buf *msg; ++ struct cm_av av = {}; + unsigned long flags; + int ret; + +@@ -3479,42 +3467,43 @@ int ib_send_cm_sidr_req(struct ib_cm_id *cm_id, + return -EINVAL; + + cm_id_priv = container_of(cm_id, struct cm_id_private, id); +- ret = cm_init_av_by_path(param->path, param->sgid_attr, +- &cm_id_priv->av, +- cm_id_priv); ++ ret = cm_init_av_by_path(param->path, param->sgid_attr, &av); + if (ret) +- goto out; ++ return ret; + ++ spin_lock_irqsave(&cm_id_priv->lock, flags); ++ cm_move_av_from_path(&cm_id_priv->av, &av); + cm_id->service_id = param->service_id; + cm_id->service_mask = ~cpu_to_be64(0); + cm_id_priv->timeout_ms = param->timeout_ms; + cm_id_priv->max_cm_retries = param->max_cm_retries; +- ret = cm_alloc_msg(cm_id_priv, &msg); +- if (ret) +- goto out; +- +- cm_format_sidr_req((struct cm_sidr_req_msg *) msg->mad, cm_id_priv, +- param); +- msg->timeout_ms = cm_id_priv->timeout_ms; +- msg->context[1] = (void *) (unsigned long) IB_CM_SIDR_REQ_SENT; +- +- spin_lock_irqsave(&cm_id_priv->lock, flags); +- if (cm_id->state == IB_CM_IDLE) { +- trace_icm_send_sidr_req(&cm_id_priv->id); +- ret = ib_post_send_mad(msg, NULL); +- } else { ++ if (cm_id->state != IB_CM_IDLE) { + ret = -EINVAL; ++ goto out_unlock; + } + +- if (ret) { +- spin_unlock_irqrestore(&cm_id_priv->lock, flags); +- cm_free_msg(msg); +- goto out; ++ msg = cm_alloc_priv_msg(cm_id_priv); ++ if (IS_ERR(msg)) { ++ ret = PTR_ERR(msg); ++ goto out_unlock; + } ++ ++ cm_format_sidr_req((struct cm_sidr_req_msg *)msg->mad, cm_id_priv, ++ param); ++ msg->timeout_ms = cm_id_priv->timeout_ms; ++ msg->context[1] = (void *)(unsigned long)IB_CM_SIDR_REQ_SENT; ++ ++ trace_icm_send_sidr_req(&cm_id_priv->id); ++ ret = ib_post_send_mad(msg, NULL); ++ if (ret) ++ goto out_free; + cm_id->state = IB_CM_SIDR_REQ_SENT; +- cm_id_priv->msg = msg; + spin_unlock_irqrestore(&cm_id_priv->lock, flags); +-out: ++ return 0; ++out_free: ++ cm_free_priv_msg(msg); ++out_unlock: ++ spin_unlock_irqrestore(&cm_id_priv->lock, flags); + return ret; + } + EXPORT_SYMBOL(ib_send_cm_sidr_req); +@@ -3661,9 +3650,9 @@ static int cm_send_sidr_rep_locked(struct cm_id_private *cm_id_priv, + if (cm_id_priv->id.state != IB_CM_SIDR_REQ_RCVD) + return -EINVAL; + +- ret = cm_alloc_msg(cm_id_priv, &msg); +- if (ret) +- return ret; ++ msg = cm_alloc_msg(cm_id_priv); ++ if (IS_ERR(msg)) ++ return PTR_ERR(msg); + + cm_format_sidr_rep((struct cm_sidr_rep_msg *) msg->mad, cm_id_priv, + param); +@@ -3963,9 +3952,7 @@ out: + static int cm_migrate(struct ib_cm_id *cm_id) + { + struct cm_id_private *cm_id_priv; +- struct cm_av tmp_av; + unsigned long flags; +- int tmp_send_port_not_ready; + int ret = 0; + + cm_id_priv = container_of(cm_id, struct cm_id_private, id); +@@ -3974,14 +3961,7 @@ static int cm_migrate(struct ib_cm_id *cm_id) + (cm_id->lap_state == IB_CM_LAP_UNINIT || + cm_id->lap_state == IB_CM_LAP_IDLE)) { + cm_id->lap_state = IB_CM_LAP_IDLE; +- /* Swap address vector */ +- tmp_av = cm_id_priv->av; + cm_id_priv->av = cm_id_priv->alt_av; +- cm_id_priv->alt_av = tmp_av; +- /* Swap port send ready state */ +- tmp_send_port_not_ready = cm_id_priv->prim_send_port_not_ready; +- cm_id_priv->prim_send_port_not_ready = cm_id_priv->altr_send_port_not_ready; +- cm_id_priv->altr_send_port_not_ready = tmp_send_port_not_ready; + } else + ret = -EINVAL; + spin_unlock_irqrestore(&cm_id_priv->lock, flags); +@@ -4356,9 +4336,6 @@ static int cm_add_one(struct ib_device *ib_device) + port->cm_dev = cm_dev; + port->port_num = i; + +- INIT_LIST_HEAD(&port->cm_priv_prim_list); +- INIT_LIST_HEAD(&port->cm_priv_altr_list); +- + ret = cm_create_port_fs(port); + if (ret) + goto error1; +@@ -4422,8 +4399,6 @@ static void cm_remove_one(struct ib_device *ib_device, void *client_data) + { + struct cm_device *cm_dev = client_data; + struct cm_port *port; +- struct cm_id_private *cm_id_priv; +- struct ib_mad_agent *cur_mad_agent; + struct ib_port_modify port_modify = { + .clr_port_cap_mask = IB_PORT_CM_SUP + }; +@@ -4444,24 +4419,13 @@ static void cm_remove_one(struct ib_device *ib_device, void *client_data) + + port = cm_dev->port[i-1]; + ib_modify_port(ib_device, port->port_num, 0, &port_modify); +- /* Mark all the cm_id's as not valid */ +- spin_lock_irq(&cm.lock); +- list_for_each_entry(cm_id_priv, &port->cm_priv_altr_list, altr_list) +- cm_id_priv->altr_send_port_not_ready = 1; +- list_for_each_entry(cm_id_priv, &port->cm_priv_prim_list, prim_list) +- cm_id_priv->prim_send_port_not_ready = 1; +- spin_unlock_irq(&cm.lock); + /* + * We flush the queue here after the going_down set, this + * verify that no new works will be queued in the recv handler, + * after that we can call the unregister_mad_agent + */ + flush_workqueue(cm.wq); +- spin_lock_irq(&cm.state_lock); +- cur_mad_agent = port->mad_agent; +- port->mad_agent = NULL; +- spin_unlock_irq(&cm.state_lock); +- ib_unregister_mad_agent(cur_mad_agent); ++ ib_unregister_mad_agent(port->mad_agent); + cm_remove_port_fs(port); + kfree(port); + } +@@ -4476,7 +4440,6 @@ static int __init ib_cm_init(void) + INIT_LIST_HEAD(&cm.device_list); + rwlock_init(&cm.device_lock); + spin_lock_init(&cm.lock); +- spin_lock_init(&cm.state_lock); + cm.listen_service_table = RB_ROOT; + cm.listen_service_id = be64_to_cpu(IB_CM_ASSIGN_SERVICE_ID); + cm.remote_id_table = RB_ROOT; +diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c +index ab148a696c0ce..ad9a9ba5f00d1 100644 +--- a/drivers/infiniband/core/cma.c ++++ b/drivers/infiniband/core/cma.c +@@ -1852,6 +1852,7 @@ static void _destroy_id(struct rdma_id_private *id_priv, + { + cma_cancel_operation(id_priv, state); + ++ rdma_restrack_del(&id_priv->res); + if (id_priv->cma_dev) { + if (rdma_cap_ib_cm(id_priv->id.device, 1)) { + if (id_priv->cm_id.ib) +@@ -1861,7 +1862,6 @@ static void _destroy_id(struct rdma_id_private *id_priv, + iw_destroy_cm_id(id_priv->cm_id.iw); + } + cma_leave_mc_groups(id_priv); +- rdma_restrack_del(&id_priv->res); + cma_release_dev(id_priv); + } + +@@ -2472,8 +2472,10 @@ static int cma_iw_listen(struct rdma_id_private *id_priv, int backlog) + if (IS_ERR(id)) + return PTR_ERR(id); + ++ mutex_lock(&id_priv->qp_mutex); + id->tos = id_priv->tos; + id->tos_set = id_priv->tos_set; ++ mutex_unlock(&id_priv->qp_mutex); + id->afonly = id_priv->afonly; + id_priv->cm_id.iw = id; + +@@ -2534,8 +2536,10 @@ static int cma_listen_on_dev(struct rdma_id_private *id_priv, + cma_id_get(id_priv); + dev_id_priv->internal_id = 1; + dev_id_priv->afonly = id_priv->afonly; ++ mutex_lock(&id_priv->qp_mutex); + dev_id_priv->tos_set = id_priv->tos_set; + dev_id_priv->tos = id_priv->tos; ++ mutex_unlock(&id_priv->qp_mutex); + + ret = rdma_listen(&dev_id_priv->id, id_priv->backlog); + if (ret) +@@ -2582,8 +2586,10 @@ void rdma_set_service_type(struct rdma_cm_id *id, int tos) + struct rdma_id_private *id_priv; + + id_priv = container_of(id, struct rdma_id_private, id); ++ mutex_lock(&id_priv->qp_mutex); + id_priv->tos = (u8) tos; + id_priv->tos_set = true; ++ mutex_unlock(&id_priv->qp_mutex); + } + EXPORT_SYMBOL(rdma_set_service_type); + +@@ -2610,8 +2616,10 @@ int rdma_set_ack_timeout(struct rdma_cm_id *id, u8 timeout) + return -EINVAL; + + id_priv = container_of(id, struct rdma_id_private, id); ++ mutex_lock(&id_priv->qp_mutex); + id_priv->timeout = timeout; + id_priv->timeout_set = true; ++ mutex_unlock(&id_priv->qp_mutex); + + return 0; + } +@@ -2647,8 +2655,10 @@ int rdma_set_min_rnr_timer(struct rdma_cm_id *id, u8 min_rnr_timer) + return -EINVAL; + + id_priv = container_of(id, struct rdma_id_private, id); ++ mutex_lock(&id_priv->qp_mutex); + id_priv->min_rnr_timer = min_rnr_timer; + id_priv->min_rnr_timer_set = true; ++ mutex_unlock(&id_priv->qp_mutex); + + return 0; + } +@@ -3034,8 +3044,11 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv) + + u8 default_roce_tos = id_priv->cma_dev->default_roce_tos[id_priv->id.port_num - + rdma_start_port(id_priv->cma_dev->device)]; +- u8 tos = id_priv->tos_set ? id_priv->tos : default_roce_tos; ++ u8 tos; + ++ mutex_lock(&id_priv->qp_mutex); ++ tos = id_priv->tos_set ? id_priv->tos : default_roce_tos; ++ mutex_unlock(&id_priv->qp_mutex); + + work = kzalloc(sizeof *work, GFP_KERNEL); + if (!work) +@@ -3082,8 +3095,12 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv) + * PacketLifeTime = local ACK timeout/2 + * as a reasonable approximation for RoCE networks. + */ +- route->path_rec->packet_life_time = id_priv->timeout_set ? +- id_priv->timeout - 1 : CMA_IBOE_PACKET_LIFETIME; ++ mutex_lock(&id_priv->qp_mutex); ++ if (id_priv->timeout_set && id_priv->timeout) ++ route->path_rec->packet_life_time = id_priv->timeout - 1; ++ else ++ route->path_rec->packet_life_time = CMA_IBOE_PACKET_LIFETIME; ++ mutex_unlock(&id_priv->qp_mutex); + + if (!route->path_rec->mtu) { + ret = -EINVAL; +@@ -4107,8 +4124,11 @@ static int cma_connect_iw(struct rdma_id_private *id_priv, + if (IS_ERR(cm_id)) + return PTR_ERR(cm_id); + ++ mutex_lock(&id_priv->qp_mutex); + cm_id->tos = id_priv->tos; + cm_id->tos_set = id_priv->tos_set; ++ mutex_unlock(&id_priv->qp_mutex); ++ + id_priv->cm_id.iw = cm_id; + + memcpy(&cm_id->local_addr, cma_src_addr(id_priv), +diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c +index 64e4be1cbec7c..a1d1deca7c063 100644 +--- a/drivers/infiniband/core/uverbs_cmd.c ++++ b/drivers/infiniband/core/uverbs_cmd.c +@@ -3034,12 +3034,29 @@ static int ib_uverbs_ex_modify_wq(struct uverbs_attr_bundle *attrs) + if (!wq) + return -EINVAL; + +- wq_attr.curr_wq_state = cmd.curr_wq_state; +- wq_attr.wq_state = cmd.wq_state; + if (cmd.attr_mask & IB_WQ_FLAGS) { + wq_attr.flags = cmd.flags; + wq_attr.flags_mask = cmd.flags_mask; + } ++ ++ if (cmd.attr_mask & IB_WQ_CUR_STATE) { ++ if (cmd.curr_wq_state > IB_WQS_ERR) ++ return -EINVAL; ++ ++ wq_attr.curr_wq_state = cmd.curr_wq_state; ++ } else { ++ wq_attr.curr_wq_state = wq->state; ++ } ++ ++ if (cmd.attr_mask & IB_WQ_STATE) { ++ if (cmd.wq_state > IB_WQS_ERR) ++ return -EINVAL; ++ ++ wq_attr.wq_state = cmd.wq_state; ++ } else { ++ wq_attr.wq_state = wq_attr.curr_wq_state; ++ } ++ + ret = wq->device->ops.modify_wq(wq, &wq_attr, cmd.attr_mask, + &attrs->driver_udata); + rdma_lookup_put_uobject(&wq->uobject->uevent.uobject, +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +index 7652dafe32eca..dcbe5e28a4f7a 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +@@ -274,8 +274,6 @@ static int set_rc_inl(struct hns_roce_qp *qp, const struct ib_send_wr *wr, + + dseg += sizeof(struct hns_roce_v2_rc_send_wqe); + +- roce_set_bit(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_INLINE_S, 1); +- + if (msg_len <= HNS_ROCE_V2_MAX_RC_INL_INN_SZ) { + roce_set_bit(rc_sq_wqe->byte_20, + V2_RC_SEND_WQE_BYTE_20_INL_TYPE_S, 0); +@@ -320,6 +318,8 @@ static int set_rwqe_data_seg(struct ib_qp *ibqp, const struct ib_send_wr *wr, + V2_RC_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_S, + (*sge_ind) & (qp->sge.sge_cnt - 1)); + ++ roce_set_bit(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_INLINE_S, ++ !!(wr->send_flags & IB_SEND_INLINE)); + if (wr->send_flags & IB_SEND_INLINE) + return set_rc_inl(qp, wr, rc_sq_wqe, sge_ind); + +@@ -791,8 +791,7 @@ out: + qp->sq.head += nreq; + qp->next_sge = sge_idx; + +- if (nreq == 1 && qp->sq.head == qp->sq.tail + 1 && +- (qp->en_flags & HNS_ROCE_QP_CAP_DIRECT_WQE)) ++ if (nreq == 1 && (qp->en_flags & HNS_ROCE_QP_CAP_DIRECT_WQE)) + write_dwqe(hr_dev, qp, wqe); + else + update_sq_db(hr_dev, qp); +@@ -1620,6 +1619,22 @@ static void hns_roce_function_clear(struct hns_roce_dev *hr_dev) + } + } + ++static int hns_roce_clear_extdb_list_info(struct hns_roce_dev *hr_dev) ++{ ++ struct hns_roce_cmq_desc desc; ++ int ret; ++ ++ hns_roce_cmq_setup_basic_desc(&desc, HNS_ROCE_OPC_CLEAR_EXTDB_LIST_INFO, ++ false); ++ ret = hns_roce_cmq_send(hr_dev, &desc, 1); ++ if (ret) ++ ibdev_err(&hr_dev->ib_dev, ++ "failed to clear extended doorbell info, ret = %d.\n", ++ ret); ++ ++ return ret; ++} ++ + static int hns_roce_query_fw_ver(struct hns_roce_dev *hr_dev) + { + struct hns_roce_query_fw_info *resp; +@@ -2093,12 +2108,6 @@ static void set_hem_page_size(struct hns_roce_dev *hr_dev) + calc_pg_sz(caps->max_cqes, caps->cqe_sz, caps->cqe_hop_num, + 1, &caps->cqe_buf_pg_sz, &caps->cqe_ba_pg_sz, HEM_TYPE_CQE); + +- if (caps->cqc_timer_entry_sz) +- calc_pg_sz(caps->num_cqc_timer, caps->cqc_timer_entry_sz, +- caps->cqc_timer_hop_num, caps->cqc_timer_bt_num, +- &caps->cqc_timer_buf_pg_sz, +- &caps->cqc_timer_ba_pg_sz, HEM_TYPE_CQC_TIMER); +- + /* SRQ */ + if (caps->flags & HNS_ROCE_CAP_FLAG_SRQ) { + calc_pg_sz(caps->num_srqs, caps->srqc_entry_sz, +@@ -2739,6 +2748,11 @@ static int hns_roce_v2_init(struct hns_roce_dev *hr_dev) + struct hns_roce_v2_priv *priv = hr_dev->priv; + int ret; + ++ /* The hns ROCEE requires the extdb info to be cleared before using */ ++ ret = hns_roce_clear_extdb_list_info(hr_dev); ++ if (ret) ++ return ret; ++ + ret = get_hem_table(hr_dev); + if (ret) + return ret; +@@ -4485,12 +4499,13 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp, + struct ib_device *ibdev = &hr_dev->ib_dev; + dma_addr_t trrl_ba; + dma_addr_t irrl_ba; +- enum ib_mtu mtu; ++ enum ib_mtu ib_mtu; + u8 lp_pktn_ini; + u64 *mtts; + u8 *dmac; + u8 *smac; + u32 port; ++ int mtu; + int ret; + + ret = config_qp_rq_buf(hr_dev, hr_qp, context, qpc_mask); +@@ -4574,19 +4589,23 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp, + roce_set_field(qpc_mask->byte_52_udpspn_dmac, V2_QPC_BYTE_52_DMAC_M, + V2_QPC_BYTE_52_DMAC_S, 0); + +- mtu = get_mtu(ibqp, attr); +- hr_qp->path_mtu = mtu; ++ ib_mtu = get_mtu(ibqp, attr); ++ hr_qp->path_mtu = ib_mtu; ++ ++ mtu = ib_mtu_enum_to_int(ib_mtu); ++ if (WARN_ON(mtu < 0)) ++ return -EINVAL; + + if (attr_mask & IB_QP_PATH_MTU) { + roce_set_field(context->byte_24_mtu_tc, V2_QPC_BYTE_24_MTU_M, +- V2_QPC_BYTE_24_MTU_S, mtu); ++ V2_QPC_BYTE_24_MTU_S, ib_mtu); + roce_set_field(qpc_mask->byte_24_mtu_tc, V2_QPC_BYTE_24_MTU_M, + V2_QPC_BYTE_24_MTU_S, 0); + } + + #define MAX_LP_MSG_LEN 65536 + /* MTU * (2 ^ LP_PKTN_INI) shouldn't be bigger than 64KB */ +- lp_pktn_ini = ilog2(MAX_LP_MSG_LEN / ib_mtu_enum_to_int(mtu)); ++ lp_pktn_ini = ilog2(MAX_LP_MSG_LEN / mtu); + + roce_set_field(context->byte_56_dqpn_err, V2_QPC_BYTE_56_LP_PKTN_INI_M, + V2_QPC_BYTE_56_LP_PKTN_INI_S, lp_pktn_ini); +@@ -4758,6 +4777,11 @@ enum { + DIP_VALID, + }; + ++enum { ++ WND_LIMIT, ++ WND_UNLIMIT, ++}; ++ + static int check_cong_type(struct ib_qp *ibqp, + struct hns_roce_congestion_algorithm *cong_alg) + { +@@ -4769,21 +4793,25 @@ static int check_cong_type(struct ib_qp *ibqp, + cong_alg->alg_sel = CONG_DCQCN; + cong_alg->alg_sub_sel = UNSUPPORT_CONG_LEVEL; + cong_alg->dip_vld = DIP_INVALID; ++ cong_alg->wnd_mode_sel = WND_LIMIT; + break; + case CONG_TYPE_LDCP: + cong_alg->alg_sel = CONG_WINDOW; + cong_alg->alg_sub_sel = CONG_LDCP; + cong_alg->dip_vld = DIP_INVALID; ++ cong_alg->wnd_mode_sel = WND_UNLIMIT; + break; + case CONG_TYPE_HC3: + cong_alg->alg_sel = CONG_WINDOW; + cong_alg->alg_sub_sel = CONG_HC3; + cong_alg->dip_vld = DIP_INVALID; ++ cong_alg->wnd_mode_sel = WND_LIMIT; + break; + case CONG_TYPE_DIP: + cong_alg->alg_sel = CONG_DCQCN; + cong_alg->alg_sub_sel = UNSUPPORT_CONG_LEVEL; + cong_alg->dip_vld = DIP_VALID; ++ cong_alg->wnd_mode_sel = WND_LIMIT; + break; + default: + ibdev_err(&hr_dev->ib_dev, +@@ -4824,6 +4852,9 @@ static int fill_cong_field(struct ib_qp *ibqp, const struct ib_qp_attr *attr, + hr_reg_write(&qpc_mask->ext, QPCEX_CONG_ALG_SUB_SEL, 0); + hr_reg_write(&context->ext, QPCEX_DIP_CTX_IDX_VLD, cong_field.dip_vld); + hr_reg_write(&qpc_mask->ext, QPCEX_DIP_CTX_IDX_VLD, 0); ++ hr_reg_write(&context->ext, QPCEX_SQ_RQ_NOT_FORBID_EN, ++ cong_field.wnd_mode_sel); ++ hr_reg_clear(&qpc_mask->ext, QPCEX_SQ_RQ_NOT_FORBID_EN); + + /* if dip is disabled, there is no need to set dip idx */ + if (cong_field.dip_vld == 0) +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h +index a2100a629859a..23cf2f6bc7a54 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h +@@ -248,6 +248,7 @@ enum hns_roce_opcode_type { + HNS_ROCE_OPC_CLR_SCCC = 0x8509, + HNS_ROCE_OPC_QUERY_SCCC = 0x850a, + HNS_ROCE_OPC_RESET_SCCC = 0x850b, ++ HNS_ROCE_OPC_CLEAR_EXTDB_LIST_INFO = 0x850d, + HNS_ROCE_OPC_QUERY_VF_RES = 0x850e, + HNS_ROCE_OPC_CFG_GMV_TBL = 0x850f, + HNS_ROCE_OPC_CFG_GMV_BT = 0x8510, +@@ -963,6 +964,7 @@ struct hns_roce_v2_qp_context { + #define QPCEX_CONG_ALG_SUB_SEL QPCEX_FIELD_LOC(1, 1) + #define QPCEX_DIP_CTX_IDX_VLD QPCEX_FIELD_LOC(2, 2) + #define QPCEX_DIP_CTX_IDX QPCEX_FIELD_LOC(22, 3) ++#define QPCEX_SQ_RQ_NOT_FORBID_EN QPCEX_FIELD_LOC(23, 23) + #define QPCEX_STASH QPCEX_FIELD_LOC(82, 82) + + #define V2_QP_RWE_S 1 /* rdma write enable */ +@@ -1642,6 +1644,7 @@ struct hns_roce_congestion_algorithm { + u8 alg_sel; + u8 alg_sub_sel; + u8 dip_vld; ++ u8 wnd_mode_sel; + }; + + #define V2_QUERY_PF_CAPS_D_CEQ_DEPTH_S 0 +diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c +index 79b3c3023fe7a..b8454dcb03183 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_mr.c ++++ b/drivers/infiniband/hw/hns/hns_roce_mr.c +@@ -776,7 +776,7 @@ int hns_roce_mtr_map(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr, + struct ib_device *ibdev = &hr_dev->ib_dev; + struct hns_roce_buf_region *r; + unsigned int i, mapped_cnt; +- int ret; ++ int ret = 0; + + /* + * Only use the first page address as root ba when hopnum is 0, this +diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c +index 92ddbcc00eb2a..2ae22bf50016a 100644 +--- a/drivers/infiniband/hw/mlx4/qp.c ++++ b/drivers/infiniband/hw/mlx4/qp.c +@@ -4251,13 +4251,8 @@ int mlx4_ib_modify_wq(struct ib_wq *ibwq, struct ib_wq_attr *wq_attr, + if (wq_attr_mask & IB_WQ_FLAGS) + return -EOPNOTSUPP; + +- cur_state = wq_attr_mask & IB_WQ_CUR_STATE ? wq_attr->curr_wq_state : +- ibwq->state; +- new_state = wq_attr_mask & IB_WQ_STATE ? wq_attr->wq_state : cur_state; +- +- if (cur_state < IB_WQS_RESET || cur_state > IB_WQS_ERR || +- new_state < IB_WQS_RESET || new_state > IB_WQS_ERR) +- return -EINVAL; ++ cur_state = wq_attr->curr_wq_state; ++ new_state = wq_attr->wq_state; + + if ((new_state == IB_WQS_RDY) && (cur_state == IB_WQS_ERR)) + return -EINVAL; +diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c +index 644d5d0ac5442..cca7296b12d01 100644 +--- a/drivers/infiniband/hw/mlx5/main.c ++++ b/drivers/infiniband/hw/mlx5/main.c +@@ -3178,8 +3178,6 @@ static void mlx5_ib_unbind_slave_port(struct mlx5_ib_dev *ibdev, + + port->mp.mpi = NULL; + +- list_add_tail(&mpi->list, &mlx5_ib_unaffiliated_port_list); +- + spin_unlock(&port->mp.mpi_lock); + + err = mlx5_nic_vport_unaffiliate_multiport(mpi->mdev); +@@ -3327,7 +3325,10 @@ static void mlx5_ib_cleanup_multiport_master(struct mlx5_ib_dev *dev) + } else { + mlx5_ib_dbg(dev, "unbinding port_num: %u\n", + i + 1); +- mlx5_ib_unbind_slave_port(dev, dev->port[i].mp.mpi); ++ list_add_tail(&dev->port[i].mp.mpi->list, ++ &mlx5_ib_unaffiliated_port_list); ++ mlx5_ib_unbind_slave_port(dev, ++ dev->port[i].mp.mpi); + } + } + } +diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c +index 9282eb10bfaed..5851486c0d930 100644 +--- a/drivers/infiniband/hw/mlx5/qp.c ++++ b/drivers/infiniband/hw/mlx5/qp.c +@@ -5309,10 +5309,8 @@ int mlx5_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr, + + rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx); + +- curr_wq_state = (wq_attr_mask & IB_WQ_CUR_STATE) ? +- wq_attr->curr_wq_state : wq->state; +- wq_state = (wq_attr_mask & IB_WQ_STATE) ? +- wq_attr->wq_state : curr_wq_state; ++ curr_wq_state = wq_attr->curr_wq_state; ++ wq_state = wq_attr->wq_state; + if (curr_wq_state == IB_WQS_ERR) + curr_wq_state = MLX5_RQC_STATE_ERR; + if (wq_state == IB_WQS_ERR) +diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c +index 01662727dca08..fc1ba49042792 100644 +--- a/drivers/infiniband/sw/rxe/rxe_net.c ++++ b/drivers/infiniband/sw/rxe/rxe_net.c +@@ -207,10 +207,8 @@ static struct socket *rxe_setup_udp_tunnel(struct net *net, __be16 port, + + /* Create UDP socket */ + err = udp_sock_create(net, &udp_cfg, &sock); +- if (err < 0) { +- pr_err("failed to create udp socket. err = %d\n", err); ++ if (err < 0) + return ERR_PTR(err); +- } + + tnl_cfg.encap_type = 1; + tnl_cfg.encap_rcv = rxe_udp_encap_recv; +@@ -619,6 +617,12 @@ static int rxe_net_ipv6_init(void) + + recv_sockets.sk6 = rxe_setup_udp_tunnel(&init_net, + htons(ROCE_V2_UDP_DPORT), true); ++ if (PTR_ERR(recv_sockets.sk6) == -EAFNOSUPPORT) { ++ recv_sockets.sk6 = NULL; ++ pr_warn("IPv6 is not supported, can not create a UDPv6 socket\n"); ++ return 0; ++ } ++ + if (IS_ERR(recv_sockets.sk6)) { + recv_sockets.sk6 = NULL; + pr_err("Failed to create IPv6 UDP tunnel\n"); +diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c +index b0f350d674fdb..93a41ebda1a85 100644 +--- a/drivers/infiniband/sw/rxe/rxe_qp.c ++++ b/drivers/infiniband/sw/rxe/rxe_qp.c +@@ -136,7 +136,6 @@ static void free_rd_atomic_resources(struct rxe_qp *qp) + void free_rd_atomic_resource(struct rxe_qp *qp, struct resp_res *res) + { + if (res->type == RXE_ATOMIC_MASK) { +- rxe_drop_ref(qp); + kfree_skb(res->atomic.skb); + } else if (res->type == RXE_READ_MASK) { + if (res->read.mr) +diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c +index 2b220659bddbf..39dc39be586ec 100644 +--- a/drivers/infiniband/sw/rxe/rxe_resp.c ++++ b/drivers/infiniband/sw/rxe/rxe_resp.c +@@ -966,8 +966,6 @@ static int send_atomic_ack(struct rxe_qp *qp, struct rxe_pkt_info *pkt, + goto out; + } + +- rxe_add_ref(qp); +- + res = &qp->resp.resources[qp->resp.res_head]; + free_rd_atomic_resource(qp, res); + rxe_advance_resp_resource(qp); +diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c +index 8fcaa1136f2cd..776e46ee95dad 100644 +--- a/drivers/infiniband/ulp/iser/iscsi_iser.c ++++ b/drivers/infiniband/ulp/iser/iscsi_iser.c +@@ -506,6 +506,7 @@ iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session, + iser_conn->iscsi_conn = conn; + + out: ++ iscsi_put_endpoint(ep); + mutex_unlock(&iser_conn->state_mutex); + return error; + } +@@ -1002,6 +1003,7 @@ static struct iscsi_transport iscsi_iser_transport = { + /* connection management */ + .create_conn = iscsi_iser_conn_create, + .bind_conn = iscsi_iser_conn_bind, ++ .unbind_conn = iscsi_conn_unbind, + .destroy_conn = iscsi_conn_teardown, + .attr_is_visible = iser_attr_is_visible, + .set_param = iscsi_iser_set_param, +diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c +index 0a794d748a7a6..ed7cf25a65c27 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c +@@ -814,6 +814,9 @@ static struct rtrs_clt_sess *get_next_path_min_inflight(struct path_it *it) + int inflight; + + list_for_each_entry_rcu(sess, &clt->paths_list, s.entry) { ++ if (unlikely(READ_ONCE(sess->state) != RTRS_CLT_CONNECTED)) ++ continue; ++ + if (unlikely(!list_empty(raw_cpu_ptr(sess->mp_skip_entry)))) + continue; + +@@ -1788,7 +1791,19 @@ static int rtrs_rdma_conn_established(struct rtrs_clt_con *con, + queue_depth); + return -ECONNRESET; + } +- if (!sess->rbufs || sess->queue_depth < queue_depth) { ++ if (sess->queue_depth > 0 && queue_depth != sess->queue_depth) { ++ rtrs_err(clt, "Error: queue depth changed\n"); ++ ++ /* ++ * Stop any more reconnection attempts ++ */ ++ sess->reconnect_attempts = -1; ++ rtrs_err(clt, ++ "Disabling auto-reconnect. Trigger a manual reconnect after issue is resolved\n"); ++ return -ECONNRESET; ++ } ++ ++ if (!sess->rbufs) { + kfree(sess->rbufs); + sess->rbufs = kcalloc(queue_depth, sizeof(*sess->rbufs), + GFP_KERNEL); +@@ -1802,7 +1817,7 @@ static int rtrs_rdma_conn_established(struct rtrs_clt_con *con, + sess->chunk_size = sess->max_io_size + sess->max_hdr_size; + + /* +- * Global queue depth and IO size is always a minimum. ++ * Global IO size is always a minimum. + * If while a reconnection server sends us a value a bit + * higher - client does not care and uses cached minimum. + * +@@ -1810,8 +1825,7 @@ static int rtrs_rdma_conn_established(struct rtrs_clt_con *con, + * connections in parallel, use lock. + */ + mutex_lock(&clt->paths_mutex); +- clt->queue_depth = min_not_zero(sess->queue_depth, +- clt->queue_depth); ++ clt->queue_depth = sess->queue_depth; + clt->max_io_size = min_not_zero(sess->max_io_size, + clt->max_io_size); + mutex_unlock(&clt->paths_mutex); +@@ -2762,6 +2776,8 @@ struct rtrs_clt *rtrs_clt_open(struct rtrs_clt_ops *ops, + if (err) { + list_del_rcu(&sess->s.entry); + rtrs_clt_close_conns(sess, true); ++ free_percpu(sess->stats->pcpu_stats); ++ kfree(sess->stats); + free_sess(sess); + goto close_all_sess; + } +@@ -2770,6 +2786,8 @@ struct rtrs_clt *rtrs_clt_open(struct rtrs_clt_ops *ops, + if (err) { + list_del_rcu(&sess->s.entry); + rtrs_clt_close_conns(sess, true); ++ free_percpu(sess->stats->pcpu_stats); ++ kfree(sess->stats); + free_sess(sess); + goto close_all_sess; + } +@@ -3052,6 +3070,8 @@ int rtrs_clt_create_path_from_sysfs(struct rtrs_clt *clt, + close_sess: + rtrs_clt_remove_path_from_arr(sess); + rtrs_clt_close_conns(sess, true); ++ free_percpu(sess->stats->pcpu_stats); ++ kfree(sess->stats); + free_sess(sess); + + return err; +diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c b/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c +index a9288175fbb54..20efd44297fbb 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c +@@ -208,6 +208,7 @@ rtrs_srv_destroy_once_sysfs_root_folders(struct rtrs_srv_sess *sess) + device_del(&srv->dev); + put_device(&srv->dev); + } else { ++ put_device(&srv->dev); + mutex_unlock(&srv->paths_mutex); + } + } +diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +index 0fa116cabc445..8a9099684b8e3 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +@@ -1481,6 +1481,7 @@ static void free_sess(struct rtrs_srv_sess *sess) + kobject_del(&sess->kobj); + kobject_put(&sess->kobj); + } else { ++ kfree(sess->stats); + kfree(sess); + } + } +@@ -1604,7 +1605,7 @@ static int create_con(struct rtrs_srv_sess *sess, + struct rtrs_sess *s = &sess->s; + struct rtrs_srv_con *con; + +- u32 cq_size, wr_queue_size; ++ u32 cq_size, max_send_wr, max_recv_wr, wr_limit; + int err, cq_vector; + + con = kzalloc(sizeof(*con), GFP_KERNEL); +@@ -1625,30 +1626,42 @@ static int create_con(struct rtrs_srv_sess *sess, + * All receive and all send (each requiring invalidate) + * + 2 for drain and heartbeat + */ +- wr_queue_size = SERVICE_CON_QUEUE_DEPTH * 3 + 2; +- cq_size = wr_queue_size; ++ max_send_wr = SERVICE_CON_QUEUE_DEPTH * 2 + 2; ++ max_recv_wr = SERVICE_CON_QUEUE_DEPTH + 2; ++ cq_size = max_send_wr + max_recv_wr; + } else { +- /* +- * If we have all receive requests posted and +- * all write requests posted and each read request +- * requires an invalidate request + drain +- * and qp gets into error state. +- */ +- cq_size = srv->queue_depth * 3 + 1; + /* + * In theory we might have queue_depth * 32 + * outstanding requests if an unsafe global key is used + * and we have queue_depth read requests each consisting + * of 32 different addresses. div 3 for mlx5. + */ +- wr_queue_size = sess->s.dev->ib_dev->attrs.max_qp_wr / 3; ++ wr_limit = sess->s.dev->ib_dev->attrs.max_qp_wr / 3; ++ /* when always_invlaidate enalbed, we need linv+rinv+mr+imm */ ++ if (always_invalidate) ++ max_send_wr = ++ min_t(int, wr_limit, ++ srv->queue_depth * (1 + 4) + 1); ++ else ++ max_send_wr = ++ min_t(int, wr_limit, ++ srv->queue_depth * (1 + 2) + 1); ++ ++ max_recv_wr = srv->queue_depth + 1; ++ /* ++ * If we have all receive requests posted and ++ * all write requests posted and each read request ++ * requires an invalidate request + drain ++ * and qp gets into error state. ++ */ ++ cq_size = max_send_wr + max_recv_wr; + } +- atomic_set(&con->sq_wr_avail, wr_queue_size); ++ atomic_set(&con->sq_wr_avail, max_send_wr); + cq_vector = rtrs_srv_get_next_cq_vector(sess); + + /* TODO: SOFTIRQ can be faster, but be careful with softirq context */ + err = rtrs_cq_qp_create(&sess->s, &con->c, 1, cq_vector, cq_size, +- wr_queue_size, wr_queue_size, ++ max_send_wr, max_recv_wr, + IB_POLL_WORKQUEUE); + if (err) { + rtrs_err(s, "rtrs_cq_qp_create(), err: %d\n", err); +diff --git a/drivers/infiniband/ulp/rtrs/rtrs.c b/drivers/infiniband/ulp/rtrs/rtrs.c +index a7847282a2ebf..4e602e40f623b 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs.c +@@ -376,7 +376,6 @@ void rtrs_stop_hb(struct rtrs_sess *sess) + { + cancel_delayed_work_sync(&sess->hb_dwork); + sess->hb_missed_cnt = 0; +- sess->hb_missed_max = 0; + } + EXPORT_SYMBOL_GPL(rtrs_stop_hb); + +diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c +index 31f8aa2c40ed8..168705c88e2fa 100644 +--- a/drivers/infiniband/ulp/srp/ib_srp.c ++++ b/drivers/infiniband/ulp/srp/ib_srp.c +@@ -998,7 +998,6 @@ static int srp_alloc_req_data(struct srp_rdma_ch *ch) + struct srp_device *srp_dev = target->srp_host->srp_dev; + struct ib_device *ibdev = srp_dev->dev; + struct srp_request *req; +- void *mr_list; + dma_addr_t dma_addr; + int i, ret = -ENOMEM; + +@@ -1009,12 +1008,12 @@ static int srp_alloc_req_data(struct srp_rdma_ch *ch) + + for (i = 0; i < target->req_ring_size; ++i) { + req = &ch->req_ring[i]; +- mr_list = kmalloc_array(target->mr_per_cmd, sizeof(void *), +- GFP_KERNEL); +- if (!mr_list) +- goto out; +- if (srp_dev->use_fast_reg) +- req->fr_list = mr_list; ++ if (srp_dev->use_fast_reg) { ++ req->fr_list = kmalloc_array(target->mr_per_cmd, ++ sizeof(void *), GFP_KERNEL); ++ if (!req->fr_list) ++ goto out; ++ } + req->indirect_desc = kmalloc(target->indirect_size, GFP_KERNEL); + if (!req->indirect_desc) + goto out; +diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c +index da8963a9f044c..947d440a3be63 100644 +--- a/drivers/input/joydev.c ++++ b/drivers/input/joydev.c +@@ -499,7 +499,7 @@ static int joydev_handle_JSIOCSBTNMAP(struct joydev *joydev, + memcpy(joydev->keypam, keypam, len); + + for (i = 0; i < joydev->nkey; i++) +- joydev->keymap[keypam[i] - BTN_MISC] = i; ++ joydev->keymap[joydev->keypam[i] - BTN_MISC] = i; + + out: + kfree(keypam); +diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig +index 32d15809ae586..40a070a2e7f5b 100644 +--- a/drivers/input/keyboard/Kconfig ++++ b/drivers/input/keyboard/Kconfig +@@ -67,9 +67,6 @@ config KEYBOARD_AMIGA + To compile this driver as a module, choose M here: the + module will be called amikbd. + +-config ATARI_KBD_CORE +- bool +- + config KEYBOARD_APPLESPI + tristate "Apple SPI keyboard and trackpad" + depends on ACPI && EFI +diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c +index bb29a7c9a1c0c..54afb38601b9f 100644 +--- a/drivers/input/keyboard/hil_kbd.c ++++ b/drivers/input/keyboard/hil_kbd.c +@@ -512,6 +512,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv) + HIL_IDD_NUM_AXES_PER_SET(*idd)) { + printk(KERN_INFO PREFIX + "combo devices are not supported.\n"); ++ error = -EINVAL; + goto bail1; + } + +diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c +index 17540bdb1eaf7..0f9e3ec99aae1 100644 +--- a/drivers/input/touchscreen/elants_i2c.c ++++ b/drivers/input/touchscreen/elants_i2c.c +@@ -1396,7 +1396,7 @@ static int elants_i2c_probe(struct i2c_client *client, + init_completion(&ts->cmd_done); + + ts->client = client; +- ts->chip_id = (enum elants_chip_id)id->driver_data; ++ ts->chip_id = (enum elants_chip_id)(uintptr_t)device_get_match_data(&client->dev); + i2c_set_clientdata(client, ts); + + ts->vcc33 = devm_regulator_get(&client->dev, "vcc33"); +@@ -1636,8 +1636,8 @@ MODULE_DEVICE_TABLE(acpi, elants_acpi_id); + + #ifdef CONFIG_OF + static const struct of_device_id elants_of_match[] = { +- { .compatible = "elan,ekth3500" }, +- { .compatible = "elan,ektf3624" }, ++ { .compatible = "elan,ekth3500", .data = (void *)EKTH3500 }, ++ { .compatible = "elan,ektf3624", .data = (void *)EKTF3624 }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, elants_of_match); +diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c +index c682b028f0a29..4f53d3c57e698 100644 +--- a/drivers/input/touchscreen/goodix.c ++++ b/drivers/input/touchscreen/goodix.c +@@ -178,51 +178,6 @@ static const unsigned long goodix_irq_flags[] = { + IRQ_TYPE_LEVEL_HIGH, + }; + +-/* +- * Those tablets have their coordinates origin at the bottom right +- * of the tablet, as if rotated 180 degrees +- */ +-static const struct dmi_system_id rotated_screen[] = { +-#if defined(CONFIG_DMI) && defined(CONFIG_X86) +- { +- .ident = "Teclast X89", +- .matches = { +- /* tPAD is too generic, also match on bios date */ +- DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"), +- DMI_MATCH(DMI_BOARD_NAME, "tPAD"), +- DMI_MATCH(DMI_BIOS_DATE, "12/19/2014"), +- }, +- }, +- { +- .ident = "Teclast X98 Pro", +- .matches = { +- /* +- * Only match BIOS date, because the manufacturers +- * BIOS does not report the board name at all +- * (sometimes)... +- */ +- DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"), +- DMI_MATCH(DMI_BIOS_DATE, "10/28/2015"), +- }, +- }, +- { +- .ident = "WinBook TW100", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "WinBook"), +- DMI_MATCH(DMI_PRODUCT_NAME, "TW100") +- } +- }, +- { +- .ident = "WinBook TW700", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "WinBook"), +- DMI_MATCH(DMI_PRODUCT_NAME, "TW700") +- }, +- }, +-#endif +- {} +-}; +- + static const struct dmi_system_id nine_bytes_report[] = { + #if defined(CONFIG_DMI) && defined(CONFIG_X86) + { +@@ -1123,13 +1078,6 @@ static int goodix_configure_dev(struct goodix_ts_data *ts) + ABS_MT_POSITION_Y, ts->prop.max_y); + } + +- if (dmi_check_system(rotated_screen)) { +- ts->prop.invert_x = true; +- ts->prop.invert_y = true; +- dev_dbg(&ts->client->dev, +- "Applying '180 degrees rotated screen' quirk\n"); +- } +- + if (dmi_check_system(nine_bytes_report)) { + ts->contact_size = 9; + +diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c +index c847453a03c26..43c521f50c851 100644 +--- a/drivers/input/touchscreen/usbtouchscreen.c ++++ b/drivers/input/touchscreen/usbtouchscreen.c +@@ -251,7 +251,7 @@ static int e2i_init(struct usbtouch_usb *usbtouch) + int ret; + struct usb_device *udev = interface_to_usbdev(usbtouch->interface); + +- ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), ++ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + 0x01, 0x02, 0x0000, 0x0081, + NULL, 0, USB_CTRL_SET_TIMEOUT); + +@@ -531,7 +531,7 @@ static int mtouch_init(struct usbtouch_usb *usbtouch) + if (ret) + return ret; + +- ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), ++ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + MTOUCHUSB_RESET, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); +@@ -543,7 +543,7 @@ static int mtouch_init(struct usbtouch_usb *usbtouch) + msleep(150); + + for (i = 0; i < 3; i++) { +- ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), ++ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + MTOUCHUSB_ASYNC_REPORT, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT); +@@ -722,7 +722,7 @@ static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) + } + + /* start sending data */ +- ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0), ++ ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + TSC10_CMD_DATA1, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); +diff --git a/drivers/iommu/amd/amd_iommu.h b/drivers/iommu/amd/amd_iommu.h +index 55dd38d814d92..416815a525d67 100644 +--- a/drivers/iommu/amd/amd_iommu.h ++++ b/drivers/iommu/amd/amd_iommu.h +@@ -11,8 +11,6 @@ + + #include "amd_iommu_types.h" + +-extern int amd_iommu_init_dma_ops(void); +-extern int amd_iommu_init_passthrough(void); + extern irqreturn_t amd_iommu_int_thread(int irq, void *data); + extern irqreturn_t amd_iommu_int_handler(int irq, void *data); + extern void amd_iommu_apply_erratum_63(u16 devid); +diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c +index d006724f4dc21..5ff7e5364ef44 100644 +--- a/drivers/iommu/amd/init.c ++++ b/drivers/iommu/amd/init.c +@@ -231,7 +231,6 @@ enum iommu_init_state { + IOMMU_ENABLED, + IOMMU_PCI_INIT, + IOMMU_INTERRUPTS_EN, +- IOMMU_DMA_OPS, + IOMMU_INITIALIZED, + IOMMU_NOT_FOUND, + IOMMU_INIT_ERROR, +@@ -1908,8 +1907,8 @@ static void print_iommu_info(void) + pci_info(pdev, "Found IOMMU cap 0x%x\n", iommu->cap_ptr); + + if (iommu->cap & (1 << IOMMU_CAP_EFR)) { +- pci_info(pdev, "Extended features (%#llx):", +- iommu->features); ++ pr_info("Extended features (%#llx):", iommu->features); ++ + for (i = 0; i < ARRAY_SIZE(feat_str); ++i) { + if (iommu_feature(iommu, (1ULL << i))) + pr_cont(" %s", feat_str[i]); +@@ -2895,10 +2894,6 @@ static int __init state_next(void) + init_state = ret ? IOMMU_INIT_ERROR : IOMMU_INTERRUPTS_EN; + break; + case IOMMU_INTERRUPTS_EN: +- ret = amd_iommu_init_dma_ops(); +- init_state = ret ? IOMMU_INIT_ERROR : IOMMU_DMA_OPS; +- break; +- case IOMMU_DMA_OPS: + init_state = IOMMU_INITIALIZED; + break; + case IOMMU_INITIALIZED: +diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c +index 3ac42bbdefc63..c46dde88a132b 100644 +--- a/drivers/iommu/amd/iommu.c ++++ b/drivers/iommu/amd/iommu.c +@@ -30,7 +30,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -1773,13 +1772,22 @@ void amd_iommu_domain_update(struct protection_domain *domain) + amd_iommu_domain_flush_complete(domain); + } + ++static void __init amd_iommu_init_dma_ops(void) ++{ ++ swiotlb = (iommu_default_passthrough() || sme_me_mask) ? 1 : 0; ++ ++ if (amd_iommu_unmap_flush) ++ pr_info("IO/TLB flush on unmap enabled\n"); ++ else ++ pr_info("Lazy IO/TLB flushing enabled\n"); ++ iommu_set_dma_strict(amd_iommu_unmap_flush); ++} ++ + int __init amd_iommu_init_api(void) + { +- int ret, err = 0; ++ int err = 0; + +- ret = iova_cache_get(); +- if (ret) +- return ret; ++ amd_iommu_init_dma_ops(); + + err = bus_set_iommu(&pci_bus_type, &amd_iommu_ops); + if (err) +@@ -1796,19 +1804,6 @@ int __init amd_iommu_init_api(void) + return 0; + } + +-int __init amd_iommu_init_dma_ops(void) +-{ +- swiotlb = (iommu_default_passthrough() || sme_me_mask) ? 1 : 0; +- +- if (amd_iommu_unmap_flush) +- pr_info("IO/TLB flush on unmap enabled\n"); +- else +- pr_info("Lazy IO/TLB flushing enabled\n"); +- iommu_set_dma_strict(amd_iommu_unmap_flush); +- return 0; +- +-} +- + /***************************************************************************** + * + * The following functions belong to the exported interface of AMD IOMMU +diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c +index 7bcdd12055358..5d96fcc45feca 100644 +--- a/drivers/iommu/dma-iommu.c ++++ b/drivers/iommu/dma-iommu.c +@@ -243,9 +243,11 @@ resv_iova: + lo = iova_pfn(iovad, start); + hi = iova_pfn(iovad, end); + reserve_iova(iovad, lo, hi); +- } else { ++ } else if (end < start) { + /* dma_ranges list should be sorted */ +- dev_err(&dev->dev, "Failed to reserve IOVA\n"); ++ dev_err(&dev->dev, ++ "Failed to reserve IOVA [%pa-%pa]\n", ++ &start, &end); + return -EINVAL; + } + +diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig +index 49d99cb084dbd..c81b1e60953c1 100644 +--- a/drivers/leds/Kconfig ++++ b/drivers/leds/Kconfig +@@ -199,6 +199,7 @@ config LEDS_LM3530 + + config LEDS_LM3532 + tristate "LCD Backlight driver for LM3532" ++ select REGMAP_I2C + depends on LEDS_CLASS + depends on I2C + help +diff --git a/drivers/leds/blink/leds-lgm-sso.c b/drivers/leds/blink/leds-lgm-sso.c +index 6a63846d10b5e..7d5f0bf2817ad 100644 +--- a/drivers/leds/blink/leds-lgm-sso.c ++++ b/drivers/leds/blink/leds-lgm-sso.c +@@ -132,8 +132,7 @@ struct sso_led_priv { + struct regmap *mmap; + struct device *dev; + struct platform_device *pdev; +- struct clk *gclk; +- struct clk *fpid_clk; ++ struct clk_bulk_data clocks[2]; + u32 fpid_clkrate; + u32 gptc_clkrate; + u32 freq[MAX_FREQ_RANK]; +@@ -763,12 +762,11 @@ static int sso_probe_gpios(struct sso_led_priv *priv) + return sso_gpio_gc_init(dev, priv); + } + +-static void sso_clk_disable(void *data) ++static void sso_clock_disable_unprepare(void *data) + { + struct sso_led_priv *priv = data; + +- clk_disable_unprepare(priv->fpid_clk); +- clk_disable_unprepare(priv->gclk); ++ clk_bulk_disable_unprepare(ARRAY_SIZE(priv->clocks), priv->clocks); + } + + static int intel_sso_led_probe(struct platform_device *pdev) +@@ -785,36 +783,30 @@ static int intel_sso_led_probe(struct platform_device *pdev) + priv->dev = dev; + + /* gate clock */ +- priv->gclk = devm_clk_get(dev, "sso"); +- if (IS_ERR(priv->gclk)) { +- dev_err(dev, "get sso gate clock failed!\n"); +- return PTR_ERR(priv->gclk); +- } ++ priv->clocks[0].id = "sso"; ++ ++ /* fpid clock */ ++ priv->clocks[1].id = "fpid"; + +- ret = clk_prepare_enable(priv->gclk); ++ ret = devm_clk_bulk_get(dev, ARRAY_SIZE(priv->clocks), priv->clocks); + if (ret) { +- dev_err(dev, "Failed to prepare/enable sso gate clock!\n"); ++ dev_err(dev, "Getting clocks failed!\n"); + return ret; + } + +- priv->fpid_clk = devm_clk_get(dev, "fpid"); +- if (IS_ERR(priv->fpid_clk)) { +- dev_err(dev, "Failed to get fpid clock!\n"); +- return PTR_ERR(priv->fpid_clk); +- } +- +- ret = clk_prepare_enable(priv->fpid_clk); ++ ret = clk_bulk_prepare_enable(ARRAY_SIZE(priv->clocks), priv->clocks); + if (ret) { +- dev_err(dev, "Failed to prepare/enable fpid clock!\n"); ++ dev_err(dev, "Failed to prepare and enable clocks!\n"); + return ret; + } +- priv->fpid_clkrate = clk_get_rate(priv->fpid_clk); + +- ret = devm_add_action_or_reset(dev, sso_clk_disable, priv); +- if (ret) { +- dev_err(dev, "Failed to devm_add_action_or_reset, %d\n", ret); ++ ret = devm_add_action_or_reset(dev, sso_clock_disable_unprepare, priv); ++ if (ret) + return ret; +- } ++ ++ priv->fpid_clkrate = clk_get_rate(priv->clocks[1].clk); ++ ++ priv->mmap = syscon_node_to_regmap(dev->of_node); + + priv->mmap = syscon_node_to_regmap(dev->of_node); + if (IS_ERR(priv->mmap)) { +@@ -859,8 +851,6 @@ static int intel_sso_led_remove(struct platform_device *pdev) + sso_led_shutdown(led); + } + +- clk_disable_unprepare(priv->fpid_clk); +- clk_disable_unprepare(priv->gclk); + regmap_exit(priv->mmap); + + return 0; +diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c +index 2e495ff678562..fa3f5f504ff7d 100644 +--- a/drivers/leds/led-class.c ++++ b/drivers/leds/led-class.c +@@ -285,10 +285,6 @@ struct led_classdev *__must_check devm_of_led_get(struct device *dev, + if (!dev) + return ERR_PTR(-EINVAL); + +- /* Not using device tree? */ +- if (!IS_ENABLED(CONFIG_OF) || !dev->of_node) +- return ERR_PTR(-ENOTSUPP); +- + led = of_led_get(dev->of_node, index); + if (IS_ERR(led)) + return led; +diff --git a/drivers/leds/leds-as3645a.c b/drivers/leds/leds-as3645a.c +index e8922fa033796..80411d41e802d 100644 +--- a/drivers/leds/leds-as3645a.c ++++ b/drivers/leds/leds-as3645a.c +@@ -545,6 +545,7 @@ static int as3645a_parse_node(struct as3645a *flash, + if (!flash->indicator_node) { + dev_warn(&flash->client->dev, + "can't find indicator node\n"); ++ rval = -ENODEV; + goto out_err; + } + +diff --git a/drivers/leds/leds-ktd2692.c b/drivers/leds/leds-ktd2692.c +index 632f10db4b3ff..f341da1503a49 100644 +--- a/drivers/leds/leds-ktd2692.c ++++ b/drivers/leds/leds-ktd2692.c +@@ -256,6 +256,17 @@ static void ktd2692_setup(struct ktd2692_context *led) + | KTD2692_REG_FLASH_CURRENT_BASE); + } + ++static void regulator_disable_action(void *_data) ++{ ++ struct device *dev = _data; ++ struct ktd2692_context *led = dev_get_drvdata(dev); ++ int ret; ++ ++ ret = regulator_disable(led->regulator); ++ if (ret) ++ dev_err(dev, "Failed to disable supply: %d\n", ret); ++} ++ + static int ktd2692_parse_dt(struct ktd2692_context *led, struct device *dev, + struct ktd2692_led_config_data *cfg) + { +@@ -286,8 +297,14 @@ static int ktd2692_parse_dt(struct ktd2692_context *led, struct device *dev, + + if (led->regulator) { + ret = regulator_enable(led->regulator); +- if (ret) ++ if (ret) { + dev_err(dev, "Failed to enable supply: %d\n", ret); ++ } else { ++ ret = devm_add_action_or_reset(dev, ++ regulator_disable_action, dev); ++ if (ret) ++ return ret; ++ } + } + + child_node = of_get_next_available_child(np, NULL); +@@ -377,17 +394,9 @@ static int ktd2692_probe(struct platform_device *pdev) + static int ktd2692_remove(struct platform_device *pdev) + { + struct ktd2692_context *led = platform_get_drvdata(pdev); +- int ret; + + led_classdev_flash_unregister(&led->fled_cdev); + +- if (led->regulator) { +- ret = regulator_disable(led->regulator); +- if (ret) +- dev_err(&pdev->dev, +- "Failed to disable supply: %d\n", ret); +- } +- + mutex_destroy(&led->lock); + + return 0; +diff --git a/drivers/leds/leds-lm36274.c b/drivers/leds/leds-lm36274.c +index aadb03468a40a..a23a9424c2f38 100644 +--- a/drivers/leds/leds-lm36274.c ++++ b/drivers/leds/leds-lm36274.c +@@ -127,6 +127,7 @@ static int lm36274_probe(struct platform_device *pdev) + + ret = lm36274_init(chip); + if (ret) { ++ fwnode_handle_put(init_data.fwnode); + dev_err(chip->dev, "Failed to init the device\n"); + return ret; + } +diff --git a/drivers/leds/leds-lm3692x.c b/drivers/leds/leds-lm3692x.c +index e945de45388ca..55e6443997ec9 100644 +--- a/drivers/leds/leds-lm3692x.c ++++ b/drivers/leds/leds-lm3692x.c +@@ -435,6 +435,7 @@ static int lm3692x_probe_dt(struct lm3692x_led *led) + + ret = fwnode_property_read_u32(child, "reg", &led->led_enable); + if (ret) { ++ fwnode_handle_put(child); + dev_err(&led->client->dev, "reg DT property missing\n"); + return ret; + } +@@ -449,12 +450,11 @@ static int lm3692x_probe_dt(struct lm3692x_led *led) + + ret = devm_led_classdev_register_ext(&led->client->dev, &led->led_dev, + &init_data); +- if (ret) { ++ if (ret) + dev_err(&led->client->dev, "led register err: %d\n", ret); +- return ret; +- } + +- return 0; ++ fwnode_handle_put(init_data.fwnode); ++ return ret; + } + + static int lm3692x_probe(struct i2c_client *client, +diff --git a/drivers/leds/leds-lm3697.c b/drivers/leds/leds-lm3697.c +index 7d216cdb91a8a..912e8bb22a995 100644 +--- a/drivers/leds/leds-lm3697.c ++++ b/drivers/leds/leds-lm3697.c +@@ -203,11 +203,9 @@ static int lm3697_probe_dt(struct lm3697 *priv) + + priv->enable_gpio = devm_gpiod_get_optional(dev, "enable", + GPIOD_OUT_LOW); +- if (IS_ERR(priv->enable_gpio)) { +- ret = PTR_ERR(priv->enable_gpio); +- dev_err(dev, "Failed to get enable gpio: %d\n", ret); +- return ret; +- } ++ if (IS_ERR(priv->enable_gpio)) ++ return dev_err_probe(dev, PTR_ERR(priv->enable_gpio), ++ "Failed to get enable GPIO\n"); + + priv->regulator = devm_regulator_get(dev, "vled"); + if (IS_ERR(priv->regulator)) +diff --git a/drivers/leds/leds-lp50xx.c b/drivers/leds/leds-lp50xx.c +index 06230614fdc56..401df1e2e05d0 100644 +--- a/drivers/leds/leds-lp50xx.c ++++ b/drivers/leds/leds-lp50xx.c +@@ -490,6 +490,7 @@ static int lp50xx_probe_dt(struct lp50xx *priv) + ret = fwnode_property_read_u32(led_node, "color", + &color_id); + if (ret) { ++ fwnode_handle_put(led_node); + dev_err(priv->dev, "Cannot read color\n"); + goto child_out; + } +@@ -512,7 +513,6 @@ static int lp50xx_probe_dt(struct lp50xx *priv) + goto child_out; + } + i++; +- fwnode_handle_put(child); + } + + return 0; +diff --git a/drivers/mailbox/qcom-apcs-ipc-mailbox.c b/drivers/mailbox/qcom-apcs-ipc-mailbox.c +index f25324d03842e..15236d7296258 100644 +--- a/drivers/mailbox/qcom-apcs-ipc-mailbox.c ++++ b/drivers/mailbox/qcom-apcs-ipc-mailbox.c +@@ -132,7 +132,7 @@ static int qcom_apcs_ipc_probe(struct platform_device *pdev) + if (apcs_data->clk_name) { + apcs->clk = platform_device_register_data(&pdev->dev, + apcs_data->clk_name, +- PLATFORM_DEVID_NONE, ++ PLATFORM_DEVID_AUTO, + NULL, 0); + if (IS_ERR(apcs->clk)) + dev_err(&pdev->dev, "failed to register APCS clk\n"); +diff --git a/drivers/mailbox/qcom-ipcc.c b/drivers/mailbox/qcom-ipcc.c +index 2d13c72944c6f..584700cd15855 100644 +--- a/drivers/mailbox/qcom-ipcc.c ++++ b/drivers/mailbox/qcom-ipcc.c +@@ -155,6 +155,11 @@ static int qcom_ipcc_mbox_send_data(struct mbox_chan *chan, void *data) + return 0; + } + ++static void qcom_ipcc_mbox_shutdown(struct mbox_chan *chan) ++{ ++ chan->con_priv = NULL; ++} ++ + static struct mbox_chan *qcom_ipcc_mbox_xlate(struct mbox_controller *mbox, + const struct of_phandle_args *ph) + { +@@ -184,6 +189,7 @@ static struct mbox_chan *qcom_ipcc_mbox_xlate(struct mbox_controller *mbox, + + static const struct mbox_chan_ops ipcc_mbox_chan_ops = { + .send_data = qcom_ipcc_mbox_send_data, ++ .shutdown = qcom_ipcc_mbox_shutdown, + }; + + static int qcom_ipcc_setup_mbox(struct qcom_ipcc *ipcc) +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 49f897fbb89ba..7ba00e4c862d7 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -441,30 +441,6 @@ check_suspended: + } + EXPORT_SYMBOL(md_handle_request); + +-struct md_io { +- struct mddev *mddev; +- bio_end_io_t *orig_bi_end_io; +- void *orig_bi_private; +- struct block_device *orig_bi_bdev; +- unsigned long start_time; +-}; +- +-static void md_end_io(struct bio *bio) +-{ +- struct md_io *md_io = bio->bi_private; +- struct mddev *mddev = md_io->mddev; +- +- bio_end_io_acct_remapped(bio, md_io->start_time, md_io->orig_bi_bdev); +- +- bio->bi_end_io = md_io->orig_bi_end_io; +- bio->bi_private = md_io->orig_bi_private; +- +- mempool_free(md_io, &mddev->md_io_pool); +- +- if (bio->bi_end_io) +- bio->bi_end_io(bio); +-} +- + static blk_qc_t md_submit_bio(struct bio *bio) + { + const int rw = bio_data_dir(bio); +@@ -489,21 +465,6 @@ static blk_qc_t md_submit_bio(struct bio *bio) + return BLK_QC_T_NONE; + } + +- if (bio->bi_end_io != md_end_io) { +- struct md_io *md_io; +- +- md_io = mempool_alloc(&mddev->md_io_pool, GFP_NOIO); +- md_io->mddev = mddev; +- md_io->orig_bi_end_io = bio->bi_end_io; +- md_io->orig_bi_private = bio->bi_private; +- md_io->orig_bi_bdev = bio->bi_bdev; +- +- bio->bi_end_io = md_end_io; +- bio->bi_private = md_io; +- +- md_io->start_time = bio_start_io_acct(bio); +- } +- + /* bio could be mergeable after passing to underlayer */ + bio->bi_opf &= ~REQ_NOMERGE; + +@@ -5608,7 +5569,6 @@ static void md_free(struct kobject *ko) + + bioset_exit(&mddev->bio_set); + bioset_exit(&mddev->sync_set); +- mempool_exit(&mddev->md_io_pool); + kfree(mddev); + } + +@@ -5705,11 +5665,6 @@ static int md_alloc(dev_t dev, char *name) + */ + mddev->hold_active = UNTIL_STOP; + +- error = mempool_init_kmalloc_pool(&mddev->md_io_pool, BIO_POOL_SIZE, +- sizeof(struct md_io)); +- if (error) +- goto abort; +- + error = -ENOMEM; + mddev->queue = blk_alloc_queue(NUMA_NO_NODE); + if (!mddev->queue) +diff --git a/drivers/md/md.h b/drivers/md/md.h +index fb7eab58cfd51..4da240ffe2c5e 100644 +--- a/drivers/md/md.h ++++ b/drivers/md/md.h +@@ -487,7 +487,6 @@ struct mddev { + struct bio_set sync_set; /* for sync operations like + * metadata and bitmap writes + */ +- mempool_t md_io_pool; + + /* Generic flush handling. + * The last to finish preflush schedules a worker to submit +diff --git a/drivers/media/cec/platform/s5p/s5p_cec.c b/drivers/media/cec/platform/s5p/s5p_cec.c +index 2a3e7ffefe0a2..028a09a7531ef 100644 +--- a/drivers/media/cec/platform/s5p/s5p_cec.c ++++ b/drivers/media/cec/platform/s5p/s5p_cec.c +@@ -35,10 +35,13 @@ MODULE_PARM_DESC(debug, "debug level (0-2)"); + + static int s5p_cec_adap_enable(struct cec_adapter *adap, bool enable) + { ++ int ret; + struct s5p_cec_dev *cec = cec_get_drvdata(adap); + + if (enable) { +- pm_runtime_get_sync(cec->dev); ++ ret = pm_runtime_resume_and_get(cec->dev); ++ if (ret < 0) ++ return ret; + + s5p_cec_reset(cec); + +@@ -51,7 +54,7 @@ static int s5p_cec_adap_enable(struct cec_adapter *adap, bool enable) + } else { + s5p_cec_mask_tx_interrupts(cec); + s5p_cec_mask_rx_interrupts(cec); +- pm_runtime_disable(cec->dev); ++ pm_runtime_put(cec->dev); + } + + return 0; +diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c +index 410cc3ac6f948..bceaf91faa15f 100644 +--- a/drivers/media/common/siano/smscoreapi.c ++++ b/drivers/media/common/siano/smscoreapi.c +@@ -908,7 +908,7 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, + void *buffer, size_t size) + { + struct sms_firmware *firmware = (struct sms_firmware *) buffer; +- struct sms_msg_data4 *msg; ++ struct sms_msg_data5 *msg; + u32 mem_address, calc_checksum = 0; + u32 i, *ptr; + u8 *payload = firmware->payload; +@@ -989,24 +989,20 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, + goto exit_fw_download; + + if (coredev->mode == DEVICE_MODE_NONE) { +- struct sms_msg_data *trigger_msg = +- (struct sms_msg_data *) msg; +- + pr_debug("sending MSG_SMS_SWDOWNLOAD_TRIGGER_REQ\n"); + SMS_INIT_MSG(&msg->x_msg_header, + MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, +- sizeof(struct sms_msg_hdr) + +- sizeof(u32) * 5); ++ sizeof(*msg)); + +- trigger_msg->msg_data[0] = firmware->start_address; ++ msg->msg_data[0] = firmware->start_address; + /* Entry point */ +- trigger_msg->msg_data[1] = 6; /* Priority */ +- trigger_msg->msg_data[2] = 0x200; /* Stack size */ +- trigger_msg->msg_data[3] = 0; /* Parameter */ +- trigger_msg->msg_data[4] = 4; /* Task ID */ ++ msg->msg_data[1] = 6; /* Priority */ ++ msg->msg_data[2] = 0x200; /* Stack size */ ++ msg->msg_data[3] = 0; /* Parameter */ ++ msg->msg_data[4] = 4; /* Task ID */ + +- rc = smscore_sendrequest_and_wait(coredev, trigger_msg, +- trigger_msg->x_msg_header.msg_length, ++ rc = smscore_sendrequest_and_wait(coredev, msg, ++ msg->x_msg_header.msg_length, + &coredev->trigger_done); + } else { + SMS_INIT_MSG(&msg->x_msg_header, MSG_SW_RELOAD_EXEC_REQ, +diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h +index 4a6b9f4c44ace..f8789ee0d554e 100644 +--- a/drivers/media/common/siano/smscoreapi.h ++++ b/drivers/media/common/siano/smscoreapi.h +@@ -624,9 +624,9 @@ struct sms_msg_data2 { + u32 msg_data[2]; + }; + +-struct sms_msg_data4 { ++struct sms_msg_data5 { + struct sms_msg_hdr x_msg_header; +- u32 msg_data[4]; ++ u32 msg_data[5]; + }; + + struct sms_data_download { +diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c +index cd5bafe9a3aca..7e4100263381c 100644 +--- a/drivers/media/common/siano/smsdvb-main.c ++++ b/drivers/media/common/siano/smsdvb-main.c +@@ -1212,6 +1212,10 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, + return 0; + + media_graph_error: ++ mutex_lock(&g_smsdvb_clientslock); ++ list_del(&client->entry); ++ mutex_unlock(&g_smsdvb_clientslock); ++ + smsdvb_debugfs_release(client); + + client_error: +diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c +index 89620da983bab..dddebea644bb8 100644 +--- a/drivers/media/dvb-core/dvb_net.c ++++ b/drivers/media/dvb-core/dvb_net.c +@@ -45,6 +45,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1462,14 +1463,20 @@ static int dvb_net_do_ioctl(struct file *file, + struct net_device *netdev; + struct dvb_net_priv *priv_data; + struct dvb_net_if *dvbnetif = parg; ++ int if_num = dvbnetif->if_num; + +- if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX || +- !dvbnet->state[dvbnetif->if_num]) { ++ if (if_num >= DVB_NET_DEVICES_MAX) { + ret = -EINVAL; + goto ioctl_error; + } ++ if_num = array_index_nospec(if_num, DVB_NET_DEVICES_MAX); + +- netdev = dvbnet->device[dvbnetif->if_num]; ++ if (!dvbnet->state[if_num]) { ++ ret = -EINVAL; ++ goto ioctl_error; ++ } ++ ++ netdev = dvbnet->device[if_num]; + + priv_data = netdev_priv(netdev); + dvbnetif->pid=priv_data->pid; +@@ -1522,14 +1529,20 @@ static int dvb_net_do_ioctl(struct file *file, + struct net_device *netdev; + struct dvb_net_priv *priv_data; + struct __dvb_net_if_old *dvbnetif = parg; ++ int if_num = dvbnetif->if_num; ++ ++ if (if_num >= DVB_NET_DEVICES_MAX) { ++ ret = -EINVAL; ++ goto ioctl_error; ++ } ++ if_num = array_index_nospec(if_num, DVB_NET_DEVICES_MAX); + +- if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX || +- !dvbnet->state[dvbnetif->if_num]) { ++ if (!dvbnet->state[if_num]) { + ret = -EINVAL; + goto ioctl_error; + } + +- netdev = dvbnet->device[dvbnetif->if_num]; ++ netdev = dvbnet->device[if_num]; + + priv_data = netdev_priv(netdev); + dvbnetif->pid=priv_data->pid; +diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c +index 3862ddc86ec48..795d9bfaba5cf 100644 +--- a/drivers/media/dvb-core/dvbdev.c ++++ b/drivers/media/dvb-core/dvbdev.c +@@ -506,6 +506,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, + break; + + if (minor == MAX_DVB_MINORS) { ++ list_del (&dvbdev->list_head); + kfree(dvbdevfops); + kfree(dvbdev); + up_write(&minor_rwsem); +@@ -526,6 +527,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, + __func__); + + dvb_media_device_free(dvbdev); ++ list_del (&dvbdev->list_head); + kfree(dvbdevfops); + kfree(dvbdev); + mutex_unlock(&dvbdev_register_lock); +@@ -541,6 +543,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, + pr_err("%s: failed to create device dvb%d.%s%d (%ld)\n", + __func__, adap->num, dnames[type], id, PTR_ERR(clsdev)); + dvb_media_device_free(dvbdev); ++ list_del (&dvbdev->list_head); + kfree(dvbdevfops); + kfree(dvbdev); + return PTR_ERR(clsdev); +diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c +index 9dc3f45da3dcd..b05f409014b2f 100644 +--- a/drivers/media/i2c/ccs/ccs-core.c ++++ b/drivers/media/i2c/ccs/ccs-core.c +@@ -3093,7 +3093,7 @@ static int __maybe_unused ccs_suspend(struct device *dev) + if (rval < 0) { + pm_runtime_put_noidle(dev); + +- return -EAGAIN; ++ return rval; + } + + if (sensor->streaming) +diff --git a/drivers/media/i2c/imx334.c b/drivers/media/i2c/imx334.c +index 047aa7658d217..23f28606e570f 100644 +--- a/drivers/media/i2c/imx334.c ++++ b/drivers/media/i2c/imx334.c +@@ -717,9 +717,9 @@ static int imx334_set_stream(struct v4l2_subdev *sd, int enable) + } + + if (enable) { +- ret = pm_runtime_get_sync(imx334->dev); +- if (ret) +- goto error_power_off; ++ ret = pm_runtime_resume_and_get(imx334->dev); ++ if (ret < 0) ++ goto error_unlock; + + ret = imx334_start_streaming(imx334); + if (ret) +@@ -737,6 +737,7 @@ static int imx334_set_stream(struct v4l2_subdev *sd, int enable) + + error_power_off: + pm_runtime_put(imx334->dev); ++error_unlock: + mutex_unlock(&imx334->mutex); + + return ret; +diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c +index e8119ad0bc71d..92376592455ee 100644 +--- a/drivers/media/i2c/ir-kbd-i2c.c ++++ b/drivers/media/i2c/ir-kbd-i2c.c +@@ -678,8 +678,8 @@ static int zilog_tx(struct rc_dev *rcdev, unsigned int *txbuf, + goto out_unlock; + } + +- i = i2c_master_recv(ir->tx_c, buf, 1); +- if (i != 1) { ++ ret = i2c_master_recv(ir->tx_c, buf, 1); ++ if (ret != 1) { + dev_err(&ir->rc->dev, "i2c_master_recv failed with %d\n", ret); + ret = -EIO; + goto out_unlock; +diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c +index 42f64175a6dff..fb78a1cedc03b 100644 +--- a/drivers/media/i2c/ov2659.c ++++ b/drivers/media/i2c/ov2659.c +@@ -204,6 +204,7 @@ struct ov2659 { + struct i2c_client *client; + struct v4l2_ctrl_handler ctrls; + struct v4l2_ctrl *link_frequency; ++ struct clk *clk; + const struct ov2659_framesize *frame_size; + struct sensor_register *format_ctrl_regs; + struct ov2659_pll_ctrl pll; +@@ -1270,6 +1271,8 @@ static int ov2659_power_off(struct device *dev) + + gpiod_set_value(ov2659->pwdn_gpio, 1); + ++ clk_disable_unprepare(ov2659->clk); ++ + return 0; + } + +@@ -1278,9 +1281,17 @@ static int ov2659_power_on(struct device *dev) + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct ov2659 *ov2659 = to_ov2659(sd); ++ int ret; + + dev_dbg(&client->dev, "%s:\n", __func__); + ++ ret = clk_prepare_enable(ov2659->clk); ++ if (ret) { ++ dev_err(&client->dev, "%s: failed to enable clock\n", ++ __func__); ++ return ret; ++ } ++ + gpiod_set_value(ov2659->pwdn_gpio, 0); + + if (ov2659->resetb_gpio) { +@@ -1425,7 +1436,6 @@ static int ov2659_probe(struct i2c_client *client) + const struct ov2659_platform_data *pdata = ov2659_get_pdata(client); + struct v4l2_subdev *sd; + struct ov2659 *ov2659; +- struct clk *clk; + int ret; + + if (!pdata) { +@@ -1440,11 +1450,11 @@ static int ov2659_probe(struct i2c_client *client) + ov2659->pdata = pdata; + ov2659->client = client; + +- clk = devm_clk_get(&client->dev, "xvclk"); +- if (IS_ERR(clk)) +- return PTR_ERR(clk); ++ ov2659->clk = devm_clk_get(&client->dev, "xvclk"); ++ if (IS_ERR(ov2659->clk)) ++ return PTR_ERR(ov2659->clk); + +- ov2659->xvclk_frequency = clk_get_rate(clk); ++ ov2659->xvclk_frequency = clk_get_rate(ov2659->clk); + if (ov2659->xvclk_frequency < 6000000 || + ov2659->xvclk_frequency > 27000000) + return -EINVAL; +@@ -1506,7 +1516,9 @@ static int ov2659_probe(struct i2c_client *client) + ov2659->frame_size = &ov2659_framesizes[2]; + ov2659->format_ctrl_regs = ov2659_formats[0].format_ctrl_regs; + +- ov2659_power_on(&client->dev); ++ ret = ov2659_power_on(&client->dev); ++ if (ret < 0) ++ goto error; + + ret = ov2659_detect(sd); + if (ret < 0) +diff --git a/drivers/media/i2c/rdacm21.c b/drivers/media/i2c/rdacm21.c +index 179d107f494ca..50e2af5227603 100644 +--- a/drivers/media/i2c/rdacm21.c ++++ b/drivers/media/i2c/rdacm21.c +@@ -69,6 +69,7 @@ + #define OV490_ISP_VSIZE_LOW 0x80820062 + #define OV490_ISP_VSIZE_HIGH 0x80820063 + ++#define OV10640_PID_TIMEOUT 20 + #define OV10640_ID_HIGH 0xa6 + #define OV10640_CHIP_ID 0x300a + #define OV10640_PIXEL_RATE 55000000 +@@ -329,30 +330,51 @@ static const struct v4l2_subdev_ops rdacm21_subdev_ops = { + .pad = &rdacm21_subdev_pad_ops, + }; + +-static int ov10640_initialize(struct rdacm21_device *dev) ++static void ov10640_power_up(struct rdacm21_device *dev) + { +- u8 val; +- +- /* Power-up OV10640 by setting RESETB and PWDNB pins high. */ ++ /* Enable GPIO0#0 (reset) and GPIO1#0 (pwdn) as output lines. */ + ov490_write_reg(dev, OV490_GPIO_SEL0, OV490_GPIO0); + ov490_write_reg(dev, OV490_GPIO_SEL1, OV490_SPWDN0); + ov490_write_reg(dev, OV490_GPIO_DIRECTION0, OV490_GPIO0); + ov490_write_reg(dev, OV490_GPIO_DIRECTION1, OV490_SPWDN0); ++ ++ /* Power up OV10640 and then reset it. */ ++ ov490_write_reg(dev, OV490_GPIO_OUTPUT_VALUE1, OV490_SPWDN0); ++ usleep_range(1500, 3000); ++ ++ ov490_write_reg(dev, OV490_GPIO_OUTPUT_VALUE0, 0x00); ++ usleep_range(1500, 3000); + ov490_write_reg(dev, OV490_GPIO_OUTPUT_VALUE0, OV490_GPIO0); +- ov490_write_reg(dev, OV490_GPIO_OUTPUT_VALUE0, OV490_SPWDN0); + usleep_range(3000, 5000); ++} + +- /* Read OV10640 ID to test communications. */ +- ov490_write_reg(dev, OV490_SCCB_SLAVE0_DIR, OV490_SCCB_SLAVE_READ); +- ov490_write_reg(dev, OV490_SCCB_SLAVE0_ADDR_HIGH, OV10640_CHIP_ID >> 8); +- ov490_write_reg(dev, OV490_SCCB_SLAVE0_ADDR_LOW, OV10640_CHIP_ID & 0xff); +- +- /* Trigger SCCB slave transaction and give it some time to complete. */ +- ov490_write_reg(dev, OV490_HOST_CMD, OV490_HOST_CMD_TRIGGER); +- usleep_range(1000, 1500); ++static int ov10640_check_id(struct rdacm21_device *dev) ++{ ++ unsigned int i; ++ u8 val; + +- ov490_read_reg(dev, OV490_SCCB_SLAVE0_DIR, &val); +- if (val != OV10640_ID_HIGH) { ++ /* Read OV10640 ID to test communications. */ ++ for (i = 0; i < OV10640_PID_TIMEOUT; ++i) { ++ ov490_write_reg(dev, OV490_SCCB_SLAVE0_DIR, ++ OV490_SCCB_SLAVE_READ); ++ ov490_write_reg(dev, OV490_SCCB_SLAVE0_ADDR_HIGH, ++ OV10640_CHIP_ID >> 8); ++ ov490_write_reg(dev, OV490_SCCB_SLAVE0_ADDR_LOW, ++ OV10640_CHIP_ID & 0xff); ++ ++ /* ++ * Trigger SCCB slave transaction and give it some time ++ * to complete. ++ */ ++ ov490_write_reg(dev, OV490_HOST_CMD, OV490_HOST_CMD_TRIGGER); ++ usleep_range(1000, 1500); ++ ++ ov490_read_reg(dev, OV490_SCCB_SLAVE0_DIR, &val); ++ if (val == OV10640_ID_HIGH) ++ break; ++ usleep_range(1000, 1500); ++ } ++ if (i == OV10640_PID_TIMEOUT) { + dev_err(dev->dev, "OV10640 ID mismatch: (0x%02x)\n", val); + return -ENODEV; + } +@@ -368,6 +390,8 @@ static int ov490_initialize(struct rdacm21_device *dev) + unsigned int i; + int ret; + ++ ov10640_power_up(dev); ++ + /* + * Read OV490 Id to test communications. Give it up to 40msec to + * exit from reset. +@@ -405,7 +429,7 @@ static int ov490_initialize(struct rdacm21_device *dev) + return -ENODEV; + } + +- ret = ov10640_initialize(dev); ++ ret = ov10640_check_id(dev); + if (ret) + return ret; + +diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c +index 5b4c4a3547c93..71804a70bc6d7 100644 +--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c ++++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c +@@ -1386,7 +1386,7 @@ static int __s5c73m3_power_on(struct s5c73m3 *state) + s5c73m3_gpio_deassert(state, STBY); + usleep_range(100, 200); + +- s5c73m3_gpio_deassert(state, RST); ++ s5c73m3_gpio_deassert(state, RSET); + usleep_range(50, 100); + + return 0; +@@ -1401,7 +1401,7 @@ static int __s5c73m3_power_off(struct s5c73m3 *state) + { + int i, ret; + +- if (s5c73m3_gpio_assert(state, RST)) ++ if (s5c73m3_gpio_assert(state, RSET)) + usleep_range(10, 50); + + if (s5c73m3_gpio_assert(state, STBY)) +@@ -1606,7 +1606,7 @@ static int s5c73m3_get_platform_data(struct s5c73m3 *state) + + state->mclk_frequency = pdata->mclk_frequency; + state->gpio[STBY] = pdata->gpio_stby; +- state->gpio[RST] = pdata->gpio_reset; ++ state->gpio[RSET] = pdata->gpio_reset; + return 0; + } + +diff --git a/drivers/media/i2c/s5c73m3/s5c73m3.h b/drivers/media/i2c/s5c73m3/s5c73m3.h +index ef7e85b34263b..c3fcfdd3ea66d 100644 +--- a/drivers/media/i2c/s5c73m3/s5c73m3.h ++++ b/drivers/media/i2c/s5c73m3/s5c73m3.h +@@ -353,7 +353,7 @@ struct s5c73m3_ctrls { + + enum s5c73m3_gpio_id { + STBY, +- RST, ++ RSET, + GPIO_NUM, + }; + +diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c +index b2d53417badf6..4e97309a67f41 100644 +--- a/drivers/media/i2c/s5k4ecgx.c ++++ b/drivers/media/i2c/s5k4ecgx.c +@@ -173,7 +173,7 @@ static const char * const s5k4ecgx_supply_names[] = { + + enum s5k4ecgx_gpio_id { + STBY, +- RST, ++ RSET, + GPIO_NUM, + }; + +@@ -476,7 +476,7 @@ static int __s5k4ecgx_power_on(struct s5k4ecgx *priv) + if (s5k4ecgx_gpio_set_value(priv, STBY, priv->gpio[STBY].level)) + usleep_range(30, 50); + +- if (s5k4ecgx_gpio_set_value(priv, RST, priv->gpio[RST].level)) ++ if (s5k4ecgx_gpio_set_value(priv, RSET, priv->gpio[RSET].level)) + usleep_range(30, 50); + + return 0; +@@ -484,7 +484,7 @@ static int __s5k4ecgx_power_on(struct s5k4ecgx *priv) + + static int __s5k4ecgx_power_off(struct s5k4ecgx *priv) + { +- if (s5k4ecgx_gpio_set_value(priv, RST, !priv->gpio[RST].level)) ++ if (s5k4ecgx_gpio_set_value(priv, RSET, !priv->gpio[RSET].level)) + usleep_range(30, 50); + + if (s5k4ecgx_gpio_set_value(priv, STBY, !priv->gpio[STBY].level)) +@@ -872,7 +872,7 @@ static int s5k4ecgx_config_gpios(struct s5k4ecgx *priv, + int ret; + + priv->gpio[STBY].gpio = -EINVAL; +- priv->gpio[RST].gpio = -EINVAL; ++ priv->gpio[RSET].gpio = -EINVAL; + + ret = s5k4ecgx_config_gpio(gpio->gpio, gpio->level, "S5K4ECGX_STBY"); + +@@ -891,7 +891,7 @@ static int s5k4ecgx_config_gpios(struct s5k4ecgx *priv, + s5k4ecgx_free_gpios(priv); + return ret; + } +- priv->gpio[RST] = *gpio; ++ priv->gpio[RSET] = *gpio; + if (gpio_is_valid(gpio->gpio)) + gpio_set_value(gpio->gpio, 0); + +diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c +index 6e702b57c37da..bc560817e5046 100644 +--- a/drivers/media/i2c/s5k5baf.c ++++ b/drivers/media/i2c/s5k5baf.c +@@ -235,7 +235,7 @@ struct s5k5baf_gpio { + + enum s5k5baf_gpio_id { + STBY, +- RST, ++ RSET, + NUM_GPIOS, + }; + +@@ -969,7 +969,7 @@ static int s5k5baf_power_on(struct s5k5baf *state) + + s5k5baf_gpio_deassert(state, STBY); + usleep_range(50, 100); +- s5k5baf_gpio_deassert(state, RST); ++ s5k5baf_gpio_deassert(state, RSET); + return 0; + + err_reg_dis: +@@ -987,7 +987,7 @@ static int s5k5baf_power_off(struct s5k5baf *state) + state->apply_cfg = 0; + state->apply_crop = 0; + +- s5k5baf_gpio_assert(state, RST); ++ s5k5baf_gpio_assert(state, RSET); + s5k5baf_gpio_assert(state, STBY); + + if (!IS_ERR(state->clock)) +diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c +index 038e385007601..e9be7323a22e9 100644 +--- a/drivers/media/i2c/s5k6aa.c ++++ b/drivers/media/i2c/s5k6aa.c +@@ -177,7 +177,7 @@ static const char * const s5k6aa_supply_names[] = { + + enum s5k6aa_gpio_id { + STBY, +- RST, ++ RSET, + GPIO_NUM, + }; + +@@ -841,7 +841,7 @@ static int __s5k6aa_power_on(struct s5k6aa *s5k6aa) + ret = s5k6aa->s_power(1); + usleep_range(4000, 5000); + +- if (s5k6aa_gpio_deassert(s5k6aa, RST)) ++ if (s5k6aa_gpio_deassert(s5k6aa, RSET)) + msleep(20); + + return ret; +@@ -851,7 +851,7 @@ static int __s5k6aa_power_off(struct s5k6aa *s5k6aa) + { + int ret; + +- if (s5k6aa_gpio_assert(s5k6aa, RST)) ++ if (s5k6aa_gpio_assert(s5k6aa, RSET)) + usleep_range(100, 150); + + if (s5k6aa->s_power) { +@@ -1510,7 +1510,7 @@ static int s5k6aa_configure_gpios(struct s5k6aa *s5k6aa, + int ret; + + s5k6aa->gpio[STBY].gpio = -EINVAL; +- s5k6aa->gpio[RST].gpio = -EINVAL; ++ s5k6aa->gpio[RSET].gpio = -EINVAL; + + gpio = &pdata->gpio_stby; + if (gpio_is_valid(gpio->gpio)) { +@@ -1533,7 +1533,7 @@ static int s5k6aa_configure_gpios(struct s5k6aa *s5k6aa, + if (ret < 0) + return ret; + +- s5k6aa->gpio[RST] = *gpio; ++ s5k6aa->gpio[RSET] = *gpio; + } + + return 0; +diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c +index 1b309bb743c7b..f21da11caf224 100644 +--- a/drivers/media/i2c/tc358743.c ++++ b/drivers/media/i2c/tc358743.c +@@ -1974,6 +1974,7 @@ static int tc358743_probe_of(struct tc358743_state *state) + bps_pr_lane = 2 * endpoint.link_frequencies[0]; + if (bps_pr_lane < 62500000U || bps_pr_lane > 1000000000U) { + dev_err(dev, "unsupported bps per lane: %u bps\n", bps_pr_lane); ++ ret = -EINVAL; + goto disable_clk; + } + +diff --git a/drivers/media/mc/Makefile b/drivers/media/mc/Makefile +index 119037f0e686d..2b7af42ba59c1 100644 +--- a/drivers/media/mc/Makefile ++++ b/drivers/media/mc/Makefile +@@ -3,7 +3,7 @@ + mc-objs := mc-device.o mc-devnode.o mc-entity.o \ + mc-request.o + +-ifeq ($(CONFIG_USB),y) ++ifneq ($(CONFIG_USB),) + mc-objs += mc-dev-allocator.o + endif + +diff --git a/drivers/media/pci/bt8xx/bt878.c b/drivers/media/pci/bt8xx/bt878.c +index 78dd35c9b65d7..90972d6952f1c 100644 +--- a/drivers/media/pci/bt8xx/bt878.c ++++ b/drivers/media/pci/bt8xx/bt878.c +@@ -300,7 +300,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id) + } + if (astat & BT878_ARISCI) { + bt->finished_block = (stat & BT878_ARISCS) >> 28; +- tasklet_schedule(&bt->tasklet); ++ if (bt->tasklet.callback) ++ tasklet_schedule(&bt->tasklet); + break; + } + count++; +@@ -477,6 +478,9 @@ static int bt878_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) + btwrite(0, BT878_AINT_MASK); + bt878_num++; + ++ if (!bt->tasklet.func) ++ tasklet_disable(&bt->tasklet); ++ + return 0; + + fail2: +diff --git a/drivers/media/pci/cobalt/cobalt-driver.c b/drivers/media/pci/cobalt/cobalt-driver.c +index 839503e654f46..16af58f2f93cc 100644 +--- a/drivers/media/pci/cobalt/cobalt-driver.c ++++ b/drivers/media/pci/cobalt/cobalt-driver.c +@@ -667,6 +667,7 @@ static int cobalt_probe(struct pci_dev *pci_dev, + return -ENOMEM; + cobalt->pci_dev = pci_dev; + cobalt->instance = i; ++ mutex_init(&cobalt->pci_lock); + + retval = v4l2_device_register(&pci_dev->dev, &cobalt->v4l2_dev); + if (retval) { +diff --git a/drivers/media/pci/cobalt/cobalt-driver.h b/drivers/media/pci/cobalt/cobalt-driver.h +index bca68572b3242..12c33e035904c 100644 +--- a/drivers/media/pci/cobalt/cobalt-driver.h ++++ b/drivers/media/pci/cobalt/cobalt-driver.h +@@ -251,6 +251,8 @@ struct cobalt { + int instance; + struct pci_dev *pci_dev; + struct v4l2_device v4l2_dev; ++ /* serialize PCI access in cobalt_s_bit_sysctrl() */ ++ struct mutex pci_lock; + + void __iomem *bar0, *bar1; + +@@ -320,10 +322,13 @@ static inline u32 cobalt_g_sysctrl(struct cobalt *cobalt) + static inline void cobalt_s_bit_sysctrl(struct cobalt *cobalt, + int bit, int val) + { +- u32 ctrl = cobalt_read_bar1(cobalt, COBALT_SYS_CTRL_BASE); ++ u32 ctrl; + ++ mutex_lock(&cobalt->pci_lock); ++ ctrl = cobalt_read_bar1(cobalt, COBALT_SYS_CTRL_BASE); + cobalt_write_bar1(cobalt, COBALT_SYS_CTRL_BASE, + (ctrl & ~(1UL << bit)) | (val << bit)); ++ mutex_unlock(&cobalt->pci_lock); + } + + static inline u32 cobalt_g_sysstat(struct cobalt *cobalt) +diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.c b/drivers/media/pci/intel/ipu3/cio2-bridge.c +index e8511787c1e43..4657e99df0339 100644 +--- a/drivers/media/pci/intel/ipu3/cio2-bridge.c ++++ b/drivers/media/pci/intel/ipu3/cio2-bridge.c +@@ -173,14 +173,15 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg, + int ret; + + for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) { +- if (!adev->status.enabled) ++ if (!adev->status.enabled) { ++ acpi_dev_put(adev); + continue; ++ } + + if (bridge->n_sensors >= CIO2_NUM_PORTS) { ++ acpi_dev_put(adev); + dev_err(&cio2->dev, "Exceeded available CIO2 ports\n"); +- cio2_bridge_unregister_sensors(bridge); +- ret = -EINVAL; +- goto err_out; ++ return -EINVAL; + } + + sensor = &bridge->sensors[bridge->n_sensors]; +@@ -228,7 +229,6 @@ err_free_swnodes: + software_node_unregister_nodes(sensor->swnodes); + err_put_adev: + acpi_dev_put(sensor->adev); +-err_out: + return ret; + } + +diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c +index 6cdc77dda0e49..1c9cb9e05fdf6 100644 +--- a/drivers/media/platform/am437x/am437x-vpfe.c ++++ b/drivers/media/platform/am437x/am437x-vpfe.c +@@ -1021,7 +1021,9 @@ static int vpfe_initialize_device(struct vpfe_device *vpfe) + if (ret) + return ret; + +- pm_runtime_get_sync(vpfe->pdev); ++ ret = pm_runtime_resume_and_get(vpfe->pdev); ++ if (ret < 0) ++ return ret; + + vpfe_config_enable(&vpfe->ccdc, 1); + +@@ -2443,7 +2445,11 @@ static int vpfe_probe(struct platform_device *pdev) + pm_runtime_enable(&pdev->dev); + + /* for now just enable it here instead of waiting for the open */ +- pm_runtime_get_sync(&pdev->dev); ++ ret = pm_runtime_resume_and_get(&pdev->dev); ++ if (ret < 0) { ++ vpfe_err(vpfe, "Unable to resume device.\n"); ++ goto probe_out_v4l2_unregister; ++ } + + vpfe_ccdc_config_defaults(ccdc); + +@@ -2530,6 +2536,11 @@ static int vpfe_suspend(struct device *dev) + + /* only do full suspend if streaming has started */ + if (vb2_start_streaming_called(&vpfe->buffer_queue)) { ++ /* ++ * ignore RPM resume errors here, as it is already too late. ++ * A check like that should happen earlier, either at ++ * open() or just before start streaming. ++ */ + pm_runtime_get_sync(dev); + vpfe_config_enable(ccdc, 1); + +diff --git a/drivers/media/platform/exynos-gsc/gsc-m2m.c b/drivers/media/platform/exynos-gsc/gsc-m2m.c +index 27a3c92c73bce..f1cf847d1cc2d 100644 +--- a/drivers/media/platform/exynos-gsc/gsc-m2m.c ++++ b/drivers/media/platform/exynos-gsc/gsc-m2m.c +@@ -56,10 +56,8 @@ static void __gsc_m2m_job_abort(struct gsc_ctx *ctx) + static int gsc_m2m_start_streaming(struct vb2_queue *q, unsigned int count) + { + struct gsc_ctx *ctx = q->drv_priv; +- int ret; + +- ret = pm_runtime_get_sync(&ctx->gsc_dev->pdev->dev); +- return ret > 0 ? 0 : ret; ++ return pm_runtime_resume_and_get(&ctx->gsc_dev->pdev->dev); + } + + static void __gsc_m2m_cleanup_queue(struct gsc_ctx *ctx) +diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c +index 13c838d3f9473..0da36443173c1 100644 +--- a/drivers/media/platform/exynos4-is/fimc-capture.c ++++ b/drivers/media/platform/exynos4-is/fimc-capture.c +@@ -478,11 +478,9 @@ static int fimc_capture_open(struct file *file) + goto unlock; + + set_bit(ST_CAPT_BUSY, &fimc->state); +- ret = pm_runtime_get_sync(&fimc->pdev->dev); +- if (ret < 0) { +- pm_runtime_put_sync(&fimc->pdev->dev); ++ ret = pm_runtime_resume_and_get(&fimc->pdev->dev); ++ if (ret < 0) + goto unlock; +- } + + ret = v4l2_fh_open(file); + if (ret) { +diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c +index 972d9601d2360..1b24f5bfc4af4 100644 +--- a/drivers/media/platform/exynos4-is/fimc-is.c ++++ b/drivers/media/platform/exynos4-is/fimc-is.c +@@ -828,9 +828,9 @@ static int fimc_is_probe(struct platform_device *pdev) + goto err_irq; + } + +- ret = pm_runtime_get_sync(dev); ++ ret = pm_runtime_resume_and_get(dev); + if (ret < 0) +- goto err_pm; ++ goto err_irq; + + vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); + +diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c +index 612b9872afc87..83688a7982f70 100644 +--- a/drivers/media/platform/exynos4-is/fimc-isp-video.c ++++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c +@@ -275,7 +275,7 @@ static int isp_video_open(struct file *file) + if (ret < 0) + goto unlock; + +- ret = pm_runtime_get_sync(&isp->pdev->dev); ++ ret = pm_runtime_resume_and_get(&isp->pdev->dev); + if (ret < 0) + goto rel_fh; + +@@ -293,7 +293,6 @@ static int isp_video_open(struct file *file) + if (!ret) + goto unlock; + rel_fh: +- pm_runtime_put_noidle(&isp->pdev->dev); + v4l2_fh_release(file); + unlock: + mutex_unlock(&isp->video_lock); +@@ -306,17 +305,20 @@ static int isp_video_release(struct file *file) + struct fimc_is_video *ivc = &isp->video_capture; + struct media_entity *entity = &ivc->ve.vdev.entity; + struct media_device *mdev = entity->graph_obj.mdev; ++ bool is_singular_file; + + mutex_lock(&isp->video_lock); + +- if (v4l2_fh_is_singular_file(file) && ivc->streaming) { ++ is_singular_file = v4l2_fh_is_singular_file(file); ++ ++ if (is_singular_file && ivc->streaming) { + media_pipeline_stop(entity); + ivc->streaming = 0; + } + + _vb2_fop_release(file, NULL); + +- if (v4l2_fh_is_singular_file(file)) { ++ if (is_singular_file) { + fimc_pipeline_call(&ivc->ve, close); + + mutex_lock(&mdev->graph_mutex); +diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c +index a77c49b185115..74b49d30901ed 100644 +--- a/drivers/media/platform/exynos4-is/fimc-isp.c ++++ b/drivers/media/platform/exynos4-is/fimc-isp.c +@@ -304,11 +304,10 @@ static int fimc_isp_subdev_s_power(struct v4l2_subdev *sd, int on) + pr_debug("on: %d\n", on); + + if (on) { +- ret = pm_runtime_get_sync(&is->pdev->dev); +- if (ret < 0) { +- pm_runtime_put(&is->pdev->dev); ++ ret = pm_runtime_resume_and_get(&is->pdev->dev); ++ if (ret < 0) + return ret; +- } ++ + set_bit(IS_ST_PWR_ON, &is->state); + + ret = fimc_is_start_firmware(is); +diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c +index fe20af3a7178a..4d8b18078ff37 100644 +--- a/drivers/media/platform/exynos4-is/fimc-lite.c ++++ b/drivers/media/platform/exynos4-is/fimc-lite.c +@@ -469,9 +469,9 @@ static int fimc_lite_open(struct file *file) + } + + set_bit(ST_FLITE_IN_USE, &fimc->state); +- ret = pm_runtime_get_sync(&fimc->pdev->dev); ++ ret = pm_runtime_resume_and_get(&fimc->pdev->dev); + if (ret < 0) +- goto err_pm; ++ goto err_in_use; + + ret = v4l2_fh_open(file); + if (ret < 0) +@@ -499,6 +499,7 @@ static int fimc_lite_open(struct file *file) + v4l2_fh_release(file); + err_pm: + pm_runtime_put_sync(&fimc->pdev->dev); ++err_in_use: + clear_bit(ST_FLITE_IN_USE, &fimc->state); + unlock: + mutex_unlock(&fimc->lock); +diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c +index c9704a147e5cf..df8e2aa454d8f 100644 +--- a/drivers/media/platform/exynos4-is/fimc-m2m.c ++++ b/drivers/media/platform/exynos4-is/fimc-m2m.c +@@ -73,17 +73,14 @@ static void fimc_m2m_shutdown(struct fimc_ctx *ctx) + static int start_streaming(struct vb2_queue *q, unsigned int count) + { + struct fimc_ctx *ctx = q->drv_priv; +- int ret; + +- ret = pm_runtime_get_sync(&ctx->fimc_dev->pdev->dev); +- return ret > 0 ? 0 : ret; ++ return pm_runtime_resume_and_get(&ctx->fimc_dev->pdev->dev); + } + + static void stop_streaming(struct vb2_queue *q) + { + struct fimc_ctx *ctx = q->drv_priv; + +- + fimc_m2m_shutdown(ctx); + fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR); + pm_runtime_put(&ctx->fimc_dev->pdev->dev); +diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c +index 13d192ba4aa6e..3b8a24bb724c8 100644 +--- a/drivers/media/platform/exynos4-is/media-dev.c ++++ b/drivers/media/platform/exynos4-is/media-dev.c +@@ -512,11 +512,9 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) + if (!fmd->pmf) + return -ENXIO; + +- ret = pm_runtime_get_sync(fmd->pmf); +- if (ret < 0) { +- pm_runtime_put(fmd->pmf); ++ ret = pm_runtime_resume_and_get(fmd->pmf); ++ if (ret < 0) + return ret; +- } + + fmd->num_sensors = 0; + +@@ -1286,13 +1284,11 @@ static DEVICE_ATTR(subdev_conf_mode, S_IWUSR | S_IRUGO, + static int cam_clk_prepare(struct clk_hw *hw) + { + struct cam_clk *camclk = to_cam_clk(hw); +- int ret; + + if (camclk->fmd->pmf == NULL) + return -ENODEV; + +- ret = pm_runtime_get_sync(camclk->fmd->pmf); +- return ret < 0 ? ret : 0; ++ return pm_runtime_resume_and_get(camclk->fmd->pmf); + } + + static void cam_clk_unprepare(struct clk_hw *hw) +diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c +index 1aac167abb175..ebf39c8568943 100644 +--- a/drivers/media/platform/exynos4-is/mipi-csis.c ++++ b/drivers/media/platform/exynos4-is/mipi-csis.c +@@ -494,7 +494,7 @@ static int s5pcsis_s_power(struct v4l2_subdev *sd, int on) + struct device *dev = &state->pdev->dev; + + if (on) +- return pm_runtime_get_sync(dev); ++ return pm_runtime_resume_and_get(dev); + + return pm_runtime_put_sync(dev); + } +@@ -509,11 +509,9 @@ static int s5pcsis_s_stream(struct v4l2_subdev *sd, int enable) + + if (enable) { + s5pcsis_clear_counters(state); +- ret = pm_runtime_get_sync(&state->pdev->dev); +- if (ret && ret != 1) { +- pm_runtime_put_noidle(&state->pdev->dev); ++ ret = pm_runtime_resume_and_get(&state->pdev->dev); ++ if (ret < 0) + return ret; +- } + } + + mutex_lock(&state->lock); +@@ -535,7 +533,7 @@ unlock: + if (!enable) + pm_runtime_put(&state->pdev->dev); + +- return ret == 1 ? 0 : ret; ++ return ret; + } + + static int s5pcsis_enum_mbus_code(struct v4l2_subdev *sd, +diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c +index 141bf5d97a044..ea87110d90738 100644 +--- a/drivers/media/platform/marvell-ccic/mcam-core.c ++++ b/drivers/media/platform/marvell-ccic/mcam-core.c +@@ -918,6 +918,7 @@ static int mclk_enable(struct clk_hw *hw) + struct mcam_camera *cam = container_of(hw, struct mcam_camera, mclk_hw); + int mclk_src; + int mclk_div; ++ int ret; + + /* + * Clock the sensor appropriately. Controller clock should +@@ -931,7 +932,9 @@ static int mclk_enable(struct clk_hw *hw) + mclk_div = 2; + } + +- pm_runtime_get_sync(cam->dev); ++ ret = pm_runtime_resume_and_get(cam->dev); ++ if (ret < 0) ++ return ret; + clk_enable(cam->clk[0]); + mcam_reg_write(cam, REG_CLKCTRL, (mclk_src << 29) | mclk_div); + mcam_ctlr_power_up(cam); +@@ -1611,7 +1614,9 @@ static int mcam_v4l_open(struct file *filp) + ret = sensor_call(cam, core, s_power, 1); + if (ret) + goto out; +- pm_runtime_get_sync(cam->dev); ++ ret = pm_runtime_resume_and_get(cam->dev); ++ if (ret < 0) ++ goto out; + __mcam_cam_reset(cam); + mcam_set_config_needed(cam, 1); + } +diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c +index ace4528cdc5ef..f14779e7596e5 100644 +--- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c ++++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c +@@ -391,12 +391,12 @@ static int mtk_mdp_m2m_start_streaming(struct vb2_queue *q, unsigned int count) + struct mtk_mdp_ctx *ctx = q->drv_priv; + int ret; + +- ret = pm_runtime_get_sync(&ctx->mdp_dev->pdev->dev); ++ ret = pm_runtime_resume_and_get(&ctx->mdp_dev->pdev->dev); + if (ret < 0) +- mtk_mdp_dbg(1, "[%d] pm_runtime_get_sync failed:%d", ++ mtk_mdp_dbg(1, "[%d] pm_runtime_resume_and_get failed:%d", + ctx->id, ret); + +- return 0; ++ return ret; + } + + static void *mtk_mdp_m2m_buf_remove(struct mtk_mdp_ctx *ctx, +diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +index 147dfef1638d2..f87dc47d9e638 100644 +--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c ++++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +@@ -126,7 +126,9 @@ static int fops_vcodec_open(struct file *file) + mtk_vcodec_dec_set_default_params(ctx); + + if (v4l2_fh_is_singular(&ctx->fh)) { +- mtk_vcodec_dec_pw_on(&dev->pm); ++ ret = mtk_vcodec_dec_pw_on(&dev->pm); ++ if (ret < 0) ++ goto err_load_fw; + /* + * Does nothing if firmware was already loaded. + */ +diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c +index ddee7046ce422..6038db96f71c3 100644 +--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c ++++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c +@@ -88,13 +88,15 @@ void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev) + put_device(dev->pm.larbvdec); + } + +-void mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm) ++int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm) + { + int ret; + +- ret = pm_runtime_get_sync(pm->dev); ++ ret = pm_runtime_resume_and_get(pm->dev); + if (ret) +- mtk_v4l2_err("pm_runtime_get_sync fail %d", ret); ++ mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret); ++ ++ return ret; + } + + void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm) +diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h +index 872d8bf8cfaf3..280aeaefdb651 100644 +--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h ++++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h +@@ -12,7 +12,7 @@ + int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *dev); + void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev); + +-void mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm); ++int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm); + void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm); + void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm); + void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm); +diff --git a/drivers/media/platform/mtk-vpu/mtk_vpu.c b/drivers/media/platform/mtk-vpu/mtk_vpu.c +index c8a56271b259e..7c4428cf14e6d 100644 +--- a/drivers/media/platform/mtk-vpu/mtk_vpu.c ++++ b/drivers/media/platform/mtk-vpu/mtk_vpu.c +@@ -987,6 +987,12 @@ static int mtk_vpu_suspend(struct device *dev) + return ret; + } + ++ if (!vpu_running(vpu)) { ++ vpu_clock_disable(vpu); ++ clk_unprepare(vpu->clk); ++ return 0; ++ } ++ + mutex_lock(&vpu->vpu_mutex); + /* disable vpu timer interrupt */ + vpu_cfg_writel(vpu, vpu_cfg_readl(vpu, VPU_INT_STATUS) | VPU_IDLE_STATE, +diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c +index 54bac7ec14c50..91b15842c5558 100644 +--- a/drivers/media/platform/qcom/venus/core.c ++++ b/drivers/media/platform/qcom/venus/core.c +@@ -78,22 +78,32 @@ static const struct hfi_core_ops venus_core_ops = { + .event_notify = venus_event_notify, + }; + ++#define RPM_WAIT_FOR_IDLE_MAX_ATTEMPTS 10 ++ + static void venus_sys_error_handler(struct work_struct *work) + { + struct venus_core *core = + container_of(work, struct venus_core, work.work); +- int ret = 0; +- +- pm_runtime_get_sync(core->dev); ++ int ret, i, max_attempts = RPM_WAIT_FOR_IDLE_MAX_ATTEMPTS; ++ const char *err_msg = ""; ++ bool failed = false; ++ ++ ret = pm_runtime_get_sync(core->dev); ++ if (ret < 0) { ++ err_msg = "resume runtime PM"; ++ max_attempts = 0; ++ failed = true; ++ } + + hfi_core_deinit(core, true); + +- dev_warn(core->dev, "system error has occurred, starting recovery!\n"); +- + mutex_lock(&core->lock); + +- while (pm_runtime_active(core->dev_dec) || pm_runtime_active(core->dev_enc)) ++ for (i = 0; i < max_attempts; i++) { ++ if (!pm_runtime_active(core->dev_dec) && !pm_runtime_active(core->dev_enc)) ++ break; + msleep(10); ++ } + + venus_shutdown(core); + +@@ -101,31 +111,55 @@ static void venus_sys_error_handler(struct work_struct *work) + + pm_runtime_put_sync(core->dev); + +- while (core->pmdomains[0] && pm_runtime_active(core->pmdomains[0])) ++ for (i = 0; i < max_attempts; i++) { ++ if (!core->pmdomains[0] || !pm_runtime_active(core->pmdomains[0])) ++ break; + usleep_range(1000, 1500); ++ } + + hfi_reinit(core); + +- pm_runtime_get_sync(core->dev); ++ ret = pm_runtime_get_sync(core->dev); ++ if (ret < 0) { ++ err_msg = "resume runtime PM"; ++ failed = true; ++ } + +- ret |= venus_boot(core); +- ret |= hfi_core_resume(core, true); ++ ret = venus_boot(core); ++ if (ret && !failed) { ++ err_msg = "boot Venus"; ++ failed = true; ++ } ++ ++ ret = hfi_core_resume(core, true); ++ if (ret && !failed) { ++ err_msg = "resume HFI"; ++ failed = true; ++ } + + enable_irq(core->irq); + + mutex_unlock(&core->lock); + +- ret |= hfi_core_init(core); ++ ret = hfi_core_init(core); ++ if (ret && !failed) { ++ err_msg = "init HFI"; ++ failed = true; ++ } + + pm_runtime_put_sync(core->dev); + +- if (ret) { ++ if (failed) { + disable_irq_nosync(core->irq); +- dev_warn(core->dev, "recovery failed (%d)\n", ret); ++ dev_warn_ratelimited(core->dev, ++ "System error has occurred, recovery failed to %s\n", ++ err_msg); + schedule_delayed_work(&core->work, msecs_to_jiffies(10)); + return; + } + ++ dev_warn(core->dev, "system error has occurred (recovered)\n"); ++ + mutex_lock(&core->lock); + core->sys_error = false; + mutex_unlock(&core->lock); +diff --git a/drivers/media/platform/qcom/venus/hfi_cmds.c b/drivers/media/platform/qcom/venus/hfi_cmds.c +index 11a8347e5f5c8..4b9dea7f6940e 100644 +--- a/drivers/media/platform/qcom/venus/hfi_cmds.c ++++ b/drivers/media/platform/qcom/venus/hfi_cmds.c +@@ -1226,6 +1226,17 @@ pkt_session_set_property_4xx(struct hfi_session_set_property_pkt *pkt, + pkt->shdr.hdr.size += sizeof(u32) + sizeof(*hdr10); + break; + } ++ case HFI_PROPERTY_PARAM_VDEC_CONCEAL_COLOR: { ++ struct hfi_conceal_color_v4 *color = prop_data; ++ u32 *in = pdata; ++ ++ color->conceal_color_8bit = *in & 0xff; ++ color->conceal_color_8bit |= ((*in >> 10) & 0xff) << 8; ++ color->conceal_color_8bit |= ((*in >> 20) & 0xff) << 16; ++ color->conceal_color_10bit = *in; ++ pkt->shdr.hdr.size += sizeof(u32) + sizeof(*color); ++ break; ++ } + + case HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE: + case HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER: +@@ -1279,17 +1290,6 @@ pkt_session_set_property_6xx(struct hfi_session_set_property_pkt *pkt, + pkt->shdr.hdr.size += sizeof(u32) + sizeof(*cq); + break; + } +- case HFI_PROPERTY_PARAM_VDEC_CONCEAL_COLOR: { +- struct hfi_conceal_color_v4 *color = prop_data; +- u32 *in = pdata; +- +- color->conceal_color_8bit = *in & 0xff; +- color->conceal_color_8bit |= ((*in >> 10) & 0xff) << 8; +- color->conceal_color_8bit |= ((*in >> 20) & 0xff) << 16; +- color->conceal_color_10bit = *in; +- pkt->shdr.hdr.size += sizeof(u32) + sizeof(*color); +- break; +- } + default: + return pkt_session_set_property_4xx(pkt, cookie, ptype, pdata); + } +diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c +index 15bcb7f6e113c..1cb5eaabf340b 100644 +--- a/drivers/media/platform/s5p-g2d/g2d.c ++++ b/drivers/media/platform/s5p-g2d/g2d.c +@@ -276,6 +276,9 @@ static int g2d_release(struct file *file) + struct g2d_dev *dev = video_drvdata(file); + struct g2d_ctx *ctx = fh2ctx(file->private_data); + ++ mutex_lock(&dev->mutex); ++ v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); ++ mutex_unlock(&dev->mutex); + v4l2_ctrl_handler_free(&ctx->ctrl_handler); + v4l2_fh_del(&ctx->fh); + v4l2_fh_exit(&ctx->fh); +diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c +index 026111505f5a5..d402e456f27df 100644 +--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c ++++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c +@@ -2566,11 +2566,8 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb) + static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count) + { + struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q); +- int ret; +- +- ret = pm_runtime_get_sync(ctx->jpeg->dev); + +- return ret > 0 ? 0 : ret; ++ return pm_runtime_resume_and_get(ctx->jpeg->dev); + } + + static void s5p_jpeg_stop_streaming(struct vb2_queue *q) +diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +index a92a9ca6e87eb..c1d3bda8385b1 100644 +--- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c ++++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +@@ -172,6 +172,7 @@ static struct mfc_control controls[] = { + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = 16383, ++ .step = 1, + .default_value = 0, + }, + { +diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c +index 4ac48441f22c4..ca4310e26c49e 100644 +--- a/drivers/media/platform/sh_vou.c ++++ b/drivers/media/platform/sh_vou.c +@@ -1133,7 +1133,11 @@ static int sh_vou_open(struct file *file) + if (v4l2_fh_is_singular_file(file) && + vou_dev->status == SH_VOU_INITIALISING) { + /* First open */ +- pm_runtime_get_sync(vou_dev->v4l2_dev.dev); ++ err = pm_runtime_resume_and_get(vou_dev->v4l2_dev.dev); ++ if (err < 0) { ++ v4l2_fh_release(file); ++ goto done_open; ++ } + err = sh_vou_hw_init(vou_dev); + if (err < 0) { + pm_runtime_put(vou_dev->v4l2_dev.dev); +diff --git a/drivers/media/platform/sti/bdisp/Makefile b/drivers/media/platform/sti/bdisp/Makefile +index caf7ccd193eaa..39ade0a347236 100644 +--- a/drivers/media/platform/sti/bdisp/Makefile ++++ b/drivers/media/platform/sti/bdisp/Makefile +@@ -1,4 +1,4 @@ + # SPDX-License-Identifier: GPL-2.0-only +-obj-$(CONFIG_VIDEO_STI_BDISP) := bdisp.o ++obj-$(CONFIG_VIDEO_STI_BDISP) += bdisp.o + + bdisp-objs := bdisp-v4l2.o bdisp-hw.o bdisp-debug.o +diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c +index 060ca85f64d5d..85288da9d2ae6 100644 +--- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c ++++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c +@@ -499,7 +499,7 @@ static int bdisp_start_streaming(struct vb2_queue *q, unsigned int count) + { + struct bdisp_ctx *ctx = q->drv_priv; + struct vb2_v4l2_buffer *buf; +- int ret = pm_runtime_get_sync(ctx->bdisp_dev->dev); ++ int ret = pm_runtime_resume_and_get(ctx->bdisp_dev->dev); + + if (ret < 0) { + dev_err(ctx->bdisp_dev->dev, "failed to set runtime PM\n"); +@@ -1364,10 +1364,10 @@ static int bdisp_probe(struct platform_device *pdev) + + /* Power management */ + pm_runtime_enable(dev); +- ret = pm_runtime_get_sync(dev); ++ ret = pm_runtime_resume_and_get(dev); + if (ret < 0) { + dev_err(dev, "failed to set PM\n"); +- goto err_pm; ++ goto err_remove; + } + + /* Filters */ +@@ -1395,6 +1395,7 @@ err_filter: + bdisp_hw_free_filters(bdisp->dev); + err_pm: + pm_runtime_put(dev); ++err_remove: + bdisp_debugfs_remove(bdisp); + v4l2_device_unregister(&bdisp->v4l2_dev); + err_clk: +diff --git a/drivers/media/platform/sti/delta/Makefile b/drivers/media/platform/sti/delta/Makefile +index 92b37e216f004..32412fa4c6328 100644 +--- a/drivers/media/platform/sti/delta/Makefile ++++ b/drivers/media/platform/sti/delta/Makefile +@@ -1,5 +1,5 @@ + # SPDX-License-Identifier: GPL-2.0-only +-obj-$(CONFIG_VIDEO_STI_DELTA_DRIVER) := st-delta.o ++obj-$(CONFIG_VIDEO_STI_DELTA_DRIVER) += st-delta.o + st-delta-y := delta-v4l2.o delta-mem.o delta-ipc.o delta-debug.o + + # MJPEG support +diff --git a/drivers/media/platform/sti/hva/Makefile b/drivers/media/platform/sti/hva/Makefile +index 74b41ec52f976..b5a5478bdd016 100644 +--- a/drivers/media/platform/sti/hva/Makefile ++++ b/drivers/media/platform/sti/hva/Makefile +@@ -1,4 +1,4 @@ + # SPDX-License-Identifier: GPL-2.0-only +-obj-$(CONFIG_VIDEO_STI_HVA) := st-hva.o ++obj-$(CONFIG_VIDEO_STI_HVA) += st-hva.o + st-hva-y := hva-v4l2.o hva-hw.o hva-mem.o hva-h264.o + st-hva-$(CONFIG_VIDEO_STI_HVA_DEBUGFS) += hva-debugfs.o +diff --git a/drivers/media/platform/sti/hva/hva-hw.c b/drivers/media/platform/sti/hva/hva-hw.c +index f59811e27f51f..6eeee5017fac4 100644 +--- a/drivers/media/platform/sti/hva/hva-hw.c ++++ b/drivers/media/platform/sti/hva/hva-hw.c +@@ -130,8 +130,7 @@ static irqreturn_t hva_hw_its_irq_thread(int irq, void *arg) + ctx_id = (hva->sts_reg & 0xFF00) >> 8; + if (ctx_id >= HVA_MAX_INSTANCES) { + dev_err(dev, "%s %s: bad context identifier: %d\n", +- ctx->name, __func__, ctx_id); +- ctx->hw_err = true; ++ HVA_PREFIX, __func__, ctx_id); + goto out; + } + +diff --git a/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c b/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c +index 3f81dd17755cb..fbcca59a0517c 100644 +--- a/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c ++++ b/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c +@@ -494,7 +494,7 @@ static int rotate_start_streaming(struct vb2_queue *vq, unsigned int count) + struct device *dev = ctx->dev->dev; + int ret; + +- ret = pm_runtime_get_sync(dev); ++ ret = pm_runtime_resume_and_get(dev); + if (ret < 0) { + dev_err(dev, "Failed to enable module\n"); + +diff --git a/drivers/media/platform/video-mux.c b/drivers/media/platform/video-mux.c +index 133122e385150..9bc0b4d8de095 100644 +--- a/drivers/media/platform/video-mux.c ++++ b/drivers/media/platform/video-mux.c +@@ -362,7 +362,7 @@ static int video_mux_async_register(struct video_mux *vmux, + + for (i = 0; i < num_input_pads; i++) { + struct v4l2_async_subdev *asd; +- struct fwnode_handle *ep; ++ struct fwnode_handle *ep, *remote_ep; + + ep = fwnode_graph_get_endpoint_by_id( + dev_fwnode(vmux->subdev.dev), i, 0, +@@ -370,6 +370,14 @@ static int video_mux_async_register(struct video_mux *vmux, + if (!ep) + continue; + ++ /* Skip dangling endpoints for backwards compatibility */ ++ remote_ep = fwnode_graph_get_remote_endpoint(ep); ++ if (!remote_ep) { ++ fwnode_handle_put(ep); ++ continue; ++ } ++ fwnode_handle_put(remote_ep); ++ + asd = v4l2_async_notifier_add_fwnode_remote_subdev( + &vmux->notifier, ep, struct v4l2_async_subdev); + +diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c +index a8a72d5fbd129..caefac07af927 100644 +--- a/drivers/media/usb/au0828/au0828-core.c ++++ b/drivers/media/usb/au0828/au0828-core.c +@@ -199,8 +199,8 @@ static int au0828_media_device_init(struct au0828_dev *dev, + struct media_device *mdev; + + mdev = media_device_usb_allocate(udev, KBUILD_MODNAME, THIS_MODULE); +- if (!mdev) +- return -ENOMEM; ++ if (IS_ERR(mdev)) ++ return PTR_ERR(mdev); + + dev->media_dev = mdev; + #endif +diff --git a/drivers/media/usb/cpia2/cpia2.h b/drivers/media/usb/cpia2/cpia2.h +index 50835f5f7512c..57b7f1ea68da5 100644 +--- a/drivers/media/usb/cpia2/cpia2.h ++++ b/drivers/media/usb/cpia2/cpia2.h +@@ -429,6 +429,7 @@ int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd); + int cpia2_do_command(struct camera_data *cam, + unsigned int command, + unsigned char direction, unsigned char param); ++void cpia2_deinit_camera_struct(struct camera_data *cam, struct usb_interface *intf); + struct camera_data *cpia2_init_camera_struct(struct usb_interface *intf); + int cpia2_init_camera(struct camera_data *cam); + int cpia2_allocate_buffers(struct camera_data *cam); +diff --git a/drivers/media/usb/cpia2/cpia2_core.c b/drivers/media/usb/cpia2/cpia2_core.c +index e747548ab2869..b5a2d06fb356b 100644 +--- a/drivers/media/usb/cpia2/cpia2_core.c ++++ b/drivers/media/usb/cpia2/cpia2_core.c +@@ -2163,6 +2163,18 @@ static void reset_camera_struct(struct camera_data *cam) + cam->height = cam->params.roi.height; + } + ++/****************************************************************************** ++ * ++ * cpia2_init_camera_struct ++ * ++ * Deinitialize camera struct ++ *****************************************************************************/ ++void cpia2_deinit_camera_struct(struct camera_data *cam, struct usb_interface *intf) ++{ ++ v4l2_device_unregister(&cam->v4l2_dev); ++ kfree(cam); ++} ++ + /****************************************************************************** + * + * cpia2_init_camera_struct +diff --git a/drivers/media/usb/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c +index 3ab80a7b44985..76aac06f9fb8e 100644 +--- a/drivers/media/usb/cpia2/cpia2_usb.c ++++ b/drivers/media/usb/cpia2/cpia2_usb.c +@@ -844,15 +844,13 @@ static int cpia2_usb_probe(struct usb_interface *intf, + ret = set_alternate(cam, USBIF_CMDONLY); + if (ret < 0) { + ERR("%s: usb_set_interface error (ret = %d)\n", __func__, ret); +- kfree(cam); +- return ret; ++ goto alt_err; + } + + + if((ret = cpia2_init_camera(cam)) < 0) { + ERR("%s: failed to initialize cpia2 camera (ret = %d)\n", __func__, ret); +- kfree(cam); +- return ret; ++ goto alt_err; + } + LOG(" CPiA Version: %d.%02d (%d.%d)\n", + cam->params.version.firmware_revision_hi, +@@ -872,11 +870,14 @@ static int cpia2_usb_probe(struct usb_interface *intf, + ret = cpia2_register_camera(cam); + if (ret < 0) { + ERR("%s: Failed to register cpia2 camera (ret = %d)\n", __func__, ret); +- kfree(cam); +- return ret; ++ goto alt_err; + } + + return 0; ++ ++alt_err: ++ cpia2_deinit_camera_struct(cam, intf); ++ return ret; + } + + /****************************************************************************** +diff --git a/drivers/media/usb/dvb-usb/cinergyT2-core.c b/drivers/media/usb/dvb-usb/cinergyT2-core.c +index 969a7ec71dff7..4116ba5c45fcb 100644 +--- a/drivers/media/usb/dvb-usb/cinergyT2-core.c ++++ b/drivers/media/usb/dvb-usb/cinergyT2-core.c +@@ -78,6 +78,8 @@ static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap) + + ret = dvb_usb_generic_rw(d, st->data, 1, st->data, 3, 0); + if (ret < 0) { ++ if (adap->fe_adap[0].fe) ++ adap->fe_adap[0].fe->ops.release(adap->fe_adap[0].fe); + deb_rc("cinergyt2_power_ctrl() Failed to retrieve sleep state info\n"); + } + mutex_unlock(&d->data_mutex); +diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c +index 761992ad05e2a..7707de7bae7ca 100644 +--- a/drivers/media/usb/dvb-usb/cxusb.c ++++ b/drivers/media/usb/dvb-usb/cxusb.c +@@ -1947,7 +1947,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = { + + .size_of_priv = sizeof(struct cxusb_state), + +- .num_adapters = 2, ++ .num_adapters = 1, + .adapter = { + { + .num_frontends = 1, +diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c +index 5aa15a7a49def..59529cbf9cd0b 100644 +--- a/drivers/media/usb/em28xx/em28xx-input.c ++++ b/drivers/media/usb/em28xx/em28xx-input.c +@@ -720,7 +720,8 @@ static int em28xx_ir_init(struct em28xx *dev) + dev->board.has_ir_i2c = 0; + dev_warn(&dev->intf->dev, + "No i2c IR remote control device found.\n"); +- return -ENODEV; ++ err = -ENODEV; ++ goto ref_put; + } + } + +@@ -735,7 +736,7 @@ static int em28xx_ir_init(struct em28xx *dev) + + ir = kzalloc(sizeof(*ir), GFP_KERNEL); + if (!ir) +- return -ENOMEM; ++ goto ref_put; + rc = rc_allocate_device(RC_DRIVER_SCANCODE); + if (!rc) + goto error; +@@ -839,6 +840,9 @@ error: + dev->ir = NULL; + rc_free_device(rc); + kfree(ir); ++ref_put: ++ em28xx_shutdown_buttons(dev); ++ kref_put(&dev->ref, em28xx_free_device); + return err; + } + +diff --git a/drivers/media/usb/gspca/gl860/gl860.c b/drivers/media/usb/gspca/gl860/gl860.c +index 2c05ea2598e76..ce4ee8bc75c85 100644 +--- a/drivers/media/usb/gspca/gl860/gl860.c ++++ b/drivers/media/usb/gspca/gl860/gl860.c +@@ -561,8 +561,8 @@ int gl860_RTx(struct gspca_dev *gspca_dev, + len, 400 + 200 * (len > 1)); + memcpy(pdata, gspca_dev->usb_buf, len); + } else { +- r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), +- req, pref, val, index, NULL, len, 400); ++ gspca_err(gspca_dev, "zero-length read request\n"); ++ r = -EINVAL; + } + } + +diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +index f4a727918e352..d38dee1792e41 100644 +--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c ++++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +@@ -2676,9 +2676,8 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw) + pvr2_stream_destroy(hdw->vid_stream); + hdw->vid_stream = NULL; + } +- pvr2_i2c_core_done(hdw); + v4l2_device_unregister(&hdw->v4l2_dev); +- pvr2_hdw_remove_usb_stuff(hdw); ++ pvr2_hdw_disconnect(hdw); + mutex_lock(&pvr2_unit_mtx); + do { + if ((hdw->unit_number >= 0) && +@@ -2705,6 +2704,7 @@ void pvr2_hdw_disconnect(struct pvr2_hdw *hdw) + { + pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw); + LOCK_TAKE(hdw->big_lock); ++ pvr2_i2c_core_done(hdw); + LOCK_TAKE(hdw->ctl_lock); + pvr2_hdw_remove_usb_stuff(hdw); + LOCK_GIVE(hdw->ctl_lock); +diff --git a/drivers/media/v4l2-core/v4l2-fh.c b/drivers/media/v4l2-core/v4l2-fh.c +index 684574f58e82d..90eec79ee995a 100644 +--- a/drivers/media/v4l2-core/v4l2-fh.c ++++ b/drivers/media/v4l2-core/v4l2-fh.c +@@ -96,6 +96,7 @@ int v4l2_fh_release(struct file *filp) + v4l2_fh_del(fh); + v4l2_fh_exit(fh); + kfree(fh); ++ filp->private_data = NULL; + } + return 0; + } +diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c +index 2673f51aafa4d..07d823656ee65 100644 +--- a/drivers/media/v4l2-core/v4l2-ioctl.c ++++ b/drivers/media/v4l2-core/v4l2-ioctl.c +@@ -3072,8 +3072,8 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size, + + static unsigned int video_translate_cmd(unsigned int cmd) + { ++#if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME) + switch (cmd) { +-#ifdef CONFIG_COMPAT_32BIT_TIME + case VIDIOC_DQEVENT_TIME32: + return VIDIOC_DQEVENT; + case VIDIOC_QUERYBUF_TIME32: +@@ -3084,8 +3084,8 @@ static unsigned int video_translate_cmd(unsigned int cmd) + return VIDIOC_DQBUF; + case VIDIOC_PREPARE_BUF_TIME32: + return VIDIOC_PREPARE_BUF; +-#endif + } ++#endif + if (in_compat_syscall()) + return v4l2_compat_translate_cmd(cmd); + +@@ -3126,8 +3126,8 @@ static int video_get_user(void __user *arg, void *parg, + } else if (in_compat_syscall()) { + err = v4l2_compat_get_user(arg, parg, cmd); + } else { ++#if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME) + switch (cmd) { +-#ifdef CONFIG_COMPAT_32BIT_TIME + case VIDIOC_QUERYBUF_TIME32: + case VIDIOC_QBUF_TIME32: + case VIDIOC_DQBUF_TIME32: +@@ -3155,8 +3155,8 @@ static int video_get_user(void __user *arg, void *parg, + }; + break; + } +-#endif + } ++#endif + } + + /* zero out anything we don't copy from userspace */ +@@ -3181,8 +3181,8 @@ static int video_put_user(void __user *arg, void *parg, + if (in_compat_syscall()) + return v4l2_compat_put_user(arg, parg, cmd); + ++#if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME) + switch (cmd) { +-#ifdef CONFIG_COMPAT_32BIT_TIME + case VIDIOC_DQEVENT_TIME32: { + struct v4l2_event *ev = parg; + struct v4l2_event_time32 ev32; +@@ -3230,8 +3230,8 @@ static int video_put_user(void __user *arg, void *parg, + return -EFAULT; + break; + } +-#endif + } ++#endif + + return 0; + } +diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c +index 956dafab43d49..bf3aa92524584 100644 +--- a/drivers/media/v4l2-core/v4l2-subdev.c ++++ b/drivers/media/v4l2-core/v4l2-subdev.c +@@ -428,30 +428,6 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) + + return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK); + +- case VIDIOC_DQEVENT_TIME32: { +- struct v4l2_event_time32 *ev32 = arg; +- struct v4l2_event ev = { }; +- +- if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)) +- return -ENOIOCTLCMD; +- +- rval = v4l2_event_dequeue(vfh, &ev, file->f_flags & O_NONBLOCK); +- +- *ev32 = (struct v4l2_event_time32) { +- .type = ev.type, +- .pending = ev.pending, +- .sequence = ev.sequence, +- .timestamp.tv_sec = ev.timestamp.tv_sec, +- .timestamp.tv_nsec = ev.timestamp.tv_nsec, +- .id = ev.id, +- }; +- +- memcpy(&ev32->u, &ev.u, sizeof(ev.u)); +- memcpy(&ev32->reserved, &ev.reserved, sizeof(ev.reserved)); +- +- return rval; +- } +- + case VIDIOC_SUBSCRIBE_EVENT: + return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg); + +diff --git a/drivers/memstick/host/rtsx_usb_ms.c b/drivers/memstick/host/rtsx_usb_ms.c +index 102dbb8080da5..29271ad4728a2 100644 +--- a/drivers/memstick/host/rtsx_usb_ms.c ++++ b/drivers/memstick/host/rtsx_usb_ms.c +@@ -799,9 +799,9 @@ static int rtsx_usb_ms_drv_probe(struct platform_device *pdev) + + return 0; + err_out: +- memstick_free_host(msh); + pm_runtime_disable(ms_dev(host)); + pm_runtime_put_noidle(ms_dev(host)); ++ memstick_free_host(msh); + return err; + } + +@@ -828,9 +828,6 @@ static int rtsx_usb_ms_drv_remove(struct platform_device *pdev) + } + mutex_unlock(&host->host_mutex); + +- memstick_remove_host(msh); +- memstick_free_host(msh); +- + /* Balance possible unbalanced usage count + * e.g. unconditional module removal + */ +@@ -838,10 +835,11 @@ static int rtsx_usb_ms_drv_remove(struct platform_device *pdev) + pm_runtime_put(ms_dev(host)); + + pm_runtime_disable(ms_dev(host)); +- platform_set_drvdata(pdev, NULL); +- ++ memstick_remove_host(msh); + dev_dbg(ms_dev(host), + ": Realtek USB Memstick controller has been removed\n"); ++ memstick_free_host(msh); ++ platform_set_drvdata(pdev, NULL); + + return 0; + } +diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig +index 5c7f2b1001911..5c408c1dc58ce 100644 +--- a/drivers/mfd/Kconfig ++++ b/drivers/mfd/Kconfig +@@ -465,6 +465,7 @@ config MFD_MP2629 + tristate "Monolithic Power Systems MP2629 ADC and Battery charger" + depends on I2C + select REGMAP_I2C ++ select MFD_CORE + help + Select this option to enable support for Monolithic Power Systems + battery charger. This provides ADC, thermal and battery charger power +diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c +index 6f02b8022c6d5..79f5c6a18815a 100644 +--- a/drivers/mfd/mfd-core.c ++++ b/drivers/mfd/mfd-core.c +@@ -266,18 +266,18 @@ static int mfd_add_device(struct device *parent, int id, + if (has_acpi_companion(&pdev->dev)) { + ret = acpi_check_resource_conflict(&res[r]); + if (ret) +- goto fail_of_entry; ++ goto fail_res_conflict; + } + } + } + + ret = platform_device_add_resources(pdev, res, cell->num_resources); + if (ret) +- goto fail_of_entry; ++ goto fail_res_conflict; + + ret = platform_device_add(pdev); + if (ret) +- goto fail_of_entry; ++ goto fail_res_conflict; + + if (cell->pm_runtime_no_callbacks) + pm_runtime_no_callbacks(&pdev->dev); +@@ -286,13 +286,15 @@ static int mfd_add_device(struct device *parent, int id, + + return 0; + ++fail_res_conflict: ++ if (cell->swnode) ++ device_remove_software_node(&pdev->dev); + fail_of_entry: + list_for_each_entry_safe(of_entry, tmp, &mfd_of_node_list, list) + if (of_entry->dev == &pdev->dev) { + list_del(&of_entry->list); + kfree(of_entry); + } +- device_remove_software_node(&pdev->dev); + fail_alias: + regulator_bulk_unregister_supply_alias(&pdev->dev, + cell->parent_supplies, +@@ -358,11 +360,12 @@ static int mfd_remove_devices_fn(struct device *dev, void *data) + if (level && cell->level > *level) + return 0; + ++ if (cell->swnode) ++ device_remove_software_node(&pdev->dev); ++ + regulator_bulk_unregister_supply_alias(dev, cell->parent_supplies, + cell->num_parent_supplies); + +- device_remove_software_node(&pdev->dev); +- + platform_device_unregister(pdev); + return 0; + } +diff --git a/drivers/mfd/rn5t618.c b/drivers/mfd/rn5t618.c +index 6ed04e6dbc783..384acb4594272 100644 +--- a/drivers/mfd/rn5t618.c ++++ b/drivers/mfd/rn5t618.c +@@ -107,7 +107,7 @@ static int rn5t618_irq_init(struct rn5t618 *rn5t618) + + ret = devm_regmap_add_irq_chip(rn5t618->dev, rn5t618->regmap, + rn5t618->irq, +- IRQF_TRIGGER_FALLING | IRQF_ONESHOT, ++ IRQF_TRIGGER_LOW | IRQF_ONESHOT, + 0, irq_chip, &rn5t618->irq_data); + if (ret) + dev_err(rn5t618->dev, "Failed to register IRQ chip\n"); +diff --git a/drivers/misc/eeprom/idt_89hpesx.c b/drivers/misc/eeprom/idt_89hpesx.c +index 81c70e5bc168f..3e4a594c110b3 100644 +--- a/drivers/misc/eeprom/idt_89hpesx.c ++++ b/drivers/misc/eeprom/idt_89hpesx.c +@@ -1126,11 +1126,10 @@ static void idt_get_fw_data(struct idt_89hpesx_dev *pdev) + + device_for_each_child_node(dev, fwnode) { + ee_id = idt_ee_match_id(fwnode); +- if (!ee_id) { +- dev_warn(dev, "Skip unsupported EEPROM device"); +- continue; +- } else ++ if (ee_id) + break; ++ ++ dev_warn(dev, "Skip unsupported EEPROM device %pfw\n", fwnode); + } + + /* If there is no fwnode EEPROM device, then set zero size */ +@@ -1161,6 +1160,7 @@ static void idt_get_fw_data(struct idt_89hpesx_dev *pdev) + else /* if (!fwnode_property_read_bool(node, "read-only")) */ + pdev->eero = false; + ++ fwnode_handle_put(fwnode); + dev_info(dev, "EEPROM of %d bytes found by 0x%x", + pdev->eesize, pdev->eeaddr); + } +diff --git a/drivers/misc/habanalabs/common/habanalabs_drv.c b/drivers/misc/habanalabs/common/habanalabs_drv.c +index 64d1530db9854..d15b912a347bd 100644 +--- a/drivers/misc/habanalabs/common/habanalabs_drv.c ++++ b/drivers/misc/habanalabs/common/habanalabs_drv.c +@@ -464,6 +464,7 @@ static int hl_pci_probe(struct pci_dev *pdev, + return 0; + + disable_device: ++ pci_disable_pcie_error_reporting(pdev); + pci_set_drvdata(pdev, NULL); + destroy_hdev(hdev); + +diff --git a/drivers/misc/pvpanic/pvpanic-mmio.c b/drivers/misc/pvpanic/pvpanic-mmio.c +index 4c08417760874..69b31f7adf4f1 100644 +--- a/drivers/misc/pvpanic/pvpanic-mmio.c ++++ b/drivers/misc/pvpanic/pvpanic-mmio.c +@@ -93,7 +93,7 @@ static int pvpanic_mmio_probe(struct platform_device *pdev) + return -EINVAL; + } + +- pi = kmalloc(sizeof(*pi), GFP_ATOMIC); ++ pi = devm_kmalloc(dev, sizeof(*pi), GFP_ATOMIC); + if (!pi) + return -ENOMEM; + +@@ -114,7 +114,6 @@ static int pvpanic_mmio_remove(struct platform_device *pdev) + struct pvpanic_instance *pi = dev_get_drvdata(&pdev->dev); + + pvpanic_remove(pi); +- kfree(pi); + + return 0; + } +diff --git a/drivers/misc/pvpanic/pvpanic-pci.c b/drivers/misc/pvpanic/pvpanic-pci.c +index 9ecc4e8559d5d..046ce4ecc1959 100644 +--- a/drivers/misc/pvpanic/pvpanic-pci.c ++++ b/drivers/misc/pvpanic/pvpanic-pci.c +@@ -78,15 +78,15 @@ static int pvpanic_pci_probe(struct pci_dev *pdev, + void __iomem *base; + int ret; + +- ret = pci_enable_device(pdev); ++ ret = pcim_enable_device(pdev); + if (ret < 0) + return ret; + +- base = pci_iomap(pdev, 0, 0); ++ base = pcim_iomap(pdev, 0, 0); + if (!base) + return -ENOMEM; + +- pi = kmalloc(sizeof(*pi), GFP_ATOMIC); ++ pi = devm_kmalloc(&pdev->dev, sizeof(*pi), GFP_ATOMIC); + if (!pi) + return -ENOMEM; + +@@ -107,9 +107,6 @@ static void pvpanic_pci_remove(struct pci_dev *pdev) + struct pvpanic_instance *pi = dev_get_drvdata(&pdev->dev); + + pvpanic_remove(pi); +- iounmap(pi->base); +- kfree(pi); +- pci_disable_device(pdev); + } + + static struct pci_driver pvpanic_pci_driver = { +diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c +index 689eb9afeeed1..2518bc0856596 100644 +--- a/drivers/mmc/core/block.c ++++ b/drivers/mmc/core/block.c +@@ -1004,6 +1004,12 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, struct request *req) + + switch (mq_rq->drv_op) { + case MMC_DRV_OP_IOCTL: ++ if (card->ext_csd.cmdq_en) { ++ ret = mmc_cmdq_disable(card); ++ if (ret) ++ break; ++ } ++ fallthrough; + case MMC_DRV_OP_IOCTL_RPMB: + idata = mq_rq->drv_op_data; + for (i = 0, ret = 0; i < mq_rq->ioc_count; i++) { +@@ -1014,6 +1020,8 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, struct request *req) + /* Always switch back to main area after RPMB access */ + if (rpmb_ioctl) + mmc_blk_part_switch(card, 0); ++ else if (card->reenable_cmdq && !card->ext_csd.cmdq_en) ++ mmc_cmdq_enable(card); + break; + case MMC_DRV_OP_BOOT_WP: + ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, +diff --git a/drivers/mmc/host/sdhci-of-aspeed.c b/drivers/mmc/host/sdhci-of-aspeed.c +index d001c51074a06..e4665a438ec56 100644 +--- a/drivers/mmc/host/sdhci-of-aspeed.c ++++ b/drivers/mmc/host/sdhci-of-aspeed.c +@@ -150,7 +150,7 @@ static int aspeed_sdhci_phase_to_tap(struct device *dev, unsigned long rate_hz, + + tap = div_u64(phase_period_ps, prop_delay_ps); + if (tap > ASPEED_SDHCI_NR_TAPS) { +- dev_warn(dev, ++ dev_dbg(dev, + "Requested out of range phase tap %d for %d degrees of phase compensation at %luHz, clamping to tap %d\n", + tap, phase_deg, rate_hz, ASPEED_SDHCI_NR_TAPS); + tap = ASPEED_SDHCI_NR_TAPS; +diff --git a/drivers/mmc/host/sdhci-sprd.c b/drivers/mmc/host/sdhci-sprd.c +index 5dc36efff47ff..11e375579cfb9 100644 +--- a/drivers/mmc/host/sdhci-sprd.c ++++ b/drivers/mmc/host/sdhci-sprd.c +@@ -393,6 +393,7 @@ static void sdhci_sprd_request_done(struct sdhci_host *host, + static struct sdhci_ops sdhci_sprd_ops = { + .read_l = sdhci_sprd_readl, + .write_l = sdhci_sprd_writel, ++ .write_w = sdhci_sprd_writew, + .write_b = sdhci_sprd_writeb, + .set_clock = sdhci_sprd_set_clock, + .get_max_clock = sdhci_sprd_get_max_clock, +diff --git a/drivers/mmc/host/usdhi6rol0.c b/drivers/mmc/host/usdhi6rol0.c +index 615f3d008af1e..b9b79b1089a00 100644 +--- a/drivers/mmc/host/usdhi6rol0.c ++++ b/drivers/mmc/host/usdhi6rol0.c +@@ -1801,6 +1801,7 @@ static int usdhi6_probe(struct platform_device *pdev) + + version = usdhi6_read(host, USDHI6_VERSION); + if ((version & 0xfff) != 0xa0d) { ++ ret = -EPERM; + dev_err(dev, "Version not recognized %x\n", version); + goto e_clk_off; + } +diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c +index a1d0985600990..c32df5530b943 100644 +--- a/drivers/mmc/host/via-sdmmc.c ++++ b/drivers/mmc/host/via-sdmmc.c +@@ -857,6 +857,9 @@ static void via_sdc_data_isr(struct via_crdr_mmc_host *host, u16 intmask) + { + BUG_ON(intmask == 0); + ++ if (!host->data) ++ return; ++ + if (intmask & VIA_CRDR_SDSTS_DT) + host->data->error = -ETIMEDOUT; + else if (intmask & (VIA_CRDR_SDSTS_RC | VIA_CRDR_SDSTS_WC)) +diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c +index 739cf63ef6e2f..4950d10d3a191 100644 +--- a/drivers/mmc/host/vub300.c ++++ b/drivers/mmc/host/vub300.c +@@ -2279,7 +2279,7 @@ static int vub300_probe(struct usb_interface *interface, + if (retval < 0) + goto error5; + retval = +- usb_control_msg(vub300->udev, usb_rcvctrlpipe(vub300->udev, 0), ++ usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0), + SET_ROM_WAIT_STATES, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + firmware_rom_wait_states, 0x0000, NULL, 0, HZ); +diff --git a/drivers/mtd/nand/raw/arasan-nand-controller.c b/drivers/mtd/nand/raw/arasan-nand-controller.c +index 549aac00228eb..390f8d719c258 100644 +--- a/drivers/mtd/nand/raw/arasan-nand-controller.c ++++ b/drivers/mtd/nand/raw/arasan-nand-controller.c +@@ -273,6 +273,37 @@ static int anfc_pkt_len_config(unsigned int len, unsigned int *steps, + return 0; + } + ++static int anfc_select_target(struct nand_chip *chip, int target) ++{ ++ struct anand *anand = to_anand(chip); ++ struct arasan_nfc *nfc = to_anfc(chip->controller); ++ int ret; ++ ++ /* Update the controller timings and the potential ECC configuration */ ++ writel_relaxed(anand->timings, nfc->base + DATA_INTERFACE_REG); ++ ++ /* Update clock frequency */ ++ if (nfc->cur_clk != anand->clk) { ++ clk_disable_unprepare(nfc->controller_clk); ++ ret = clk_set_rate(nfc->controller_clk, anand->clk); ++ if (ret) { ++ dev_err(nfc->dev, "Failed to change clock rate\n"); ++ return ret; ++ } ++ ++ ret = clk_prepare_enable(nfc->controller_clk); ++ if (ret) { ++ dev_err(nfc->dev, ++ "Failed to re-enable the controller clock\n"); ++ return ret; ++ } ++ ++ nfc->cur_clk = anand->clk; ++ } ++ ++ return 0; ++} ++ + /* + * When using the embedded hardware ECC engine, the controller is in charge of + * feeding the engine with, first, the ECC residue present in the data array. +@@ -401,6 +432,18 @@ static int anfc_read_page_hw_ecc(struct nand_chip *chip, u8 *buf, + return 0; + } + ++static int anfc_sel_read_page_hw_ecc(struct nand_chip *chip, u8 *buf, ++ int oob_required, int page) ++{ ++ int ret; ++ ++ ret = anfc_select_target(chip, chip->cur_cs); ++ if (ret) ++ return ret; ++ ++ return anfc_read_page_hw_ecc(chip, buf, oob_required, page); ++}; ++ + static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf, + int oob_required, int page) + { +@@ -461,6 +504,18 @@ static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf, + return ret; + } + ++static int anfc_sel_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf, ++ int oob_required, int page) ++{ ++ int ret; ++ ++ ret = anfc_select_target(chip, chip->cur_cs); ++ if (ret) ++ return ret; ++ ++ return anfc_write_page_hw_ecc(chip, buf, oob_required, page); ++}; ++ + /* NAND framework ->exec_op() hooks and related helpers */ + static int anfc_parse_instructions(struct nand_chip *chip, + const struct nand_subop *subop, +@@ -753,37 +808,6 @@ static const struct nand_op_parser anfc_op_parser = NAND_OP_PARSER( + NAND_OP_PARSER_PAT_WAITRDY_ELEM(false)), + ); + +-static int anfc_select_target(struct nand_chip *chip, int target) +-{ +- struct anand *anand = to_anand(chip); +- struct arasan_nfc *nfc = to_anfc(chip->controller); +- int ret; +- +- /* Update the controller timings and the potential ECC configuration */ +- writel_relaxed(anand->timings, nfc->base + DATA_INTERFACE_REG); +- +- /* Update clock frequency */ +- if (nfc->cur_clk != anand->clk) { +- clk_disable_unprepare(nfc->controller_clk); +- ret = clk_set_rate(nfc->controller_clk, anand->clk); +- if (ret) { +- dev_err(nfc->dev, "Failed to change clock rate\n"); +- return ret; +- } +- +- ret = clk_prepare_enable(nfc->controller_clk); +- if (ret) { +- dev_err(nfc->dev, +- "Failed to re-enable the controller clock\n"); +- return ret; +- } +- +- nfc->cur_clk = anand->clk; +- } +- +- return 0; +-} +- + static int anfc_check_op(struct nand_chip *chip, + const struct nand_operation *op) + { +@@ -1007,8 +1031,8 @@ static int anfc_init_hw_ecc_controller(struct arasan_nfc *nfc, + if (!anand->bch) + return -EINVAL; + +- ecc->read_page = anfc_read_page_hw_ecc; +- ecc->write_page = anfc_write_page_hw_ecc; ++ ecc->read_page = anfc_sel_read_page_hw_ecc; ++ ecc->write_page = anfc_sel_write_page_hw_ecc; + + return 0; + } +diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c +index 79da6b02e2095..f83525a1ab0e6 100644 +--- a/drivers/mtd/nand/raw/marvell_nand.c ++++ b/drivers/mtd/nand/raw/marvell_nand.c +@@ -3030,8 +3030,10 @@ static int __maybe_unused marvell_nfc_resume(struct device *dev) + return ret; + + ret = clk_prepare_enable(nfc->reg_clk); +- if (ret < 0) ++ if (ret < 0) { ++ clk_disable_unprepare(nfc->core_clk); + return ret; ++ } + + /* + * Reset nfc->selected_chip so the next command will cause the timing +diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c +index 17f63f95f4a28..54ae540bc66b4 100644 +--- a/drivers/mtd/nand/spi/core.c ++++ b/drivers/mtd/nand/spi/core.c +@@ -290,6 +290,8 @@ static int spinand_ondie_ecc_finish_io_req(struct nand_device *nand, + { + struct spinand_ondie_ecc_conf *engine_conf = nand->ecc.ctx.priv; + struct spinand_device *spinand = nand_to_spinand(nand); ++ struct mtd_info *mtd = spinand_to_mtd(spinand); ++ int ret; + + if (req->mode == MTD_OPS_RAW) + return 0; +@@ -299,7 +301,13 @@ static int spinand_ondie_ecc_finish_io_req(struct nand_device *nand, + return 0; + + /* Finish a page write: check the status, report errors/bitflips */ +- return spinand_check_ecc_status(spinand, engine_conf->status); ++ ret = spinand_check_ecc_status(spinand, engine_conf->status); ++ if (ret == -EBADMSG) ++ mtd->ecc_stats.failed++; ++ else if (ret > 0) ++ mtd->ecc_stats.corrected += ret; ++ ++ return ret; + } + + static struct nand_ecc_engine_ops spinand_ondie_ecc_engine_ops = { +@@ -620,13 +628,10 @@ static int spinand_mtd_read(struct mtd_info *mtd, loff_t from, + if (ret < 0 && ret != -EBADMSG) + break; + +- if (ret == -EBADMSG) { ++ if (ret == -EBADMSG) + ecc_failed = true; +- mtd->ecc_stats.failed++; +- } else { +- mtd->ecc_stats.corrected += ret; ++ else + max_bitflips = max_t(unsigned int, max_bitflips, ret); +- } + + ret = 0; + ops->retlen += iter.req.datalen; +diff --git a/drivers/mtd/parsers/qcomsmempart.c b/drivers/mtd/parsers/qcomsmempart.c +index d9083308f6ba6..06a818cd2433f 100644 +--- a/drivers/mtd/parsers/qcomsmempart.c ++++ b/drivers/mtd/parsers/qcomsmempart.c +@@ -159,6 +159,15 @@ out_free_parts: + return ret; + } + ++static void parse_qcomsmem_cleanup(const struct mtd_partition *pparts, ++ int nr_parts) ++{ ++ int i; ++ ++ for (i = 0; i < nr_parts; i++) ++ kfree(pparts[i].name); ++} ++ + static const struct of_device_id qcomsmem_of_match_table[] = { + { .compatible = "qcom,smem-part" }, + {}, +@@ -167,6 +176,7 @@ MODULE_DEVICE_TABLE(of, qcomsmem_of_match_table); + + static struct mtd_part_parser mtd_parser_qcomsmem = { + .parse_fn = parse_qcomsmem_part, ++ .cleanup = parse_qcomsmem_cleanup, + .name = "qcomsmem", + .of_match_table = qcomsmem_of_match_table, + }; +diff --git a/drivers/mtd/parsers/redboot.c b/drivers/mtd/parsers/redboot.c +index 91146bdc47132..3ccd6363ee8cb 100644 +--- a/drivers/mtd/parsers/redboot.c ++++ b/drivers/mtd/parsers/redboot.c +@@ -45,6 +45,7 @@ static inline int redboot_checksum(struct fis_image_desc *img) + static void parse_redboot_of(struct mtd_info *master) + { + struct device_node *np; ++ struct device_node *npart; + u32 dirblock; + int ret; + +@@ -52,7 +53,11 @@ static void parse_redboot_of(struct mtd_info *master) + if (!np) + return; + +- ret = of_property_read_u32(np, "fis-index-block", &dirblock); ++ npart = of_get_child_by_name(np, "partitions"); ++ if (!npart) ++ return; ++ ++ ret = of_property_read_u32(npart, "fis-index-block", &dirblock); + if (ret) + return; + +diff --git a/drivers/mtd/spi-nor/otp.c b/drivers/mtd/spi-nor/otp.c +index fcf38d2603450..d8e68120a4b11 100644 +--- a/drivers/mtd/spi-nor/otp.c ++++ b/drivers/mtd/spi-nor/otp.c +@@ -40,7 +40,6 @@ int spi_nor_otp_read_secr(struct spi_nor *nor, loff_t addr, size_t len, u8 *buf) + rdesc = nor->dirmap.rdesc; + + nor->read_opcode = SPINOR_OP_RSECR; +- nor->addr_width = 3; + nor->read_dummy = 8; + nor->read_proto = SNOR_PROTO_1_1_1; + nor->dirmap.rdesc = NULL; +@@ -84,7 +83,6 @@ int spi_nor_otp_write_secr(struct spi_nor *nor, loff_t addr, size_t len, + wdesc = nor->dirmap.wdesc; + + nor->program_opcode = SPINOR_OP_PSECR; +- nor->addr_width = 3; + nor->write_proto = SNOR_PROTO_1_1_1; + nor->dirmap.wdesc = NULL; + +@@ -240,6 +238,29 @@ out: + return ret; + } + ++static int spi_nor_mtd_otp_range_is_locked(struct spi_nor *nor, loff_t ofs, ++ size_t len) ++{ ++ const struct spi_nor_otp_ops *ops = nor->params->otp.ops; ++ unsigned int region; ++ int locked; ++ ++ /* ++ * If any of the affected OTP regions are locked the entire range is ++ * considered locked. ++ */ ++ for (region = spi_nor_otp_offset_to_region(nor, ofs); ++ region <= spi_nor_otp_offset_to_region(nor, ofs + len - 1); ++ region++) { ++ locked = ops->is_locked(nor, region); ++ /* take the branch it is locked or in case of an error */ ++ if (locked) ++ return locked; ++ } ++ ++ return 0; ++} ++ + static int spi_nor_mtd_otp_read_write(struct mtd_info *mtd, loff_t ofs, + size_t total_len, size_t *retlen, + const u8 *buf, bool is_write) +@@ -255,14 +276,26 @@ static int spi_nor_mtd_otp_read_write(struct mtd_info *mtd, loff_t ofs, + if (ofs < 0 || ofs >= spi_nor_otp_size(nor)) + return 0; + ++ /* don't access beyond the end */ ++ total_len = min_t(size_t, total_len, spi_nor_otp_size(nor) - ofs); ++ ++ if (!total_len) ++ return 0; ++ + ret = spi_nor_lock_and_prep(nor); + if (ret) + return ret; + +- /* don't access beyond the end */ +- total_len = min_t(size_t, total_len, spi_nor_otp_size(nor) - ofs); ++ if (is_write) { ++ ret = spi_nor_mtd_otp_range_is_locked(nor, ofs, total_len); ++ if (ret < 0) { ++ goto out; ++ } else if (ret) { ++ ret = -EROFS; ++ goto out; ++ } ++ } + +- *retlen = 0; + while (total_len) { + /* + * The OTP regions are mapped into a contiguous area starting +diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig +index 74dc8e249faa3..9b12a8e110f43 100644 +--- a/drivers/net/Kconfig ++++ b/drivers/net/Kconfig +@@ -431,6 +431,7 @@ config VSOCKMON + config MHI_NET + tristate "MHI network driver" + depends on MHI_BUS ++ select WWAN + help + This is the network driver for MHI bus. It can be used with + QCOM based WWAN modems (like SDX55). Say Y or M. +diff --git a/drivers/net/can/peak_canfd/peak_canfd.c b/drivers/net/can/peak_canfd/peak_canfd.c +index 00847cbaf7b62..d08718e98e110 100644 +--- a/drivers/net/can/peak_canfd/peak_canfd.c ++++ b/drivers/net/can/peak_canfd/peak_canfd.c +@@ -351,8 +351,8 @@ static int pucan_handle_status(struct peak_canfd_priv *priv, + return err; + } + +- /* start network queue (echo_skb array is empty) */ +- netif_start_queue(ndev); ++ /* wake network queue up (echo_skb array is empty) */ ++ netif_wake_queue(ndev); + + return 0; + } +diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c +index 5af69787d9d5d..0a37af4a3fa40 100644 +--- a/drivers/net/can/usb/ems_usb.c ++++ b/drivers/net/can/usb/ems_usb.c +@@ -1053,7 +1053,6 @@ static void ems_usb_disconnect(struct usb_interface *intf) + + if (dev) { + unregister_netdev(dev->netdev); +- free_candev(dev->netdev); + + unlink_all_urbs(dev); + +@@ -1061,6 +1060,8 @@ static void ems_usb_disconnect(struct usb_interface *intf) + + kfree(dev->intr_in_buffer); + kfree(dev->tx_msg_buffer); ++ ++ free_candev(dev->netdev); + } + } + +diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c +index eca285aaf72f8..961fa6b75cad8 100644 +--- a/drivers/net/dsa/mv88e6xxx/chip.c ++++ b/drivers/net/dsa/mv88e6xxx/chip.c +@@ -1618,9 +1618,6 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port, + struct mv88e6xxx_vtu_entry vlan; + int i, err; + +- if (!vid) +- return -EOPNOTSUPP; +- + /* DSA and CPU ports have to be members of multiple vlans */ + if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port)) + return 0; +@@ -2109,6 +2106,9 @@ static int mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, + u8 member; + int err; + ++ if (!vlan->vid) ++ return 0; ++ + err = mv88e6xxx_port_vlan_prepare(ds, port, vlan); + if (err) + return err; +diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c +index b88d9ef45a1f1..ebe4d33cda276 100644 +--- a/drivers/net/dsa/sja1105/sja1105_main.c ++++ b/drivers/net/dsa/sja1105/sja1105_main.c +@@ -1798,6 +1798,12 @@ static int sja1105_reload_cbs(struct sja1105_private *priv) + { + int rc = 0, i; + ++ /* The credit based shapers are only allocated if ++ * CONFIG_NET_SCH_CBS is enabled. ++ */ ++ if (!priv->cbs) ++ return 0; ++ + for (i = 0; i < priv->info->num_cbs_shapers; i++) { + struct sja1105_cbs_entry *cbs = &priv->cbs[i]; + +diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c +index d77fafbc15301..c560ad06f0be3 100644 +--- a/drivers/net/ethernet/aeroflex/greth.c ++++ b/drivers/net/ethernet/aeroflex/greth.c +@@ -1539,10 +1539,11 @@ static int greth_of_remove(struct platform_device *of_dev) + mdiobus_unregister(greth->mdio); + + unregister_netdev(ndev); +- free_netdev(ndev); + + of_iounmap(&of_dev->resource[0], greth->regs, resource_size(&of_dev->resource[0])); + ++ free_netdev(ndev); ++ + return 0; + } + +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_macsec.h b/drivers/net/ethernet/aquantia/atlantic/aq_macsec.h +index f5fba8b8cdea9..a47e2710487ec 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_macsec.h ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_macsec.h +@@ -91,7 +91,7 @@ struct aq_macsec_txsc { + u32 hw_sc_idx; + unsigned long tx_sa_idx_busy; + const struct macsec_secy *sw_secy; +- u8 tx_sa_key[MACSEC_NUM_AN][MACSEC_KEYID_LEN]; ++ u8 tx_sa_key[MACSEC_NUM_AN][MACSEC_MAX_KEY_LEN]; + struct aq_macsec_tx_sc_stats stats; + struct aq_macsec_tx_sa_stats tx_sa_stats[MACSEC_NUM_AN]; + }; +@@ -101,7 +101,7 @@ struct aq_macsec_rxsc { + unsigned long rx_sa_idx_busy; + const struct macsec_secy *sw_secy; + const struct macsec_rx_sc *sw_rxsc; +- u8 rx_sa_key[MACSEC_NUM_AN][MACSEC_KEYID_LEN]; ++ u8 rx_sa_key[MACSEC_NUM_AN][MACSEC_MAX_KEY_LEN]; + struct aq_macsec_rx_sa_stats rx_sa_stats[MACSEC_NUM_AN]; + }; + +diff --git a/drivers/net/ethernet/broadcom/bcm4908_enet.c b/drivers/net/ethernet/broadcom/bcm4908_enet.c +index 60d908507f51d..02a569500234c 100644 +--- a/drivers/net/ethernet/broadcom/bcm4908_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c +@@ -174,9 +174,6 @@ static int bcm4908_dma_alloc_buf_descs(struct bcm4908_enet *enet, + if (!ring->slots) + goto err_free_buf_descs; + +- ring->read_idx = 0; +- ring->write_idx = 0; +- + return 0; + + err_free_buf_descs: +@@ -304,6 +301,9 @@ static void bcm4908_enet_dma_ring_init(struct bcm4908_enet *enet, + + enet_write(enet, ring->st_ram_block + ENET_DMA_CH_STATE_RAM_BASE_DESC_PTR, + (uint32_t)ring->dma_addr); ++ ++ ring->read_idx = 0; ++ ring->write_idx = 0; + } + + static void bcm4908_enet_dma_uninit(struct bcm4908_enet *enet) +diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +index fcca023f22e54..41f7f078cd27c 100644 +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +@@ -4296,3 +4296,4 @@ MODULE_AUTHOR("Broadcom Corporation"); + MODULE_DESCRIPTION("Broadcom GENET Ethernet controller driver"); + MODULE_ALIAS("platform:bcmgenet"); + MODULE_LICENSE("GPL"); ++MODULE_SOFTDEP("pre: mdio-bcm-unimac"); +diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c +index 701c12c9e0337..649c5c429bd7c 100644 +--- a/drivers/net/ethernet/emulex/benet/be_cmds.c ++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c +@@ -550,7 +550,7 @@ int be_process_mcc(struct be_adapter *adapter) + int num = 0, status = 0; + struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; + +- spin_lock_bh(&adapter->mcc_cq_lock); ++ spin_lock(&adapter->mcc_cq_lock); + + while ((compl = be_mcc_compl_get(adapter))) { + if (compl->flags & CQE_FLAGS_ASYNC_MASK) { +@@ -566,7 +566,7 @@ int be_process_mcc(struct be_adapter *adapter) + if (num) + be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num); + +- spin_unlock_bh(&adapter->mcc_cq_lock); ++ spin_unlock(&adapter->mcc_cq_lock); + return status; + } + +@@ -581,7 +581,9 @@ static int be_mcc_wait_compl(struct be_adapter *adapter) + if (be_check_error(adapter, BE_ERROR_ANY)) + return -EIO; + ++ local_bh_disable(); + status = be_process_mcc(adapter); ++ local_bh_enable(); + + if (atomic_read(&mcc_obj->q.used) == 0) + break; +diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c +index 7968568bbe214..361c1c87c1830 100644 +--- a/drivers/net/ethernet/emulex/benet/be_main.c ++++ b/drivers/net/ethernet/emulex/benet/be_main.c +@@ -5501,7 +5501,9 @@ static void be_worker(struct work_struct *work) + * mcc completions + */ + if (!netif_running(adapter->netdev)) { ++ local_bh_disable(); + be_process_mcc(adapter); ++ local_bh_enable(); + goto reschedule; + } + +diff --git a/drivers/net/ethernet/ezchip/nps_enet.c b/drivers/net/ethernet/ezchip/nps_enet.c +index e3954d8835e71..49957598301b5 100644 +--- a/drivers/net/ethernet/ezchip/nps_enet.c ++++ b/drivers/net/ethernet/ezchip/nps_enet.c +@@ -607,7 +607,7 @@ static s32 nps_enet_probe(struct platform_device *pdev) + + /* Get IRQ number */ + priv->irq = platform_get_irq(pdev, 0); +- if (!priv->irq) { ++ if (priv->irq < 0) { + dev_err(dev, "failed to retrieve value from device tree\n"); + err = -ENODEV; + goto out_netdev; +@@ -642,8 +642,8 @@ static s32 nps_enet_remove(struct platform_device *pdev) + struct nps_enet_priv *priv = netdev_priv(ndev); + + unregister_netdev(ndev); +- free_netdev(ndev); + netif_napi_del(&priv->napi); ++ free_netdev(ndev); + + return 0; + } +diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c +index 04421aec2dfd6..11dbbfd38770c 100644 +--- a/drivers/net/ethernet/faraday/ftgmac100.c ++++ b/drivers/net/ethernet/faraday/ftgmac100.c +@@ -1830,14 +1830,17 @@ static int ftgmac100_probe(struct platform_device *pdev) + if (np && of_get_property(np, "use-ncsi", NULL)) { + if (!IS_ENABLED(CONFIG_NET_NCSI)) { + dev_err(&pdev->dev, "NCSI stack not enabled\n"); ++ err = -EINVAL; + goto err_phy_connect; + } + + dev_info(&pdev->dev, "Using NCSI interface\n"); + priv->use_ncsi = true; + priv->ndev = ncsi_register_dev(netdev, ftgmac100_ncsi_handler); +- if (!priv->ndev) ++ if (!priv->ndev) { ++ err = -EINVAL; + goto err_phy_connect; ++ } + } else if (np && of_get_property(np, "phy-handle", NULL)) { + struct phy_device *phy; + +@@ -1856,6 +1859,7 @@ static int ftgmac100_probe(struct platform_device *pdev) + &ftgmac100_adjust_link); + if (!phy) { + dev_err(&pdev->dev, "Failed to connect to phy\n"); ++ err = -EINVAL; + goto err_phy_connect; + } + +diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c +index bbc423e931223..79cefe85a799f 100644 +--- a/drivers/net/ethernet/google/gve/gve_main.c ++++ b/drivers/net/ethernet/google/gve/gve_main.c +@@ -1295,8 +1295,8 @@ static int gve_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + + gve_write_version(®_bar->driver_version); + /* Get max queues to alloc etherdev */ +- max_rx_queues = ioread32be(®_bar->max_tx_queues); +- max_tx_queues = ioread32be(®_bar->max_rx_queues); ++ max_tx_queues = ioread32be(®_bar->max_tx_queues); ++ max_rx_queues = ioread32be(®_bar->max_rx_queues); + /* Alloc and setup the netdev and priv */ + dev = alloc_etherdev_mqs(sizeof(*priv), max_tx_queues, max_rx_queues); + if (!dev) { +diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c +index ea55314b209db..d105bfbc7c1c0 100644 +--- a/drivers/net/ethernet/ibm/ehea/ehea_main.c ++++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c +@@ -2618,10 +2618,8 @@ static int ehea_restart_qps(struct net_device *dev) + u16 dummy16 = 0; + + cb0 = (void *)get_zeroed_page(GFP_KERNEL); +- if (!cb0) { +- ret = -ENOMEM; +- goto out; +- } ++ if (!cb0) ++ return -ENOMEM; + + for (i = 0; i < (port->num_def_qps); i++) { + struct ehea_port_res *pr = &port->port_res[i]; +@@ -2641,6 +2639,7 @@ static int ehea_restart_qps(struct net_device *dev) + cb0); + if (hret != H_SUCCESS) { + netdev_err(dev, "query_ehea_qp failed (1)\n"); ++ ret = -EFAULT; + goto out; + } + +@@ -2653,6 +2652,7 @@ static int ehea_restart_qps(struct net_device *dev) + &dummy64, &dummy16, &dummy16); + if (hret != H_SUCCESS) { + netdev_err(dev, "modify_ehea_qp failed (1)\n"); ++ ret = -EFAULT; + goto out; + } + +@@ -2661,6 +2661,7 @@ static int ehea_restart_qps(struct net_device *dev) + cb0); + if (hret != H_SUCCESS) { + netdev_err(dev, "query_ehea_qp failed (2)\n"); ++ ret = -EFAULT; + goto out; + } + +diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c +index 5788bb956d733..ede65b32f8212 100644 +--- a/drivers/net/ethernet/ibm/ibmvnic.c ++++ b/drivers/net/ethernet/ibm/ibmvnic.c +@@ -106,6 +106,8 @@ static void release_crq_queue(struct ibmvnic_adapter *); + static int __ibmvnic_set_mac(struct net_device *, u8 *); + static int init_crq_queue(struct ibmvnic_adapter *adapter); + static int send_query_phys_parms(struct ibmvnic_adapter *adapter); ++static void ibmvnic_tx_scrq_clean_buffer(struct ibmvnic_adapter *adapter, ++ struct ibmvnic_sub_crq_queue *tx_scrq); + + struct ibmvnic_stat { + char name[ETH_GSTRING_LEN]; +@@ -209,12 +211,11 @@ static int alloc_long_term_buff(struct ibmvnic_adapter *adapter, + mutex_lock(&adapter->fw_lock); + adapter->fw_done_rc = 0; + reinit_completion(&adapter->fw_done); +- rc = send_request_map(adapter, ltb->addr, +- ltb->size, ltb->map_id); ++ ++ rc = send_request_map(adapter, ltb->addr, ltb->size, ltb->map_id); + if (rc) { +- dma_free_coherent(dev, ltb->size, ltb->buff, ltb->addr); +- mutex_unlock(&adapter->fw_lock); +- return rc; ++ dev_err(dev, "send_request_map failed, rc = %d\n", rc); ++ goto out; + } + + rc = ibmvnic_wait_for_completion(adapter, &adapter->fw_done, 10000); +@@ -222,20 +223,23 @@ static int alloc_long_term_buff(struct ibmvnic_adapter *adapter, + dev_err(dev, + "Long term map request aborted or timed out,rc = %d\n", + rc); +- dma_free_coherent(dev, ltb->size, ltb->buff, ltb->addr); +- mutex_unlock(&adapter->fw_lock); +- return rc; ++ goto out; + } + + if (adapter->fw_done_rc) { + dev_err(dev, "Couldn't map long term buffer,rc = %d\n", + adapter->fw_done_rc); ++ rc = -1; ++ goto out; ++ } ++ rc = 0; ++out: ++ if (rc) { + dma_free_coherent(dev, ltb->size, ltb->buff, ltb->addr); +- mutex_unlock(&adapter->fw_lock); +- return -1; ++ ltb->buff = NULL; + } + mutex_unlock(&adapter->fw_lock); +- return 0; ++ return rc; + } + + static void free_long_term_buff(struct ibmvnic_adapter *adapter, +@@ -255,14 +259,44 @@ static void free_long_term_buff(struct ibmvnic_adapter *adapter, + adapter->reset_reason != VNIC_RESET_TIMEOUT) + send_request_unmap(adapter, ltb->map_id); + dma_free_coherent(dev, ltb->size, ltb->buff, ltb->addr); ++ ltb->buff = NULL; ++ ltb->map_id = 0; + } + +-static int reset_long_term_buff(struct ibmvnic_long_term_buff *ltb) ++static int reset_long_term_buff(struct ibmvnic_adapter *adapter, ++ struct ibmvnic_long_term_buff *ltb) + { +- if (!ltb->buff) +- return -EINVAL; ++ struct device *dev = &adapter->vdev->dev; ++ int rc; + + memset(ltb->buff, 0, ltb->size); ++ ++ mutex_lock(&adapter->fw_lock); ++ adapter->fw_done_rc = 0; ++ ++ reinit_completion(&adapter->fw_done); ++ rc = send_request_map(adapter, ltb->addr, ltb->size, ltb->map_id); ++ if (rc) { ++ mutex_unlock(&adapter->fw_lock); ++ return rc; ++ } ++ ++ rc = ibmvnic_wait_for_completion(adapter, &adapter->fw_done, 10000); ++ if (rc) { ++ dev_info(dev, ++ "Reset failed, long term map request timed out or aborted\n"); ++ mutex_unlock(&adapter->fw_lock); ++ return rc; ++ } ++ ++ if (adapter->fw_done_rc) { ++ dev_info(dev, ++ "Reset failed, attempting to free and reallocate buffer\n"); ++ free_long_term_buff(adapter, ltb); ++ mutex_unlock(&adapter->fw_lock); ++ return alloc_long_term_buff(adapter, ltb, ltb->size); ++ } ++ mutex_unlock(&adapter->fw_lock); + return 0; + } + +@@ -298,7 +332,14 @@ static void replenish_rx_pool(struct ibmvnic_adapter *adapter, + + rx_scrq = adapter->rx_scrq[pool->index]; + ind_bufp = &rx_scrq->ind_buf; +- for (i = 0; i < count; ++i) { ++ ++ /* netdev_skb_alloc() could have failed after we saved a few skbs ++ * in the indir_buf and we would not have sent them to VIOS yet. ++ * To account for them, start the loop at ind_bufp->index rather ++ * than 0. If we pushed all the skbs to VIOS, ind_bufp->index will ++ * be 0. ++ */ ++ for (i = ind_bufp->index; i < count; ++i) { + skb = netdev_alloc_skb(adapter->netdev, pool->buff_size); + if (!skb) { + dev_err(dev, "Couldn't replenish rx buff\n"); +@@ -484,7 +525,8 @@ static int reset_rx_pools(struct ibmvnic_adapter *adapter) + rx_pool->size * + rx_pool->buff_size); + } else { +- rc = reset_long_term_buff(&rx_pool->long_term_buff); ++ rc = reset_long_term_buff(adapter, ++ &rx_pool->long_term_buff); + } + + if (rc) +@@ -607,11 +649,12 @@ static int init_rx_pools(struct net_device *netdev) + return 0; + } + +-static int reset_one_tx_pool(struct ibmvnic_tx_pool *tx_pool) ++static int reset_one_tx_pool(struct ibmvnic_adapter *adapter, ++ struct ibmvnic_tx_pool *tx_pool) + { + int rc, i; + +- rc = reset_long_term_buff(&tx_pool->long_term_buff); ++ rc = reset_long_term_buff(adapter, &tx_pool->long_term_buff); + if (rc) + return rc; + +@@ -638,10 +681,11 @@ static int reset_tx_pools(struct ibmvnic_adapter *adapter) + + tx_scrqs = adapter->num_active_tx_pools; + for (i = 0; i < tx_scrqs; i++) { +- rc = reset_one_tx_pool(&adapter->tso_pool[i]); ++ ibmvnic_tx_scrq_clean_buffer(adapter, adapter->tx_scrq[i]); ++ rc = reset_one_tx_pool(adapter, &adapter->tso_pool[i]); + if (rc) + return rc; +- rc = reset_one_tx_pool(&adapter->tx_pool[i]); ++ rc = reset_one_tx_pool(adapter, &adapter->tx_pool[i]); + if (rc) + return rc; + } +@@ -734,8 +778,11 @@ static int init_tx_pools(struct net_device *netdev) + + adapter->tso_pool = kcalloc(tx_subcrqs, + sizeof(struct ibmvnic_tx_pool), GFP_KERNEL); +- if (!adapter->tso_pool) ++ if (!adapter->tso_pool) { ++ kfree(adapter->tx_pool); ++ adapter->tx_pool = NULL; + return -1; ++ } + + adapter->num_active_tx_pools = tx_subcrqs; + +@@ -1180,6 +1227,11 @@ static int __ibmvnic_open(struct net_device *netdev) + + netif_tx_start_all_queues(netdev); + ++ if (prev_state == VNIC_CLOSED) { ++ for (i = 0; i < adapter->req_rx_queues; i++) ++ napi_schedule(&adapter->napi[i]); ++ } ++ + adapter->state = VNIC_OPEN; + return rc; + } +@@ -1583,7 +1635,8 @@ static void ibmvnic_tx_scrq_clean_buffer(struct ibmvnic_adapter *adapter, + ind_bufp->index = 0; + if (atomic_sub_return(entries, &tx_scrq->used) <= + (adapter->req_tx_entries_per_subcrq / 2) && +- __netif_subqueue_stopped(adapter->netdev, queue_num)) { ++ __netif_subqueue_stopped(adapter->netdev, queue_num) && ++ !test_bit(0, &adapter->resetting)) { + netif_wake_subqueue(adapter->netdev, queue_num); + netdev_dbg(adapter->netdev, "Started queue %d\n", + queue_num); +@@ -1676,7 +1729,6 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) + tx_send_failed++; + tx_dropped++; + ret = NETDEV_TX_OK; +- ibmvnic_tx_scrq_flush(adapter, tx_scrq); + goto out; + } + +@@ -3140,6 +3192,7 @@ static void release_sub_crqs(struct ibmvnic_adapter *adapter, bool do_h_free) + + netdev_dbg(adapter->netdev, "Releasing tx_scrq[%d]\n", + i); ++ ibmvnic_tx_scrq_clean_buffer(adapter, adapter->tx_scrq[i]); + if (adapter->tx_scrq[i]->irq) { + free_irq(adapter->tx_scrq[i]->irq, + adapter->tx_scrq[i]); +diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c +index 88e9035b75cf7..dc0ded7e5e614 100644 +--- a/drivers/net/ethernet/intel/e1000e/netdev.c ++++ b/drivers/net/ethernet/intel/e1000e/netdev.c +@@ -5223,18 +5223,20 @@ static void e1000_watchdog_task(struct work_struct *work) + pm_runtime_resume(netdev->dev.parent); + + /* Checking if MAC is in DMoff state*/ +- pcim_state = er32(STATUS); +- while (pcim_state & E1000_STATUS_PCIM_STATE) { +- if (tries++ == dmoff_exit_timeout) { +- e_dbg("Error in exiting dmoff\n"); +- break; +- } +- usleep_range(10000, 20000); ++ if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID) { + pcim_state = er32(STATUS); +- +- /* Checking if MAC exited DMoff state */ +- if (!(pcim_state & E1000_STATUS_PCIM_STATE)) +- e1000_phy_hw_reset(&adapter->hw); ++ while (pcim_state & E1000_STATUS_PCIM_STATE) { ++ if (tries++ == dmoff_exit_timeout) { ++ e_dbg("Error in exiting dmoff\n"); ++ break; ++ } ++ usleep_range(10000, 20000); ++ pcim_state = er32(STATUS); ++ ++ /* Checking if MAC exited DMoff state */ ++ if (!(pcim_state & E1000_STATUS_PCIM_STATE)) ++ e1000_phy_hw_reset(&adapter->hw); ++ } + } + + /* update snapshot of PHY registers on LSC */ +diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +index ccd5b9486ea98..3e822bad48513 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +@@ -1262,8 +1262,7 @@ static int i40e_set_link_ksettings(struct net_device *netdev, + if (ethtool_link_ksettings_test_link_mode(&safe_ks, + supported, + Autoneg) && +- hw->phy.link_info.phy_type != +- I40E_PHY_TYPE_10GBASE_T) { ++ hw->phy.media_type != I40E_MEDIA_TYPE_BASET) { + netdev_info(netdev, "Autoneg cannot be disabled on this phy\n"); + err = -EINVAL; + goto done; +diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c +index 704e474879c5b..f9fe500d4ec44 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -32,7 +32,7 @@ static void i40e_vsi_reinit_locked(struct i40e_vsi *vsi); + static void i40e_handle_reset_warning(struct i40e_pf *pf, bool lock_acquired); + static int i40e_add_vsi(struct i40e_vsi *vsi); + static int i40e_add_veb(struct i40e_veb *veb, struct i40e_vsi *vsi); +-static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit); ++static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit, bool lock_acquired); + static int i40e_setup_misc_vector(struct i40e_pf *pf); + static void i40e_determine_queue_usage(struct i40e_pf *pf); + static int i40e_setup_pf_filter_control(struct i40e_pf *pf); +@@ -8703,6 +8703,8 @@ int i40e_vsi_open(struct i40e_vsi *vsi) + dev_driver_string(&pf->pdev->dev), + dev_name(&pf->pdev->dev)); + err = i40e_vsi_request_irq(vsi, int_name); ++ if (err) ++ goto err_setup_rx; + + } else { + err = -EINVAL; +@@ -10569,7 +10571,7 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired) + #endif /* CONFIG_I40E_DCB */ + if (!lock_acquired) + rtnl_lock(); +- ret = i40e_setup_pf_switch(pf, reinit); ++ ret = i40e_setup_pf_switch(pf, reinit, true); + if (ret) + goto end_unlock; + +@@ -14627,10 +14629,11 @@ int i40e_fetch_switch_configuration(struct i40e_pf *pf, bool printconfig) + * i40e_setup_pf_switch - Setup the HW switch on startup or after reset + * @pf: board private structure + * @reinit: if the Main VSI needs to re-initialized. ++ * @lock_acquired: indicates whether or not the lock has been acquired + * + * Returns 0 on success, negative value on failure + **/ +-static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit) ++static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit, bool lock_acquired) + { + u16 flags = 0; + int ret; +@@ -14732,9 +14735,15 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit) + + i40e_ptp_init(pf); + ++ if (!lock_acquired) ++ rtnl_lock(); ++ + /* repopulate tunnel port filters */ + udp_tunnel_nic_reset_ntf(pf->vsi[pf->lan_vsi]->netdev); + ++ if (!lock_acquired) ++ rtnl_unlock(); ++ + return ret; + } + +@@ -15528,7 +15537,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + pf->flags |= I40E_FLAG_VEB_MODE_ENABLED; + } + #endif +- err = i40e_setup_pf_switch(pf, false); ++ err = i40e_setup_pf_switch(pf, false, false); + if (err) { + dev_info(&pdev->dev, "setup_pf_switch failed: %d\n", err); + goto err_vsis; +diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +index d39c7639cdbab..b3041fe6c0aed 100644 +--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c ++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +@@ -7588,6 +7588,8 @@ static int mvpp2_probe(struct platform_device *pdev) + return 0; + + err_port_probe: ++ fwnode_handle_put(port_fwnode); ++ + i = 0; + fwnode_for_each_available_child_node(fwnode, port_fwnode) { + if (priv->port_list[i]) +diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c +index e967867828d89..9b48ae4bac39f 100644 +--- a/drivers/net/ethernet/marvell/pxa168_eth.c ++++ b/drivers/net/ethernet/marvell/pxa168_eth.c +@@ -1528,6 +1528,7 @@ static int pxa168_eth_remove(struct platform_device *pdev) + struct net_device *dev = platform_get_drvdata(pdev); + struct pxa168_eth_private *pep = netdev_priv(dev); + ++ cancel_work_sync(&pep->tx_timeout_task); + if (pep->htpr) { + dma_free_coherent(pep->dev->dev.parent, HASH_ADDR_TABLE_SIZE, + pep->htpr, pep->htpr_dma); +@@ -1539,7 +1540,6 @@ static int pxa168_eth_remove(struct platform_device *pdev) + clk_disable_unprepare(pep->clk); + mdiobus_unregister(pep->smi_bus); + mdiobus_free(pep->smi_bus); +- cancel_work_sync(&pep->tx_timeout_task); + unregister_netdev(dev); + free_netdev(dev); + return 0; +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index 04d067243457b..1ed25e48f6165 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -1230,8 +1230,10 @@ static int mana_create_txq(struct mana_port_context *apc, + + cq->gdma_id = cq->gdma_cq->id; + +- if (WARN_ON(cq->gdma_id >= gc->max_num_cqs)) +- return -EINVAL; ++ if (WARN_ON(cq->gdma_id >= gc->max_num_cqs)) { ++ err = -EINVAL; ++ goto out; ++ } + + gc->cq_table[cq->gdma_id] = cq->gdma_cq; + +diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +index 334af49e5add1..3dc29b282a884 100644 +--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c ++++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +@@ -2532,9 +2532,13 @@ static int pch_gbe_probe(struct pci_dev *pdev, + adapter->pdev = pdev; + adapter->hw.back = adapter; + adapter->hw.reg = pcim_iomap_table(pdev)[PCH_GBE_PCI_BAR]; ++ + adapter->pdata = (struct pch_gbe_privdata *)pci_id->driver_data; +- if (adapter->pdata && adapter->pdata->platform_init) +- adapter->pdata->platform_init(pdev); ++ if (adapter->pdata && adapter->pdata->platform_init) { ++ ret = adapter->pdata->platform_init(pdev); ++ if (ret) ++ goto err_free_netdev; ++ } + + adapter->ptp_pdev = + pci_get_domain_bus_and_slot(pci_domain_nr(adapter->pdev->bus), +@@ -2629,7 +2633,7 @@ err_free_netdev: + */ + static int pch_gbe_minnow_platform_init(struct pci_dev *pdev) + { +- unsigned long flags = GPIOF_DIR_OUT | GPIOF_INIT_HIGH | GPIOF_EXPORT; ++ unsigned long flags = GPIOF_OUT_INIT_HIGH; + unsigned gpio = MINNOW_PHY_RESET_GPIO; + int ret; + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h +index b6cd43eda7acc..8aa55612d0949 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h +@@ -75,7 +75,7 @@ struct stmmac_tx_queue { + unsigned int cur_tx; + unsigned int dirty_tx; + dma_addr_t dma_tx_phy; +- u32 tx_tail_addr; ++ dma_addr_t tx_tail_addr; + u32 mss; + }; + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index c87202cbd3d6d..91cd5073ddb26 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -5138,7 +5138,7 @@ read_again: + + /* Buffer is good. Go on. */ + +- prefetch(page_address(buf->page)); ++ prefetch(page_address(buf->page) + buf->page_offset); + if (buf->sec_page) + prefetch(page_address(buf->sec_page)); + +diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c +index 6a67b026df0b6..718539cdd2f2e 100644 +--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c ++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c +@@ -1506,12 +1506,12 @@ static void am65_cpsw_nuss_free_tx_chns(void *data) + for (i = 0; i < common->tx_ch_num; i++) { + struct am65_cpsw_tx_chn *tx_chn = &common->tx_chns[i]; + +- if (!IS_ERR_OR_NULL(tx_chn->tx_chn)) +- k3_udma_glue_release_tx_chn(tx_chn->tx_chn); +- + if (!IS_ERR_OR_NULL(tx_chn->desc_pool)) + k3_cppi_desc_pool_destroy(tx_chn->desc_pool); + ++ if (!IS_ERR_OR_NULL(tx_chn->tx_chn)) ++ k3_udma_glue_release_tx_chn(tx_chn->tx_chn); ++ + memset(tx_chn, 0, sizeof(*tx_chn)); + } + } +@@ -1531,12 +1531,12 @@ void am65_cpsw_nuss_remove_tx_chns(struct am65_cpsw_common *common) + + netif_napi_del(&tx_chn->napi_tx); + +- if (!IS_ERR_OR_NULL(tx_chn->tx_chn)) +- k3_udma_glue_release_tx_chn(tx_chn->tx_chn); +- + if (!IS_ERR_OR_NULL(tx_chn->desc_pool)) + k3_cppi_desc_pool_destroy(tx_chn->desc_pool); + ++ if (!IS_ERR_OR_NULL(tx_chn->tx_chn)) ++ k3_udma_glue_release_tx_chn(tx_chn->tx_chn); ++ + memset(tx_chn, 0, sizeof(*tx_chn)); + } + } +@@ -1624,11 +1624,11 @@ static void am65_cpsw_nuss_free_rx_chns(void *data) + + rx_chn = &common->rx_chns; + +- if (!IS_ERR_OR_NULL(rx_chn->rx_chn)) +- k3_udma_glue_release_rx_chn(rx_chn->rx_chn); +- + if (!IS_ERR_OR_NULL(rx_chn->desc_pool)) + k3_cppi_desc_pool_destroy(rx_chn->desc_pool); ++ ++ if (!IS_ERR_OR_NULL(rx_chn->rx_chn)) ++ k3_udma_glue_release_rx_chn(rx_chn->rx_chn); + } + + static int am65_cpsw_nuss_init_rx_chns(struct am65_cpsw_common *common) +diff --git a/drivers/net/ieee802154/mac802154_hwsim.c b/drivers/net/ieee802154/mac802154_hwsim.c +index da9135231c079..ebc976b7fcc2a 100644 +--- a/drivers/net/ieee802154/mac802154_hwsim.c ++++ b/drivers/net/ieee802154/mac802154_hwsim.c +@@ -480,7 +480,7 @@ static int hwsim_del_edge_nl(struct sk_buff *msg, struct genl_info *info) + struct hwsim_edge *e; + u32 v0, v1; + +- if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] && ++ if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] || + !info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE]) + return -EINVAL; + +@@ -715,6 +715,8 @@ static int hwsim_subscribe_all_others(struct hwsim_phy *phy) + + return 0; + ++sub_fail: ++ hwsim_edge_unsubscribe_me(phy); + me_fail: + rcu_read_lock(); + list_for_each_entry_rcu(e, &phy->edges, list) { +@@ -722,8 +724,6 @@ me_fail: + hwsim_free_edge(e); + } + rcu_read_unlock(); +-sub_fail: +- hwsim_edge_unsubscribe_me(phy); + return -ENOMEM; + } + +@@ -824,12 +824,17 @@ err_pib: + static void hwsim_del(struct hwsim_phy *phy) + { + struct hwsim_pib *pib; ++ struct hwsim_edge *e; + + hwsim_edge_unsubscribe_me(phy); + + list_del(&phy->list); + + rcu_read_lock(); ++ list_for_each_entry_rcu(e, &phy->edges, list) { ++ list_del_rcu(&e->list); ++ hwsim_free_edge(e); ++ } + pib = rcu_dereference(phy->pib); + rcu_read_unlock(); + +diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c +index 92425e1fd70c0..93dc48b9b4f24 100644 +--- a/drivers/net/macsec.c ++++ b/drivers/net/macsec.c +@@ -1819,7 +1819,7 @@ static int macsec_add_rxsa(struct sk_buff *skb, struct genl_info *info) + ctx.sa.rx_sa = rx_sa; + ctx.secy = secy; + memcpy(ctx.sa.key, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), +- MACSEC_KEYID_LEN); ++ secy->key_len); + + err = macsec_offload(ops->mdo_add_rxsa, &ctx); + if (err) +@@ -2061,7 +2061,7 @@ static int macsec_add_txsa(struct sk_buff *skb, struct genl_info *info) + ctx.sa.tx_sa = tx_sa; + ctx.secy = secy; + memcpy(ctx.sa.key, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), +- MACSEC_KEYID_LEN); ++ secy->key_len); + + err = macsec_offload(ops->mdo_add_txsa, &ctx); + if (err) +diff --git a/drivers/net/phy/mscc/mscc_macsec.c b/drivers/net/phy/mscc/mscc_macsec.c +index 10be266e48e8b..b7b2521c73fb6 100644 +--- a/drivers/net/phy/mscc/mscc_macsec.c ++++ b/drivers/net/phy/mscc/mscc_macsec.c +@@ -501,7 +501,7 @@ static u32 vsc8584_macsec_flow_context_id(struct macsec_flow *flow) + } + + /* Derive the AES key to get a key for the hash autentication */ +-static int vsc8584_macsec_derive_key(const u8 key[MACSEC_KEYID_LEN], ++static int vsc8584_macsec_derive_key(const u8 key[MACSEC_MAX_KEY_LEN], + u16 key_len, u8 hkey[16]) + { + const u8 input[AES_BLOCK_SIZE] = {0}; +diff --git a/drivers/net/phy/mscc/mscc_macsec.h b/drivers/net/phy/mscc/mscc_macsec.h +index 9c6d25e36de2a..453304bae7784 100644 +--- a/drivers/net/phy/mscc/mscc_macsec.h ++++ b/drivers/net/phy/mscc/mscc_macsec.h +@@ -81,7 +81,7 @@ struct macsec_flow { + /* Highest takes precedence [0..15] */ + u8 priority; + +- u8 key[MACSEC_KEYID_LEN]; ++ u8 key[MACSEC_MAX_KEY_LEN]; + + union { + struct macsec_rx_sa *rx_sa; +diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c +index 28a6c4cfe9b8c..414afcb0a23f8 100644 +--- a/drivers/net/vrf.c ++++ b/drivers/net/vrf.c +@@ -1366,22 +1366,22 @@ static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev, + int orig_iif = skb->skb_iif; + bool need_strict = rt6_need_strict(&ipv6_hdr(skb)->daddr); + bool is_ndisc = ipv6_ndisc_frame(skb); +- bool is_ll_src; + + /* loopback, multicast & non-ND link-local traffic; do not push through + * packet taps again. Reset pkt_type for upper layers to process skb. +- * for packets with lladdr src, however, skip so that the dst can be +- * determine at input using original ifindex in the case that daddr +- * needs strict ++ * For strict packets with a source LLA, determine the dst using the ++ * original ifindex. + */ +- is_ll_src = ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL; +- if (skb->pkt_type == PACKET_LOOPBACK || +- (need_strict && !is_ndisc && !is_ll_src)) { ++ if (skb->pkt_type == PACKET_LOOPBACK || (need_strict && !is_ndisc)) { + skb->dev = vrf_dev; + skb->skb_iif = vrf_dev->ifindex; + IP6CB(skb)->flags |= IP6SKB_L3SLAVE; ++ + if (skb->pkt_type == PACKET_LOOPBACK) + skb->pkt_type = PACKET_HOST; ++ else if (ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL) ++ vrf_ip6_input_dst(skb, vrf_dev, orig_iif); ++ + goto out; + } + +diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c +index 02a14f1b938ad..5a8df5a195cb5 100644 +--- a/drivers/net/vxlan.c ++++ b/drivers/net/vxlan.c +@@ -2164,6 +2164,7 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni) + struct neighbour *n; + struct nd_msg *msg; + ++ rcu_read_lock(); + in6_dev = __in6_dev_get(dev); + if (!in6_dev) + goto out; +@@ -2215,6 +2216,7 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni) + } + + out: ++ rcu_read_unlock(); + consume_skb(skb); + return NETDEV_TX_OK; + } +diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c +index 5ce4f8d038b9b..c272b290fa73d 100644 +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -5592,6 +5592,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, + + if (arvif->nohwcrypt && + !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) { ++ ret = -EINVAL; + ath10k_warn(ar, "cryptmode module param needed for sw crypto\n"); + goto err; + } +diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c +index e7fde635e0eef..71878ab35b93c 100644 +--- a/drivers/net/wireless/ath/ath10k/pci.c ++++ b/drivers/net/wireless/ath/ath10k/pci.c +@@ -3685,8 +3685,10 @@ static int ath10k_pci_probe(struct pci_dev *pdev, + ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS); + if (bus_params.chip_id != 0xffffffff) { + if (!ath10k_pci_chip_is_supported(pdev->device, +- bus_params.chip_id)) ++ bus_params.chip_id)) { ++ ret = -ENODEV; + goto err_unsupported; ++ } + } + } + +@@ -3697,11 +3699,15 @@ static int ath10k_pci_probe(struct pci_dev *pdev, + } + + bus_params.chip_id = ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS); +- if (bus_params.chip_id == 0xffffffff) ++ if (bus_params.chip_id == 0xffffffff) { ++ ret = -ENODEV; + goto err_unsupported; ++ } + +- if (!ath10k_pci_chip_is_supported(pdev->device, bus_params.chip_id)) +- goto err_free_irq; ++ if (!ath10k_pci_chip_is_supported(pdev->device, bus_params.chip_id)) { ++ ret = -ENODEV; ++ goto err_unsupported; ++ } + + ret = ath10k_core_register(ar, &bus_params); + if (ret) { +diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c +index 77ce3347ab86d..595e83fe09904 100644 +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -488,7 +488,8 @@ static int ath11k_core_fetch_board_data_api_n(struct ath11k_base *ab, + if (len < ALIGN(ie_len, 4)) { + ath11k_err(ab, "invalid length for board ie_id %d ie_len %zu len %zu\n", + ie_id, ie_len, len); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err; + } + + switch (ie_id) { +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index 9d0ff150ec30f..eb52332dbe3f1 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -5379,11 +5379,6 @@ ath11k_mac_update_vif_chan(struct ath11k *ar, + if (WARN_ON(!arvif->is_up)) + continue; + +- ret = ath11k_mac_setup_bcn_tmpl(arvif); +- if (ret) +- ath11k_warn(ab, "failed to update bcn tmpl during csa: %d\n", +- ret); +- + ret = ath11k_mac_vdev_restart(arvif, &vifs[i].new_ctx->def); + if (ret) { + ath11k_warn(ab, "failed to restart vdev %d: %d\n", +@@ -5391,6 +5386,11 @@ ath11k_mac_update_vif_chan(struct ath11k *ar, + continue; + } + ++ ret = ath11k_mac_setup_bcn_tmpl(arvif); ++ if (ret) ++ ath11k_warn(ab, "failed to update bcn tmpl during csa: %d\n", ++ ret); ++ + ret = ath11k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid, + arvif->bssid); + if (ret) { +diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c +index 45f6402478b50..97c3a53f9cef2 100644 +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -307,6 +307,11 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan) + hchan = ah->curchan; + } + ++ if (!hchan) { ++ fastcc = false; ++ hchan = ath9k_cmn_get_channel(sc->hw, ah, &sc->cur_chan->chandef); ++ } ++ + if (!ath_prepare_reset(sc)) + fastcc = false; + +diff --git a/drivers/net/wireless/ath/carl9170/Kconfig b/drivers/net/wireless/ath/carl9170/Kconfig +index b2d760873992f..ba9bea79381c5 100644 +--- a/drivers/net/wireless/ath/carl9170/Kconfig ++++ b/drivers/net/wireless/ath/carl9170/Kconfig +@@ -16,13 +16,11 @@ config CARL9170 + + config CARL9170_LEDS + bool "SoftLED Support" +- depends on CARL9170 +- select MAC80211_LEDS +- select LEDS_CLASS +- select NEW_LEDS + default y ++ depends on CARL9170 ++ depends on MAC80211_LEDS + help +- This option is necessary, if you want your device' LEDs to blink ++ This option is necessary, if you want your device's LEDs to blink. + + Say Y, unless you need the LEDs for firmware debugging. + +diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c +index afb4877eaad8f..dabed4e3ca457 100644 +--- a/drivers/net/wireless/ath/wcn36xx/main.c ++++ b/drivers/net/wireless/ath/wcn36xx/main.c +@@ -293,23 +293,16 @@ static int wcn36xx_start(struct ieee80211_hw *hw) + goto out_free_dxe_pool; + } + +- wcn->hal_buf = kmalloc(WCN36XX_HAL_BUF_SIZE, GFP_KERNEL); +- if (!wcn->hal_buf) { +- wcn36xx_err("Failed to allocate smd buf\n"); +- ret = -ENOMEM; +- goto out_free_dxe_ctl; +- } +- + ret = wcn36xx_smd_load_nv(wcn); + if (ret) { + wcn36xx_err("Failed to push NV to chip\n"); +- goto out_free_smd_buf; ++ goto out_free_dxe_ctl; + } + + ret = wcn36xx_smd_start(wcn); + if (ret) { + wcn36xx_err("Failed to start chip\n"); +- goto out_free_smd_buf; ++ goto out_free_dxe_ctl; + } + + if (!wcn36xx_is_fw_version(wcn, 1, 2, 2, 24)) { +@@ -336,8 +329,6 @@ static int wcn36xx_start(struct ieee80211_hw *hw) + + out_smd_stop: + wcn36xx_smd_stop(wcn); +-out_free_smd_buf: +- kfree(wcn->hal_buf); + out_free_dxe_ctl: + wcn36xx_dxe_free_ctl_blks(wcn); + out_free_dxe_pool: +@@ -372,8 +363,6 @@ static void wcn36xx_stop(struct ieee80211_hw *hw) + + wcn36xx_dxe_free_mem_pools(wcn); + wcn36xx_dxe_free_ctl_blks(wcn); +- +- kfree(wcn->hal_buf); + } + + static void wcn36xx_change_ps(struct wcn36xx *wcn, bool enable) +@@ -1401,6 +1390,12 @@ static int wcn36xx_probe(struct platform_device *pdev) + mutex_init(&wcn->hal_mutex); + mutex_init(&wcn->scan_lock); + ++ wcn->hal_buf = devm_kmalloc(wcn->dev, WCN36XX_HAL_BUF_SIZE, GFP_KERNEL); ++ if (!wcn->hal_buf) { ++ ret = -ENOMEM; ++ goto out_wq; ++ } ++ + ret = dma_set_mask_and_coherent(wcn->dev, DMA_BIT_MASK(32)); + if (ret < 0) { + wcn36xx_err("failed to set DMA mask: %d\n", ret); +diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c +index 6746fd206d2a9..1ff2679963f06 100644 +--- a/drivers/net/wireless/ath/wil6210/cfg80211.c ++++ b/drivers/net/wireless/ath/wil6210/cfg80211.c +@@ -2842,9 +2842,7 @@ void wil_p2p_wdev_free(struct wil6210_priv *wil) + wil->radio_wdev = wil->main_ndev->ieee80211_ptr; + mutex_unlock(&wil->vif_mutex); + if (p2p_wdev) { +- wiphy_lock(wil->wiphy); + cfg80211_unregister_wdev(p2p_wdev); +- wiphy_unlock(wil->wiphy); + kfree(p2p_wdev); + } + } +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index f4405d7861b69..d8822a01d277e 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -2767,8 +2767,9 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, + struct brcmf_sta_info_le sta_info_le; + u32 sta_flags; + u32 is_tdls_peer; +- s32 total_rssi; +- s32 count_rssi; ++ s32 total_rssi_avg = 0; ++ s32 total_rssi = 0; ++ s32 count_rssi = 0; + int rssi; + u32 i; + +@@ -2834,25 +2835,27 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES); + sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes); + } +- total_rssi = 0; +- count_rssi = 0; + for (i = 0; i < BRCMF_ANT_MAX; i++) { +- if (sta_info_le.rssi[i]) { +- sinfo->chain_signal_avg[count_rssi] = +- sta_info_le.rssi[i]; +- sinfo->chain_signal[count_rssi] = +- sta_info_le.rssi[i]; +- total_rssi += sta_info_le.rssi[i]; +- count_rssi++; +- } ++ if (sta_info_le.rssi[i] == 0 || ++ sta_info_le.rx_lastpkt_rssi[i] == 0) ++ continue; ++ sinfo->chains |= BIT(count_rssi); ++ sinfo->chain_signal[count_rssi] = ++ sta_info_le.rx_lastpkt_rssi[i]; ++ sinfo->chain_signal_avg[count_rssi] = ++ sta_info_le.rssi[i]; ++ total_rssi += sta_info_le.rx_lastpkt_rssi[i]; ++ total_rssi_avg += sta_info_le.rssi[i]; ++ count_rssi++; + } + if (count_rssi) { +- sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL); +- sinfo->chains = count_rssi; +- + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); +- total_rssi /= count_rssi; +- sinfo->signal = total_rssi; ++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); ++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL); ++ sinfo->filled |= ++ BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG); ++ sinfo->signal = total_rssi / count_rssi; ++ sinfo->signal_avg = total_rssi_avg / count_rssi; + } else if (test_bit(BRCMF_VIF_STATUS_CONNECTED, + &ifp->vif->sme_state)) { + memset(&scb_val, 0, sizeof(scb_val)); +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +index 16ed325795a8b..faf5f8e5eee33 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -626,8 +626,8 @@ BRCMF_FW_DEF(4373, "brcmfmac4373-sdio"); + BRCMF_FW_DEF(43012, "brcmfmac43012-sdio"); + + /* firmware config files */ +-MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac*-sdio.*.txt"); +-MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac*-pcie.*.txt"); ++MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-sdio.*.txt"); ++MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.*.txt"); + + static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = { + BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143), +@@ -4162,7 +4162,6 @@ static int brcmf_sdio_bus_reset(struct device *dev) + if (ret) { + brcmf_err("Failed to probe after sdio device reset: ret %d\n", + ret); +- brcmf_sdiod_remove(sdiodev); + } + + return ret; +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c +index 39f3af2d0439b..eadac0f5590fc 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c +@@ -1220,6 +1220,7 @@ static int brcms_bcma_probe(struct bcma_device *pdev) + { + struct brcms_info *wl; + struct ieee80211_hw *hw; ++ int ret; + + dev_info(&pdev->dev, "mfg %x core %x rev %d class %d irq %d\n", + pdev->id.manuf, pdev->id.id, pdev->id.rev, pdev->id.class, +@@ -1244,11 +1245,16 @@ static int brcms_bcma_probe(struct bcma_device *pdev) + wl = brcms_attach(pdev); + if (!wl) { + pr_err("%s: brcms_attach failed!\n", __func__); +- return -ENODEV; ++ ret = -ENODEV; ++ goto err_free_ieee80211; + } + brcms_led_register(wl); + + return 0; ++ ++err_free_ieee80211: ++ ieee80211_free_hw(hw); ++ return ret; + } + + static int brcms_suspend(struct bcma_device *pdev) +diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.h b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.h +index e4f91bce222d8..61d3d4e0b7d94 100644 +--- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.h ++++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.h +@@ -1,7 +1,7 @@ + /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ + /****************************************************************************** + * +- * Copyright(c) 2020 Intel Corporation ++ * Copyright(c) 2020-2021 Intel Corporation + * + *****************************************************************************/ + +@@ -10,7 +10,7 @@ + + #include "fw/notif-wait.h" + +-#define MVM_UCODE_PNVM_TIMEOUT (HZ / 10) ++#define MVM_UCODE_PNVM_TIMEOUT (HZ / 4) + + int iwl_pnvm_load(struct iwl_trans *trans, + struct iwl_notif_wait_data *notif_wait); +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +index 1ad621d13ad3a..0a13c2bda2eed 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +@@ -1032,6 +1032,9 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb, + if (WARN_ON_ONCE(mvmsta->sta_id == IWL_MVM_INVALID_STA)) + return -1; + ++ if (unlikely(ieee80211_is_any_nullfunc(fc)) && sta->he_cap.has_he) ++ return -1; ++ + if (unlikely(ieee80211_is_probe_resp(fc))) + iwl_mvm_probe_resp_set_noa(mvm, skb); + +diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c +index 94228b316df1b..46517515ba728 100644 +--- a/drivers/net/wireless/marvell/mwifiex/pcie.c ++++ b/drivers/net/wireless/marvell/mwifiex/pcie.c +@@ -1231,7 +1231,7 @@ static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter) + static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter) + { + struct pcie_service_card *card = adapter->card; +- u32 tmp; ++ u32 *cookie; + + card->sleep_cookie_vbase = dma_alloc_coherent(&card->dev->dev, + sizeof(u32), +@@ -1242,13 +1242,11 @@ static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter) + "dma_alloc_coherent failed!\n"); + return -ENOMEM; + } ++ cookie = (u32 *)card->sleep_cookie_vbase; + /* Init val of Sleep Cookie */ +- tmp = FW_AWAKE_COOKIE; +- put_unaligned(tmp, card->sleep_cookie_vbase); ++ *cookie = FW_AWAKE_COOKIE; + +- mwifiex_dbg(adapter, INFO, +- "alloc_scook: sleep cookie=0x%x\n", +- get_unaligned(card->sleep_cookie_vbase)); ++ mwifiex_dbg(adapter, INFO, "alloc_scook: sleep cookie=0x%x\n", *cookie); + + return 0; + } +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +index aa42af9ebfd6a..ae2191371f511 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +@@ -411,6 +411,9 @@ mt7615_mcu_rx_csa_notify(struct mt7615_dev *dev, struct sk_buff *skb) + + c = (struct mt7615_mcu_csa_notify *)skb->data; + ++ if (c->omac_idx > EXT_BSSID_MAX) ++ return; ++ + if (ext_phy && ext_phy->omac_mask & BIT_ULL(c->omac_idx)) + mphy = dev->mt76.phy2; + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c +index d7cbef752f9fd..cc278d8cb8886 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c +@@ -131,20 +131,21 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, + struct mt76_tx_info *tx_info) + { + struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76); +- struct mt7615_sta *msta = container_of(wcid, struct mt7615_sta, wcid); + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb); + struct ieee80211_key_conf *key = info->control.hw_key; + int pid, id; + u8 *txwi = (u8 *)txwi_ptr; + struct mt76_txwi_cache *t; ++ struct mt7615_sta *msta; + void *txp; + ++ msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL; + if (!wcid) + wcid = &dev->mt76.global_wcid; + + pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb); + +- if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) { ++ if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && msta) { + struct mt7615_phy *phy = &dev->phy; + + if ((info->hw_queue & MT_TX_HW_QUEUE_EXT_PHY) && mdev->phy2) +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c +index f8d3673c2cae8..7010101f6b147 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c +@@ -191,14 +191,15 @@ int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, + struct ieee80211_sta *sta, + struct mt76_tx_info *tx_info) + { +- struct mt7615_sta *msta = container_of(wcid, struct mt7615_sta, wcid); + struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76); + struct sk_buff *skb = tx_info->skb; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); ++ struct mt7615_sta *msta; + int pad; + ++ msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL; + if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && +- !msta->rate_probe) { ++ msta && !msta->rate_probe) { + /* request to configure sampling rate */ + spin_lock_bh(&dev->mt76.lock); + mt7615_mac_set_rates(&dev->phy, msta, &info->control.rates[0], +diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac.h +index 6c889b90fd12a..c26cfef425ed8 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h ++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h +@@ -12,7 +12,7 @@ + #define MT76_CONNAC_MAX_SCAN_MATCH 16 + + #define MT76_CONNAC_COREDUMP_TIMEOUT (HZ / 20) +-#define MT76_CONNAC_COREDUMP_SZ (128 * 1024) ++#define MT76_CONNAC_COREDUMP_SZ (1300 * 1024) + + enum { + CMD_CBW_20MHZ = IEEE80211_STA_RX_BW_20, +@@ -45,6 +45,7 @@ enum { + + struct mt76_connac_pm { + bool enable; ++ bool suspended; + + spinlock_t txq_lock; + struct { +@@ -127,8 +128,12 @@ mt76_connac_pm_unref(struct mt76_connac_pm *pm) + static inline bool + mt76_connac_skip_fw_pmctrl(struct mt76_phy *phy, struct mt76_connac_pm *pm) + { ++ struct mt76_dev *dev = phy->dev; + bool ret; + ++ if (dev->token_count) ++ return true; ++ + spin_lock_bh(&pm->wake.lock); + ret = pm->wake.count || test_and_set_bit(MT76_STATE_PM, &phy->state); + spin_unlock_bh(&pm->wake.lock); +diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c +index 6f180c92d4132..5f2705fbd6803 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c +@@ -17,6 +17,9 @@ int mt76_connac_pm_wake(struct mt76_phy *phy, struct mt76_connac_pm *pm) + if (!test_bit(MT76_STATE_PM, &phy->state)) + return 0; + ++ if (pm->suspended) ++ return 0; ++ + queue_work(dev->wq, &pm->wake_work); + if (!wait_event_timeout(pm->wait, + !test_bit(MT76_STATE_PM, &phy->state), +@@ -40,6 +43,9 @@ void mt76_connac_power_save_sched(struct mt76_phy *phy, + if (!pm->enable) + return; + ++ if (pm->suspended) ++ return; ++ + pm->last_activity = jiffies; + + if (!test_bit(MT76_STATE_PM, &phy->state)) { +diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +index 619561606f96d..eb19721f9d79a 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +@@ -1939,7 +1939,7 @@ mt76_connac_mcu_set_wow_pattern(struct mt76_dev *dev, + ptlv->index = index; + + memcpy(ptlv->pattern, pattern->pattern, pattern->pattern_len); +- memcpy(ptlv->mask, pattern->mask, pattern->pattern_len / 8); ++ memcpy(ptlv->mask, pattern->mask, DIV_ROUND_UP(pattern->pattern_len, 8)); + + return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD_SUSPEND, true); + } +@@ -1974,14 +1974,17 @@ mt76_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif, + }; + + if (wowlan->magic_pkt) +- req.wow_ctrl_tlv.trigger |= BIT(0); ++ req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_MAGIC; + if (wowlan->disconnect) +- req.wow_ctrl_tlv.trigger |= BIT(2); ++ req.wow_ctrl_tlv.trigger |= (UNI_WOW_DETECT_TYPE_DISCONNECT | ++ UNI_WOW_DETECT_TYPE_BCN_LOST); + if (wowlan->nd_config) { + mt76_connac_mcu_sched_scan_req(phy, vif, wowlan->nd_config); +- req.wow_ctrl_tlv.trigger |= BIT(5); ++ req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_SCH_SCAN_HIT; + mt76_connac_mcu_sched_scan_enable(phy, vif, suspend); + } ++ if (wowlan->n_patterns) ++ req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_BITMAP; + + if (mt76_is_mmio(dev)) + req.wow_ctrl_tlv.wakeup_hif = WOW_PCIE; +diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h +index a1096861d04a3..3bcae732872ed 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h ++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h +@@ -590,6 +590,14 @@ enum { + UNI_OFFLOAD_OFFLOAD_BMC_RPY_DETECT, + }; + ++#define UNI_WOW_DETECT_TYPE_MAGIC BIT(0) ++#define UNI_WOW_DETECT_TYPE_ANY BIT(1) ++#define UNI_WOW_DETECT_TYPE_DISCONNECT BIT(2) ++#define UNI_WOW_DETECT_TYPE_GTK_REKEY_FAIL BIT(3) ++#define UNI_WOW_DETECT_TYPE_BCN_LOST BIT(4) ++#define UNI_WOW_DETECT_TYPE_SCH_SCAN_HIT BIT(5) ++#define UNI_WOW_DETECT_TYPE_BITMAP BIT(6) ++ + enum { + UNI_SUSPEND_MODE_SETTING, + UNI_SUSPEND_WOW_CTRL, +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h +index 033fb592bdf02..30bf41b8ed152 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h +@@ -33,7 +33,7 @@ enum mt7915_eeprom_field { + #define MT_EE_WIFI_CAL_GROUP BIT(0) + #define MT_EE_WIFI_CAL_DPD GENMASK(2, 1) + #define MT_EE_CAL_UNIT 1024 +-#define MT_EE_CAL_GROUP_SIZE (44 * MT_EE_CAL_UNIT) ++#define MT_EE_CAL_GROUP_SIZE (49 * MT_EE_CAL_UNIT + 16) + #define MT_EE_CAL_DPD_SIZE (54 * MT_EE_CAL_UNIT) + + #define MT_EE_WIFI_CONF0_TX_PATH GENMASK(2, 0) +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +index b3f14ff67c5ae..764f25a828fa2 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +@@ -3440,8 +3440,9 @@ int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy) + { + struct mt7915_dev *dev = phy->dev; + struct cfg80211_chan_def *chandef = &phy->mt76->chandef; +- u16 total = 2, idx, center_freq = chandef->center_freq1; ++ u16 total = 2, center_freq = chandef->center_freq1; + u8 *cal = dev->cal, *eep = dev->mt76.eeprom.data; ++ int idx; + + if (!(eep[MT_EE_DO_PRE_CAL] & MT_EE_WIFI_CAL_DPD)) + return 0; +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c +index f9d81e36ef09a..b220b334906bc 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c +@@ -464,10 +464,17 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en) + static void + mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en) + { +- if (en) ++ mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, false); ++ ++ if (en) { ++ struct mt7915_dev *dev = phy->dev; ++ + mt7915_tm_update_channel(phy); + +- mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, en); ++ /* read-clear */ ++ mt76_rr(dev, MT_MIB_SDR3(phy != &dev->phy)); ++ mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, en); ++ } + } + + static int +@@ -690,7 +697,11 @@ static int + mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg) + { + struct mt7915_phy *phy = mphy->priv; ++ struct mt7915_dev *dev = phy->dev; ++ bool ext_phy = phy != &dev->phy; ++ enum mt76_rxq_id q; + void *rx, *rssi; ++ u16 fcs_err; + int i; + + rx = nla_nest_start(msg, MT76_TM_STATS_ATTR_LAST_RX); +@@ -735,6 +746,12 @@ mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg) + + nla_nest_end(msg, rx); + ++ fcs_err = mt76_get_field(dev, MT_MIB_SDR3(ext_phy), ++ MT_MIB_SDR3_FCS_ERR_MASK); ++ q = ext_phy ? MT_RXQ_EXT : MT_RXQ_MAIN; ++ mphy->test.rx_stats.packets[q] += fcs_err; ++ mphy->test.rx_stats.fcs_error[q] += fcs_err; ++ + return 0; + } + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c +index 6ee423dd4027c..6602903c0d026 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c +@@ -184,7 +184,10 @@ mt7921_txpwr(struct seq_file *s, void *data) + struct mt7921_txpwr txpwr; + int ret; + ++ mt7921_mutex_acquire(dev); + ret = mt7921_get_txpwr_info(dev, &txpwr); ++ mt7921_mutex_release(dev); ++ + if (ret) + return ret; + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c +index 71e664ee76520..bd9143dc865f9 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c +@@ -313,9 +313,9 @@ static int mt7921_dma_reset(struct mt7921_dev *dev, bool force) + + int mt7921_wfsys_reset(struct mt7921_dev *dev) + { +- mt76_set(dev, 0x70002600, BIT(0)); +- msleep(200); +- mt76_clear(dev, 0x70002600, BIT(0)); ++ mt76_clear(dev, MT_WFSYS_SW_RST_B, WFSYS_SW_RST_B); ++ msleep(50); ++ mt76_set(dev, MT_WFSYS_SW_RST_B, WFSYS_SW_RST_B); + + if (!__mt76_poll_msec(&dev->mt76, MT_WFSYS_SW_RST_B, + WFSYS_SW_INIT_DONE, WFSYS_SW_INIT_DONE, 500)) +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c +index 1763ea0614ce2..2cb0252e63b21 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c +@@ -73,6 +73,7 @@ static void + mt7921_init_wiphy(struct ieee80211_hw *hw) + { + struct mt7921_phy *phy = mt7921_hw_phy(hw); ++ struct mt7921_dev *dev = phy->dev; + struct wiphy *wiphy = hw->wiphy; + + hw->queues = 4; +@@ -110,36 +111,21 @@ mt7921_init_wiphy(struct ieee80211_hw *hw) + ieee80211_hw_set(hw, SUPPORTS_PS); + ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); + ++ if (dev->pm.enable) ++ ieee80211_hw_set(hw, CONNECTION_MONITOR); ++ + hw->max_tx_fragments = 4; + } + + static void + mt7921_mac_init_band(struct mt7921_dev *dev, u8 band) + { +- u32 mask, set; +- + mt76_rmw_field(dev, MT_TMAC_CTCR0(band), + MT_TMAC_CTCR0_INS_DDLMT_REFTIME, 0x3f); + mt76_set(dev, MT_TMAC_CTCR0(band), + MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN | + MT_TMAC_CTCR0_INS_DDLMT_EN); + +- mask = MT_MDP_RCFR0_MCU_RX_MGMT | +- MT_MDP_RCFR0_MCU_RX_CTL_NON_BAR | +- MT_MDP_RCFR0_MCU_RX_CTL_BAR; +- set = FIELD_PREP(MT_MDP_RCFR0_MCU_RX_MGMT, MT_MDP_TO_HIF) | +- FIELD_PREP(MT_MDP_RCFR0_MCU_RX_CTL_NON_BAR, MT_MDP_TO_HIF) | +- FIELD_PREP(MT_MDP_RCFR0_MCU_RX_CTL_BAR, MT_MDP_TO_HIF); +- mt76_rmw(dev, MT_MDP_BNRCFR0(band), mask, set); +- +- mask = MT_MDP_RCFR1_MCU_RX_BYPASS | +- MT_MDP_RCFR1_RX_DROPPED_UCAST | +- MT_MDP_RCFR1_RX_DROPPED_MCAST; +- set = FIELD_PREP(MT_MDP_RCFR1_MCU_RX_BYPASS, MT_MDP_TO_HIF) | +- FIELD_PREP(MT_MDP_RCFR1_RX_DROPPED_UCAST, MT_MDP_TO_HIF) | +- FIELD_PREP(MT_MDP_RCFR1_RX_DROPPED_MCAST, MT_MDP_TO_HIF); +- mt76_rmw(dev, MT_MDP_BNRCFR1(band), mask, set); +- + mt76_set(dev, MT_WF_RMAC_MIB_TIME0(band), MT_WF_RMAC_MIB_RXTIME_EN); + mt76_set(dev, MT_WF_RMAC_MIB_AIRTIME0(band), MT_WF_RMAC_MIB_RXTIME_EN); + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c +index decf2d5f0ce3a..493c2aba2f791 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c +@@ -444,16 +444,19 @@ int mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) + status->chain_signal[1] = to_rssi(MT_PRXV_RCPI1, v1); + status->chain_signal[2] = to_rssi(MT_PRXV_RCPI2, v1); + status->chain_signal[3] = to_rssi(MT_PRXV_RCPI3, v1); +- status->signal = status->chain_signal[0]; +- +- for (i = 1; i < hweight8(mphy->antenna_mask); i++) { +- if (!(status->chains & BIT(i))) ++ status->signal = -128; ++ for (i = 0; i < hweight8(mphy->antenna_mask); i++) { ++ if (!(status->chains & BIT(i)) || ++ status->chain_signal[i] >= 0) + continue; + + status->signal = max(status->signal, + status->chain_signal[i]); + } + ++ if (status->signal == -128) ++ status->flag |= RX_FLAG_NO_SIGNAL_VAL; ++ + stbc = FIELD_GET(MT_PRXV_STBC, v0); + gi = FIELD_GET(MT_PRXV_SGI, v0); + cck = false; +@@ -1196,7 +1199,8 @@ mt7921_vif_connect_iter(void *priv, u8 *mac, + struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; + struct mt7921_dev *dev = mvif->phy->dev; + +- ieee80211_disconnect(vif, true); ++ if (vif->type == NL80211_IFTYPE_STATION) ++ ieee80211_disconnect(vif, true); + + mt76_connac_mcu_uni_add_dev(&dev->mphy, vif, &mvif->sta.wcid, true); + mt7921_mcu_set_tx(dev, vif); +@@ -1269,6 +1273,7 @@ void mt7921_mac_reset_work(struct work_struct *work) + hw = mt76_hw(dev); + + dev_err(dev->mt76.dev, "chip reset\n"); ++ dev->hw_full_reset = true; + ieee80211_stop_queues(hw); + + cancel_delayed_work_sync(&dev->mphy.mac_work); +@@ -1293,6 +1298,7 @@ void mt7921_mac_reset_work(struct work_struct *work) + ieee80211_scan_completed(dev->mphy.hw, &info); + } + ++ dev->hw_full_reset = false; + ieee80211_wake_queues(hw); + ieee80211_iterate_active_interfaces(hw, + IEEE80211_IFACE_ITER_RESUME_ALL, +@@ -1303,7 +1309,11 @@ void mt7921_reset(struct mt76_dev *mdev) + { + struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); + +- queue_work(dev->mt76.wq, &dev->reset_work); ++ if (!test_bit(MT76_STATE_RUNNING, &dev->mphy.state)) ++ return; ++ ++ if (!dev->hw_full_reset) ++ queue_work(dev->mt76.wq, &dev->reset_work); + } + + static void +@@ -1494,7 +1504,7 @@ void mt7921_coredump_work(struct work_struct *work) + break; + + skb_pull(skb, sizeof(struct mt7921_mcu_rxd)); +- if (data + skb->len - dump > MT76_CONNAC_COREDUMP_SZ) { ++ if (!dump || data + skb->len - dump > MT76_CONNAC_COREDUMP_SZ) { + dev_kfree_skb(skb); + continue; + } +@@ -1504,7 +1514,10 @@ void mt7921_coredump_work(struct work_struct *work) + + dev_kfree_skb(skb); + } +- dev_coredumpv(dev->mt76.dev, dump, MT76_CONNAC_COREDUMP_SZ, +- GFP_KERNEL); ++ ++ if (dump) ++ dev_coredumpv(dev->mt76.dev, dump, MT76_CONNAC_COREDUMP_SZ, ++ GFP_KERNEL); ++ + mt7921_reset(&dev->mt76); + } +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c +index 97a0ef331ac32..bd77a04a15fb2 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c +@@ -223,54 +223,6 @@ static void mt7921_stop(struct ieee80211_hw *hw) + mt7921_mutex_release(dev); + } + +-static inline int get_free_idx(u32 mask, u8 start, u8 end) +-{ +- return ffs(~mask & GENMASK(end, start)); +-} +- +-static int get_omac_idx(enum nl80211_iftype type, u64 mask) +-{ +- int i; +- +- switch (type) { +- case NL80211_IFTYPE_STATION: +- /* prefer hw bssid slot 1-3 */ +- i = get_free_idx(mask, HW_BSSID_1, HW_BSSID_3); +- if (i) +- return i - 1; +- +- /* next, try to find a free repeater entry for the sta */ +- i = get_free_idx(mask >> REPEATER_BSSID_START, 0, +- REPEATER_BSSID_MAX - REPEATER_BSSID_START); +- if (i) +- return i + 32 - 1; +- +- i = get_free_idx(mask, EXT_BSSID_1, EXT_BSSID_MAX); +- if (i) +- return i - 1; +- +- if (~mask & BIT(HW_BSSID_0)) +- return HW_BSSID_0; +- +- break; +- case NL80211_IFTYPE_MONITOR: +- /* ap uses hw bssid 0 and ext bssid */ +- if (~mask & BIT(HW_BSSID_0)) +- return HW_BSSID_0; +- +- i = get_free_idx(mask, EXT_BSSID_1, EXT_BSSID_MAX); +- if (i) +- return i - 1; +- +- break; +- default: +- WARN_ON(1); +- break; +- } +- +- return -1; +-} +- + static int mt7921_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) + { +@@ -292,12 +244,7 @@ static int mt7921_add_interface(struct ieee80211_hw *hw, + goto out; + } + +- idx = get_omac_idx(vif->type, phy->omac_mask); +- if (idx < 0) { +- ret = -ENOSPC; +- goto out; +- } +- mvif->mt76.omac_idx = idx; ++ mvif->mt76.omac_idx = mvif->mt76.idx; + mvif->phy = phy; + mvif->mt76.band_idx = 0; + mvif->mt76.wmm_idx = mvif->mt76.idx % MT7921_MAX_WMM_SETS; +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +index 67dc4b4cc0945..7c68182cad552 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +@@ -450,22 +450,33 @@ mt7921_mcu_scan_event(struct mt7921_dev *dev, struct sk_buff *skb) + } + + static void +-mt7921_mcu_beacon_loss_event(struct mt7921_dev *dev, struct sk_buff *skb) ++mt7921_mcu_connection_loss_iter(void *priv, u8 *mac, ++ struct ieee80211_vif *vif) ++{ ++ struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; ++ struct mt76_connac_beacon_loss_event *event = priv; ++ ++ if (mvif->idx != event->bss_idx) ++ return; ++ ++ if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER)) ++ return; ++ ++ ieee80211_connection_loss(vif); ++} ++ ++static void ++mt7921_mcu_connection_loss_event(struct mt7921_dev *dev, struct sk_buff *skb) + { + struct mt76_connac_beacon_loss_event *event; +- struct mt76_phy *mphy; +- u8 band_idx = 0; /* DBDC support */ ++ struct mt76_phy *mphy = &dev->mt76.phy; + + skb_pull(skb, sizeof(struct mt7921_mcu_rxd)); + event = (struct mt76_connac_beacon_loss_event *)skb->data; +- if (band_idx && dev->mt76.phy2) +- mphy = dev->mt76.phy2; +- else +- mphy = &dev->mt76.phy; + + ieee80211_iterate_active_interfaces_atomic(mphy->hw, + IEEE80211_IFACE_ITER_RESUME_ALL, +- mt76_connac_mcu_beacon_loss_iter, event); ++ mt7921_mcu_connection_loss_iter, event); + } + + static void +@@ -530,7 +541,7 @@ mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb) + + switch (rxd->eid) { + case MCU_EVENT_BSS_BEACON_LOSS: +- mt7921_mcu_beacon_loss_event(dev, skb); ++ mt7921_mcu_connection_loss_event(dev, skb); + break; + case MCU_EVENT_SCHED_SCAN_DONE: + case MCU_EVENT_SCAN_DONE: +@@ -1368,6 +1379,7 @@ mt7921_pm_interface_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) + { + struct mt7921_phy *phy = priv; + struct mt7921_dev *dev = phy->dev; ++ struct ieee80211_hw *hw = mt76_hw(dev); + int ret; + + if (dev->pm.enable) +@@ -1380,9 +1392,11 @@ mt7921_pm_interface_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) + + if (dev->pm.enable) { + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; ++ ieee80211_hw_set(hw, CONNECTION_MONITOR); + mt76_set(dev, MT_WF_RFCR(0), MT_WF_RFCR_DROP_OTHER_BEACON); + } else { + vif->driver_flags &= ~IEEE80211_VIF_BEACON_FILTER; ++ __clear_bit(IEEE80211_HW_CONNECTION_MONITOR, hw->flags); + mt76_clear(dev, MT_WF_RFCR(0), MT_WF_RFCR_DROP_OTHER_BEACON); + } + } +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +index 59862ea4951ce..4cc8a372b2772 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +@@ -156,6 +156,7 @@ struct mt7921_dev { + u16 chainmask; + + struct work_struct reset_work; ++ bool hw_full_reset; + + struct list_head sta_poll_list; + spinlock_t sta_poll_lock; +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c +index fa02d934f0bff..13263f50dc00a 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c +@@ -188,21 +188,26 @@ static int mt7921_pci_suspend(struct pci_dev *pdev, pm_message_t state) + { + struct mt76_dev *mdev = pci_get_drvdata(pdev); + struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); ++ struct mt76_connac_pm *pm = &dev->pm; + bool hif_suspend; + int i, err; + +- err = mt76_connac_pm_wake(&dev->mphy, &dev->pm); ++ pm->suspended = true; ++ cancel_delayed_work_sync(&pm->ps_work); ++ cancel_work_sync(&pm->wake_work); ++ ++ err = mt7921_mcu_drv_pmctrl(dev); + if (err < 0) +- return err; ++ goto restore_suspend; + + hif_suspend = !test_bit(MT76_STATE_SUSPEND, &dev->mphy.state); + if (hif_suspend) { + err = mt76_connac_mcu_set_hif_suspend(mdev, true); + if (err) +- return err; ++ goto restore_suspend; + } + +- if (!dev->pm.enable) ++ if (!pm->enable) + mt76_connac_mcu_set_deep_sleep(&dev->mt76, true); + + napi_disable(&mdev->tx_napi); +@@ -231,27 +236,30 @@ static int mt7921_pci_suspend(struct pci_dev *pdev, pm_message_t state) + + err = mt7921_mcu_fw_pmctrl(dev); + if (err) +- goto restore; ++ goto restore_napi; + + pci_save_state(pdev); + err = pci_set_power_state(pdev, pci_choose_state(pdev, state)); + if (err) +- goto restore; ++ goto restore_napi; + + return 0; + +-restore: ++restore_napi: + mt76_for_each_q_rx(mdev, i) { + napi_enable(&mdev->napi[i]); + } + napi_enable(&mdev->tx_napi); + +- if (!dev->pm.enable) ++ if (!pm->enable) + mt76_connac_mcu_set_deep_sleep(&dev->mt76, false); + + if (hif_suspend) + mt76_connac_mcu_set_hif_suspend(mdev, false); + ++restore_suspend: ++ pm->suspended = false; ++ + return err; + } + +@@ -261,6 +269,7 @@ static int mt7921_pci_resume(struct pci_dev *pdev) + struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); + int i, err; + ++ dev->pm.suspended = false; + err = pci_set_power_state(pdev, PCI_D0); + if (err) + return err; +diff --git a/drivers/net/wireless/mediatek/mt76/testmode.c b/drivers/net/wireless/mediatek/mt76/testmode.c +index 001d0ba5f73e6..f614c887f3233 100644 +--- a/drivers/net/wireless/mediatek/mt76/testmode.c ++++ b/drivers/net/wireless/mediatek/mt76/testmode.c +@@ -158,19 +158,18 @@ int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len) + frag_len = MT_TXP_MAX_LEN; + + frag = alloc_skb(frag_len, GFP_KERNEL); +- if (!frag) ++ if (!frag) { ++ mt76_testmode_free_skb(phy); ++ dev_kfree_skb(head); + return -ENOMEM; ++ } + + __skb_put_zero(frag, frag_len); + head->len += frag->len; + head->data_len += frag->len; + +- if (*frag_tail) { +- (*frag_tail)->next = frag; +- frag_tail = &frag; +- } else { +- *frag_tail = frag; +- } ++ *frag_tail = frag; ++ frag_tail = &(*frag_tail)->next; + } + + mt76_testmode_free_skb(phy); +diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c +index 53ea8de82df06..441d06e30b1a5 100644 +--- a/drivers/net/wireless/mediatek/mt76/tx.c ++++ b/drivers/net/wireless/mediatek/mt76/tx.c +@@ -285,7 +285,7 @@ mt76_tx(struct mt76_phy *phy, struct ieee80211_sta *sta, + skb_set_queue_mapping(skb, qid); + } + +- if (!(wcid->tx_info & MT_WCID_TX_INFO_SET)) ++ if (wcid && !(wcid->tx_info & MT_WCID_TX_INFO_SET)) + ieee80211_get_tx_rates(info->control.vif, sta, skb, + info->control.rates, 1); + +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +index 6cb593cc33c2d..6d06f26a48942 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -4371,26 +4371,28 @@ static void rtw8822c_pwrtrack_set(struct rtw_dev *rtwdev, u8 rf_path) + } + } + +-static void rtw8822c_pwr_track_path(struct rtw_dev *rtwdev, +- struct rtw_swing_table *swing_table, +- u8 path) ++static void rtw8822c_pwr_track_stats(struct rtw_dev *rtwdev, u8 path) + { +- struct rtw_dm_info *dm_info = &rtwdev->dm_info; +- u8 thermal_value, delta; ++ u8 thermal_value; + + if (rtwdev->efuse.thermal_meter[path] == 0xff) + return; + + thermal_value = rtw_read_rf(rtwdev, path, RF_T_METER, 0x7e); +- + rtw_phy_pwrtrack_avg(rtwdev, thermal_value, path); ++} + +- delta = rtw_phy_pwrtrack_get_delta(rtwdev, path); ++static void rtw8822c_pwr_track_path(struct rtw_dev *rtwdev, ++ struct rtw_swing_table *swing_table, ++ u8 path) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ u8 delta; + ++ delta = rtw_phy_pwrtrack_get_delta(rtwdev, path); + dm_info->delta_power_index[path] = + rtw_phy_pwrtrack_get_pwridx(rtwdev, swing_table, path, path, + delta); +- + rtw8822c_pwrtrack_set(rtwdev, path); + } + +@@ -4401,12 +4403,12 @@ static void __rtw8822c_pwr_track(struct rtw_dev *rtwdev) + + rtw_phy_config_swing_table(rtwdev, &swing_table); + ++ for (i = 0; i < rtwdev->hal.rf_path_num; i++) ++ rtw8822c_pwr_track_stats(rtwdev, i); + if (rtw_phy_pwrtrack_need_lck(rtwdev)) + rtw8822c_do_lck(rtwdev); +- + for (i = 0; i < rtwdev->hal.rf_path_num; i++) + rtw8822c_pwr_track_path(rtwdev, &swing_table, i); +- + } + + static void rtw8822c_pwr_track(struct rtw_dev *rtwdev) +diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c +index ce9892152f4d4..99b21a2c83861 100644 +--- a/drivers/net/wireless/rsi/rsi_91x_hal.c ++++ b/drivers/net/wireless/rsi/rsi_91x_hal.c +@@ -203,7 +203,7 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb) + wh->frame_control |= cpu_to_le16(RSI_SET_PS_ENABLE); + + if ((!(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) && +- (common->secinfo.security_enable)) { ++ info->control.hw_key) { + if (rsi_is_cipher_wep(common)) + ieee80211_size += 4; + else +@@ -470,9 +470,9 @@ int rsi_prepare_beacon(struct rsi_common *common, struct sk_buff *skb) + } + + if (common->band == NL80211_BAND_2GHZ) +- bcn_frm->bbp_info |= cpu_to_le16(RSI_RATE_1); ++ bcn_frm->rate_info |= cpu_to_le16(RSI_RATE_1); + else +- bcn_frm->bbp_info |= cpu_to_le16(RSI_RATE_6); ++ bcn_frm->rate_info |= cpu_to_le16(RSI_RATE_6); + + if (mac_bcn->data[tim_offset + 2] == 0) + bcn_frm->frame_info |= cpu_to_le16(RSI_DATA_DESC_DTIM_BEACON); +diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c +index 16025300cddb3..57c9e3559dfd1 100644 +--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c ++++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c +@@ -1028,7 +1028,6 @@ static int rsi_mac80211_set_key(struct ieee80211_hw *hw, + mutex_lock(&common->mutex); + switch (cmd) { + case SET_KEY: +- secinfo->security_enable = true; + status = rsi_hal_key_config(hw, vif, key, sta); + if (status) { + mutex_unlock(&common->mutex); +@@ -1047,8 +1046,6 @@ static int rsi_mac80211_set_key(struct ieee80211_hw *hw, + break; + + case DISABLE_KEY: +- if (vif->type == NL80211_IFTYPE_STATION) +- secinfo->security_enable = false; + rsi_dbg(ERR_ZONE, "%s: RSI del key\n", __func__); + memset(key, 0, sizeof(struct ieee80211_key_conf)); + status = rsi_hal_key_config(hw, vif, key, sta); +diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c +index 33c76d39a8e96..b6d050a2fbe7e 100644 +--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c ++++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c +@@ -1803,8 +1803,7 @@ int rsi_send_wowlan_request(struct rsi_common *common, u16 flags, + RSI_WIFI_MGMT_Q); + cmd_frame->desc.desc_dword0.frame_type = WOWLAN_CONFIG_PARAMS; + cmd_frame->host_sleep_status = sleep_status; +- if (common->secinfo.security_enable && +- common->secinfo.gtk_cipher) ++ if (common->secinfo.gtk_cipher) + flags |= RSI_WOW_GTK_REKEY; + if (sleep_status) + cmd_frame->wow_flags = flags; +diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h +index a1065e5a92b43..0f535850a3836 100644 +--- a/drivers/net/wireless/rsi/rsi_main.h ++++ b/drivers/net/wireless/rsi/rsi_main.h +@@ -151,7 +151,6 @@ enum edca_queue { + }; + + struct security_info { +- bool security_enable; + u32 ptk_cipher; + u32 gtk_cipher; + }; +diff --git a/drivers/net/wireless/st/cw1200/scan.c b/drivers/net/wireless/st/cw1200/scan.c +index 988581cc134b7..1f856fbbc0ea4 100644 +--- a/drivers/net/wireless/st/cw1200/scan.c ++++ b/drivers/net/wireless/st/cw1200/scan.c +@@ -75,30 +75,27 @@ int cw1200_hw_scan(struct ieee80211_hw *hw, + if (req->n_ssids > WSM_SCAN_MAX_NUM_OF_SSIDS) + return -EINVAL; + +- /* will be unlocked in cw1200_scan_work() */ +- down(&priv->scan.lock); +- mutex_lock(&priv->conf_mutex); +- + frame.skb = ieee80211_probereq_get(hw, priv->vif->addr, NULL, 0, + req->ie_len); +- if (!frame.skb) { +- mutex_unlock(&priv->conf_mutex); +- up(&priv->scan.lock); ++ if (!frame.skb) + return -ENOMEM; +- } + + if (req->ie_len) + skb_put_data(frame.skb, req->ie, req->ie_len); + ++ /* will be unlocked in cw1200_scan_work() */ ++ down(&priv->scan.lock); ++ mutex_lock(&priv->conf_mutex); ++ + ret = wsm_set_template_frame(priv, &frame); + if (!ret) { + /* Host want to be the probe responder. */ + ret = wsm_set_probe_responder(priv, true); + } + if (ret) { +- dev_kfree_skb(frame.skb); + mutex_unlock(&priv->conf_mutex); + up(&priv->scan.lock); ++ dev_kfree_skb(frame.skb); + return ret; + } + +@@ -120,8 +117,8 @@ int cw1200_hw_scan(struct ieee80211_hw *hw, + ++priv->scan.n_ssids; + } + +- dev_kfree_skb(frame.skb); + mutex_unlock(&priv->conf_mutex); ++ dev_kfree_skb(frame.skb); + queue_work(priv->workqueue, &priv->scan.work); + return 0; + } +diff --git a/drivers/net/wwan/Kconfig b/drivers/net/wwan/Kconfig +index 7ad1920120bcb..e9d8a1c25e433 100644 +--- a/drivers/net/wwan/Kconfig ++++ b/drivers/net/wwan/Kconfig +@@ -3,15 +3,9 @@ + # Wireless WAN device configuration + # + +-menuconfig WWAN +- bool "Wireless WAN" +- help +- This section contains Wireless WAN configuration for WWAN framework +- and drivers. +- +-if WWAN ++menu "Wireless WAN" + +-config WWAN_CORE ++config WWAN + tristate "WWAN Driver Core" + help + Say Y here if you want to use the WWAN driver core. This driver +@@ -20,9 +14,10 @@ config WWAN_CORE + To compile this driver as a module, choose M here: the module will be + called wwan. + ++if WWAN ++ + config MHI_WWAN_CTRL + tristate "MHI WWAN control driver for QCOM-based PCIe modems" +- select WWAN_CORE + depends on MHI_BUS + help + MHI WWAN CTRL allows QCOM-based PCIe modems to expose different modem +@@ -35,3 +30,5 @@ config MHI_WWAN_CTRL + called mhi_wwan_ctrl. + + endif # WWAN ++ ++endmenu +diff --git a/drivers/net/wwan/Makefile b/drivers/net/wwan/Makefile +index 556cd90958cae..289771a4f952e 100644 +--- a/drivers/net/wwan/Makefile ++++ b/drivers/net/wwan/Makefile +@@ -3,7 +3,7 @@ + # Makefile for the Linux WWAN device drivers. + # + +-obj-$(CONFIG_WWAN_CORE) += wwan.o ++obj-$(CONFIG_WWAN) += wwan.o + wwan-objs += wwan_core.o + + obj-$(CONFIG_MHI_WWAN_CTRL) += mhi_wwan_ctrl.o +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index a29b170701fc6..42ad75ff13481 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -1032,7 +1032,7 @@ static inline void nvme_handle_cqe(struct nvme_queue *nvmeq, u16 idx) + + static inline void nvme_update_cq_head(struct nvme_queue *nvmeq) + { +- u16 tmp = nvmeq->cq_head + 1; ++ u32 tmp = nvmeq->cq_head + 1; + + if (tmp == nvmeq->q_depth) { + nvmeq->cq_head = 0; +@@ -2831,10 +2831,7 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev) + #ifdef CONFIG_ACPI + static bool nvme_acpi_storage_d3(struct pci_dev *dev) + { +- struct acpi_device *adev; +- struct pci_dev *root; +- acpi_handle handle; +- acpi_status status; ++ struct acpi_device *adev = ACPI_COMPANION(&dev->dev); + u8 val; + + /* +@@ -2842,28 +2839,9 @@ static bool nvme_acpi_storage_d3(struct pci_dev *dev) + * must use D3 to support deep platform power savings during + * suspend-to-idle. + */ +- root = pcie_find_root_port(dev); +- if (!root) +- return false; + +- adev = ACPI_COMPANION(&root->dev); + if (!adev) + return false; +- +- /* +- * The property is defined in the PXSX device for South complex ports +- * and in the PEGP device for North complex ports. +- */ +- status = acpi_get_handle(adev->handle, "PXSX", &handle); +- if (ACPI_FAILURE(status)) { +- status = acpi_get_handle(adev->handle, "PEGP", &handle); +- if (ACPI_FAILURE(status)) +- return false; +- } +- +- if (acpi_bus_get_device(handle, &adev)) +- return false; +- + if (fwnode_property_read_u8(acpi_fwnode_handle(adev), "StorageD3Enable", + &val)) + return false; +diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c +index 34f4b3402f7c1..79a463090dd30 100644 +--- a/drivers/nvme/host/tcp.c ++++ b/drivers/nvme/host/tcp.c +@@ -1973,11 +1973,13 @@ static int nvme_tcp_setup_ctrl(struct nvme_ctrl *ctrl, bool new) + return ret; + + if (ctrl->icdoff) { ++ ret = -EOPNOTSUPP; + dev_err(ctrl->device, "icdoff is not supported!\n"); + goto destroy_admin; + } + + if (!(ctrl->sgls & ((1 << 0) | (1 << 1)))) { ++ ret = -EOPNOTSUPP; + dev_err(ctrl->device, "Mandatory sgls are not supported!\n"); + goto destroy_admin; + } +diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c +index 19e113240fff9..22b5108168a6a 100644 +--- a/drivers/nvme/target/fc.c ++++ b/drivers/nvme/target/fc.c +@@ -2510,13 +2510,6 @@ nvmet_fc_handle_fcp_rqst(struct nvmet_fc_tgtport *tgtport, + u32 xfrlen = be32_to_cpu(cmdiu->data_len); + int ret; + +- /* +- * if there is no nvmet mapping to the targetport there +- * shouldn't be requests. just terminate them. +- */ +- if (!tgtport->pe) +- goto transport_error; +- + /* + * Fused commands are currently not supported in the linux + * implementation. +@@ -2544,7 +2537,8 @@ nvmet_fc_handle_fcp_rqst(struct nvmet_fc_tgtport *tgtport, + + fod->req.cmd = &fod->cmdiubuf.sqe; + fod->req.cqe = &fod->rspiubuf.cqe; +- fod->req.port = tgtport->pe->port; ++ if (tgtport->pe) ++ fod->req.port = tgtport->pe->port; + + /* clear any response payload */ + memset(&fod->rspiubuf, 0, sizeof(fod->rspiubuf)); +diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c +index ba17a80b8c79c..cc71e0b3eed9f 100644 +--- a/drivers/of/fdt.c ++++ b/drivers/of/fdt.c +@@ -510,11 +510,11 @@ static int __init __reserved_mem_reserve_reg(unsigned long node, + + if (size && + early_init_dt_reserve_memory_arch(base, size, nomap) == 0) +- pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %ld MiB\n", +- uname, &base, (unsigned long)size / SZ_1M); ++ pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n", ++ uname, &base, (unsigned long)(size / SZ_1M)); + else +- pr_info("Reserved memory: failed to reserve memory for node '%s': base %pa, size %ld MiB\n", +- uname, &base, (unsigned long)size / SZ_1M); ++ pr_info("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n", ++ uname, &base, (unsigned long)(size / SZ_1M)); + + len -= t_len; + if (first) { +diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c +index 15e2417974d67..3502ba522c397 100644 +--- a/drivers/of/of_reserved_mem.c ++++ b/drivers/of/of_reserved_mem.c +@@ -134,9 +134,9 @@ static int __init __reserved_mem_alloc_size(unsigned long node, + ret = early_init_dt_alloc_reserved_memory_arch(size, + align, start, end, nomap, &base); + if (ret == 0) { +- pr_debug("allocated memory for '%s' node: base %pa, size %ld MiB\n", ++ pr_debug("allocated memory for '%s' node: base %pa, size %lu MiB\n", + uname, &base, +- (unsigned long)size / SZ_1M); ++ (unsigned long)(size / SZ_1M)); + break; + } + len -= t_len; +@@ -146,8 +146,8 @@ static int __init __reserved_mem_alloc_size(unsigned long node, + ret = early_init_dt_alloc_reserved_memory_arch(size, align, + 0, 0, nomap, &base); + if (ret == 0) +- pr_debug("allocated memory for '%s' node: base %pa, size %ld MiB\n", +- uname, &base, (unsigned long)size / SZ_1M); ++ pr_debug("allocated memory for '%s' node: base %pa, size %lu MiB\n", ++ uname, &base, (unsigned long)(size / SZ_1M)); + } + + if (base == 0) { +diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c +index 6511648271b23..bebe3eeebc4e1 100644 +--- a/drivers/pci/controller/pci-hyperv.c ++++ b/drivers/pci/controller/pci-hyperv.c +@@ -3476,6 +3476,9 @@ static void __exit exit_hv_pci_drv(void) + + static int __init init_hv_pci_drv(void) + { ++ if (!hv_is_hyperv_initialized()) ++ return -ENODEV; ++ + /* Set the invalid domain number's bit, so it will not be used */ + set_bit(HVPCI_DOM_INVALID, hvpci_dom_map); + +diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c +index 56a5c355701d0..49016f2f505e0 100644 +--- a/drivers/perf/arm-cmn.c ++++ b/drivers/perf/arm-cmn.c +@@ -1212,7 +1212,7 @@ static int arm_cmn_init_irqs(struct arm_cmn *cmn) + irq = cmn->dtc[i].irq; + for (j = i; j--; ) { + if (cmn->dtc[j].irq == irq) { +- cmn->dtc[j].irq_friend = j - i; ++ cmn->dtc[j].irq_friend = i - j; + goto next; + } + } +diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c +index ff6fab4bae30d..863d9f702aa17 100644 +--- a/drivers/perf/arm_smmuv3_pmu.c ++++ b/drivers/perf/arm_smmuv3_pmu.c +@@ -277,7 +277,7 @@ static int smmu_pmu_apply_event_filter(struct smmu_pmu *smmu_pmu, + struct perf_event *event, int idx) + { + u32 span, sid; +- unsigned int num_ctrs = smmu_pmu->num_counters; ++ unsigned int cur_idx, num_ctrs = smmu_pmu->num_counters; + bool filter_en = !!get_filter_enable(event); + + span = filter_en ? get_filter_span(event) : +@@ -285,17 +285,19 @@ static int smmu_pmu_apply_event_filter(struct smmu_pmu *smmu_pmu, + sid = filter_en ? get_filter_stream_id(event) : + SMMU_PMCG_DEFAULT_FILTER_SID; + +- /* Support individual filter settings */ +- if (!smmu_pmu->global_filter) { ++ cur_idx = find_first_bit(smmu_pmu->used_counters, num_ctrs); ++ /* ++ * Per-counter filtering, or scheduling the first globally-filtered ++ * event into an empty PMU so idx == 0 and it works out equivalent. ++ */ ++ if (!smmu_pmu->global_filter || cur_idx == num_ctrs) { + smmu_pmu_set_event_filter(event, idx, span, sid); + return 0; + } + +- /* Requested settings same as current global settings*/ +- idx = find_first_bit(smmu_pmu->used_counters, num_ctrs); +- if (idx == num_ctrs || +- smmu_pmu_check_global_filter(smmu_pmu->events[idx], event)) { +- smmu_pmu_set_event_filter(event, 0, span, sid); ++ /* Otherwise, must match whatever's currently scheduled */ ++ if (smmu_pmu_check_global_filter(smmu_pmu->events[cur_idx], event)) { ++ smmu_pmu_set_evtyper(smmu_pmu, idx, get_event(event)); + return 0; + } + +diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c +index 2bbb931880649..7b87aaf267d57 100644 +--- a/drivers/perf/fsl_imx8_ddr_perf.c ++++ b/drivers/perf/fsl_imx8_ddr_perf.c +@@ -705,8 +705,10 @@ static int ddr_perf_probe(struct platform_device *pdev) + + name = devm_kasprintf(&pdev->dev, GFP_KERNEL, DDR_PERF_DEV_NAME "%d", + num); +- if (!name) +- return -ENOMEM; ++ if (!name) { ++ ret = -ENOMEM; ++ goto cpuhp_state_err; ++ } + + pmu->devtype_data = of_device_get_match_data(&pdev->dev); + +diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c +index 0316fabe32f1a..acc864bded2be 100644 +--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c ++++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c +@@ -90,7 +90,7 @@ static void hisi_hha_pmu_config_ds(struct perf_event *event) + + val = readl(hha_pmu->base + HHA_DATSRC_CTRL); + val |= HHA_DATSRC_SKT_EN; +- writel(ds_skt, hha_pmu->base + HHA_DATSRC_CTRL); ++ writel(val, hha_pmu->base + HHA_DATSRC_CTRL); + } + } + +@@ -104,7 +104,7 @@ static void hisi_hha_pmu_clear_ds(struct perf_event *event) + + val = readl(hha_pmu->base + HHA_DATSRC_CTRL); + val &= ~HHA_DATSRC_SKT_EN; +- writel(ds_skt, hha_pmu->base + HHA_DATSRC_CTRL); ++ writel(val, hha_pmu->base + HHA_DATSRC_CTRL); + } + } + +diff --git a/drivers/phy/ralink/phy-mt7621-pci.c b/drivers/phy/ralink/phy-mt7621-pci.c +index 2a9465f4bb3a9..3b1245fc5a02e 100644 +--- a/drivers/phy/ralink/phy-mt7621-pci.c ++++ b/drivers/phy/ralink/phy-mt7621-pci.c +@@ -272,8 +272,8 @@ static struct phy *mt7621_pcie_phy_of_xlate(struct device *dev, + + mt7621_phy->has_dual_port = args->args[0]; + +- dev_info(dev, "PHY for 0x%08x (dual port = %d)\n", +- (unsigned int)mt7621_phy->port_base, mt7621_phy->has_dual_port); ++ dev_dbg(dev, "PHY for 0x%px (dual port = %d)\n", ++ mt7621_phy->port_base, mt7621_phy->has_dual_port); + + return mt7621_phy->phy; + } +diff --git a/drivers/phy/socionext/phy-uniphier-pcie.c b/drivers/phy/socionext/phy-uniphier-pcie.c +index e4adab375c737..6bdbd1f214dd4 100644 +--- a/drivers/phy/socionext/phy-uniphier-pcie.c ++++ b/drivers/phy/socionext/phy-uniphier-pcie.c +@@ -24,11 +24,13 @@ + #define PORT_SEL_1 FIELD_PREP(PORT_SEL_MASK, 1) + + #define PCL_PHY_TEST_I 0x2000 +-#define PCL_PHY_TEST_O 0x2004 + #define TESTI_DAT_MASK GENMASK(13, 6) + #define TESTI_ADR_MASK GENMASK(5, 1) + #define TESTI_WR_EN BIT(0) + ++#define PCL_PHY_TEST_O 0x2004 ++#define TESTO_DAT_MASK GENMASK(7, 0) ++ + #define PCL_PHY_RESET 0x200c + #define PCL_PHY_RESET_N_MNMODE BIT(8) /* =1:manual */ + #define PCL_PHY_RESET_N BIT(0) /* =1:deasssert */ +@@ -77,11 +79,12 @@ static void uniphier_pciephy_set_param(struct uniphier_pciephy_priv *priv, + val = FIELD_PREP(TESTI_DAT_MASK, 1); + val |= FIELD_PREP(TESTI_ADR_MASK, reg); + uniphier_pciephy_testio_write(priv, val); +- val = readl(priv->base + PCL_PHY_TEST_O); ++ val = readl(priv->base + PCL_PHY_TEST_O) & TESTO_DAT_MASK; + + /* update value */ +- val &= ~FIELD_PREP(TESTI_DAT_MASK, mask); +- val = FIELD_PREP(TESTI_DAT_MASK, mask & param); ++ val &= ~mask; ++ val |= mask & param; ++ val = FIELD_PREP(TESTI_DAT_MASK, val); + val |= FIELD_PREP(TESTI_ADR_MASK, reg); + uniphier_pciephy_testio_write(priv, val); + uniphier_pciephy_testio_write(priv, val | TESTI_WR_EN); +diff --git a/drivers/phy/ti/phy-dm816x-usb.c b/drivers/phy/ti/phy-dm816x-usb.c +index 57adc08a89b2d..9fe6ea6fdae55 100644 +--- a/drivers/phy/ti/phy-dm816x-usb.c ++++ b/drivers/phy/ti/phy-dm816x-usb.c +@@ -242,19 +242,28 @@ static int dm816x_usb_phy_probe(struct platform_device *pdev) + + pm_runtime_enable(phy->dev); + generic_phy = devm_phy_create(phy->dev, NULL, &ops); +- if (IS_ERR(generic_phy)) +- return PTR_ERR(generic_phy); ++ if (IS_ERR(generic_phy)) { ++ error = PTR_ERR(generic_phy); ++ goto clk_unprepare; ++ } + + phy_set_drvdata(generic_phy, phy); + + phy_provider = devm_of_phy_provider_register(phy->dev, + of_phy_simple_xlate); +- if (IS_ERR(phy_provider)) +- return PTR_ERR(phy_provider); ++ if (IS_ERR(phy_provider)) { ++ error = PTR_ERR(phy_provider); ++ goto clk_unprepare; ++ } + + usb_add_phy_dev(&phy->phy); + + return 0; ++ ++clk_unprepare: ++ pm_runtime_disable(phy->dev); ++ clk_unprepare(phy->refclk); ++ return error; + } + + static int dm816x_usb_phy_remove(struct platform_device *pdev) +diff --git a/drivers/pinctrl/renesas/pfc-r8a7796.c b/drivers/pinctrl/renesas/pfc-r8a7796.c +index 44e9d2eea484a..bbb1b436ded31 100644 +--- a/drivers/pinctrl/renesas/pfc-r8a7796.c ++++ b/drivers/pinctrl/renesas/pfc-r8a7796.c +@@ -67,6 +67,7 @@ + PIN_NOGP_CFG(QSPI1_MOSI_IO0, "QSPI1_MOSI_IO0", fn, CFG_FLAGS), \ + PIN_NOGP_CFG(QSPI1_SPCLK, "QSPI1_SPCLK", fn, CFG_FLAGS), \ + PIN_NOGP_CFG(QSPI1_SSL, "QSPI1_SSL", fn, CFG_FLAGS), \ ++ PIN_NOGP_CFG(PRESET_N, "PRESET#", fn, SH_PFC_PIN_CFG_PULL_DOWN),\ + PIN_NOGP_CFG(RPC_INT_N, "RPC_INT#", fn, CFG_FLAGS), \ + PIN_NOGP_CFG(RPC_RESET_N, "RPC_RESET#", fn, CFG_FLAGS), \ + PIN_NOGP_CFG(RPC_WP_N, "RPC_WP#", fn, CFG_FLAGS), \ +@@ -6218,7 +6219,7 @@ static const struct pinmux_bias_reg pinmux_bias_regs[] = { + [ 4] = RCAR_GP_PIN(6, 29), /* USB30_OVC */ + [ 5] = RCAR_GP_PIN(6, 30), /* GP6_30 */ + [ 6] = RCAR_GP_PIN(6, 31), /* GP6_31 */ +- [ 7] = SH_PFC_PIN_NONE, ++ [ 7] = PIN_PRESET_N, /* PRESET# */ + [ 8] = SH_PFC_PIN_NONE, + [ 9] = SH_PFC_PIN_NONE, + [10] = SH_PFC_PIN_NONE, +diff --git a/drivers/pinctrl/renesas/pfc-r8a77990.c b/drivers/pinctrl/renesas/pfc-r8a77990.c +index d040eb3e305da..eeebbab4dd811 100644 +--- a/drivers/pinctrl/renesas/pfc-r8a77990.c ++++ b/drivers/pinctrl/renesas/pfc-r8a77990.c +@@ -53,10 +53,10 @@ + PIN_NOGP_CFG(FSCLKST_N, "FSCLKST_N", fn, CFG_FLAGS), \ + PIN_NOGP_CFG(MLB_REF, "MLB_REF", fn, CFG_FLAGS), \ + PIN_NOGP_CFG(PRESETOUT_N, "PRESETOUT_N", fn, CFG_FLAGS), \ +- PIN_NOGP_CFG(TCK, "TCK", fn, CFG_FLAGS), \ +- PIN_NOGP_CFG(TDI, "TDI", fn, CFG_FLAGS), \ +- PIN_NOGP_CFG(TMS, "TMS", fn, CFG_FLAGS), \ +- PIN_NOGP_CFG(TRST_N, "TRST_N", fn, CFG_FLAGS) ++ PIN_NOGP_CFG(TCK, "TCK", fn, SH_PFC_PIN_CFG_PULL_UP), \ ++ PIN_NOGP_CFG(TDI, "TDI", fn, SH_PFC_PIN_CFG_PULL_UP), \ ++ PIN_NOGP_CFG(TMS, "TMS", fn, SH_PFC_PIN_CFG_PULL_UP), \ ++ PIN_NOGP_CFG(TRST_N, "TRST_N", fn, SH_PFC_PIN_CFG_PULL_UP) + + /* + * F_() : just information +diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c +index d41d7ad14be0d..0cb927f0f301a 100644 +--- a/drivers/platform/x86/asus-nb-wmi.c ++++ b/drivers/platform/x86/asus-nb-wmi.c +@@ -110,11 +110,6 @@ static struct quirk_entry quirk_asus_forceals = { + .wmi_force_als_set = true, + }; + +-static struct quirk_entry quirk_asus_vendor_backlight = { +- .wmi_backlight_power = true, +- .wmi_backlight_set_devstate = true, +-}; +- + static struct quirk_entry quirk_asus_use_kbd_dock_devid = { + .use_kbd_dock_devid = true, + }; +@@ -425,78 +420,6 @@ static const struct dmi_system_id asus_quirks[] = { + }, + .driver_data = &quirk_asus_forceals, + }, +- { +- .callback = dmi_matched, +- .ident = "ASUSTeK COMPUTER INC. GA401IH", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), +- DMI_MATCH(DMI_PRODUCT_NAME, "GA401IH"), +- }, +- .driver_data = &quirk_asus_vendor_backlight, +- }, +- { +- .callback = dmi_matched, +- .ident = "ASUSTeK COMPUTER INC. GA401II", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), +- DMI_MATCH(DMI_PRODUCT_NAME, "GA401II"), +- }, +- .driver_data = &quirk_asus_vendor_backlight, +- }, +- { +- .callback = dmi_matched, +- .ident = "ASUSTeK COMPUTER INC. GA401IU", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), +- DMI_MATCH(DMI_PRODUCT_NAME, "GA401IU"), +- }, +- .driver_data = &quirk_asus_vendor_backlight, +- }, +- { +- .callback = dmi_matched, +- .ident = "ASUSTeK COMPUTER INC. GA401IV", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), +- DMI_MATCH(DMI_PRODUCT_NAME, "GA401IV"), +- }, +- .driver_data = &quirk_asus_vendor_backlight, +- }, +- { +- .callback = dmi_matched, +- .ident = "ASUSTeK COMPUTER INC. GA401IVC", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), +- DMI_MATCH(DMI_PRODUCT_NAME, "GA401IVC"), +- }, +- .driver_data = &quirk_asus_vendor_backlight, +- }, +- { +- .callback = dmi_matched, +- .ident = "ASUSTeK COMPUTER INC. GA502II", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), +- DMI_MATCH(DMI_PRODUCT_NAME, "GA502II"), +- }, +- .driver_data = &quirk_asus_vendor_backlight, +- }, +- { +- .callback = dmi_matched, +- .ident = "ASUSTeK COMPUTER INC. GA502IU", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), +- DMI_MATCH(DMI_PRODUCT_NAME, "GA502IU"), +- }, +- .driver_data = &quirk_asus_vendor_backlight, +- }, +- { +- .callback = dmi_matched, +- .ident = "ASUSTeK COMPUTER INC. GA502IV", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), +- DMI_MATCH(DMI_PRODUCT_NAME, "GA502IV"), +- }, +- .driver_data = &quirk_asus_vendor_backlight, +- }, + { + .callback = dmi_matched, + .ident = "Asus Transformer T100TA / T100HA / T100CHI", +diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c +index fa7232ad8c395..352508d304675 100644 +--- a/drivers/platform/x86/toshiba_acpi.c ++++ b/drivers/platform/x86/toshiba_acpi.c +@@ -2831,6 +2831,7 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) + + if (!dev->info_supported && !dev->system_event_supported) { + pr_warn("No hotkey query interface found\n"); ++ error = -EINVAL; + goto err_remove_filter; + } + +diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c +index bde740d6120e1..424cf2a847448 100644 +--- a/drivers/platform/x86/touchscreen_dmi.c ++++ b/drivers/platform/x86/touchscreen_dmi.c +@@ -299,6 +299,35 @@ static const struct ts_dmi_data estar_beauty_hd_data = { + .properties = estar_beauty_hd_props, + }; + ++/* Generic props + data for upside-down mounted GDIX1001 touchscreens */ ++static const struct property_entry gdix1001_upside_down_props[] = { ++ PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"), ++ PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), ++ { } ++}; ++ ++static const struct ts_dmi_data gdix1001_00_upside_down_data = { ++ .acpi_name = "GDIX1001:00", ++ .properties = gdix1001_upside_down_props, ++}; ++ ++static const struct ts_dmi_data gdix1001_01_upside_down_data = { ++ .acpi_name = "GDIX1001:01", ++ .properties = gdix1001_upside_down_props, ++}; ++ ++static const struct property_entry glavey_tm800a550l_props[] = { ++ PROPERTY_ENTRY_STRING("firmware-name", "gt912-glavey-tm800a550l.fw"), ++ PROPERTY_ENTRY_STRING("goodix,config-name", "gt912-glavey-tm800a550l.cfg"), ++ PROPERTY_ENTRY_U32("goodix,main-clk", 54), ++ { } ++}; ++ ++static const struct ts_dmi_data glavey_tm800a550l_data = { ++ .acpi_name = "GDIX1001:00", ++ .properties = glavey_tm800a550l_props, ++}; ++ + static const struct property_entry gp_electronic_t701_props[] = { + PROPERTY_ENTRY_U32("touchscreen-size-x", 960), + PROPERTY_ENTRY_U32("touchscreen-size-y", 640), +@@ -1038,6 +1067,15 @@ const struct dmi_system_id touchscreen_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "eSTAR BEAUTY HD Intel Quad core"), + }, + }, ++ { /* Glavey TM800A550L */ ++ .driver_data = (void *)&glavey_tm800a550l_data, ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), ++ DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), ++ /* Above strings are too generic, also match on BIOS version */ ++ DMI_MATCH(DMI_BIOS_VERSION, "ZY-8-BI-PX4S70VTR400-X423B-005-D"), ++ }, ++ }, + { + /* GP-electronic T701 */ + .driver_data = (void *)&gp_electronic_t701_data, +@@ -1330,6 +1368,24 @@ const struct dmi_system_id touchscreen_dmi_table[] = { + DMI_MATCH(DMI_BOARD_NAME, "X3 Plus"), + }, + }, ++ { ++ /* Teclast X89 (Android version / BIOS) */ ++ .driver_data = (void *)&gdix1001_00_upside_down_data, ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "WISKY"), ++ DMI_MATCH(DMI_BOARD_NAME, "3G062i"), ++ }, ++ }, ++ { ++ /* Teclast X89 (Windows version / BIOS) */ ++ .driver_data = (void *)&gdix1001_01_upside_down_data, ++ .matches = { ++ /* tPAD is too generic, also match on bios date */ ++ DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"), ++ DMI_MATCH(DMI_BOARD_NAME, "tPAD"), ++ DMI_MATCH(DMI_BIOS_DATE, "12/19/2014"), ++ }, ++ }, + { + /* Teclast X98 Plus II */ + .driver_data = (void *)&teclast_x98plus2_data, +@@ -1338,6 +1394,19 @@ const struct dmi_system_id touchscreen_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "X98 Plus II"), + }, + }, ++ { ++ /* Teclast X98 Pro */ ++ .driver_data = (void *)&gdix1001_00_upside_down_data, ++ .matches = { ++ /* ++ * Only match BIOS date, because the manufacturers ++ * BIOS does not report the board name at all ++ * (sometimes)... ++ */ ++ DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"), ++ DMI_MATCH(DMI_BIOS_DATE, "10/28/2015"), ++ }, ++ }, + { + /* Trekstor Primebook C11 */ + .driver_data = (void *)&trekstor_primebook_c11_data, +@@ -1413,6 +1482,22 @@ const struct dmi_system_id touchscreen_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "VINGA Twizzle J116"), + }, + }, ++ { ++ /* "WinBook TW100" */ ++ .driver_data = (void *)&gdix1001_00_upside_down_data, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "WinBook"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "TW100") ++ } ++ }, ++ { ++ /* WinBook TW700 */ ++ .driver_data = (void *)&gdix1001_00_upside_down_data, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "WinBook"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "TW700") ++ }, ++ }, + { + /* Yours Y8W81, same case and touchscreen as Chuwi Vi8 */ + .driver_data = (void *)&chuwi_vi8_data, +diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig +index 3e7a38525cb3f..fc9e8f589d16e 100644 +--- a/drivers/regulator/Kconfig ++++ b/drivers/regulator/Kconfig +@@ -207,6 +207,7 @@ config REGULATOR_BD70528 + config REGULATOR_BD71815 + tristate "ROHM BD71815 Power Regulator" + depends on MFD_ROHM_BD71828 ++ select REGULATOR_ROHM + help + This driver supports voltage regulators on ROHM BD71815 PMIC. + This will enable support for the software controllable buck +diff --git a/drivers/regulator/bd9576-regulator.c b/drivers/regulator/bd9576-regulator.c +index 204a2da054f53..cdf30481a5820 100644 +--- a/drivers/regulator/bd9576-regulator.c ++++ b/drivers/regulator/bd9576-regulator.c +@@ -312,8 +312,8 @@ static int bd957x_probe(struct platform_device *pdev) + } + + static const struct platform_device_id bd957x_pmic_id[] = { +- { "bd9573-pmic", ROHM_CHIP_TYPE_BD9573 }, +- { "bd9576-pmic", ROHM_CHIP_TYPE_BD9576 }, ++ { "bd9573-regulator", ROHM_CHIP_TYPE_BD9573 }, ++ { "bd9576-regulator", ROHM_CHIP_TYPE_BD9576 }, + { }, + }; + MODULE_DEVICE_TABLE(platform, bd957x_pmic_id); +diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c +index e18d291c7f21c..23fa429ebe760 100644 +--- a/drivers/regulator/da9052-regulator.c ++++ b/drivers/regulator/da9052-regulator.c +@@ -250,7 +250,8 @@ static int da9052_regulator_set_voltage_time_sel(struct regulator_dev *rdev, + case DA9052_ID_BUCK3: + case DA9052_ID_LDO2: + case DA9052_ID_LDO3: +- ret = (new_sel - old_sel) * info->step_uV / 6250; ++ ret = DIV_ROUND_UP(abs(new_sel - old_sel) * info->step_uV, ++ 6250); + break; + } + +diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c +index 26f06f685b1b6..b2ee38c5b573a 100644 +--- a/drivers/regulator/fan53555.c ++++ b/drivers/regulator/fan53555.c +@@ -293,6 +293,9 @@ static int fan53526_voltages_setup_fairchild(struct fan53555_device_info *di) + return -EINVAL; + } + ++ di->slew_reg = FAN53555_CONTROL; ++ di->slew_mask = CTL_SLEW_MASK; ++ di->slew_shift = CTL_SLEW_SHIFT; + di->vsel_count = FAN53526_NVOLTAGES; + + return 0; +diff --git a/drivers/regulator/fan53880.c b/drivers/regulator/fan53880.c +index 1684faf82ed25..94f02f3099dd4 100644 +--- a/drivers/regulator/fan53880.c ++++ b/drivers/regulator/fan53880.c +@@ -79,7 +79,7 @@ static const struct regulator_desc fan53880_regulators[] = { + .n_linear_ranges = 2, + .n_voltages = 0xf8, + .vsel_reg = FAN53880_BUCKVOUT, +- .vsel_mask = 0x7f, ++ .vsel_mask = 0xff, + .enable_reg = FAN53880_ENABLE, + .enable_mask = 0x10, + .enable_time = 480, +diff --git a/drivers/regulator/hi6421v600-regulator.c b/drivers/regulator/hi6421v600-regulator.c +index d6340bb492967..d1e9406b2e3e2 100644 +--- a/drivers/regulator/hi6421v600-regulator.c ++++ b/drivers/regulator/hi6421v600-regulator.c +@@ -129,7 +129,7 @@ static unsigned int hi6421_spmi_regulator_get_mode(struct regulator_dev *rdev) + { + struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev); + struct hi6421_spmi_pmic *pmic = sreg->pmic; +- u32 reg_val; ++ unsigned int reg_val; + + regmap_read(pmic->regmap, rdev->desc->enable_reg, ®_val); + +@@ -144,14 +144,17 @@ static int hi6421_spmi_regulator_set_mode(struct regulator_dev *rdev, + { + struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev); + struct hi6421_spmi_pmic *pmic = sreg->pmic; +- u32 val; ++ unsigned int val; + + switch (mode) { + case REGULATOR_MODE_NORMAL: + val = 0; + break; + case REGULATOR_MODE_IDLE: +- val = sreg->eco_mode_mask << (ffs(sreg->eco_mode_mask) - 1); ++ if (!sreg->eco_mode_mask) ++ return -EINVAL; ++ ++ val = sreg->eco_mode_mask; + break; + default: + return -EINVAL; +diff --git a/drivers/regulator/hi655x-regulator.c b/drivers/regulator/hi655x-regulator.c +index 68cdb173196d6..556bb73f33292 100644 +--- a/drivers/regulator/hi655x-regulator.c ++++ b/drivers/regulator/hi655x-regulator.c +@@ -72,7 +72,7 @@ enum hi655x_regulator_id { + static int hi655x_is_enabled(struct regulator_dev *rdev) + { + unsigned int value = 0; +- struct hi655x_regulator *regulator = rdev_get_drvdata(rdev); ++ const struct hi655x_regulator *regulator = rdev_get_drvdata(rdev); + + regmap_read(rdev->regmap, regulator->status_reg, &value); + return (value & rdev->desc->enable_mask); +@@ -80,7 +80,7 @@ static int hi655x_is_enabled(struct regulator_dev *rdev) + + static int hi655x_disable(struct regulator_dev *rdev) + { +- struct hi655x_regulator *regulator = rdev_get_drvdata(rdev); ++ const struct hi655x_regulator *regulator = rdev_get_drvdata(rdev); + + return regmap_write(rdev->regmap, regulator->disable_reg, + rdev->desc->enable_mask); +@@ -169,7 +169,6 @@ static const struct hi655x_regulator regulators[] = { + static int hi655x_regulator_probe(struct platform_device *pdev) + { + unsigned int i; +- struct hi655x_regulator *regulator; + struct hi655x_pmic *pmic; + struct regulator_config config = { }; + struct regulator_dev *rdev; +@@ -180,22 +179,17 @@ static int hi655x_regulator_probe(struct platform_device *pdev) + return -ENODEV; + } + +- regulator = devm_kzalloc(&pdev->dev, sizeof(*regulator), GFP_KERNEL); +- if (!regulator) +- return -ENOMEM; +- +- platform_set_drvdata(pdev, regulator); +- + config.dev = pdev->dev.parent; + config.regmap = pmic->regmap; +- config.driver_data = regulator; + for (i = 0; i < ARRAY_SIZE(regulators); i++) { ++ config.driver_data = (void *) ®ulators[i]; ++ + rdev = devm_regulator_register(&pdev->dev, + ®ulators[i].rdesc, + &config); + if (IS_ERR(rdev)) { + dev_err(&pdev->dev, "failed to register regulator %s\n", +- regulator->rdesc.name); ++ regulators[i].rdesc.name); + return PTR_ERR(rdev); + } + } +diff --git a/drivers/regulator/mt6315-regulator.c b/drivers/regulator/mt6315-regulator.c +index 6b8be52c3772a..7514702f78cf7 100644 +--- a/drivers/regulator/mt6315-regulator.c ++++ b/drivers/regulator/mt6315-regulator.c +@@ -223,8 +223,8 @@ static int mt6315_regulator_probe(struct spmi_device *pdev) + int i; + + regmap = devm_regmap_init_spmi_ext(pdev, &mt6315_regmap_config); +- if (!regmap) +- return -ENODEV; ++ if (IS_ERR(regmap)) ++ return PTR_ERR(regmap); + + chip = devm_kzalloc(dev, sizeof(struct mt6315_chip), GFP_KERNEL); + if (!chip) +diff --git a/drivers/regulator/mt6358-regulator.c b/drivers/regulator/mt6358-regulator.c +index 13cb6ac9a8929..1d4eb5dc4fac8 100644 +--- a/drivers/regulator/mt6358-regulator.c ++++ b/drivers/regulator/mt6358-regulator.c +@@ -457,7 +457,7 @@ static struct mt6358_regulator_info mt6358_regulators[] = { + MT6358_REG_FIXED("ldo_vaud28", VAUD28, + MT6358_LDO_VAUD28_CON0, 0, 2800000), + MT6358_LDO("ldo_vdram2", VDRAM2, vdram2_voltages, vdram2_idx, +- MT6358_LDO_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0x10, 0), ++ MT6358_LDO_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0xf, 0), + MT6358_LDO("ldo_vsim1", VSIM1, vsim_voltages, vsim_idx, + MT6358_LDO_VSIM1_CON0, 0, MT6358_VSIM1_ANA_CON0, 0xf00, 8), + MT6358_LDO("ldo_vibr", VIBR, vibr_voltages, vibr_idx, +diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c +index 22fec370fa610..ac79dc34f9e8b 100644 +--- a/drivers/regulator/qcom-rpmh-regulator.c ++++ b/drivers/regulator/qcom-rpmh-regulator.c +@@ -1070,6 +1070,7 @@ static const struct rpmh_vreg_init_data pm7325_vreg_data[] = { + RPMH_VREG("ldo17", "ldo%s17", &pmic5_pldo_lv, "vdd-l11-l17-l18-l19"), + RPMH_VREG("ldo18", "ldo%s18", &pmic5_pldo_lv, "vdd-l11-l17-l18-l19"), + RPMH_VREG("ldo19", "ldo%s19", &pmic5_pldo_lv, "vdd-l11-l17-l18-l19"), ++ {} + }; + + static const struct rpmh_vreg_init_data pmr735a_vreg_data[] = { +@@ -1083,6 +1084,7 @@ static const struct rpmh_vreg_init_data pmr735a_vreg_data[] = { + RPMH_VREG("ldo5", "ldo%s5", &pmic5_nldo, "vdd-l5-l6"), + RPMH_VREG("ldo6", "ldo%s6", &pmic5_nldo, "vdd-l5-l6"), + RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo, "vdd-l7-bob"), ++ {} + }; + + static int rpmh_regulator_probe(struct platform_device *pdev) +diff --git a/drivers/regulator/uniphier-regulator.c b/drivers/regulator/uniphier-regulator.c +index 2e02e26b516c4..e75b0973e3256 100644 +--- a/drivers/regulator/uniphier-regulator.c ++++ b/drivers/regulator/uniphier-regulator.c +@@ -201,6 +201,7 @@ static const struct of_device_id uniphier_regulator_match[] = { + }, + { /* Sentinel */ }, + }; ++MODULE_DEVICE_TABLE(of, uniphier_regulator_match); + + static struct platform_driver uniphier_regulator_driver = { + .probe = uniphier_regulator_probe, +diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c +index 75a8924ba12b3..ac9e228b56d0b 100644 +--- a/drivers/rtc/rtc-stm32.c ++++ b/drivers/rtc/rtc-stm32.c +@@ -754,7 +754,7 @@ static int stm32_rtc_probe(struct platform_device *pdev) + + ret = clk_prepare_enable(rtc->rtc_ck); + if (ret) +- goto err; ++ goto err_no_rtc_ck; + + if (rtc->data->need_dbp) + regmap_update_bits(rtc->dbp, rtc->dbp_reg, +@@ -830,10 +830,12 @@ static int stm32_rtc_probe(struct platform_device *pdev) + } + + return 0; ++ + err: ++ clk_disable_unprepare(rtc->rtc_ck); ++err_no_rtc_ck: + if (rtc->data->has_pclk) + clk_disable_unprepare(rtc->pclk); +- clk_disable_unprepare(rtc->rtc_ck); + + if (rtc->data->need_dbp) + regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0); +diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c +index e421138254152..1097e76982a5d 100644 +--- a/drivers/s390/cio/chp.c ++++ b/drivers/s390/cio/chp.c +@@ -255,6 +255,9 @@ static ssize_t chp_status_write(struct device *dev, + if (!num_args) + return count; + ++ /* Wait until previous actions have settled. */ ++ css_wait_for_slow_path(); ++ + if (!strncasecmp(cmd, "on", 2) || !strcmp(cmd, "1")) { + mutex_lock(&cp->lock); + error = s390_vary_chpid(cp->chpid, 1); +diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c +index c22d9ee27ba19..297fb399363cc 100644 +--- a/drivers/s390/cio/chsc.c ++++ b/drivers/s390/cio/chsc.c +@@ -801,8 +801,6 @@ int chsc_chp_vary(struct chp_id chpid, int on) + { + struct channel_path *chp = chpid_to_chp(chpid); + +- /* Wait until previous actions have settled. */ +- css_wait_for_slow_path(); + /* + * Redo PathVerification on the devices the chpid connects to + */ +diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c +index 0464e37c806a4..2e25ef67825ac 100644 +--- a/drivers/scsi/FlashPoint.c ++++ b/drivers/scsi/FlashPoint.c +@@ -40,7 +40,7 @@ struct sccb_mgr_info { + u16 si_per_targ_ultra_nego; + u16 si_per_targ_no_disc; + u16 si_per_targ_wide_nego; +- u16 si_flags; ++ u16 si_mflags; + unsigned char si_card_family; + unsigned char si_bustype; + unsigned char si_card_model[3]; +@@ -1073,22 +1073,22 @@ static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo) + ScamFlg = + (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2); + +- pCardInfo->si_flags = 0x0000; ++ pCardInfo->si_mflags = 0x0000; + + if (i & 0x01) +- pCardInfo->si_flags |= SCSI_PARITY_ENA; ++ pCardInfo->si_mflags |= SCSI_PARITY_ENA; + + if (!(i & 0x02)) +- pCardInfo->si_flags |= SOFT_RESET; ++ pCardInfo->si_mflags |= SOFT_RESET; + + if (i & 0x10) +- pCardInfo->si_flags |= EXTENDED_TRANSLATION; ++ pCardInfo->si_mflags |= EXTENDED_TRANSLATION; + + if (ScamFlg & SCAM_ENABLED) +- pCardInfo->si_flags |= FLAG_SCAM_ENABLED; ++ pCardInfo->si_mflags |= FLAG_SCAM_ENABLED; + + if (ScamFlg & SCAM_LEVEL2) +- pCardInfo->si_flags |= FLAG_SCAM_LEVEL2; ++ pCardInfo->si_mflags |= FLAG_SCAM_LEVEL2; + + j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L); + if (i & 0x04) { +@@ -1104,7 +1104,7 @@ static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo) + + if (!(RD_HARPOON(ioport + hp_page_ctrl) & NARROW_SCSI_CARD)) + +- pCardInfo->si_flags |= SUPPORT_16TAR_32LUN; ++ pCardInfo->si_mflags |= SUPPORT_16TAR_32LUN; + + pCardInfo->si_card_family = HARPOON_FAMILY; + pCardInfo->si_bustype = BUSTYPE_PCI; +@@ -1140,15 +1140,15 @@ static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo) + + if (pCardInfo->si_card_model[1] == '3') { + if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)) +- pCardInfo->si_flags |= LOW_BYTE_TERM; ++ pCardInfo->si_mflags |= LOW_BYTE_TERM; + } else if (pCardInfo->si_card_model[2] == '0') { + temp = RD_HARPOON(ioport + hp_xfer_pad); + WR_HARPOON(ioport + hp_xfer_pad, (temp & ~BIT(4))); + if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)) +- pCardInfo->si_flags |= LOW_BYTE_TERM; ++ pCardInfo->si_mflags |= LOW_BYTE_TERM; + WR_HARPOON(ioport + hp_xfer_pad, (temp | BIT(4))); + if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)) +- pCardInfo->si_flags |= HIGH_BYTE_TERM; ++ pCardInfo->si_mflags |= HIGH_BYTE_TERM; + WR_HARPOON(ioport + hp_xfer_pad, temp); + } else { + temp = RD_HARPOON(ioport + hp_ee_ctrl); +@@ -1166,9 +1166,9 @@ static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo) + WR_HARPOON(ioport + hp_ee_ctrl, temp); + WR_HARPOON(ioport + hp_xfer_pad, temp2); + if (!(temp3 & BIT(7))) +- pCardInfo->si_flags |= LOW_BYTE_TERM; ++ pCardInfo->si_mflags |= LOW_BYTE_TERM; + if (!(temp3 & BIT(6))) +- pCardInfo->si_flags |= HIGH_BYTE_TERM; ++ pCardInfo->si_mflags |= HIGH_BYTE_TERM; + } + + ARAM_ACCESS(ioport); +@@ -1275,7 +1275,7 @@ static void *FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info + WR_HARPOON(ioport + hp_arb_id, pCardInfo->si_id); + CurrCard->ourId = pCardInfo->si_id; + +- i = (unsigned char)pCardInfo->si_flags; ++ i = (unsigned char)pCardInfo->si_mflags; + if (i & SCSI_PARITY_ENA) + WR_HARPOON(ioport + hp_portctrl_1, (HOST_MODE8 | CHK_SCSI_P)); + +@@ -1289,14 +1289,14 @@ static void *FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info + j |= SCSI_TERM_ENA_H; + WR_HARPOON(ioport + hp_ee_ctrl, j); + +- if (!(pCardInfo->si_flags & SOFT_RESET)) { ++ if (!(pCardInfo->si_mflags & SOFT_RESET)) { + + FPT_sresb(ioport, thisCard); + + FPT_scini(thisCard, pCardInfo->si_id, 0); + } + +- if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS) ++ if (pCardInfo->si_mflags & POST_ALL_UNDERRRUNS) + CurrCard->globalFlags |= F_NO_FILTER; + + if (pCurrNvRam) { +diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c +index 0e935c49b57bd..dd419e295184d 100644 +--- a/drivers/scsi/be2iscsi/be_iscsi.c ++++ b/drivers/scsi/be2iscsi/be_iscsi.c +@@ -182,6 +182,7 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session, + struct beiscsi_endpoint *beiscsi_ep; + struct iscsi_endpoint *ep; + uint16_t cri_index; ++ int rc = 0; + + ep = iscsi_lookup_endpoint(transport_fd); + if (!ep) +@@ -189,15 +190,17 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session, + + beiscsi_ep = ep->dd_data; + +- if (iscsi_conn_bind(cls_session, cls_conn, is_leading)) +- return -EINVAL; ++ if (iscsi_conn_bind(cls_session, cls_conn, is_leading)) { ++ rc = -EINVAL; ++ goto put_ep; ++ } + + if (beiscsi_ep->phba != phba) { + beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, + "BS_%d : beiscsi_ep->hba=%p not equal to phba=%p\n", + beiscsi_ep->phba, phba); +- +- return -EEXIST; ++ rc = -EEXIST; ++ goto put_ep; + } + cri_index = BE_GET_CRI_FROM_CID(beiscsi_ep->ep_cid); + if (phba->conn_table[cri_index]) { +@@ -209,7 +212,8 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session, + beiscsi_ep->ep_cid, + beiscsi_conn, + phba->conn_table[cri_index]); +- return -EINVAL; ++ rc = -EINVAL; ++ goto put_ep; + } + } + +@@ -226,7 +230,10 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session, + "BS_%d : cid %d phba->conn_table[%u]=%p\n", + beiscsi_ep->ep_cid, cri_index, beiscsi_conn); + phba->conn_table[cri_index] = beiscsi_conn; +- return 0; ++ ++put_ep: ++ iscsi_put_endpoint(ep); ++ return rc; + } + + static int beiscsi_iface_create_ipv4(struct beiscsi_hba *phba) +diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c +index 22cf7f4b8d8c8..27c4f1598f765 100644 +--- a/drivers/scsi/be2iscsi/be_main.c ++++ b/drivers/scsi/be2iscsi/be_main.c +@@ -5809,6 +5809,7 @@ struct iscsi_transport beiscsi_iscsi_transport = { + .destroy_session = beiscsi_session_destroy, + .create_conn = beiscsi_conn_create, + .bind_conn = beiscsi_conn_bind, ++ .unbind_conn = iscsi_conn_unbind, + .destroy_conn = iscsi_conn_teardown, + .attr_is_visible = beiscsi_attr_is_visible, + .set_iface_param = beiscsi_iface_set_param, +diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c +index 1e6d8f62ea3c2..2ad85c6b99fd2 100644 +--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c ++++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c +@@ -1420,17 +1420,23 @@ static int bnx2i_conn_bind(struct iscsi_cls_session *cls_session, + * Forcefully terminate all in progress connection recovery at the + * earliest, either in bind(), send_pdu(LOGIN), or conn_start() + */ +- if (bnx2i_adapter_ready(hba)) +- return -EIO; ++ if (bnx2i_adapter_ready(hba)) { ++ ret_code = -EIO; ++ goto put_ep; ++ } + + bnx2i_ep = ep->dd_data; + if ((bnx2i_ep->state == EP_STATE_TCP_FIN_RCVD) || +- (bnx2i_ep->state == EP_STATE_TCP_RST_RCVD)) ++ (bnx2i_ep->state == EP_STATE_TCP_RST_RCVD)) { + /* Peer disconnect via' FIN or RST */ +- return -EINVAL; ++ ret_code = -EINVAL; ++ goto put_ep; ++ } + +- if (iscsi_conn_bind(cls_session, cls_conn, is_leading)) +- return -EINVAL; ++ if (iscsi_conn_bind(cls_session, cls_conn, is_leading)) { ++ ret_code = -EINVAL; ++ goto put_ep; ++ } + + if (bnx2i_ep->hba != hba) { + /* Error - TCP connection does not belong to this device +@@ -1441,7 +1447,8 @@ static int bnx2i_conn_bind(struct iscsi_cls_session *cls_session, + iscsi_conn_printk(KERN_ALERT, cls_conn->dd_data, + "belong to hba (%s)\n", + hba->netdev->name); +- return -EEXIST; ++ ret_code = -EEXIST; ++ goto put_ep; + } + bnx2i_ep->conn = bnx2i_conn; + bnx2i_conn->ep = bnx2i_ep; +@@ -1458,6 +1465,8 @@ static int bnx2i_conn_bind(struct iscsi_cls_session *cls_session, + bnx2i_put_rq_buf(bnx2i_conn, 0); + + bnx2i_arm_cq_event_coalescing(bnx2i_conn->ep, CNIC_ARM_CQE); ++put_ep: ++ iscsi_put_endpoint(ep); + return ret_code; + } + +@@ -2276,6 +2285,7 @@ struct iscsi_transport bnx2i_iscsi_transport = { + .destroy_session = bnx2i_session_destroy, + .create_conn = bnx2i_conn_create, + .bind_conn = bnx2i_conn_bind, ++ .unbind_conn = iscsi_conn_unbind, + .destroy_conn = bnx2i_conn_destroy, + .attr_is_visible = bnx2i_attr_is_visible, + .set_param = iscsi_set_param, +diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c +index 203f938fca7e5..f949a4e007834 100644 +--- a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c ++++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c +@@ -117,6 +117,7 @@ static struct iscsi_transport cxgb3i_iscsi_transport = { + /* connection management */ + .create_conn = cxgbi_create_conn, + .bind_conn = cxgbi_bind_conn, ++ .unbind_conn = iscsi_conn_unbind, + .destroy_conn = iscsi_tcp_conn_teardown, + .start_conn = iscsi_conn_start, + .stop_conn = iscsi_conn_stop, +diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c +index 2c3491528d424..efb3e2b3398e2 100644 +--- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c ++++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c +@@ -134,6 +134,7 @@ static struct iscsi_transport cxgb4i_iscsi_transport = { + /* connection management */ + .create_conn = cxgbi_create_conn, + .bind_conn = cxgbi_bind_conn, ++ .unbind_conn = iscsi_conn_unbind, + .destroy_conn = iscsi_tcp_conn_teardown, + .start_conn = iscsi_conn_start, + .stop_conn = iscsi_conn_stop, +diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c +index f078b3c4e083f..f6bcae829c29b 100644 +--- a/drivers/scsi/cxgbi/libcxgbi.c ++++ b/drivers/scsi/cxgbi/libcxgbi.c +@@ -2690,11 +2690,13 @@ int cxgbi_bind_conn(struct iscsi_cls_session *cls_session, + err = csk->cdev->csk_ddp_setup_pgidx(csk, csk->tid, + ppm->tformat.pgsz_idx_dflt); + if (err < 0) +- return err; ++ goto put_ep; + + err = iscsi_conn_bind(cls_session, cls_conn, is_leading); +- if (err) +- return -EINVAL; ++ if (err) { ++ err = -EINVAL; ++ goto put_ep; ++ } + + /* calculate the tag idx bits needed for this conn based on cmds_max */ + cconn->task_idx_bits = (__ilog2_u32(conn->session->cmds_max - 1)) + 1; +@@ -2715,7 +2717,9 @@ int cxgbi_bind_conn(struct iscsi_cls_session *cls_session, + /* init recv engine */ + iscsi_tcp_hdr_recv_prep(tcp_conn); + +- return 0; ++put_ep: ++ iscsi_put_endpoint(ep); ++ return err; + } + EXPORT_SYMBOL_GPL(cxgbi_bind_conn); + +diff --git a/drivers/scsi/libfc/fc_encode.h b/drivers/scsi/libfc/fc_encode.h +index 602c97a651bc0..9ea4ceadb5594 100644 +--- a/drivers/scsi/libfc/fc_encode.h ++++ b/drivers/scsi/libfc/fc_encode.h +@@ -166,9 +166,11 @@ static inline int fc_ct_ns_fill(struct fc_lport *lport, + static inline void fc_ct_ms_fill_attr(struct fc_fdmi_attr_entry *entry, + const char *in, size_t len) + { +- int copied = strscpy(entry->value, in, len); +- if (copied > 0) +- memset(entry->value, copied, len - copied); ++ int copied; ++ ++ copied = strscpy((char *)&entry->value, in, len); ++ if (copied > 0 && (copied + 1) < len) ++ memset((entry->value + copied + 1), 0, len - copied - 1); + } + + /** +diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c +index 4834219497eeb..2aaf836786548 100644 +--- a/drivers/scsi/libiscsi.c ++++ b/drivers/scsi/libiscsi.c +@@ -1387,23 +1387,32 @@ void iscsi_session_failure(struct iscsi_session *session, + } + EXPORT_SYMBOL_GPL(iscsi_session_failure); + +-void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) ++static bool iscsi_set_conn_failed(struct iscsi_conn *conn) + { + struct iscsi_session *session = conn->session; + +- spin_lock_bh(&session->frwd_lock); +- if (session->state == ISCSI_STATE_FAILED) { +- spin_unlock_bh(&session->frwd_lock); +- return; +- } ++ if (session->state == ISCSI_STATE_FAILED) ++ return false; + + if (conn->stop_stage == 0) + session->state = ISCSI_STATE_FAILED; +- spin_unlock_bh(&session->frwd_lock); + + set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); + set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx); +- iscsi_conn_error_event(conn->cls_conn, err); ++ return true; ++} ++ ++void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) ++{ ++ struct iscsi_session *session = conn->session; ++ bool needs_evt; ++ ++ spin_lock_bh(&session->frwd_lock); ++ needs_evt = iscsi_set_conn_failed(conn); ++ spin_unlock_bh(&session->frwd_lock); ++ ++ if (needs_evt) ++ iscsi_conn_error_event(conn->cls_conn, err); + } + EXPORT_SYMBOL_GPL(iscsi_conn_failure); + +@@ -2180,6 +2189,51 @@ done: + spin_unlock(&session->frwd_lock); + } + ++/** ++ * iscsi_conn_unbind - prevent queueing to conn. ++ * @cls_conn: iscsi conn ep is bound to. ++ * @is_active: is the conn in use for boot or is this for EH/termination ++ * ++ * This must be called by drivers implementing the ep_disconnect callout. ++ * It disables queueing to the connection from libiscsi in preparation for ++ * an ep_disconnect call. ++ */ ++void iscsi_conn_unbind(struct iscsi_cls_conn *cls_conn, bool is_active) ++{ ++ struct iscsi_session *session; ++ struct iscsi_conn *conn; ++ ++ if (!cls_conn) ++ return; ++ ++ conn = cls_conn->dd_data; ++ session = conn->session; ++ /* ++ * Wait for iscsi_eh calls to exit. We don't wait for the tmf to ++ * complete or timeout. The caller just wants to know what's running ++ * is everything that needs to be cleaned up, and no cmds will be ++ * queued. ++ */ ++ mutex_lock(&session->eh_mutex); ++ ++ iscsi_suspend_queue(conn); ++ iscsi_suspend_tx(conn); ++ ++ spin_lock_bh(&session->frwd_lock); ++ if (!is_active) { ++ /* ++ * if logout timed out before userspace could even send a PDU ++ * the state might still be in ISCSI_STATE_LOGGED_IN and ++ * allowing new cmds and TMFs. ++ */ ++ if (session->state == ISCSI_STATE_LOGGED_IN) ++ iscsi_set_conn_failed(conn); ++ } ++ spin_unlock_bh(&session->frwd_lock); ++ mutex_unlock(&session->eh_mutex); ++} ++EXPORT_SYMBOL_GPL(iscsi_conn_unbind); ++ + static void iscsi_prep_abort_task_pdu(struct iscsi_task *task, + struct iscsi_tm *hdr) + { +diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c +index 658a962832b35..7bddd74658b9e 100644 +--- a/drivers/scsi/lpfc/lpfc_debugfs.c ++++ b/drivers/scsi/lpfc/lpfc_debugfs.c +@@ -868,11 +868,8 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) + len += scnprintf(buf+len, size-len, + "WWNN x%llx ", + wwn_to_u64(ndlp->nlp_nodename.u.wwn)); +- if (ndlp->nlp_flag & NLP_RPI_REGISTERED) +- len += scnprintf(buf+len, size-len, "RPI:%04d ", +- ndlp->nlp_rpi); +- else +- len += scnprintf(buf+len, size-len, "RPI:none "); ++ len += scnprintf(buf+len, size-len, "RPI:x%04x ", ++ ndlp->nlp_rpi); + len += scnprintf(buf+len, size-len, "flag:x%08x ", + ndlp->nlp_flag); + if (!ndlp->nlp_type) +diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c +index 21108f322c995..c3ca2ccf9f828 100644 +--- a/drivers/scsi/lpfc/lpfc_els.c ++++ b/drivers/scsi/lpfc/lpfc_els.c +@@ -1998,9 +1998,20 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, + lpfc_disc_state_machine(vport, ndlp, cmdiocb, + NLP_EVT_CMPL_PLOGI); + +- /* As long as this node is not registered with the scsi or nvme +- * transport, it is no longer an active node. Otherwise +- * devloss handles the final cleanup. ++ /* If a PLOGI collision occurred, the node needs to continue ++ * with the reglogin process. ++ */ ++ spin_lock_irq(&ndlp->lock); ++ if ((ndlp->nlp_flag & (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI)) && ++ ndlp->nlp_state == NLP_STE_REG_LOGIN_ISSUE) { ++ spin_unlock_irq(&ndlp->lock); ++ goto out; ++ } ++ spin_unlock_irq(&ndlp->lock); ++ ++ /* No PLOGI collision and the node is not registered with the ++ * scsi or nvme transport. It is no longer an active node. Just ++ * start the device remove process. + */ + if (!(ndlp->fc4_xpt_flags & (SCSI_XPT_REGD | NVME_XPT_REGD))) { + spin_lock_irq(&ndlp->lock); +@@ -2869,6 +2880,11 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, + * log into the remote port. + */ + if (ndlp->nlp_flag & NLP_TARGET_REMOVE) { ++ spin_lock_irq(&ndlp->lock); ++ if (phba->sli_rev == LPFC_SLI_REV4) ++ ndlp->nlp_flag |= NLP_RELEASE_RPI; ++ ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; ++ spin_unlock_irq(&ndlp->lock); + lpfc_disc_state_machine(vport, ndlp, cmdiocb, + NLP_EVT_DEVICE_RM); + lpfc_els_free_iocb(phba, cmdiocb); +@@ -4371,6 +4387,7 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, + struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1; + struct lpfc_vport *vport = cmdiocb->vport; + IOCB_t *irsp; ++ u32 xpt_flags = 0, did_mask = 0; + + irsp = &rspiocb->iocb; + lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, +@@ -4386,9 +4403,20 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, + if (ndlp->nlp_state == NLP_STE_NPR_NODE) { + /* NPort Recovery mode or node is just allocated */ + if (!lpfc_nlp_not_used(ndlp)) { +- /* If the ndlp is being used by another discovery +- * thread, just unregister the RPI. ++ /* A LOGO is completing and the node is in NPR state. ++ * If this a fabric node that cleared its transport ++ * registration, release the rpi. + */ ++ xpt_flags = SCSI_XPT_REGD | NVME_XPT_REGD; ++ did_mask = ndlp->nlp_DID & Fabric_DID_MASK; ++ if (did_mask == Fabric_DID_MASK && ++ !(ndlp->fc4_xpt_flags & xpt_flags)) { ++ spin_lock_irq(&ndlp->lock); ++ ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; ++ if (phba->sli_rev == LPFC_SLI_REV4) ++ ndlp->nlp_flag |= NLP_RELEASE_RPI; ++ spin_unlock_irq(&ndlp->lock); ++ } + lpfc_unreg_rpi(vport, ndlp); + } else { + /* Indicate the node has already released, should +@@ -4424,28 +4452,37 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) + { + struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *)(pmb->ctx_buf); + struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp; ++ u32 mbx_flag = pmb->mbox_flag; ++ u32 mbx_cmd = pmb->u.mb.mbxCommand; + + pmb->ctx_buf = NULL; + pmb->ctx_ndlp = NULL; + +- lpfc_mbuf_free(phba, mp->virt, mp->phys); +- kfree(mp); +- mempool_free(pmb, phba->mbox_mem_pool); + if (ndlp) { + lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, +- "0006 rpi x%x DID:%x flg:%x %d x%px\n", ++ "0006 rpi x%x DID:%x flg:%x %d x%px " ++ "mbx_cmd x%x mbx_flag x%x x%px\n", + ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, +- kref_read(&ndlp->kref), +- ndlp); +- /* This is the end of the default RPI cleanup logic for +- * this ndlp and it could get released. Clear the nlp_flags to +- * prevent any further processing. ++ kref_read(&ndlp->kref), ndlp, mbx_cmd, ++ mbx_flag, pmb); ++ ++ /* This ends the default/temporary RPI cleanup logic for this ++ * ndlp and the node and rpi needs to be released. Free the rpi ++ * first on an UNREG_LOGIN and then release the final ++ * references. + */ ++ spin_lock_irq(&ndlp->lock); + ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND; ++ if (mbx_cmd == MBX_UNREG_LOGIN) ++ ndlp->nlp_flag &= ~NLP_UNREG_INP; ++ spin_unlock_irq(&ndlp->lock); + lpfc_nlp_put(ndlp); +- lpfc_nlp_not_used(ndlp); ++ lpfc_drop_node(ndlp->vport, ndlp); + } + ++ lpfc_mbuf_free(phba, mp->virt, mp->phys); ++ kfree(mp); ++ mempool_free(pmb, phba->mbox_mem_pool); + return; + } + +@@ -4503,11 +4540,11 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, + /* ELS response tag completes */ + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0110 ELS response tag x%x completes " +- "Data: x%x x%x x%x x%x x%x x%x x%x\n", ++ "Data: x%x x%x x%x x%x x%x x%x x%x x%x x%px\n", + cmdiocb->iocb.ulpIoTag, rspiocb->iocb.ulpStatus, + rspiocb->iocb.un.ulpWord[4], rspiocb->iocb.ulpTimeout, + ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, +- ndlp->nlp_rpi); ++ ndlp->nlp_rpi, kref_read(&ndlp->kref), mbox); + if (mbox) { + if ((rspiocb->iocb.ulpStatus == 0) && + (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) { +@@ -4587,6 +4624,20 @@ out: + spin_unlock_irq(&ndlp->lock); + } + ++ /* An SLI4 NPIV instance wants to drop the node at this point under ++ * these conditions and release the RPI. ++ */ ++ if (phba->sli_rev == LPFC_SLI_REV4 && ++ (vport && vport->port_type == LPFC_NPIV_PORT) && ++ ndlp->nlp_flag & NLP_RELEASE_RPI) { ++ lpfc_sli4_free_rpi(phba, ndlp->nlp_rpi); ++ spin_lock_irq(&ndlp->lock); ++ ndlp->nlp_rpi = LPFC_RPI_ALLOC_ERROR; ++ ndlp->nlp_flag &= ~NLP_RELEASE_RPI; ++ spin_unlock_irq(&ndlp->lock); ++ lpfc_drop_node(vport, ndlp); ++ } ++ + /* Release the originating I/O reference. */ + lpfc_els_free_iocb(phba, cmdiocb); + lpfc_nlp_put(ndlp); +@@ -4775,10 +4826,10 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0128 Xmit ELS ACC response Status: x%x, IoTag: x%x, " + "XRI: x%x, DID: x%x, nlp_flag: x%x nlp_state: x%x " +- "RPI: x%x, fc_flag x%x\n", ++ "RPI: x%x, fc_flag x%x refcnt %d\n", + rc, elsiocb->iotag, elsiocb->sli4_xritag, + ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, +- ndlp->nlp_rpi, vport->fc_flag); ++ ndlp->nlp_rpi, vport->fc_flag, kref_read(&ndlp->kref)); + return 0; + } + +@@ -4856,6 +4907,17 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, + return 1; + } + ++ /* The NPIV instance is rejecting this unsolicited ELS. Make sure the ++ * node's assigned RPI needs to be released as this node will get ++ * freed. ++ */ ++ if (phba->sli_rev == LPFC_SLI_REV4 && ++ vport->port_type == LPFC_NPIV_PORT) { ++ spin_lock_irq(&ndlp->lock); ++ ndlp->nlp_flag |= NLP_RELEASE_RPI; ++ spin_unlock_irq(&ndlp->lock); ++ } ++ + rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); + if (rc == IOCB_ERROR) { + lpfc_els_free_iocb(phba, elsiocb); +diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c +index f5a898c2c9043..3ea07034ab97c 100644 +--- a/drivers/scsi/lpfc/lpfc_hbadisc.c ++++ b/drivers/scsi/lpfc/lpfc_hbadisc.c +@@ -4789,12 +4789,17 @@ lpfc_nlp_logo_unreg(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) + ndlp->nlp_defer_did = NLP_EVT_NOTHING_PENDING; + lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0); + } else { ++ /* NLP_RELEASE_RPI is only set for SLI4 ports. */ + if (ndlp->nlp_flag & NLP_RELEASE_RPI) { + lpfc_sli4_free_rpi(vport->phba, ndlp->nlp_rpi); ++ spin_lock_irq(&ndlp->lock); + ndlp->nlp_flag &= ~NLP_RELEASE_RPI; + ndlp->nlp_rpi = LPFC_RPI_ALLOC_ERROR; ++ spin_unlock_irq(&ndlp->lock); + } ++ spin_lock_irq(&ndlp->lock); + ndlp->nlp_flag &= ~NLP_UNREG_INP; ++ spin_unlock_irq(&ndlp->lock); + } + } + +@@ -5129,8 +5134,10 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) + list_del_init(&ndlp->dev_loss_evt.evt_listp); + list_del_init(&ndlp->recovery_evt.evt_listp); + lpfc_cleanup_vports_rrqs(vport, ndlp); ++ + if (phba->sli_rev == LPFC_SLI_REV4) + ndlp->nlp_flag |= NLP_RELEASE_RPI; ++ + return 0; + } + +@@ -6176,8 +6183,23 @@ lpfc_nlp_release(struct kref *kref) + lpfc_cancel_retry_delay_tmo(vport, ndlp); + lpfc_cleanup_node(vport, ndlp); + +- /* Clear Node key fields to give other threads notice +- * that this node memory is not valid anymore. ++ /* Not all ELS transactions have registered the RPI with the port. ++ * In these cases the rpi usage is temporary and the node is ++ * released when the WQE is completed. Catch this case to free the ++ * RPI to the pool. Because this node is in the release path, a lock ++ * is unnecessary. All references are gone and the node has been ++ * dequeued. ++ */ ++ if (ndlp->nlp_flag & NLP_RELEASE_RPI) { ++ if (ndlp->nlp_rpi != LPFC_RPI_ALLOC_ERROR && ++ !(ndlp->nlp_flag & (NLP_RPI_REGISTERED | NLP_UNREG_INP))) { ++ lpfc_sli4_free_rpi(vport->phba, ndlp->nlp_rpi); ++ ndlp->nlp_rpi = LPFC_RPI_ALLOC_ERROR; ++ } ++ } ++ ++ /* The node is not freed back to memory, it is released to a pool so ++ * the node fields need to be cleaned up. + */ + ndlp->vport = NULL; + ndlp->nlp_state = NLP_STE_FREED_NODE; +@@ -6257,6 +6279,7 @@ lpfc_nlp_not_used(struct lpfc_nodelist *ndlp) + "node not used: did:x%x flg:x%x refcnt:x%x", + ndlp->nlp_DID, ndlp->nlp_flag, + kref_read(&ndlp->kref)); ++ + if (kref_read(&ndlp->kref) == 1) + if (lpfc_nlp_put(ndlp)) + return 1; +diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c +index 5f018d02bf562..f81dfa3cb0a1e 100644 +--- a/drivers/scsi/lpfc/lpfc_init.c ++++ b/drivers/scsi/lpfc/lpfc_init.c +@@ -3532,13 +3532,6 @@ lpfc_offline_prep(struct lpfc_hba *phba, int mbx_action) + list_for_each_entry_safe(ndlp, next_ndlp, + &vports[i]->fc_nodes, + nlp_listp) { +- if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) { +- /* Driver must assume RPI is invalid for +- * any unused or inactive node. +- */ +- ndlp->nlp_rpi = LPFC_RPI_ALLOC_ERROR; +- continue; +- } + + spin_lock_irq(&ndlp->lock); + ndlp->nlp_flag &= ~NLP_NPR_ADISC; +diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c +index bb4e65a32ecc6..3dac116c405bf 100644 +--- a/drivers/scsi/lpfc/lpfc_nportdisc.c ++++ b/drivers/scsi/lpfc/lpfc_nportdisc.c +@@ -567,15 +567,24 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, + /* no deferred ACC */ + kfree(save_iocb); + +- /* In order to preserve RPIs, we want to cleanup +- * the default RPI the firmware created to rcv +- * this ELS request. The only way to do this is +- * to register, then unregister the RPI. ++ /* This is an NPIV SLI4 instance that does not need to register ++ * a default RPI. + */ +- spin_lock_irq(&ndlp->lock); +- ndlp->nlp_flag |= (NLP_RM_DFLT_RPI | NLP_ACC_REGLOGIN | +- NLP_RCV_PLOGI); +- spin_unlock_irq(&ndlp->lock); ++ if (phba->sli_rev == LPFC_SLI_REV4) { ++ mempool_free(login_mbox, phba->mbox_mem_pool); ++ login_mbox = NULL; ++ } else { ++ /* In order to preserve RPIs, we want to cleanup ++ * the default RPI the firmware created to rcv ++ * this ELS request. The only way to do this is ++ * to register, then unregister the RPI. ++ */ ++ spin_lock_irq(&ndlp->lock); ++ ndlp->nlp_flag |= (NLP_RM_DFLT_RPI | NLP_ACC_REGLOGIN | ++ NLP_RCV_PLOGI); ++ spin_unlock_irq(&ndlp->lock); ++ } ++ + stat.un.b.lsRjtRsnCode = LSRJT_INVALID_CMD; + stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; + rc = lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, +diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c +index fc3682f15f509..bc0bcb0dccc9a 100644 +--- a/drivers/scsi/lpfc/lpfc_sli.c ++++ b/drivers/scsi/lpfc/lpfc_sli.c +@@ -13625,9 +13625,15 @@ lpfc_sli4_sp_handle_mbox_event(struct lpfc_hba *phba, struct lpfc_mcqe *mcqe) + if (mcqe_status == MB_CQE_STATUS_SUCCESS) { + mp = (struct lpfc_dmabuf *)(pmb->ctx_buf); + ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp; +- /* Reg_LOGIN of dflt RPI was successful. Now lets get +- * RID of the PPI using the same mbox buffer. ++ ++ /* Reg_LOGIN of dflt RPI was successful. Mark the ++ * node as having an UNREG_LOGIN in progress to stop ++ * an unsolicited PLOGI from the same NPortId from ++ * starting another mailbox transaction. + */ ++ spin_lock_irqsave(&ndlp->lock, iflags); ++ ndlp->nlp_flag |= NLP_UNREG_INP; ++ spin_unlock_irqrestore(&ndlp->lock, iflags); + lpfc_unreg_login(phba, vport->vpi, + pmbox->un.varWords[0], pmb); + pmb->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi; +diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c +index 2221175ae051f..cd94a0c81f835 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c ++++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c +@@ -3203,6 +3203,8 @@ megasas_build_io_fusion(struct megasas_instance *instance, + { + int sge_count; + u8 cmd_type; ++ u16 pd_index = 0; ++ u8 drive_type = 0; + struct MPI2_RAID_SCSI_IO_REQUEST *io_request = cmd->io_request; + struct MR_PRIV_DEVICE *mr_device_priv_data; + mr_device_priv_data = scp->device->hostdata; +@@ -3237,8 +3239,12 @@ megasas_build_io_fusion(struct megasas_instance *instance, + megasas_build_syspd_fusion(instance, scp, cmd, true); + break; + case NON_READ_WRITE_SYSPDIO: +- if (instance->secure_jbod_support || +- mr_device_priv_data->is_tm_capable) ++ pd_index = MEGASAS_PD_INDEX(scp); ++ drive_type = instance->pd_list[pd_index].driveType; ++ if ((instance->secure_jbod_support || ++ mr_device_priv_data->is_tm_capable) || ++ (instance->adapter_type >= VENTURA_SERIES && ++ drive_type == TYPE_ENCLOSURE)) + megasas_build_syspd_fusion(instance, scp, cmd, false); + else + megasas_build_syspd_fusion(instance, scp, cmd, true); +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index d00aca3c77cec..a5f70f0e02871 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -6884,8 +6884,10 @@ _scsih_expander_add(struct MPT3SAS_ADAPTER *ioc, u16 handle) + handle, parent_handle, + (u64)sas_expander->sas_address, sas_expander->num_phys); + +- if (!sas_expander->num_phys) ++ if (!sas_expander->num_phys) { ++ rc = -1; + goto out_fail; ++ } + sas_expander->phy = kcalloc(sas_expander->num_phys, + sizeof(struct _sas_phy), GFP_KERNEL); + if (!sas_expander->phy) { +diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c +index 08c05403cd720..087c7ff28cd52 100644 +--- a/drivers/scsi/qedi/qedi_iscsi.c ++++ b/drivers/scsi/qedi/qedi_iscsi.c +@@ -377,6 +377,7 @@ static int qedi_conn_bind(struct iscsi_cls_session *cls_session, + struct qedi_ctx *qedi = iscsi_host_priv(shost); + struct qedi_endpoint *qedi_ep; + struct iscsi_endpoint *ep; ++ int rc = 0; + + ep = iscsi_lookup_endpoint(transport_fd); + if (!ep) +@@ -384,11 +385,16 @@ static int qedi_conn_bind(struct iscsi_cls_session *cls_session, + + qedi_ep = ep->dd_data; + if ((qedi_ep->state == EP_STATE_TCP_FIN_RCVD) || +- (qedi_ep->state == EP_STATE_TCP_RST_RCVD)) +- return -EINVAL; ++ (qedi_ep->state == EP_STATE_TCP_RST_RCVD)) { ++ rc = -EINVAL; ++ goto put_ep; ++ } ++ ++ if (iscsi_conn_bind(cls_session, cls_conn, is_leading)) { ++ rc = -EINVAL; ++ goto put_ep; ++ } + +- if (iscsi_conn_bind(cls_session, cls_conn, is_leading)) +- return -EINVAL; + + qedi_ep->conn = qedi_conn; + qedi_conn->ep = qedi_ep; +@@ -398,13 +404,18 @@ static int qedi_conn_bind(struct iscsi_cls_session *cls_session, + qedi_conn->cmd_cleanup_req = 0; + qedi_conn->cmd_cleanup_cmpl = 0; + +- if (qedi_bind_conn_to_iscsi_cid(qedi, qedi_conn)) +- return -EINVAL; ++ if (qedi_bind_conn_to_iscsi_cid(qedi, qedi_conn)) { ++ rc = -EINVAL; ++ goto put_ep; ++ } ++ + + spin_lock_init(&qedi_conn->tmf_work_lock); + INIT_LIST_HEAD(&qedi_conn->tmf_work_list); + init_waitqueue_head(&qedi_conn->wait_queue); +- return 0; ++put_ep: ++ iscsi_put_endpoint(ep); ++ return rc; + } + + static int qedi_iscsi_update_conn(struct qedi_ctx *qedi, +@@ -1401,6 +1412,7 @@ struct iscsi_transport qedi_iscsi_transport = { + .destroy_session = qedi_session_destroy, + .create_conn = qedi_conn_create, + .bind_conn = qedi_conn_bind, ++ .unbind_conn = iscsi_conn_unbind, + .start_conn = qedi_conn_start, + .stop_conn = iscsi_conn_stop, + .destroy_conn = qedi_conn_destroy, +diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c +index ad3afe30f617d..0e7a7e82e0284 100644 +--- a/drivers/scsi/qla4xxx/ql4_os.c ++++ b/drivers/scsi/qla4xxx/ql4_os.c +@@ -259,6 +259,7 @@ static struct iscsi_transport qla4xxx_iscsi_transport = { + .start_conn = qla4xxx_conn_start, + .create_conn = qla4xxx_conn_create, + .bind_conn = qla4xxx_conn_bind, ++ .unbind_conn = iscsi_conn_unbind, + .stop_conn = iscsi_conn_stop, + .destroy_conn = qla4xxx_conn_destroy, + .set_param = iscsi_set_param, +@@ -3234,6 +3235,7 @@ static int qla4xxx_conn_bind(struct iscsi_cls_session *cls_session, + conn = cls_conn->dd_data; + qla_conn = conn->dd_data; + qla_conn->qla_ep = ep->dd_data; ++ iscsi_put_endpoint(ep); + return 0; + } + +diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c +index 532304d42f00e..269bfb8f91655 100644 +--- a/drivers/scsi/scsi_lib.c ++++ b/drivers/scsi/scsi_lib.c +@@ -728,6 +728,7 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result) + case 0x07: /* operation in progress */ + case 0x08: /* Long write in progress */ + case 0x09: /* self test in progress */ ++ case 0x11: /* notify (enable spinup) required */ + case 0x14: /* space allocation in progress */ + case 0x1a: /* start stop unit in progress */ + case 0x1b: /* sanitize in progress */ +diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c +index 441f0152193f7..6ce1cc992d1d0 100644 +--- a/drivers/scsi/scsi_transport_iscsi.c ++++ b/drivers/scsi/scsi_transport_iscsi.c +@@ -86,16 +86,10 @@ struct iscsi_internal { + struct transport_container session_cont; + }; + +-/* Worker to perform connection failure on unresponsive connections +- * completely in kernel space. +- */ +-static void stop_conn_work_fn(struct work_struct *work); +-static DECLARE_WORK(stop_conn_work, stop_conn_work_fn); +- + static atomic_t iscsi_session_nr; /* sysfs session id for next new session */ + static struct workqueue_struct *iscsi_eh_timer_workq; + +-static struct workqueue_struct *iscsi_destroy_workq; ++static struct workqueue_struct *iscsi_conn_cleanup_workq; + + static DEFINE_IDA(iscsi_sess_ida); + /* +@@ -268,9 +262,20 @@ void iscsi_destroy_endpoint(struct iscsi_endpoint *ep) + } + EXPORT_SYMBOL_GPL(iscsi_destroy_endpoint); + ++void iscsi_put_endpoint(struct iscsi_endpoint *ep) ++{ ++ put_device(&ep->dev); ++} ++EXPORT_SYMBOL_GPL(iscsi_put_endpoint); ++ ++/** ++ * iscsi_lookup_endpoint - get ep from handle ++ * @handle: endpoint handle ++ * ++ * Caller must do a iscsi_put_endpoint. ++ */ + struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle) + { +- struct iscsi_endpoint *ep; + struct device *dev; + + dev = class_find_device(&iscsi_endpoint_class, NULL, &handle, +@@ -278,13 +283,7 @@ struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle) + if (!dev) + return NULL; + +- ep = iscsi_dev_to_endpoint(dev); +- /* +- * we can drop this now because the interface will prevent +- * removals and lookups from racing. +- */ +- put_device(dev); +- return ep; ++ return iscsi_dev_to_endpoint(dev); + } + EXPORT_SYMBOL_GPL(iscsi_lookup_endpoint); + +@@ -1620,12 +1619,6 @@ static DECLARE_TRANSPORT_CLASS(iscsi_connection_class, + static struct sock *nls; + static DEFINE_MUTEX(rx_queue_mutex); + +-/* +- * conn_mutex protects the {start,bind,stop,destroy}_conn from racing +- * against the kernel stop_connection recovery mechanism +- */ +-static DEFINE_MUTEX(conn_mutex); +- + static LIST_HEAD(sesslist); + static DEFINE_SPINLOCK(sesslock); + static LIST_HEAD(connlist); +@@ -1976,6 +1969,8 @@ static void __iscsi_unblock_session(struct work_struct *work) + */ + void iscsi_unblock_session(struct iscsi_cls_session *session) + { ++ flush_work(&session->block_work); ++ + queue_work(iscsi_eh_timer_workq, &session->unblock_work); + /* + * Blocking the session can be done from any context so we only +@@ -2242,6 +2237,123 @@ void iscsi_remove_session(struct iscsi_cls_session *session) + } + EXPORT_SYMBOL_GPL(iscsi_remove_session); + ++static void iscsi_stop_conn(struct iscsi_cls_conn *conn, int flag) ++{ ++ ISCSI_DBG_TRANS_CONN(conn, "Stopping conn.\n"); ++ ++ switch (flag) { ++ case STOP_CONN_RECOVER: ++ conn->state = ISCSI_CONN_FAILED; ++ break; ++ case STOP_CONN_TERM: ++ conn->state = ISCSI_CONN_DOWN; ++ break; ++ default: ++ iscsi_cls_conn_printk(KERN_ERR, conn, "invalid stop flag %d\n", ++ flag); ++ return; ++ } ++ ++ conn->transport->stop_conn(conn, flag); ++ ISCSI_DBG_TRANS_CONN(conn, "Stopping conn done.\n"); ++} ++ ++static int iscsi_if_stop_conn(struct iscsi_transport *transport, ++ struct iscsi_uevent *ev) ++{ ++ int flag = ev->u.stop_conn.flag; ++ struct iscsi_cls_conn *conn; ++ ++ conn = iscsi_conn_lookup(ev->u.stop_conn.sid, ev->u.stop_conn.cid); ++ if (!conn) ++ return -EINVAL; ++ ++ ISCSI_DBG_TRANS_CONN(conn, "iscsi if conn stop.\n"); ++ /* ++ * If this is a termination we have to call stop_conn with that flag ++ * so the correct states get set. If we haven't run the work yet try to ++ * avoid the extra run. ++ */ ++ if (flag == STOP_CONN_TERM) { ++ cancel_work_sync(&conn->cleanup_work); ++ iscsi_stop_conn(conn, flag); ++ } else { ++ /* ++ * Figure out if it was the kernel or userspace initiating this. ++ */ ++ if (!test_and_set_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags)) { ++ iscsi_stop_conn(conn, flag); ++ } else { ++ ISCSI_DBG_TRANS_CONN(conn, ++ "flush kernel conn cleanup.\n"); ++ flush_work(&conn->cleanup_work); ++ } ++ /* ++ * Only clear for recovery to avoid extra cleanup runs during ++ * termination. ++ */ ++ clear_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags); ++ } ++ ISCSI_DBG_TRANS_CONN(conn, "iscsi if conn stop done.\n"); ++ return 0; ++} ++ ++static void iscsi_ep_disconnect(struct iscsi_cls_conn *conn, bool is_active) ++{ ++ struct iscsi_cls_session *session = iscsi_conn_to_session(conn); ++ struct iscsi_endpoint *ep; ++ ++ ISCSI_DBG_TRANS_CONN(conn, "disconnect ep.\n"); ++ conn->state = ISCSI_CONN_FAILED; ++ ++ if (!conn->ep || !session->transport->ep_disconnect) ++ return; ++ ++ ep = conn->ep; ++ conn->ep = NULL; ++ ++ session->transport->unbind_conn(conn, is_active); ++ session->transport->ep_disconnect(ep); ++ ISCSI_DBG_TRANS_CONN(conn, "disconnect ep done.\n"); ++} ++ ++static void iscsi_cleanup_conn_work_fn(struct work_struct *work) ++{ ++ struct iscsi_cls_conn *conn = container_of(work, struct iscsi_cls_conn, ++ cleanup_work); ++ struct iscsi_cls_session *session = iscsi_conn_to_session(conn); ++ ++ mutex_lock(&conn->ep_mutex); ++ /* ++ * If we are not at least bound there is nothing for us to do. Userspace ++ * will do a ep_disconnect call if offload is used, but will not be ++ * doing a stop since there is nothing to clean up, so we have to clear ++ * the cleanup bit here. ++ */ ++ if (conn->state != ISCSI_CONN_BOUND && conn->state != ISCSI_CONN_UP) { ++ ISCSI_DBG_TRANS_CONN(conn, "Got error while conn is already failed. Ignoring.\n"); ++ clear_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags); ++ mutex_unlock(&conn->ep_mutex); ++ return; ++ } ++ ++ iscsi_ep_disconnect(conn, false); ++ ++ if (system_state != SYSTEM_RUNNING) { ++ /* ++ * If the user has set up for the session to never timeout ++ * then hang like they wanted. For all other cases fail right ++ * away since userspace is not going to relogin. ++ */ ++ if (session->recovery_tmo > 0) ++ session->recovery_tmo = 0; ++ } ++ ++ iscsi_stop_conn(conn, STOP_CONN_RECOVER); ++ mutex_unlock(&conn->ep_mutex); ++ ISCSI_DBG_TRANS_CONN(conn, "cleanup done.\n"); ++} ++ + void iscsi_free_session(struct iscsi_cls_session *session) + { + ISCSI_DBG_TRANS_SESSION(session, "Freeing session\n"); +@@ -2281,7 +2393,7 @@ iscsi_create_conn(struct iscsi_cls_session *session, int dd_size, uint32_t cid) + + mutex_init(&conn->ep_mutex); + INIT_LIST_HEAD(&conn->conn_list); +- INIT_LIST_HEAD(&conn->conn_list_err); ++ INIT_WORK(&conn->cleanup_work, iscsi_cleanup_conn_work_fn); + conn->transport = transport; + conn->cid = cid; + conn->state = ISCSI_CONN_DOWN; +@@ -2338,7 +2450,6 @@ int iscsi_destroy_conn(struct iscsi_cls_conn *conn) + + spin_lock_irqsave(&connlock, flags); + list_del(&conn->conn_list); +- list_del(&conn->conn_list_err); + spin_unlock_irqrestore(&connlock, flags); + + transport_unregister_device(&conn->dev); +@@ -2453,77 +2564,6 @@ int iscsi_offload_mesg(struct Scsi_Host *shost, + } + EXPORT_SYMBOL_GPL(iscsi_offload_mesg); + +-/* +- * This can be called without the rx_queue_mutex, if invoked by the kernel +- * stop work. But, in that case, it is guaranteed not to race with +- * iscsi_destroy by conn_mutex. +- */ +-static void iscsi_if_stop_conn(struct iscsi_cls_conn *conn, int flag) +-{ +- /* +- * It is important that this path doesn't rely on +- * rx_queue_mutex, otherwise, a thread doing allocation on a +- * start_session/start_connection could sleep waiting on a +- * writeback to a failed iscsi device, that cannot be recovered +- * because the lock is held. If we don't hold it here, the +- * kernel stop_conn_work_fn has a chance to stop the broken +- * session and resolve the allocation. +- * +- * Still, the user invoked .stop_conn() needs to be serialized +- * with stop_conn_work_fn by a private mutex. Not pretty, but +- * it works. +- */ +- mutex_lock(&conn_mutex); +- switch (flag) { +- case STOP_CONN_RECOVER: +- conn->state = ISCSI_CONN_FAILED; +- break; +- case STOP_CONN_TERM: +- conn->state = ISCSI_CONN_DOWN; +- break; +- default: +- iscsi_cls_conn_printk(KERN_ERR, conn, +- "invalid stop flag %d\n", flag); +- goto unlock; +- } +- +- conn->transport->stop_conn(conn, flag); +-unlock: +- mutex_unlock(&conn_mutex); +-} +- +-static void stop_conn_work_fn(struct work_struct *work) +-{ +- struct iscsi_cls_conn *conn, *tmp; +- unsigned long flags; +- LIST_HEAD(recovery_list); +- +- spin_lock_irqsave(&connlock, flags); +- if (list_empty(&connlist_err)) { +- spin_unlock_irqrestore(&connlock, flags); +- return; +- } +- list_splice_init(&connlist_err, &recovery_list); +- spin_unlock_irqrestore(&connlock, flags); +- +- list_for_each_entry_safe(conn, tmp, &recovery_list, conn_list_err) { +- uint32_t sid = iscsi_conn_get_sid(conn); +- struct iscsi_cls_session *session; +- +- session = iscsi_session_lookup(sid); +- if (session) { +- if (system_state != SYSTEM_RUNNING) { +- session->recovery_tmo = 0; +- iscsi_if_stop_conn(conn, STOP_CONN_TERM); +- } else { +- iscsi_if_stop_conn(conn, STOP_CONN_RECOVER); +- } +- } +- +- list_del_init(&conn->conn_list_err); +- } +-} +- + void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error) + { + struct nlmsghdr *nlh; +@@ -2531,12 +2571,9 @@ void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error) + struct iscsi_uevent *ev; + struct iscsi_internal *priv; + int len = nlmsg_total_size(sizeof(*ev)); +- unsigned long flags; + +- spin_lock_irqsave(&connlock, flags); +- list_add(&conn->conn_list_err, &connlist_err); +- spin_unlock_irqrestore(&connlock, flags); +- queue_work(system_unbound_wq, &stop_conn_work); ++ if (!test_and_set_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags)) ++ queue_work(iscsi_conn_cleanup_workq, &conn->cleanup_work); + + priv = iscsi_if_transport_lookup(conn->transport); + if (!priv) +@@ -2866,26 +2903,17 @@ static int + iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev) + { + struct iscsi_cls_conn *conn; +- unsigned long flags; + + conn = iscsi_conn_lookup(ev->u.d_conn.sid, ev->u.d_conn.cid); + if (!conn) + return -EINVAL; + +- spin_lock_irqsave(&connlock, flags); +- if (!list_empty(&conn->conn_list_err)) { +- spin_unlock_irqrestore(&connlock, flags); +- return -EAGAIN; +- } +- spin_unlock_irqrestore(&connlock, flags); +- ++ ISCSI_DBG_TRANS_CONN(conn, "Flushing cleanup during destruction\n"); ++ flush_work(&conn->cleanup_work); + ISCSI_DBG_TRANS_CONN(conn, "Destroying transport conn\n"); + +- mutex_lock(&conn_mutex); + if (transport->destroy_conn) + transport->destroy_conn(conn); +- mutex_unlock(&conn_mutex); +- + return 0; + } + +@@ -2975,15 +3003,31 @@ static int iscsi_if_ep_disconnect(struct iscsi_transport *transport, + ep = iscsi_lookup_endpoint(ep_handle); + if (!ep) + return -EINVAL; ++ + conn = ep->conn; +- if (conn) { +- mutex_lock(&conn->ep_mutex); +- conn->ep = NULL; ++ if (!conn) { ++ /* ++ * conn was not even bound yet, so we can't get iscsi conn ++ * failures yet. ++ */ ++ transport->ep_disconnect(ep); ++ goto put_ep; ++ } ++ ++ mutex_lock(&conn->ep_mutex); ++ /* Check if this was a conn error and the kernel took ownership */ ++ if (test_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags)) { ++ ISCSI_DBG_TRANS_CONN(conn, "flush kernel conn cleanup.\n"); + mutex_unlock(&conn->ep_mutex); +- conn->state = ISCSI_CONN_FAILED; ++ ++ flush_work(&conn->cleanup_work); ++ goto put_ep; + } + +- transport->ep_disconnect(ep); ++ iscsi_ep_disconnect(conn, false); ++ mutex_unlock(&conn->ep_mutex); ++put_ep: ++ iscsi_put_endpoint(ep); + return 0; + } + +@@ -3009,6 +3053,7 @@ iscsi_if_transport_ep(struct iscsi_transport *transport, + + ev->r.retcode = transport->ep_poll(ep, + ev->u.ep_poll.timeout_ms); ++ iscsi_put_endpoint(ep); + break; + case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT: + rc = iscsi_if_ep_disconnect(transport, +@@ -3639,18 +3684,129 @@ exit_host_stats: + return err; + } + ++static int iscsi_if_transport_conn(struct iscsi_transport *transport, ++ struct nlmsghdr *nlh) ++{ ++ struct iscsi_uevent *ev = nlmsg_data(nlh); ++ struct iscsi_cls_session *session; ++ struct iscsi_cls_conn *conn = NULL; ++ struct iscsi_endpoint *ep; ++ uint32_t pdu_len; ++ int err = 0; ++ ++ switch (nlh->nlmsg_type) { ++ case ISCSI_UEVENT_CREATE_CONN: ++ return iscsi_if_create_conn(transport, ev); ++ case ISCSI_UEVENT_DESTROY_CONN: ++ return iscsi_if_destroy_conn(transport, ev); ++ case ISCSI_UEVENT_STOP_CONN: ++ return iscsi_if_stop_conn(transport, ev); ++ } ++ ++ /* ++ * The following cmds need to be run under the ep_mutex so in kernel ++ * conn cleanup (ep_disconnect + unbind and conn) is not done while ++ * these are running. They also must not run if we have just run a conn ++ * cleanup because they would set the state in a way that might allow ++ * IO or send IO themselves. ++ */ ++ switch (nlh->nlmsg_type) { ++ case ISCSI_UEVENT_START_CONN: ++ conn = iscsi_conn_lookup(ev->u.start_conn.sid, ++ ev->u.start_conn.cid); ++ break; ++ case ISCSI_UEVENT_BIND_CONN: ++ conn = iscsi_conn_lookup(ev->u.b_conn.sid, ev->u.b_conn.cid); ++ break; ++ case ISCSI_UEVENT_SEND_PDU: ++ conn = iscsi_conn_lookup(ev->u.send_pdu.sid, ev->u.send_pdu.cid); ++ break; ++ } ++ ++ if (!conn) ++ return -EINVAL; ++ ++ mutex_lock(&conn->ep_mutex); ++ if (test_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags)) { ++ mutex_unlock(&conn->ep_mutex); ++ ev->r.retcode = -ENOTCONN; ++ return 0; ++ } ++ ++ switch (nlh->nlmsg_type) { ++ case ISCSI_UEVENT_BIND_CONN: ++ if (conn->ep) { ++ /* ++ * For offload boot support where iscsid is restarted ++ * during the pivot root stage, the ep will be intact ++ * here when the new iscsid instance starts up and ++ * reconnects. ++ */ ++ iscsi_ep_disconnect(conn, true); ++ } ++ ++ session = iscsi_session_lookup(ev->u.b_conn.sid); ++ if (!session) { ++ err = -EINVAL; ++ break; ++ } ++ ++ ev->r.retcode = transport->bind_conn(session, conn, ++ ev->u.b_conn.transport_eph, ++ ev->u.b_conn.is_leading); ++ if (!ev->r.retcode) ++ conn->state = ISCSI_CONN_BOUND; ++ ++ if (ev->r.retcode || !transport->ep_connect) ++ break; ++ ++ ep = iscsi_lookup_endpoint(ev->u.b_conn.transport_eph); ++ if (ep) { ++ ep->conn = conn; ++ conn->ep = ep; ++ iscsi_put_endpoint(ep); ++ } else { ++ err = -ENOTCONN; ++ iscsi_cls_conn_printk(KERN_ERR, conn, ++ "Could not set ep conn binding\n"); ++ } ++ break; ++ case ISCSI_UEVENT_START_CONN: ++ ev->r.retcode = transport->start_conn(conn); ++ if (!ev->r.retcode) ++ conn->state = ISCSI_CONN_UP; ++ break; ++ case ISCSI_UEVENT_SEND_PDU: ++ pdu_len = nlh->nlmsg_len - sizeof(*nlh) - sizeof(*ev); ++ ++ if ((ev->u.send_pdu.hdr_size > pdu_len) || ++ (ev->u.send_pdu.data_size > (pdu_len - ev->u.send_pdu.hdr_size))) { ++ err = -EINVAL; ++ break; ++ } ++ ++ ev->r.retcode = transport->send_pdu(conn, ++ (struct iscsi_hdr *)((char *)ev + sizeof(*ev)), ++ (char *)ev + sizeof(*ev) + ev->u.send_pdu.hdr_size, ++ ev->u.send_pdu.data_size); ++ break; ++ default: ++ err = -ENOSYS; ++ } ++ ++ mutex_unlock(&conn->ep_mutex); ++ return err; ++} + + static int + iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) + { + int err = 0; + u32 portid; +- u32 pdu_len; + struct iscsi_uevent *ev = nlmsg_data(nlh); + struct iscsi_transport *transport = NULL; + struct iscsi_internal *priv; + struct iscsi_cls_session *session; +- struct iscsi_cls_conn *conn; + struct iscsi_endpoint *ep = NULL; + + if (!netlink_capable(skb, CAP_SYS_ADMIN)) +@@ -3691,6 +3847,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) + ev->u.c_bound_session.initial_cmdsn, + ev->u.c_bound_session.cmds_max, + ev->u.c_bound_session.queue_depth); ++ iscsi_put_endpoint(ep); + break; + case ISCSI_UEVENT_DESTROY_SESSION: + session = iscsi_session_lookup(ev->u.d_session.sid); +@@ -3715,7 +3872,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) + list_del_init(&session->sess_list); + spin_unlock_irqrestore(&sesslock, flags); + +- queue_work(iscsi_destroy_workq, &session->destroy_work); ++ queue_work(system_unbound_wq, &session->destroy_work); + } + break; + case ISCSI_UEVENT_UNBIND_SESSION: +@@ -3726,89 +3883,16 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) + else + err = -EINVAL; + break; +- case ISCSI_UEVENT_CREATE_CONN: +- err = iscsi_if_create_conn(transport, ev); +- break; +- case ISCSI_UEVENT_DESTROY_CONN: +- err = iscsi_if_destroy_conn(transport, ev); +- break; +- case ISCSI_UEVENT_BIND_CONN: +- session = iscsi_session_lookup(ev->u.b_conn.sid); +- conn = iscsi_conn_lookup(ev->u.b_conn.sid, ev->u.b_conn.cid); +- +- if (conn && conn->ep) +- iscsi_if_ep_disconnect(transport, conn->ep->id); +- +- if (!session || !conn) { +- err = -EINVAL; +- break; +- } +- +- mutex_lock(&conn_mutex); +- ev->r.retcode = transport->bind_conn(session, conn, +- ev->u.b_conn.transport_eph, +- ev->u.b_conn.is_leading); +- if (!ev->r.retcode) +- conn->state = ISCSI_CONN_BOUND; +- mutex_unlock(&conn_mutex); +- +- if (ev->r.retcode || !transport->ep_connect) +- break; +- +- ep = iscsi_lookup_endpoint(ev->u.b_conn.transport_eph); +- if (ep) { +- ep->conn = conn; +- +- mutex_lock(&conn->ep_mutex); +- conn->ep = ep; +- mutex_unlock(&conn->ep_mutex); +- } else +- iscsi_cls_conn_printk(KERN_ERR, conn, +- "Could not set ep conn " +- "binding\n"); +- break; + case ISCSI_UEVENT_SET_PARAM: + err = iscsi_set_param(transport, ev); + break; +- case ISCSI_UEVENT_START_CONN: +- conn = iscsi_conn_lookup(ev->u.start_conn.sid, ev->u.start_conn.cid); +- if (conn) { +- mutex_lock(&conn_mutex); +- ev->r.retcode = transport->start_conn(conn); +- if (!ev->r.retcode) +- conn->state = ISCSI_CONN_UP; +- mutex_unlock(&conn_mutex); +- } +- else +- err = -EINVAL; +- break; ++ case ISCSI_UEVENT_CREATE_CONN: ++ case ISCSI_UEVENT_DESTROY_CONN: + case ISCSI_UEVENT_STOP_CONN: +- conn = iscsi_conn_lookup(ev->u.stop_conn.sid, ev->u.stop_conn.cid); +- if (conn) +- iscsi_if_stop_conn(conn, ev->u.stop_conn.flag); +- else +- err = -EINVAL; +- break; ++ case ISCSI_UEVENT_START_CONN: ++ case ISCSI_UEVENT_BIND_CONN: + case ISCSI_UEVENT_SEND_PDU: +- pdu_len = nlh->nlmsg_len - sizeof(*nlh) - sizeof(*ev); +- +- if ((ev->u.send_pdu.hdr_size > pdu_len) || +- (ev->u.send_pdu.data_size > (pdu_len - ev->u.send_pdu.hdr_size))) { +- err = -EINVAL; +- break; +- } +- +- conn = iscsi_conn_lookup(ev->u.send_pdu.sid, ev->u.send_pdu.cid); +- if (conn) { +- mutex_lock(&conn_mutex); +- ev->r.retcode = transport->send_pdu(conn, +- (struct iscsi_hdr*)((char*)ev + sizeof(*ev)), +- (char*)ev + sizeof(*ev) + ev->u.send_pdu.hdr_size, +- ev->u.send_pdu.data_size); +- mutex_unlock(&conn_mutex); +- } +- else +- err = -EINVAL; ++ err = iscsi_if_transport_conn(transport, nlh); + break; + case ISCSI_UEVENT_GET_STATS: + err = iscsi_if_get_stats(transport, nlh); +@@ -4656,6 +4740,7 @@ iscsi_register_transport(struct iscsi_transport *tt) + int err; + + BUG_ON(!tt); ++ WARN_ON(tt->ep_disconnect && !tt->unbind_conn); + + priv = iscsi_if_transport_lookup(tt); + if (priv) +@@ -4810,10 +4895,10 @@ static __init int iscsi_transport_init(void) + goto release_nls; + } + +- iscsi_destroy_workq = alloc_workqueue("%s", +- WQ_SYSFS | __WQ_LEGACY | WQ_MEM_RECLAIM | WQ_UNBOUND, +- 1, "iscsi_destroy"); +- if (!iscsi_destroy_workq) { ++ iscsi_conn_cleanup_workq = alloc_workqueue("%s", ++ WQ_SYSFS | WQ_MEM_RECLAIM | WQ_UNBOUND, 0, ++ "iscsi_conn_cleanup"); ++ if (!iscsi_conn_cleanup_workq) { + err = -ENOMEM; + goto destroy_wq; + } +@@ -4843,7 +4928,7 @@ unregister_transport_class: + + static void __exit iscsi_transport_exit(void) + { +- destroy_workqueue(iscsi_destroy_workq); ++ destroy_workqueue(iscsi_conn_cleanup_workq); + destroy_workqueue(iscsi_eh_timer_workq); + netlink_kernel_release(nls); + bus_unregister(&iscsi_flashnode_bus); +diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c +index 1eaedaaba0944..1a18308f4ef4f 100644 +--- a/drivers/soundwire/stream.c ++++ b/drivers/soundwire/stream.c +@@ -422,7 +422,6 @@ static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus, + struct completion *port_ready; + struct sdw_dpn_prop *dpn_prop; + struct sdw_prepare_ch prep_ch; +- unsigned int time_left; + bool intr = false; + int ret = 0, val; + u32 addr; +@@ -479,15 +478,15 @@ static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus, + + /* Wait for completion on port ready */ + port_ready = &s_rt->slave->port_ready[prep_ch.num]; +- time_left = wait_for_completion_timeout(port_ready, +- msecs_to_jiffies(dpn_prop->ch_prep_timeout)); ++ wait_for_completion_timeout(port_ready, ++ msecs_to_jiffies(dpn_prop->ch_prep_timeout)); + + val = sdw_read(s_rt->slave, SDW_DPN_PREPARESTATUS(p_rt->num)); +- val &= p_rt->ch_mask; +- if (!time_left || val) { ++ if ((val < 0) || (val & p_rt->ch_mask)) { ++ ret = (val < 0) ? val : -ETIMEDOUT; + dev_err(&s_rt->slave->dev, +- "Chn prep failed for port:%d\n", prep_ch.num); +- return -ETIMEDOUT; ++ "Chn prep failed for port %d: %d\n", prep_ch.num, ret); ++ return ret; + } + } + +diff --git a/drivers/spi/spi-loopback-test.c b/drivers/spi/spi-loopback-test.c +index f1cf2232f0b5e..4d4f77a186a98 100644 +--- a/drivers/spi/spi-loopback-test.c ++++ b/drivers/spi/spi-loopback-test.c +@@ -875,7 +875,7 @@ static int spi_test_run_iter(struct spi_device *spi, + test.transfers[i].len = len; + if (test.transfers[i].tx_buf) + test.transfers[i].tx_buf += tx_off; +- if (test.transfers[i].tx_buf) ++ if (test.transfers[i].rx_buf) + test.transfers[i].rx_buf += rx_off; + } + +diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c +index ecba6b4a5d85d..b2c4621db34d7 100644 +--- a/drivers/spi/spi-meson-spicc.c ++++ b/drivers/spi/spi-meson-spicc.c +@@ -725,7 +725,7 @@ static int meson_spicc_probe(struct platform_device *pdev) + ret = clk_prepare_enable(spicc->pclk); + if (ret) { + dev_err(&pdev->dev, "pclk clock enable failed\n"); +- goto out_master; ++ goto out_core_clk; + } + + device_reset_optional(&pdev->dev); +@@ -752,7 +752,7 @@ static int meson_spicc_probe(struct platform_device *pdev) + ret = meson_spicc_clk_init(spicc); + if (ret) { + dev_err(&pdev->dev, "clock registration failed\n"); +- goto out_master; ++ goto out_clk; + } + + ret = devm_spi_register_master(&pdev->dev, master); +@@ -764,9 +764,11 @@ static int meson_spicc_probe(struct platform_device *pdev) + return 0; + + out_clk: +- clk_disable_unprepare(spicc->core); + clk_disable_unprepare(spicc->pclk); + ++out_core_clk: ++ clk_disable_unprepare(spicc->core); ++ + out_master: + spi_master_put(master); + +diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c +index 7062f29022539..f104470605b38 100644 +--- a/drivers/spi/spi-omap-100k.c ++++ b/drivers/spi/spi-omap-100k.c +@@ -241,7 +241,7 @@ static int omap1_spi100k_setup_transfer(struct spi_device *spi, + else + word_len = spi->bits_per_word; + +- if (spi->bits_per_word > 32) ++ if (word_len > 32) + return -EINVAL; + cs->word_len = word_len; + +diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c +index cc8401980125d..23ad052528dbe 100644 +--- a/drivers/spi/spi-sun6i.c ++++ b/drivers/spi/spi-sun6i.c +@@ -379,6 +379,10 @@ static int sun6i_spi_transfer_one(struct spi_master *master, + } + + sun6i_spi_write(sspi, SUN6I_CLK_CTL_REG, reg); ++ /* Finally enable the bus - doing so before might raise SCK to HIGH */ ++ reg = sun6i_spi_read(sspi, SUN6I_GBL_CTL_REG); ++ reg |= SUN6I_GBL_CTL_BUS_ENABLE; ++ sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG, reg); + + /* Setup the transfer now... */ + if (sspi->tx_buf) +@@ -504,7 +508,7 @@ static int sun6i_spi_runtime_resume(struct device *dev) + } + + sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG, +- SUN6I_GBL_CTL_BUS_ENABLE | SUN6I_GBL_CTL_MASTER | SUN6I_GBL_CTL_TP); ++ SUN6I_GBL_CTL_MASTER | SUN6I_GBL_CTL_TP); + + return 0; + +diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c +index b8870784fc6ef..8c4615b763398 100644 +--- a/drivers/spi/spi-topcliff-pch.c ++++ b/drivers/spi/spi-topcliff-pch.c +@@ -580,8 +580,10 @@ static void pch_spi_set_tx(struct pch_spi_data *data, int *bpw) + data->pkt_tx_buff = kzalloc(size, GFP_KERNEL); + if (data->pkt_tx_buff != NULL) { + data->pkt_rx_buff = kzalloc(size, GFP_KERNEL); +- if (!data->pkt_rx_buff) ++ if (!data->pkt_rx_buff) { + kfree(data->pkt_tx_buff); ++ data->pkt_tx_buff = NULL; ++ } + } + + if (!data->pkt_rx_buff) { +diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c +index e353b7a9e54eb..56c173869d975 100644 +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -2057,6 +2057,7 @@ of_register_spi_device(struct spi_controller *ctlr, struct device_node *nc) + /* Store a pointer to the node in the device structure */ + of_node_get(nc); + spi->dev.of_node = nc; ++ spi->dev.fwnode = of_fwnode_handle(nc); + + /* Register the new device */ + rc = spi_add_device(spi); +@@ -2621,9 +2622,10 @@ static int spi_get_gpio_descs(struct spi_controller *ctlr) + native_cs_mask |= BIT(i); + } + +- ctlr->unused_native_cs = ffz(native_cs_mask); +- if (num_cs_gpios && ctlr->max_native_cs && +- ctlr->unused_native_cs >= ctlr->max_native_cs) { ++ ctlr->unused_native_cs = ffs(~native_cs_mask) - 1; ++ ++ if ((ctlr->flags & SPI_MASTER_GPIO_SS) && num_cs_gpios && ++ ctlr->max_native_cs && ctlr->unused_native_cs >= ctlr->max_native_cs) { + dev_err(dev, "No unused native chip select available\n"); + return -EINVAL; + } +diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c +index f49ab1aa2149a..4161e5d1f276e 100644 +--- a/drivers/ssb/scan.c ++++ b/drivers/ssb/scan.c +@@ -325,6 +325,7 @@ int ssb_bus_scan(struct ssb_bus *bus, + if (bus->nr_devices > ARRAY_SIZE(bus->devices)) { + pr_err("More than %d ssb cores found (%d)\n", + SSB_MAX_NR_CORES, bus->nr_devices); ++ err = -EINVAL; + goto err_unmap; + } + if (bus->bustype == SSB_BUSTYPE_SSB) { +diff --git a/drivers/ssb/sdio.c b/drivers/ssb/sdio.c +index 7fe0afb42234f..66c5c2169704b 100644 +--- a/drivers/ssb/sdio.c ++++ b/drivers/ssb/sdio.c +@@ -411,7 +411,6 @@ static void ssb_sdio_block_write(struct ssb_device *dev, const void *buffer, + sdio_claim_host(bus->host_sdio); + if (unlikely(ssb_sdio_switch_core(bus, dev))) { + error = -EIO; +- memset((void *)buffer, 0xff, count); + goto err_out; + } + offset |= bus->sdio_sbaddr & 0xffff; +diff --git a/drivers/staging/fbtft/fb_agm1264k-fl.c b/drivers/staging/fbtft/fb_agm1264k-fl.c +index eeeeec97ad278..b545c2ca80a41 100644 +--- a/drivers/staging/fbtft/fb_agm1264k-fl.c ++++ b/drivers/staging/fbtft/fb_agm1264k-fl.c +@@ -84,9 +84,9 @@ static void reset(struct fbtft_par *par) + + dev_dbg(par->info->device, "%s()\n", __func__); + +- gpiod_set_value(par->gpio.reset, 0); +- udelay(20); + gpiod_set_value(par->gpio.reset, 1); ++ udelay(20); ++ gpiod_set_value(par->gpio.reset, 0); + mdelay(120); + } + +@@ -194,12 +194,12 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) + /* select chip */ + if (*buf) { + /* cs1 */ +- gpiod_set_value(par->CS0, 1); +- gpiod_set_value(par->CS1, 0); +- } else { +- /* cs0 */ + gpiod_set_value(par->CS0, 0); + gpiod_set_value(par->CS1, 1); ++ } else { ++ /* cs0 */ ++ gpiod_set_value(par->CS0, 1); ++ gpiod_set_value(par->CS1, 0); + } + + gpiod_set_value(par->RS, 0); /* RS->0 (command mode) */ +@@ -397,8 +397,8 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) + } + kfree(convert_buf); + +- gpiod_set_value(par->CS0, 1); +- gpiod_set_value(par->CS1, 1); ++ gpiod_set_value(par->CS0, 0); ++ gpiod_set_value(par->CS1, 0); + + return ret; + } +@@ -419,10 +419,10 @@ static int write(struct fbtft_par *par, void *buf, size_t len) + for (i = 0; i < 8; ++i) + gpiod_set_value(par->gpio.db[i], data & (1 << i)); + /* set E */ +- gpiod_set_value(par->EPIN, 1); ++ gpiod_set_value(par->EPIN, 0); + udelay(5); + /* unset E - write */ +- gpiod_set_value(par->EPIN, 0); ++ gpiod_set_value(par->EPIN, 1); + udelay(1); + } + +diff --git a/drivers/staging/fbtft/fb_bd663474.c b/drivers/staging/fbtft/fb_bd663474.c +index e2c7646588f8c..1629c2c440a97 100644 +--- a/drivers/staging/fbtft/fb_bd663474.c ++++ b/drivers/staging/fbtft/fb_bd663474.c +@@ -12,7 +12,6 @@ + #include + #include + #include +-#include + #include + + #include "fbtft.h" +@@ -24,9 +23,6 @@ + + static int init_display(struct fbtft_par *par) + { +- if (par->gpio.cs) +- gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ +- + par->fbtftops.reset(par); + + /* Initialization sequence from Lib_UTFT */ +diff --git a/drivers/staging/fbtft/fb_ili9163.c b/drivers/staging/fbtft/fb_ili9163.c +index 05648c3ffe474..6582a2c90aafc 100644 +--- a/drivers/staging/fbtft/fb_ili9163.c ++++ b/drivers/staging/fbtft/fb_ili9163.c +@@ -11,7 +11,6 @@ + #include + #include + #include +-#include + #include + #include