From: "Mike Pagano" <mpagano@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/linux-patches:5.18 commit in: /
Date: Fri, 29 Jul 2022 16:39:10 +0000 (UTC) [thread overview]
Message-ID: <1659112740.e3d4af682ac7e412f6f7e870493e0cbb2b17a0d2.mpagano@gentoo> (raw)
commit: e3d4af682ac7e412f6f7e870493e0cbb2b17a0d2
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Fri Jul 29 16:39:00 2022 +0000
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Fri Jul 29 16:39:00 2022 +0000
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=e3d4af68
Linux patch 5.18.15
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
0000_README | 4 +
1014_linux-5.18.15.patch | 9072 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 9076 insertions(+)
diff --git a/0000_README b/0000_README
index 32e6ba50..7c448f23 100644
--- a/0000_README
+++ b/0000_README
@@ -99,6 +99,10 @@ Patch: 1013_linux-5.18.14.patch
From: http://www.kernel.org
Desc: Linux 5.18.14
+Patch: 1014_linux-5.18.15.patch
+From: http://www.kernel.org
+Desc: Linux 5.18.15
+
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/1014_linux-5.18.15.patch b/1014_linux-5.18.15.patch
new file mode 100644
index 00000000..01c926b9
--- /dev/null
+++ b/1014_linux-5.18.15.patch
@@ -0,0 +1,9072 @@
+diff --git a/Makefile b/Makefile
+index d3723b2f6d6ca..5957afa296922 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 5
+ PATCHLEVEL = 18
+-SUBLEVEL = 14
++SUBLEVEL = 15
+ EXTRAVERSION =
+ NAME = Superb Owl
+
+diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
+index c6ca1b9cbf712..8e236a0221564 100644
+--- a/arch/riscv/Makefile
++++ b/arch/riscv/Makefile
+@@ -73,6 +73,7 @@ ifeq ($(CONFIG_PERF_EVENTS),y)
+ endif
+
+ KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-relax)
++KBUILD_AFLAGS_MODULE += $(call as-option,-Wa$(comma)-mno-relax)
+
+ # GCC versions that support the "-mstrict-align" option default to allowing
+ # unaligned accesses. While unaligned accesses are explicitly allowed in the
+diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
+index fe1742c4ca498..1f156098a5bf5 100644
+--- a/arch/x86/events/intel/lbr.c
++++ b/arch/x86/events/intel/lbr.c
+@@ -278,9 +278,9 @@ enum {
+ };
+
+ /*
+- * For formats with LBR_TSX flags (e.g. LBR_FORMAT_EIP_FLAGS2), bits 61:62 in
+- * MSR_LAST_BRANCH_FROM_x are the TSX flags when TSX is supported, but when
+- * TSX is not supported they have no consistent behavior:
++ * For format LBR_FORMAT_EIP_FLAGS2, bits 61:62 in MSR_LAST_BRANCH_FROM_x
++ * are the TSX flags when TSX is supported, but when TSX is not supported
++ * they have no consistent behavior:
+ *
+ * - For wrmsr(), bits 61:62 are considered part of the sign extension.
+ * - For HW updates (branch captures) bits 61:62 are always OFF and are not
+@@ -288,7 +288,7 @@ enum {
+ *
+ * Therefore, if:
+ *
+- * 1) LBR has TSX format
++ * 1) LBR format LBR_FORMAT_EIP_FLAGS2
+ * 2) CPU has no TSX support enabled
+ *
+ * ... then any value passed to wrmsr() must be sign extended to 63 bits and any
+@@ -300,7 +300,7 @@ static inline bool lbr_from_signext_quirk_needed(void)
+ bool tsx_support = boot_cpu_has(X86_FEATURE_HLE) ||
+ boot_cpu_has(X86_FEATURE_RTM);
+
+- return !tsx_support && x86_pmu.lbr_has_tsx;
++ return !tsx_support;
+ }
+
+ static DEFINE_STATIC_KEY_FALSE(lbr_from_quirk_key);
+@@ -1611,9 +1611,6 @@ void intel_pmu_lbr_init_hsw(void)
+ x86_pmu.lbr_sel_map = hsw_lbr_sel_map;
+
+ x86_get_pmu(smp_processor_id())->task_ctx_cache = create_lbr_kmem_cache(size, 0);
+-
+- if (lbr_from_signext_quirk_needed())
+- static_branch_enable(&lbr_from_quirk_key);
+ }
+
+ /* skylake */
+@@ -1704,7 +1701,11 @@ void intel_pmu_lbr_init(void)
+ switch (x86_pmu.intel_cap.lbr_format) {
+ case LBR_FORMAT_EIP_FLAGS2:
+ x86_pmu.lbr_has_tsx = 1;
+- fallthrough;
++ x86_pmu.lbr_from_flags = 1;
++ if (lbr_from_signext_quirk_needed())
++ static_branch_enable(&lbr_from_quirk_key);
++ break;
++
+ case LBR_FORMAT_EIP_FLAGS:
+ x86_pmu.lbr_from_flags = 1;
+ break;
+diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
+index 5d09ded0c491f..49889f171e860 100644
+--- a/arch/x86/include/asm/cpufeatures.h
++++ b/arch/x86/include/asm/cpufeatures.h
+@@ -301,6 +301,7 @@
+ #define X86_FEATURE_RETPOLINE_LFENCE (11*32+13) /* "" Use LFENCE for Spectre variant 2 */
+ #define X86_FEATURE_RETHUNK (11*32+14) /* "" Use REturn THUNK */
+ #define X86_FEATURE_UNRET (11*32+15) /* "" AMD BTB untrain return */
++#define X86_FEATURE_USE_IBPB_FW (11*32+16) /* "" Use IBPB during runtime firmware calls */
+
+ /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
+ #define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */
+diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
+index 10a3bfc1eb230..38a3e86e665ef 100644
+--- a/arch/x86/include/asm/nospec-branch.h
++++ b/arch/x86/include/asm/nospec-branch.h
+@@ -297,6 +297,8 @@ do { \
+ alternative_msr_write(MSR_IA32_SPEC_CTRL, \
+ spec_ctrl_current() | SPEC_CTRL_IBRS, \
+ X86_FEATURE_USE_IBRS_FW); \
++ alternative_msr_write(MSR_IA32_PRED_CMD, PRED_CMD_IBPB, \
++ X86_FEATURE_USE_IBPB_FW); \
+ } while (0)
+
+ #define firmware_restrict_branch_speculation_end() \
+diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
+index 46427b785bc89..d440f6726df07 100644
+--- a/arch/x86/kernel/alternative.c
++++ b/arch/x86/kernel/alternative.c
+@@ -555,7 +555,9 @@ void __init_or_module noinline apply_returns(s32 *start, s32 *end)
+ dest = addr + insn.length + insn.immediate.value;
+
+ if (__static_call_fixup(addr, op, dest) ||
+- WARN_ON_ONCE(dest != &__x86_return_thunk))
++ WARN_ONCE(dest != &__x86_return_thunk,
++ "missing return thunk: %pS-%pS: %*ph",
++ addr, dest, 5, addr))
+ continue;
+
+ DPRINTK("return thunk at: %pS (%px) len: %d to: %pS",
+diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
+index 0b64e894b3838..8179fa4d5004f 100644
+--- a/arch/x86/kernel/cpu/bugs.c
++++ b/arch/x86/kernel/cpu/bugs.c
+@@ -968,6 +968,7 @@ static inline const char *spectre_v2_module_string(void) { return ""; }
+ #define SPECTRE_V2_LFENCE_MSG "WARNING: LFENCE mitigation is not recommended for this CPU, data leaks possible!\n"
+ #define SPECTRE_V2_EIBRS_EBPF_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS on, data leaks possible via Spectre v2 BHB attacks!\n"
+ #define SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS+LFENCE mitigation and SMT, data leaks possible via Spectre v2 BHB attacks!\n"
++#define SPECTRE_V2_IBRS_PERF_MSG "WARNING: IBRS mitigation selected on Enhanced IBRS CPU, this may cause unnecessary performance loss\n"
+
+ #ifdef CONFIG_BPF_SYSCALL
+ void unpriv_ebpf_notify(int new_state)
+@@ -1408,6 +1409,8 @@ static void __init spectre_v2_select_mitigation(void)
+
+ case SPECTRE_V2_IBRS:
+ setup_force_cpu_cap(X86_FEATURE_KERNEL_IBRS);
++ if (boot_cpu_has(X86_FEATURE_IBRS_ENHANCED))
++ pr_warn(SPECTRE_V2_IBRS_PERF_MSG);
+ break;
+
+ case SPECTRE_V2_LFENCE:
+@@ -1509,7 +1512,16 @@ static void __init spectre_v2_select_mitigation(void)
+ * the CPU supports Enhanced IBRS, kernel might un-intentionally not
+ * enable IBRS around firmware calls.
+ */
+- if (boot_cpu_has(X86_FEATURE_IBRS) && !spectre_v2_in_ibrs_mode(mode)) {
++ if (boot_cpu_has_bug(X86_BUG_RETBLEED) &&
++ (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
++ boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)) {
++
++ if (retbleed_cmd != RETBLEED_CMD_IBPB) {
++ setup_force_cpu_cap(X86_FEATURE_USE_IBPB_FW);
++ pr_info("Enabling Speculation Barrier for firmware calls\n");
++ }
++
++ } else if (boot_cpu_has(X86_FEATURE_IBRS) && !spectre_v2_in_ibrs_mode(mode)) {
+ setup_force_cpu_cap(X86_FEATURE_USE_IBRS_FW);
+ pr_info("Enabling Restricted Speculation for firmware calls\n");
+ }
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index 57ca7aa0e169a..b8e26b6b55236 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -764,7 +764,8 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
+
+ if (!osc_cpc_flexible_adr_space_confirmed) {
+ pr_debug("Flexible address space capability not supported\n");
+- goto out_free;
++ if (!cpc_supported_by_cpu())
++ goto out_free;
+ }
+
+ addr = ioremap(gas_t->address, gas_t->bit_width/8);
+@@ -791,7 +792,8 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
+ }
+ if (!osc_cpc_flexible_adr_space_confirmed) {
+ pr_debug("Flexible address space capability not supported\n");
+- goto out_free;
++ if (!cpc_supported_by_cpu())
++ goto out_free;
+ }
+ } else {
+ if (gas_t->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE || !cpc_ffh_supported()) {
+diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_generic.c
+index 541ced27d9412..de1e934a4f7ec 100644
+--- a/drivers/bus/mhi/host/pci_generic.c
++++ b/drivers/bus/mhi/host/pci_generic.c
+@@ -446,14 +446,93 @@ static const struct mhi_pci_dev_info mhi_sierra_em919x_info = {
+ .sideband_wake = false,
+ };
+
++static const struct mhi_channel_config mhi_telit_fn980_hw_v1_channels[] = {
++ MHI_CHANNEL_CONFIG_UL(14, "QMI", 32, 0),
++ MHI_CHANNEL_CONFIG_DL(15, "QMI", 32, 0),
++ MHI_CHANNEL_CONFIG_UL(20, "IPCR", 16, 0),
++ MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(21, "IPCR", 16, 0),
++ MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 128, 1),
++ MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0", 128, 2),
++};
++
++static struct mhi_event_config mhi_telit_fn980_hw_v1_events[] = {
++ MHI_EVENT_CONFIG_CTRL(0, 128),
++ MHI_EVENT_CONFIG_HW_DATA(1, 1024, 100),
++ MHI_EVENT_CONFIG_HW_DATA(2, 2048, 101)
++};
++
++static struct mhi_controller_config modem_telit_fn980_hw_v1_config = {
++ .max_channels = 128,
++ .timeout_ms = 20000,
++ .num_channels = ARRAY_SIZE(mhi_telit_fn980_hw_v1_channels),
++ .ch_cfg = mhi_telit_fn980_hw_v1_channels,
++ .num_events = ARRAY_SIZE(mhi_telit_fn980_hw_v1_events),
++ .event_cfg = mhi_telit_fn980_hw_v1_events,
++};
++
++static const struct mhi_pci_dev_info mhi_telit_fn980_hw_v1_info = {
++ .name = "telit-fn980-hwv1",
++ .fw = "qcom/sdx55m/sbl1.mbn",
++ .edl = "qcom/sdx55m/edl.mbn",
++ .config = &modem_telit_fn980_hw_v1_config,
++ .bar_num = MHI_PCI_DEFAULT_BAR_NUM,
++ .dma_data_width = 32,
++ .mru_default = 32768,
++ .sideband_wake = false,
++};
++
++static const struct mhi_channel_config mhi_telit_fn990_channels[] = {
++ MHI_CHANNEL_CONFIG_UL_SBL(2, "SAHARA", 32, 0),
++ MHI_CHANNEL_CONFIG_DL_SBL(3, "SAHARA", 32, 0),
++ MHI_CHANNEL_CONFIG_UL(4, "DIAG", 64, 1),
++ MHI_CHANNEL_CONFIG_DL(5, "DIAG", 64, 1),
++ MHI_CHANNEL_CONFIG_UL(12, "MBIM", 32, 0),
++ MHI_CHANNEL_CONFIG_DL(13, "MBIM", 32, 0),
++ MHI_CHANNEL_CONFIG_UL(32, "DUN", 32, 0),
++ MHI_CHANNEL_CONFIG_DL(33, "DUN", 32, 0),
++ MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0_MBIM", 128, 2),
++ MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0_MBIM", 128, 3),
++};
++
++static struct mhi_event_config mhi_telit_fn990_events[] = {
++ MHI_EVENT_CONFIG_CTRL(0, 128),
++ MHI_EVENT_CONFIG_DATA(1, 128),
++ MHI_EVENT_CONFIG_HW_DATA(2, 1024, 100),
++ MHI_EVENT_CONFIG_HW_DATA(3, 2048, 101)
++};
++
++static const struct mhi_controller_config modem_telit_fn990_config = {
++ .max_channels = 128,
++ .timeout_ms = 20000,
++ .num_channels = ARRAY_SIZE(mhi_telit_fn990_channels),
++ .ch_cfg = mhi_telit_fn990_channels,
++ .num_events = ARRAY_SIZE(mhi_telit_fn990_events),
++ .event_cfg = mhi_telit_fn990_events,
++};
++
++static const struct mhi_pci_dev_info mhi_telit_fn990_info = {
++ .name = "telit-fn990",
++ .config = &modem_telit_fn990_config,
++ .bar_num = MHI_PCI_DEFAULT_BAR_NUM,
++ .dma_data_width = 32,
++ .sideband_wake = false,
++ .mru_default = 32768,
++};
++
+ static const struct pci_device_id mhi_pci_id_table[] = {
+ /* EM919x (sdx55), use the same vid:pid as qcom-sdx55m */
+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, 0x18d7, 0x0200),
+ .driver_data = (kernel_ulong_t) &mhi_sierra_em919x_info },
++ /* Telit FN980 hardware revision v1 */
++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, 0x1C5D, 0x2000),
++ .driver_data = (kernel_ulong_t) &mhi_telit_fn980_hw_v1_info },
+ { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0306),
+ .driver_data = (kernel_ulong_t) &mhi_qcom_sdx55_info },
+ { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0304),
+ .driver_data = (kernel_ulong_t) &mhi_qcom_sdx24_info },
++ /* Telit FN990 */
++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, 0x1c5d, 0x2010),
++ .driver_data = (kernel_ulong_t) &mhi_telit_fn990_info },
+ { PCI_DEVICE(0x1eac, 0x1001), /* EM120R-GL (sdx24) */
+ .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
+ { PCI_DEVICE(0x1eac, 0x1002), /* EM160R-GL (sdx24) */
+diff --git a/drivers/clk/clk-lan966x.c b/drivers/clk/clk-lan966x.c
+index d1535ac13e894..81cb90955d68b 100644
+--- a/drivers/clk/clk-lan966x.c
++++ b/drivers/clk/clk-lan966x.c
+@@ -213,7 +213,7 @@ static int lan966x_gate_clk_register(struct device *dev,
+
+ hw_data->hws[i] =
+ devm_clk_hw_register_gate(dev, clk_gate_desc[idx].name,
+- "lan966x", 0, base,
++ "lan966x", 0, gate_base,
+ clk_gate_desc[idx].bit_idx,
+ 0, &clk_gate_lock);
+
+diff --git a/drivers/crypto/qat/qat_4xxx/adf_drv.c b/drivers/crypto/qat/qat_4xxx/adf_drv.c
+index fa4c350c1bf92..a6c78b9c730bc 100644
+--- a/drivers/crypto/qat/qat_4xxx/adf_drv.c
++++ b/drivers/crypto/qat/qat_4xxx/adf_drv.c
+@@ -75,13 +75,6 @@ static int adf_crypto_dev_config(struct adf_accel_dev *accel_dev)
+ if (ret)
+ goto err;
+
+- /* Temporarily set the number of crypto instances to zero to avoid
+- * registering the crypto algorithms.
+- * This will be removed when the algorithms will support the
+- * CRYPTO_TFM_REQ_MAY_BACKLOG flag
+- */
+- instances = 0;
+-
+ for (i = 0; i < instances; i++) {
+ val = i;
+ bank = i * 2;
+diff --git a/drivers/crypto/qat/qat_common/Makefile b/drivers/crypto/qat/qat_common/Makefile
+index f25a6c8edfc73..04f058acc4d37 100644
+--- a/drivers/crypto/qat/qat_common/Makefile
++++ b/drivers/crypto/qat/qat_common/Makefile
+@@ -16,6 +16,7 @@ intel_qat-objs := adf_cfg.o \
+ qat_crypto.o \
+ qat_algs.o \
+ qat_asym_algs.o \
++ qat_algs_send.o \
+ qat_uclo.o \
+ qat_hal.o
+
+diff --git a/drivers/crypto/qat/qat_common/adf_transport.c b/drivers/crypto/qat/qat_common/adf_transport.c
+index 8ba28409fb74b..630d0483c4e0a 100644
+--- a/drivers/crypto/qat/qat_common/adf_transport.c
++++ b/drivers/crypto/qat/qat_common/adf_transport.c
+@@ -8,6 +8,9 @@
+ #include "adf_cfg.h"
+ #include "adf_common_drv.h"
+
++#define ADF_MAX_RING_THRESHOLD 80
++#define ADF_PERCENT(tot, percent) (((tot) * (percent)) / 100)
++
+ static inline u32 adf_modulo(u32 data, u32 shift)
+ {
+ u32 div = data >> shift;
+@@ -77,6 +80,11 @@ static void adf_disable_ring_irq(struct adf_etr_bank_data *bank, u32 ring)
+ bank->irq_mask);
+ }
+
++bool adf_ring_nearly_full(struct adf_etr_ring_data *ring)
++{
++ return atomic_read(ring->inflights) > ring->threshold;
++}
++
+ int adf_send_message(struct adf_etr_ring_data *ring, u32 *msg)
+ {
+ struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(ring->bank->accel_dev);
+@@ -217,6 +225,7 @@ int adf_create_ring(struct adf_accel_dev *accel_dev, const char *section,
+ struct adf_etr_bank_data *bank;
+ struct adf_etr_ring_data *ring;
+ char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
++ int max_inflights;
+ u32 ring_num;
+ int ret;
+
+@@ -263,6 +272,8 @@ int adf_create_ring(struct adf_accel_dev *accel_dev, const char *section,
+ ring->ring_size = adf_verify_ring_size(msg_size, num_msgs);
+ ring->head = 0;
+ ring->tail = 0;
++ max_inflights = ADF_MAX_INFLIGHTS(ring->ring_size, ring->msg_size);
++ ring->threshold = ADF_PERCENT(max_inflights, ADF_MAX_RING_THRESHOLD);
+ atomic_set(ring->inflights, 0);
+ ret = adf_init_ring(ring);
+ if (ret)
+diff --git a/drivers/crypto/qat/qat_common/adf_transport.h b/drivers/crypto/qat/qat_common/adf_transport.h
+index 2c95f1697c76f..e6ef6f9b76913 100644
+--- a/drivers/crypto/qat/qat_common/adf_transport.h
++++ b/drivers/crypto/qat/qat_common/adf_transport.h
+@@ -14,6 +14,7 @@ int adf_create_ring(struct adf_accel_dev *accel_dev, const char *section,
+ const char *ring_name, adf_callback_fn callback,
+ int poll_mode, struct adf_etr_ring_data **ring_ptr);
+
++bool adf_ring_nearly_full(struct adf_etr_ring_data *ring);
+ int adf_send_message(struct adf_etr_ring_data *ring, u32 *msg);
+ void adf_remove_ring(struct adf_etr_ring_data *ring);
+ #endif
+diff --git a/drivers/crypto/qat/qat_common/adf_transport_internal.h b/drivers/crypto/qat/qat_common/adf_transport_internal.h
+index 501bcf0f1809a..8b2c92ba7ca1f 100644
+--- a/drivers/crypto/qat/qat_common/adf_transport_internal.h
++++ b/drivers/crypto/qat/qat_common/adf_transport_internal.h
+@@ -22,6 +22,7 @@ struct adf_etr_ring_data {
+ spinlock_t lock; /* protects ring data struct */
+ u16 head;
+ u16 tail;
++ u32 threshold;
+ u8 ring_number;
+ u8 ring_size;
+ u8 msg_size;
+diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c
+index f998ed58457c2..873533dc43a74 100644
+--- a/drivers/crypto/qat/qat_common/qat_algs.c
++++ b/drivers/crypto/qat/qat_common/qat_algs.c
+@@ -17,7 +17,7 @@
+ #include <crypto/xts.h>
+ #include <linux/dma-mapping.h>
+ #include "adf_accel_devices.h"
+-#include "adf_transport.h"
++#include "qat_algs_send.h"
+ #include "adf_common_drv.h"
+ #include "qat_crypto.h"
+ #include "icp_qat_hw.h"
+@@ -46,19 +46,6 @@
+ static DEFINE_MUTEX(algs_lock);
+ static unsigned int active_devs;
+
+-struct qat_alg_buf {
+- u32 len;
+- u32 resrvd;
+- u64 addr;
+-} __packed;
+-
+-struct qat_alg_buf_list {
+- u64 resrvd;
+- u32 num_bufs;
+- u32 num_mapped_bufs;
+- struct qat_alg_buf bufers[];
+-} __packed __aligned(64);
+-
+ /* Common content descriptor */
+ struct qat_alg_cd {
+ union {
+@@ -693,7 +680,10 @@ static void qat_alg_free_bufl(struct qat_crypto_instance *inst,
+ bl->bufers[i].len, DMA_BIDIRECTIONAL);
+
+ dma_unmap_single(dev, blp, sz, DMA_TO_DEVICE);
+- kfree(bl);
++
++ if (!qat_req->buf.sgl_src_valid)
++ kfree(bl);
++
+ if (blp != blpout) {
+ /* If out of place operation dma unmap only data */
+ int bufless = blout->num_bufs - blout->num_mapped_bufs;
+@@ -704,7 +694,9 @@ static void qat_alg_free_bufl(struct qat_crypto_instance *inst,
+ DMA_BIDIRECTIONAL);
+ }
+ dma_unmap_single(dev, blpout, sz_out, DMA_TO_DEVICE);
+- kfree(blout);
++
++ if (!qat_req->buf.sgl_dst_valid)
++ kfree(blout);
+ }
+ }
+
+@@ -721,15 +713,24 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,
+ dma_addr_t blp = DMA_MAPPING_ERROR;
+ dma_addr_t bloutp = DMA_MAPPING_ERROR;
+ struct scatterlist *sg;
+- size_t sz_out, sz = struct_size(bufl, bufers, n + 1);
++ size_t sz_out, sz = struct_size(bufl, bufers, n);
++ int node = dev_to_node(&GET_DEV(inst->accel_dev));
+
+ if (unlikely(!n))
+ return -EINVAL;
+
+- bufl = kzalloc_node(sz, GFP_ATOMIC,
+- dev_to_node(&GET_DEV(inst->accel_dev)));
+- if (unlikely(!bufl))
+- return -ENOMEM;
++ qat_req->buf.sgl_src_valid = false;
++ qat_req->buf.sgl_dst_valid = false;
++
++ if (n > QAT_MAX_BUFF_DESC) {
++ bufl = kzalloc_node(sz, GFP_ATOMIC, node);
++ if (unlikely(!bufl))
++ return -ENOMEM;
++ } else {
++ bufl = &qat_req->buf.sgl_src.sgl_hdr;
++ memset(bufl, 0, sizeof(struct qat_alg_buf_list));
++ qat_req->buf.sgl_src_valid = true;
++ }
+
+ for_each_sg(sgl, sg, n, i)
+ bufl->bufers[i].addr = DMA_MAPPING_ERROR;
+@@ -760,12 +761,18 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,
+ struct qat_alg_buf *bufers;
+
+ n = sg_nents(sglout);
+- sz_out = struct_size(buflout, bufers, n + 1);
++ sz_out = struct_size(buflout, bufers, n);
+ sg_nctr = 0;
+- buflout = kzalloc_node(sz_out, GFP_ATOMIC,
+- dev_to_node(&GET_DEV(inst->accel_dev)));
+- if (unlikely(!buflout))
+- goto err_in;
++
++ if (n > QAT_MAX_BUFF_DESC) {
++ buflout = kzalloc_node(sz_out, GFP_ATOMIC, node);
++ if (unlikely(!buflout))
++ goto err_in;
++ } else {
++ buflout = &qat_req->buf.sgl_dst.sgl_hdr;
++ memset(buflout, 0, sizeof(struct qat_alg_buf_list));
++ qat_req->buf.sgl_dst_valid = true;
++ }
+
+ bufers = buflout->bufers;
+ for_each_sg(sglout, sg, n, i)
+@@ -810,7 +817,9 @@ err_out:
+ dma_unmap_single(dev, buflout->bufers[i].addr,
+ buflout->bufers[i].len,
+ DMA_BIDIRECTIONAL);
+- kfree(buflout);
++
++ if (!qat_req->buf.sgl_dst_valid)
++ kfree(buflout);
+
+ err_in:
+ if (!dma_mapping_error(dev, blp))
+@@ -823,7 +832,8 @@ err_in:
+ bufl->bufers[i].len,
+ DMA_BIDIRECTIONAL);
+
+- kfree(bufl);
++ if (!qat_req->buf.sgl_src_valid)
++ kfree(bufl);
+
+ dev_err(dev, "Failed to map buf for dma\n");
+ return -ENOMEM;
+@@ -925,8 +935,25 @@ void qat_alg_callback(void *resp)
+ struct icp_qat_fw_la_resp *qat_resp = resp;
+ struct qat_crypto_request *qat_req =
+ (void *)(__force long)qat_resp->opaque_data;
++ struct qat_instance_backlog *backlog = qat_req->alg_req.backlog;
+
+ qat_req->cb(qat_resp, qat_req);
++
++ qat_alg_send_backlog(backlog);
++}
++
++static int qat_alg_send_sym_message(struct qat_crypto_request *qat_req,
++ struct qat_crypto_instance *inst,
++ struct crypto_async_request *base)
++{
++ struct qat_alg_req *alg_req = &qat_req->alg_req;
++
++ alg_req->fw_req = (u32 *)&qat_req->req;
++ alg_req->tx_ring = inst->sym_tx;
++ alg_req->base = base;
++ alg_req->backlog = &inst->backlog;
++
++ return qat_alg_send_message(alg_req);
+ }
+
+ static int qat_alg_aead_dec(struct aead_request *areq)
+@@ -939,7 +966,7 @@ static int qat_alg_aead_dec(struct aead_request *areq)
+ struct icp_qat_fw_la_auth_req_params *auth_param;
+ struct icp_qat_fw_la_bulk_req *msg;
+ int digst_size = crypto_aead_authsize(aead_tfm);
+- int ret, ctr = 0;
++ int ret;
+ u32 cipher_len;
+
+ cipher_len = areq->cryptlen - digst_size;
+@@ -965,15 +992,12 @@ static int qat_alg_aead_dec(struct aead_request *areq)
+ auth_param = (void *)((u8 *)cipher_param + sizeof(*cipher_param));
+ auth_param->auth_off = 0;
+ auth_param->auth_len = areq->assoclen + cipher_param->cipher_length;
+- do {
+- ret = adf_send_message(ctx->inst->sym_tx, (u32 *)msg);
+- } while (ret == -EAGAIN && ctr++ < 10);
+
+- if (ret == -EAGAIN) {
++ ret = qat_alg_send_sym_message(qat_req, ctx->inst, &areq->base);
++ if (ret == -ENOSPC)
+ qat_alg_free_bufl(ctx->inst, qat_req);
+- return -EBUSY;
+- }
+- return -EINPROGRESS;
++
++ return ret;
+ }
+
+ static int qat_alg_aead_enc(struct aead_request *areq)
+@@ -986,7 +1010,7 @@ static int qat_alg_aead_enc(struct aead_request *areq)
+ struct icp_qat_fw_la_auth_req_params *auth_param;
+ struct icp_qat_fw_la_bulk_req *msg;
+ u8 *iv = areq->iv;
+- int ret, ctr = 0;
++ int ret;
+
+ if (areq->cryptlen % AES_BLOCK_SIZE != 0)
+ return -EINVAL;
+@@ -1013,15 +1037,11 @@ static int qat_alg_aead_enc(struct aead_request *areq)
+ auth_param->auth_off = 0;
+ auth_param->auth_len = areq->assoclen + areq->cryptlen;
+
+- do {
+- ret = adf_send_message(ctx->inst->sym_tx, (u32 *)msg);
+- } while (ret == -EAGAIN && ctr++ < 10);
+-
+- if (ret == -EAGAIN) {
++ ret = qat_alg_send_sym_message(qat_req, ctx->inst, &areq->base);
++ if (ret == -ENOSPC)
+ qat_alg_free_bufl(ctx->inst, qat_req);
+- return -EBUSY;
+- }
+- return -EINPROGRESS;
++
++ return ret;
+ }
+
+ static int qat_alg_skcipher_rekey(struct qat_alg_skcipher_ctx *ctx,
+@@ -1174,7 +1194,7 @@ static int qat_alg_skcipher_encrypt(struct skcipher_request *req)
+ struct qat_crypto_request *qat_req = skcipher_request_ctx(req);
+ struct icp_qat_fw_la_cipher_req_params *cipher_param;
+ struct icp_qat_fw_la_bulk_req *msg;
+- int ret, ctr = 0;
++ int ret;
+
+ if (req->cryptlen == 0)
+ return 0;
+@@ -1198,15 +1218,11 @@ static int qat_alg_skcipher_encrypt(struct skcipher_request *req)
+
+ qat_alg_set_req_iv(qat_req);
+
+- do {
+- ret = adf_send_message(ctx->inst->sym_tx, (u32 *)msg);
+- } while (ret == -EAGAIN && ctr++ < 10);
+-
+- if (ret == -EAGAIN) {
++ ret = qat_alg_send_sym_message(qat_req, ctx->inst, &req->base);
++ if (ret == -ENOSPC)
+ qat_alg_free_bufl(ctx->inst, qat_req);
+- return -EBUSY;
+- }
+- return -EINPROGRESS;
++
++ return ret;
+ }
+
+ static int qat_alg_skcipher_blk_encrypt(struct skcipher_request *req)
+@@ -1243,7 +1259,7 @@ static int qat_alg_skcipher_decrypt(struct skcipher_request *req)
+ struct qat_crypto_request *qat_req = skcipher_request_ctx(req);
+ struct icp_qat_fw_la_cipher_req_params *cipher_param;
+ struct icp_qat_fw_la_bulk_req *msg;
+- int ret, ctr = 0;
++ int ret;
+
+ if (req->cryptlen == 0)
+ return 0;
+@@ -1268,15 +1284,11 @@ static int qat_alg_skcipher_decrypt(struct skcipher_request *req)
+ qat_alg_set_req_iv(qat_req);
+ qat_alg_update_iv(qat_req);
+
+- do {
+- ret = adf_send_message(ctx->inst->sym_tx, (u32 *)msg);
+- } while (ret == -EAGAIN && ctr++ < 10);
+-
+- if (ret == -EAGAIN) {
++ ret = qat_alg_send_sym_message(qat_req, ctx->inst, &req->base);
++ if (ret == -ENOSPC)
+ qat_alg_free_bufl(ctx->inst, qat_req);
+- return -EBUSY;
+- }
+- return -EINPROGRESS;
++
++ return ret;
+ }
+
+ static int qat_alg_skcipher_blk_decrypt(struct skcipher_request *req)
+diff --git a/drivers/crypto/qat/qat_common/qat_algs_send.c b/drivers/crypto/qat/qat_common/qat_algs_send.c
+new file mode 100644
+index 0000000000000..ff5b4347f7831
+--- /dev/null
++++ b/drivers/crypto/qat/qat_common/qat_algs_send.c
+@@ -0,0 +1,86 @@
++// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
++/* Copyright(c) 2022 Intel Corporation */
++#include "adf_transport.h"
++#include "qat_algs_send.h"
++#include "qat_crypto.h"
++
++#define ADF_MAX_RETRIES 20
++
++static int qat_alg_send_message_retry(struct qat_alg_req *req)
++{
++ int ret = 0, ctr = 0;
++
++ do {
++ ret = adf_send_message(req->tx_ring, req->fw_req);
++ } while (ret == -EAGAIN && ctr++ < ADF_MAX_RETRIES);
++
++ if (ret == -EAGAIN)
++ return -ENOSPC;
++
++ return -EINPROGRESS;
++}
++
++void qat_alg_send_backlog(struct qat_instance_backlog *backlog)
++{
++ struct qat_alg_req *req, *tmp;
++
++ spin_lock_bh(&backlog->lock);
++ list_for_each_entry_safe(req, tmp, &backlog->list, list) {
++ if (adf_send_message(req->tx_ring, req->fw_req)) {
++ /* The HW ring is full. Do nothing.
++ * qat_alg_send_backlog() will be invoked again by
++ * another callback.
++ */
++ break;
++ }
++ list_del(&req->list);
++ req->base->complete(req->base, -EINPROGRESS);
++ }
++ spin_unlock_bh(&backlog->lock);
++}
++
++static void qat_alg_backlog_req(struct qat_alg_req *req,
++ struct qat_instance_backlog *backlog)
++{
++ INIT_LIST_HEAD(&req->list);
++
++ spin_lock_bh(&backlog->lock);
++ list_add_tail(&req->list, &backlog->list);
++ spin_unlock_bh(&backlog->lock);
++}
++
++static int qat_alg_send_message_maybacklog(struct qat_alg_req *req)
++{
++ struct qat_instance_backlog *backlog = req->backlog;
++ struct adf_etr_ring_data *tx_ring = req->tx_ring;
++ u32 *fw_req = req->fw_req;
++
++ /* If any request is already backlogged, then add to backlog list */
++ if (!list_empty(&backlog->list))
++ goto enqueue;
++
++ /* If ring is nearly full, then add to backlog list */
++ if (adf_ring_nearly_full(tx_ring))
++ goto enqueue;
++
++ /* If adding request to HW ring fails, then add to backlog list */
++ if (adf_send_message(tx_ring, fw_req))
++ goto enqueue;
++
++ return -EINPROGRESS;
++
++enqueue:
++ qat_alg_backlog_req(req, backlog);
++
++ return -EBUSY;
++}
++
++int qat_alg_send_message(struct qat_alg_req *req)
++{
++ u32 flags = req->base->flags;
++
++ if (flags & CRYPTO_TFM_REQ_MAY_BACKLOG)
++ return qat_alg_send_message_maybacklog(req);
++ else
++ return qat_alg_send_message_retry(req);
++}
+diff --git a/drivers/crypto/qat/qat_common/qat_algs_send.h b/drivers/crypto/qat/qat_common/qat_algs_send.h
+new file mode 100644
+index 0000000000000..5ce9f4f69d8ff
+--- /dev/null
++++ b/drivers/crypto/qat/qat_common/qat_algs_send.h
+@@ -0,0 +1,11 @@
++/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) */
++/* Copyright(c) 2022 Intel Corporation */
++#ifndef QAT_ALGS_SEND_H
++#define QAT_ALGS_SEND_H
++
++#include "qat_crypto.h"
++
++int qat_alg_send_message(struct qat_alg_req *req);
++void qat_alg_send_backlog(struct qat_instance_backlog *backlog);
++
++#endif
+diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c b/drivers/crypto/qat/qat_common/qat_asym_algs.c
+index b0b78445418bb..7173a2a0a484f 100644
+--- a/drivers/crypto/qat/qat_common/qat_asym_algs.c
++++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c
+@@ -12,6 +12,7 @@
+ #include <crypto/scatterwalk.h>
+ #include "icp_qat_fw_pke.h"
+ #include "adf_accel_devices.h"
++#include "qat_algs_send.h"
+ #include "adf_transport.h"
+ #include "adf_common_drv.h"
+ #include "qat_crypto.h"
+@@ -135,8 +136,23 @@ struct qat_asym_request {
+ } areq;
+ int err;
+ void (*cb)(struct icp_qat_fw_pke_resp *resp);
++ struct qat_alg_req alg_req;
+ } __aligned(64);
+
++static int qat_alg_send_asym_message(struct qat_asym_request *qat_req,
++ struct qat_crypto_instance *inst,
++ struct crypto_async_request *base)
++{
++ struct qat_alg_req *alg_req = &qat_req->alg_req;
++
++ alg_req->fw_req = (u32 *)&qat_req->req;
++ alg_req->tx_ring = inst->pke_tx;
++ alg_req->base = base;
++ alg_req->backlog = &inst->backlog;
++
++ return qat_alg_send_message(alg_req);
++}
++
+ static void qat_dh_cb(struct icp_qat_fw_pke_resp *resp)
+ {
+ struct qat_asym_request *req = (void *)(__force long)resp->opaque;
+@@ -148,26 +164,21 @@ static void qat_dh_cb(struct icp_qat_fw_pke_resp *resp)
+ err = (err == ICP_QAT_FW_COMN_STATUS_FLAG_OK) ? 0 : -EINVAL;
+
+ if (areq->src) {
+- if (req->src_align)
+- dma_free_coherent(dev, req->ctx.dh->p_size,
+- req->src_align, req->in.dh.in.b);
+- else
+- dma_unmap_single(dev, req->in.dh.in.b,
+- req->ctx.dh->p_size, DMA_TO_DEVICE);
++ dma_unmap_single(dev, req->in.dh.in.b, req->ctx.dh->p_size,
++ DMA_TO_DEVICE);
++ kfree_sensitive(req->src_align);
+ }
+
+ areq->dst_len = req->ctx.dh->p_size;
+ if (req->dst_align) {
+ scatterwalk_map_and_copy(req->dst_align, areq->dst, 0,
+ areq->dst_len, 1);
+-
+- dma_free_coherent(dev, req->ctx.dh->p_size, req->dst_align,
+- req->out.dh.r);
+- } else {
+- dma_unmap_single(dev, req->out.dh.r, req->ctx.dh->p_size,
+- DMA_FROM_DEVICE);
++ kfree_sensitive(req->dst_align);
+ }
+
++ dma_unmap_single(dev, req->out.dh.r, req->ctx.dh->p_size,
++ DMA_FROM_DEVICE);
++
+ dma_unmap_single(dev, req->phy_in, sizeof(struct qat_dh_input_params),
+ DMA_TO_DEVICE);
+ dma_unmap_single(dev, req->phy_out,
+@@ -213,8 +224,9 @@ static int qat_dh_compute_value(struct kpp_request *req)
+ struct qat_asym_request *qat_req =
+ PTR_ALIGN(kpp_request_ctx(req), 64);
+ struct icp_qat_fw_pke_request *msg = &qat_req->req;
+- int ret, ctr = 0;
++ int ret;
+ int n_input_params = 0;
++ u8 *vaddr;
+
+ if (unlikely(!ctx->xa))
+ return -EINVAL;
+@@ -223,6 +235,10 @@ static int qat_dh_compute_value(struct kpp_request *req)
+ req->dst_len = ctx->p_size;
+ return -EOVERFLOW;
+ }
++
++ if (req->src_len > ctx->p_size)
++ return -EINVAL;
++
+ memset(msg, '\0', sizeof(*msg));
+ ICP_QAT_FW_PKE_HDR_VALID_FLAG_SET(msg->pke_hdr,
+ ICP_QAT_FW_COMN_REQ_FLAG_SET);
+@@ -271,27 +287,24 @@ static int qat_dh_compute_value(struct kpp_request *req)
+ */
+ if (sg_is_last(req->src) && req->src_len == ctx->p_size) {
+ qat_req->src_align = NULL;
+- qat_req->in.dh.in.b = dma_map_single(dev,
+- sg_virt(req->src),
+- req->src_len,
+- DMA_TO_DEVICE);
+- if (unlikely(dma_mapping_error(dev,
+- qat_req->in.dh.in.b)))
+- return ret;
+-
++ vaddr = sg_virt(req->src);
+ } else {
+ int shift = ctx->p_size - req->src_len;
+
+- qat_req->src_align = dma_alloc_coherent(dev,
+- ctx->p_size,
+- &qat_req->in.dh.in.b,
+- GFP_KERNEL);
++ qat_req->src_align = kzalloc(ctx->p_size, GFP_KERNEL);
+ if (unlikely(!qat_req->src_align))
+ return ret;
+
+ scatterwalk_map_and_copy(qat_req->src_align + shift,
+ req->src, 0, req->src_len, 0);
++
++ vaddr = qat_req->src_align;
+ }
++
++ qat_req->in.dh.in.b = dma_map_single(dev, vaddr, ctx->p_size,
++ DMA_TO_DEVICE);
++ if (unlikely(dma_mapping_error(dev, qat_req->in.dh.in.b)))
++ goto unmap_src;
+ }
+ /*
+ * dst can be of any size in valid range, but HW expects it to be the
+@@ -302,20 +315,18 @@ static int qat_dh_compute_value(struct kpp_request *req)
+ */
+ if (sg_is_last(req->dst) && req->dst_len == ctx->p_size) {
+ qat_req->dst_align = NULL;
+- qat_req->out.dh.r = dma_map_single(dev, sg_virt(req->dst),
+- req->dst_len,
+- DMA_FROM_DEVICE);
+-
+- if (unlikely(dma_mapping_error(dev, qat_req->out.dh.r)))
+- goto unmap_src;
+-
++ vaddr = sg_virt(req->dst);
+ } else {
+- qat_req->dst_align = dma_alloc_coherent(dev, ctx->p_size,
+- &qat_req->out.dh.r,
+- GFP_KERNEL);
++ qat_req->dst_align = kzalloc(ctx->p_size, GFP_KERNEL);
+ if (unlikely(!qat_req->dst_align))
+ goto unmap_src;
++
++ vaddr = qat_req->dst_align;
+ }
++ qat_req->out.dh.r = dma_map_single(dev, vaddr, ctx->p_size,
++ DMA_FROM_DEVICE);
++ if (unlikely(dma_mapping_error(dev, qat_req->out.dh.r)))
++ goto unmap_dst;
+
+ qat_req->in.dh.in_tab[n_input_params] = 0;
+ qat_req->out.dh.out_tab[1] = 0;
+@@ -338,13 +349,13 @@ static int qat_dh_compute_value(struct kpp_request *req)
+ msg->input_param_count = n_input_params;
+ msg->output_param_count = 1;
+
+- do {
+- ret = adf_send_message(ctx->inst->pke_tx, (u32 *)msg);
+- } while (ret == -EBUSY && ctr++ < 100);
++ ret = qat_alg_send_asym_message(qat_req, inst, &req->base);
++ if (ret == -ENOSPC)
++ goto unmap_all;
+
+- if (!ret)
+- return -EINPROGRESS;
++ return ret;
+
++unmap_all:
+ if (!dma_mapping_error(dev, qat_req->phy_out))
+ dma_unmap_single(dev, qat_req->phy_out,
+ sizeof(struct qat_dh_output_params),
+@@ -355,23 +366,17 @@ unmap_in_params:
+ sizeof(struct qat_dh_input_params),
+ DMA_TO_DEVICE);
+ unmap_dst:
+- if (qat_req->dst_align)
+- dma_free_coherent(dev, ctx->p_size, qat_req->dst_align,
+- qat_req->out.dh.r);
+- else
+- if (!dma_mapping_error(dev, qat_req->out.dh.r))
+- dma_unmap_single(dev, qat_req->out.dh.r, ctx->p_size,
+- DMA_FROM_DEVICE);
++ if (!dma_mapping_error(dev, qat_req->out.dh.r))
++ dma_unmap_single(dev, qat_req->out.dh.r, ctx->p_size,
++ DMA_FROM_DEVICE);
++ kfree_sensitive(qat_req->dst_align);
+ unmap_src:
+ if (req->src) {
+- if (qat_req->src_align)
+- dma_free_coherent(dev, ctx->p_size, qat_req->src_align,
+- qat_req->in.dh.in.b);
+- else
+- if (!dma_mapping_error(dev, qat_req->in.dh.in.b))
+- dma_unmap_single(dev, qat_req->in.dh.in.b,
+- ctx->p_size,
+- DMA_TO_DEVICE);
++ if (!dma_mapping_error(dev, qat_req->in.dh.in.b))
++ dma_unmap_single(dev, qat_req->in.dh.in.b,
++ ctx->p_size,
++ DMA_TO_DEVICE);
++ kfree_sensitive(qat_req->src_align);
+ }
+ return ret;
+ }
+@@ -420,14 +425,17 @@ static int qat_dh_set_params(struct qat_dh_ctx *ctx, struct dh *params)
+ static void qat_dh_clear_ctx(struct device *dev, struct qat_dh_ctx *ctx)
+ {
+ if (ctx->g) {
++ memset(ctx->g, 0, ctx->p_size);
+ dma_free_coherent(dev, ctx->p_size, ctx->g, ctx->dma_g);
+ ctx->g = NULL;
+ }
+ if (ctx->xa) {
++ memset(ctx->xa, 0, ctx->p_size);
+ dma_free_coherent(dev, ctx->p_size, ctx->xa, ctx->dma_xa);
+ ctx->xa = NULL;
+ }
+ if (ctx->p) {
++ memset(ctx->p, 0, ctx->p_size);
+ dma_free_coherent(dev, ctx->p_size, ctx->p, ctx->dma_p);
+ ctx->p = NULL;
+ }
+@@ -510,25 +518,22 @@ static void qat_rsa_cb(struct icp_qat_fw_pke_resp *resp)
+
+ err = (err == ICP_QAT_FW_COMN_STATUS_FLAG_OK) ? 0 : -EINVAL;
+
+- if (req->src_align)
+- dma_free_coherent(dev, req->ctx.rsa->key_sz, req->src_align,
+- req->in.rsa.enc.m);
+- else
+- dma_unmap_single(dev, req->in.rsa.enc.m, req->ctx.rsa->key_sz,
+- DMA_TO_DEVICE);
++ kfree_sensitive(req->src_align);
++
++ dma_unmap_single(dev, req->in.rsa.enc.m, req->ctx.rsa->key_sz,
++ DMA_TO_DEVICE);
+
+ areq->dst_len = req->ctx.rsa->key_sz;
+ if (req->dst_align) {
+ scatterwalk_map_and_copy(req->dst_align, areq->dst, 0,
+ areq->dst_len, 1);
+
+- dma_free_coherent(dev, req->ctx.rsa->key_sz, req->dst_align,
+- req->out.rsa.enc.c);
+- } else {
+- dma_unmap_single(dev, req->out.rsa.enc.c, req->ctx.rsa->key_sz,
+- DMA_FROM_DEVICE);
++ kfree_sensitive(req->dst_align);
+ }
+
++ dma_unmap_single(dev, req->out.rsa.enc.c, req->ctx.rsa->key_sz,
++ DMA_FROM_DEVICE);
++
+ dma_unmap_single(dev, req->phy_in, sizeof(struct qat_rsa_input_params),
+ DMA_TO_DEVICE);
+ dma_unmap_single(dev, req->phy_out,
+@@ -542,8 +547,11 @@ void qat_alg_asym_callback(void *_resp)
+ {
+ struct icp_qat_fw_pke_resp *resp = _resp;
+ struct qat_asym_request *areq = (void *)(__force long)resp->opaque;
++ struct qat_instance_backlog *backlog = areq->alg_req.backlog;
+
+ areq->cb(resp);
++
++ qat_alg_send_backlog(backlog);
+ }
+
+ #define PKE_RSA_EP_512 0x1c161b21
+@@ -642,7 +650,8 @@ static int qat_rsa_enc(struct akcipher_request *req)
+ struct qat_asym_request *qat_req =
+ PTR_ALIGN(akcipher_request_ctx(req), 64);
+ struct icp_qat_fw_pke_request *msg = &qat_req->req;
+- int ret, ctr = 0;
++ u8 *vaddr;
++ int ret;
+
+ if (unlikely(!ctx->n || !ctx->e))
+ return -EINVAL;
+@@ -651,6 +660,10 @@ static int qat_rsa_enc(struct akcipher_request *req)
+ req->dst_len = ctx->key_sz;
+ return -EOVERFLOW;
+ }
++
++ if (req->src_len > ctx->key_sz)
++ return -EINVAL;
++
+ memset(msg, '\0', sizeof(*msg));
+ ICP_QAT_FW_PKE_HDR_VALID_FLAG_SET(msg->pke_hdr,
+ ICP_QAT_FW_COMN_REQ_FLAG_SET);
+@@ -679,40 +692,39 @@ static int qat_rsa_enc(struct akcipher_request *req)
+ */
+ if (sg_is_last(req->src) && req->src_len == ctx->key_sz) {
+ qat_req->src_align = NULL;
+- qat_req->in.rsa.enc.m = dma_map_single(dev, sg_virt(req->src),
+- req->src_len, DMA_TO_DEVICE);
+- if (unlikely(dma_mapping_error(dev, qat_req->in.rsa.enc.m)))
+- return ret;
+-
++ vaddr = sg_virt(req->src);
+ } else {
+ int shift = ctx->key_sz - req->src_len;
+
+- qat_req->src_align = dma_alloc_coherent(dev, ctx->key_sz,
+- &qat_req->in.rsa.enc.m,
+- GFP_KERNEL);
++ qat_req->src_align = kzalloc(ctx->key_sz, GFP_KERNEL);
+ if (unlikely(!qat_req->src_align))
+ return ret;
+
+ scatterwalk_map_and_copy(qat_req->src_align + shift, req->src,
+ 0, req->src_len, 0);
++ vaddr = qat_req->src_align;
+ }
+- if (sg_is_last(req->dst) && req->dst_len == ctx->key_sz) {
+- qat_req->dst_align = NULL;
+- qat_req->out.rsa.enc.c = dma_map_single(dev, sg_virt(req->dst),
+- req->dst_len,
+- DMA_FROM_DEVICE);
+
+- if (unlikely(dma_mapping_error(dev, qat_req->out.rsa.enc.c)))
+- goto unmap_src;
++ qat_req->in.rsa.enc.m = dma_map_single(dev, vaddr, ctx->key_sz,
++ DMA_TO_DEVICE);
++ if (unlikely(dma_mapping_error(dev, qat_req->in.rsa.enc.m)))
++ goto unmap_src;
+
++ if (sg_is_last(req->dst) && req->dst_len == ctx->key_sz) {
++ qat_req->dst_align = NULL;
++ vaddr = sg_virt(req->dst);
+ } else {
+- qat_req->dst_align = dma_alloc_coherent(dev, ctx->key_sz,
+- &qat_req->out.rsa.enc.c,
+- GFP_KERNEL);
++ qat_req->dst_align = kzalloc(ctx->key_sz, GFP_KERNEL);
+ if (unlikely(!qat_req->dst_align))
+ goto unmap_src;
+-
++ vaddr = qat_req->dst_align;
+ }
++
++ qat_req->out.rsa.enc.c = dma_map_single(dev, vaddr, ctx->key_sz,
++ DMA_FROM_DEVICE);
++ if (unlikely(dma_mapping_error(dev, qat_req->out.rsa.enc.c)))
++ goto unmap_dst;
++
+ qat_req->in.rsa.in_tab[3] = 0;
+ qat_req->out.rsa.out_tab[1] = 0;
+ qat_req->phy_in = dma_map_single(dev, &qat_req->in.rsa.enc.m,
+@@ -732,13 +744,14 @@ static int qat_rsa_enc(struct akcipher_request *req)
+ msg->pke_mid.opaque = (u64)(__force long)qat_req;
+ msg->input_param_count = 3;
+ msg->output_param_count = 1;
+- do {
+- ret = adf_send_message(ctx->inst->pke_tx, (u32 *)msg);
+- } while (ret == -EBUSY && ctr++ < 100);
+
+- if (!ret)
+- return -EINPROGRESS;
++ ret = qat_alg_send_asym_message(qat_req, inst, &req->base);
++ if (ret == -ENOSPC)
++ goto unmap_all;
+
++ return ret;
++
++unmap_all:
+ if (!dma_mapping_error(dev, qat_req->phy_out))
+ dma_unmap_single(dev, qat_req->phy_out,
+ sizeof(struct qat_rsa_output_params),
+@@ -749,21 +762,15 @@ unmap_in_params:
+ sizeof(struct qat_rsa_input_params),
+ DMA_TO_DEVICE);
+ unmap_dst:
+- if (qat_req->dst_align)
+- dma_free_coherent(dev, ctx->key_sz, qat_req->dst_align,
+- qat_req->out.rsa.enc.c);
+- else
+- if (!dma_mapping_error(dev, qat_req->out.rsa.enc.c))
+- dma_unmap_single(dev, qat_req->out.rsa.enc.c,
+- ctx->key_sz, DMA_FROM_DEVICE);
++ if (!dma_mapping_error(dev, qat_req->out.rsa.enc.c))
++ dma_unmap_single(dev, qat_req->out.rsa.enc.c,
++ ctx->key_sz, DMA_FROM_DEVICE);
++ kfree_sensitive(qat_req->dst_align);
+ unmap_src:
+- if (qat_req->src_align)
+- dma_free_coherent(dev, ctx->key_sz, qat_req->src_align,
+- qat_req->in.rsa.enc.m);
+- else
+- if (!dma_mapping_error(dev, qat_req->in.rsa.enc.m))
+- dma_unmap_single(dev, qat_req->in.rsa.enc.m,
+- ctx->key_sz, DMA_TO_DEVICE);
++ if (!dma_mapping_error(dev, qat_req->in.rsa.enc.m))
++ dma_unmap_single(dev, qat_req->in.rsa.enc.m, ctx->key_sz,
++ DMA_TO_DEVICE);
++ kfree_sensitive(qat_req->src_align);
+ return ret;
+ }
+
+@@ -776,7 +783,8 @@ static int qat_rsa_dec(struct akcipher_request *req)
+ struct qat_asym_request *qat_req =
+ PTR_ALIGN(akcipher_request_ctx(req), 64);
+ struct icp_qat_fw_pke_request *msg = &qat_req->req;
+- int ret, ctr = 0;
++ u8 *vaddr;
++ int ret;
+
+ if (unlikely(!ctx->n || !ctx->d))
+ return -EINVAL;
+@@ -785,6 +793,10 @@ static int qat_rsa_dec(struct akcipher_request *req)
+ req->dst_len = ctx->key_sz;
+ return -EOVERFLOW;
+ }
++
++ if (req->src_len > ctx->key_sz)
++ return -EINVAL;
++
+ memset(msg, '\0', sizeof(*msg));
+ ICP_QAT_FW_PKE_HDR_VALID_FLAG_SET(msg->pke_hdr,
+ ICP_QAT_FW_COMN_REQ_FLAG_SET);
+@@ -823,40 +835,37 @@ static int qat_rsa_dec(struct akcipher_request *req)
+ */
+ if (sg_is_last(req->src) && req->src_len == ctx->key_sz) {
+ qat_req->src_align = NULL;
+- qat_req->in.rsa.dec.c = dma_map_single(dev, sg_virt(req->src),
+- req->dst_len, DMA_TO_DEVICE);
+- if (unlikely(dma_mapping_error(dev, qat_req->in.rsa.dec.c)))
+- return ret;
+-
++ vaddr = sg_virt(req->src);
+ } else {
+ int shift = ctx->key_sz - req->src_len;
+
+- qat_req->src_align = dma_alloc_coherent(dev, ctx->key_sz,
+- &qat_req->in.rsa.dec.c,
+- GFP_KERNEL);
++ qat_req->src_align = kzalloc(ctx->key_sz, GFP_KERNEL);
+ if (unlikely(!qat_req->src_align))
+ return ret;
+
+ scatterwalk_map_and_copy(qat_req->src_align + shift, req->src,
+ 0, req->src_len, 0);
++ vaddr = qat_req->src_align;
+ }
+- if (sg_is_last(req->dst) && req->dst_len == ctx->key_sz) {
+- qat_req->dst_align = NULL;
+- qat_req->out.rsa.dec.m = dma_map_single(dev, sg_virt(req->dst),
+- req->dst_len,
+- DMA_FROM_DEVICE);
+
+- if (unlikely(dma_mapping_error(dev, qat_req->out.rsa.dec.m)))
+- goto unmap_src;
++ qat_req->in.rsa.dec.c = dma_map_single(dev, vaddr, ctx->key_sz,
++ DMA_TO_DEVICE);
++ if (unlikely(dma_mapping_error(dev, qat_req->in.rsa.dec.c)))
++ goto unmap_src;
+
++ if (sg_is_last(req->dst) && req->dst_len == ctx->key_sz) {
++ qat_req->dst_align = NULL;
++ vaddr = sg_virt(req->dst);
+ } else {
+- qat_req->dst_align = dma_alloc_coherent(dev, ctx->key_sz,
+- &qat_req->out.rsa.dec.m,
+- GFP_KERNEL);
++ qat_req->dst_align = kzalloc(ctx->key_sz, GFP_KERNEL);
+ if (unlikely(!qat_req->dst_align))
+ goto unmap_src;
+-
++ vaddr = qat_req->dst_align;
+ }
++ qat_req->out.rsa.dec.m = dma_map_single(dev, vaddr, ctx->key_sz,
++ DMA_FROM_DEVICE);
++ if (unlikely(dma_mapping_error(dev, qat_req->out.rsa.dec.m)))
++ goto unmap_dst;
+
+ if (ctx->crt_mode)
+ qat_req->in.rsa.in_tab[6] = 0;
+@@ -884,13 +893,14 @@ static int qat_rsa_dec(struct akcipher_request *req)
+ msg->input_param_count = 3;
+
+ msg->output_param_count = 1;
+- do {
+- ret = adf_send_message(ctx->inst->pke_tx, (u32 *)msg);
+- } while (ret == -EBUSY && ctr++ < 100);
+
+- if (!ret)
+- return -EINPROGRESS;
++ ret = qat_alg_send_asym_message(qat_req, inst, &req->base);
++ if (ret == -ENOSPC)
++ goto unmap_all;
++
++ return ret;
+
++unmap_all:
+ if (!dma_mapping_error(dev, qat_req->phy_out))
+ dma_unmap_single(dev, qat_req->phy_out,
+ sizeof(struct qat_rsa_output_params),
+@@ -901,21 +911,15 @@ unmap_in_params:
+ sizeof(struct qat_rsa_input_params),
+ DMA_TO_DEVICE);
+ unmap_dst:
+- if (qat_req->dst_align)
+- dma_free_coherent(dev, ctx->key_sz, qat_req->dst_align,
+- qat_req->out.rsa.dec.m);
+- else
+- if (!dma_mapping_error(dev, qat_req->out.rsa.dec.m))
+- dma_unmap_single(dev, qat_req->out.rsa.dec.m,
+- ctx->key_sz, DMA_FROM_DEVICE);
++ if (!dma_mapping_error(dev, qat_req->out.rsa.dec.m))
++ dma_unmap_single(dev, qat_req->out.rsa.dec.m,
++ ctx->key_sz, DMA_FROM_DEVICE);
++ kfree_sensitive(qat_req->dst_align);
+ unmap_src:
+- if (qat_req->src_align)
+- dma_free_coherent(dev, ctx->key_sz, qat_req->src_align,
+- qat_req->in.rsa.dec.c);
+- else
+- if (!dma_mapping_error(dev, qat_req->in.rsa.dec.c))
+- dma_unmap_single(dev, qat_req->in.rsa.dec.c,
+- ctx->key_sz, DMA_TO_DEVICE);
++ if (!dma_mapping_error(dev, qat_req->in.rsa.dec.c))
++ dma_unmap_single(dev, qat_req->in.rsa.dec.c, ctx->key_sz,
++ DMA_TO_DEVICE);
++ kfree_sensitive(qat_req->src_align);
+ return ret;
+ }
+
+@@ -1233,18 +1237,8 @@ static void qat_rsa_exit_tfm(struct crypto_akcipher *tfm)
+ struct qat_rsa_ctx *ctx = akcipher_tfm_ctx(tfm);
+ struct device *dev = &GET_DEV(ctx->inst->accel_dev);
+
+- if (ctx->n)
+- dma_free_coherent(dev, ctx->key_sz, ctx->n, ctx->dma_n);
+- if (ctx->e)
+- dma_free_coherent(dev, ctx->key_sz, ctx->e, ctx->dma_e);
+- if (ctx->d) {
+- memset(ctx->d, '\0', ctx->key_sz);
+- dma_free_coherent(dev, ctx->key_sz, ctx->d, ctx->dma_d);
+- }
++ qat_rsa_clear_ctx(dev, ctx);
+ qat_crypto_put_instance(ctx->inst);
+- ctx->n = NULL;
+- ctx->e = NULL;
+- ctx->d = NULL;
+ }
+
+ static struct akcipher_alg rsa = {
+diff --git a/drivers/crypto/qat/qat_common/qat_crypto.c b/drivers/crypto/qat/qat_common/qat_crypto.c
+index 67c9588e89df9..9341d892533a7 100644
+--- a/drivers/crypto/qat/qat_common/qat_crypto.c
++++ b/drivers/crypto/qat/qat_common/qat_crypto.c
+@@ -161,13 +161,6 @@ int qat_crypto_dev_config(struct adf_accel_dev *accel_dev)
+ if (ret)
+ goto err;
+
+- /* Temporarily set the number of crypto instances to zero to avoid
+- * registering the crypto algorithms.
+- * This will be removed when the algorithms will support the
+- * CRYPTO_TFM_REQ_MAY_BACKLOG flag
+- */
+- instances = 0;
+-
+ for (i = 0; i < instances; i++) {
+ val = i;
+ snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_BANK_NUM, i);
+@@ -353,6 +346,9 @@ static int qat_crypto_create_instances(struct adf_accel_dev *accel_dev)
+ &inst->pke_rx);
+ if (ret)
+ goto err;
++
++ INIT_LIST_HEAD(&inst->backlog.list);
++ spin_lock_init(&inst->backlog.lock);
+ }
+ return 0;
+ err:
+diff --git a/drivers/crypto/qat/qat_common/qat_crypto.h b/drivers/crypto/qat/qat_common/qat_crypto.h
+index b6a4c95ae003f..245b6d9a36507 100644
+--- a/drivers/crypto/qat/qat_common/qat_crypto.h
++++ b/drivers/crypto/qat/qat_common/qat_crypto.h
+@@ -9,6 +9,19 @@
+ #include "adf_accel_devices.h"
+ #include "icp_qat_fw_la.h"
+
++struct qat_instance_backlog {
++ struct list_head list;
++ spinlock_t lock; /* protects backlog list */
++};
++
++struct qat_alg_req {
++ u32 *fw_req;
++ struct adf_etr_ring_data *tx_ring;
++ struct crypto_async_request *base;
++ struct list_head list;
++ struct qat_instance_backlog *backlog;
++};
++
+ struct qat_crypto_instance {
+ struct adf_etr_ring_data *sym_tx;
+ struct adf_etr_ring_data *sym_rx;
+@@ -19,8 +32,29 @@ struct qat_crypto_instance {
+ unsigned long state;
+ int id;
+ atomic_t refctr;
++ struct qat_instance_backlog backlog;
+ };
+
++#define QAT_MAX_BUFF_DESC 4
++
++struct qat_alg_buf {
++ u32 len;
++ u32 resrvd;
++ u64 addr;
++} __packed;
++
++struct qat_alg_buf_list {
++ u64 resrvd;
++ u32 num_bufs;
++ u32 num_mapped_bufs;
++ struct qat_alg_buf bufers[];
++} __packed;
++
++struct qat_alg_fixed_buf_list {
++ struct qat_alg_buf_list sgl_hdr;
++ struct qat_alg_buf descriptors[QAT_MAX_BUFF_DESC];
++} __packed __aligned(64);
++
+ struct qat_crypto_request_buffs {
+ struct qat_alg_buf_list *bl;
+ dma_addr_t blp;
+@@ -28,6 +62,10 @@ struct qat_crypto_request_buffs {
+ dma_addr_t bloutp;
+ size_t sz;
+ size_t sz_out;
++ bool sgl_src_valid;
++ bool sgl_dst_valid;
++ struct qat_alg_fixed_buf_list sgl_src;
++ struct qat_alg_fixed_buf_list sgl_dst;
+ };
+
+ struct qat_crypto_request;
+@@ -53,6 +91,7 @@ struct qat_crypto_request {
+ u8 iv[AES_BLOCK_SIZE];
+ };
+ bool encryption;
++ struct qat_alg_req alg_req;
+ };
+
+ static inline bool adf_hw_dev_has_crypto(struct adf_accel_dev *accel_dev)
+diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
+index 33683295a0bfe..64befd6f702b2 100644
+--- a/drivers/gpio/gpio-pca953x.c
++++ b/drivers/gpio/gpio-pca953x.c
+@@ -351,6 +351,9 @@ static const struct regmap_config pca953x_i2c_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
++ .use_single_read = true,
++ .use_single_write = true,
++
+ .readable_reg = pca953x_readable_register,
+ .writeable_reg = pca953x_writeable_register,
+ .volatile_reg = pca953x_volatile_register,
+@@ -894,15 +897,18 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
+ static int device_pca95xx_init(struct pca953x_chip *chip, u32 invert)
+ {
+ DECLARE_BITMAP(val, MAX_LINE);
++ u8 regaddr;
+ int ret;
+
+- ret = regcache_sync_region(chip->regmap, chip->regs->output,
+- chip->regs->output + NBANK(chip));
++ regaddr = pca953x_recalc_addr(chip, chip->regs->output, 0);
++ ret = regcache_sync_region(chip->regmap, regaddr,
++ regaddr + NBANK(chip) - 1);
+ if (ret)
+ goto out;
+
+- ret = regcache_sync_region(chip->regmap, chip->regs->direction,
+- chip->regs->direction + NBANK(chip));
++ regaddr = pca953x_recalc_addr(chip, chip->regs->direction, 0);
++ ret = regcache_sync_region(chip->regmap, regaddr,
++ regaddr + NBANK(chip) - 1);
+ if (ret)
+ goto out;
+
+@@ -1115,14 +1121,14 @@ static int pca953x_regcache_sync(struct device *dev)
+ * sync these registers first and only then sync the rest.
+ */
+ regaddr = pca953x_recalc_addr(chip, chip->regs->direction, 0);
+- ret = regcache_sync_region(chip->regmap, regaddr, regaddr + NBANK(chip));
++ ret = regcache_sync_region(chip->regmap, regaddr, regaddr + NBANK(chip) - 1);
+ if (ret) {
+ dev_err(dev, "Failed to sync GPIO dir registers: %d\n", ret);
+ return ret;
+ }
+
+ regaddr = pca953x_recalc_addr(chip, chip->regs->output, 0);
+- ret = regcache_sync_region(chip->regmap, regaddr, regaddr + NBANK(chip));
++ ret = regcache_sync_region(chip->regmap, regaddr, regaddr + NBANK(chip) - 1);
+ if (ret) {
+ dev_err(dev, "Failed to sync GPIO out registers: %d\n", ret);
+ return ret;
+@@ -1132,7 +1138,7 @@ static int pca953x_regcache_sync(struct device *dev)
+ if (chip->driver_data & PCA_PCAL) {
+ regaddr = pca953x_recalc_addr(chip, PCAL953X_IN_LATCH, 0);
+ ret = regcache_sync_region(chip->regmap, regaddr,
+- regaddr + NBANK(chip));
++ regaddr + NBANK(chip) - 1);
+ if (ret) {
+ dev_err(dev, "Failed to sync INT latch registers: %d\n",
+ ret);
+@@ -1141,7 +1147,7 @@ static int pca953x_regcache_sync(struct device *dev)
+
+ regaddr = pca953x_recalc_addr(chip, PCAL953X_INT_MASK, 0);
+ ret = regcache_sync_region(chip->regmap, regaddr,
+- regaddr + NBANK(chip));
++ regaddr + NBANK(chip) - 1);
+ if (ret) {
+ dev_err(dev, "Failed to sync INT mask registers: %d\n",
+ ret);
+diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
+index b6d3a57e27edc..7f8e2fed29884 100644
+--- a/drivers/gpio/gpio-xilinx.c
++++ b/drivers/gpio/gpio-xilinx.c
+@@ -99,7 +99,7 @@ static inline void xgpio_set_value32(unsigned long *map, int bit, u32 v)
+ const unsigned long offset = (bit % BITS_PER_LONG) & BIT(5);
+
+ map[index] &= ~(0xFFFFFFFFul << offset);
+- map[index] |= v << offset;
++ map[index] |= (unsigned long)v << offset;
+ }
+
+ static inline int xgpio_regoffset(struct xgpio_instance *chip, int ch)
+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 810965bd06921..a2575195c4e07 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -1670,7 +1670,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
+ #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
+ adev->dm.crc_rd_wrk = amdgpu_dm_crtc_secure_display_create_work();
+ #endif
+- if (dc_enable_dmub_notifications(adev->dm.dc)) {
++ if (dc_is_dmub_outbox_supported(adev->dm.dc)) {
+ init_completion(&adev->dm.dmub_aux_transfer_done);
+ adev->dm.dmub_notify = kzalloc(sizeof(struct dmub_notification), GFP_KERNEL);
+ if (!adev->dm.dmub_notify) {
+@@ -1708,6 +1708,13 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
+ goto error;
+ }
+
++ /* Enable outbox notification only after IRQ handlers are registered and DMUB is alive.
++ * It is expected that DMUB will resend any pending notifications at this point, for
++ * example HPD from DPIA.
++ */
++ if (dc_is_dmub_outbox_supported(adev->dm.dc))
++ dc_enable_dmub_outbox(adev->dm.dc);
++
+ /* create fake encoders for MST */
+ dm_dp_create_fake_mst_encoders(adev);
+
+@@ -2701,9 +2708,6 @@ static int dm_resume(void *handle)
+ */
+ link_enc_cfg_copy(adev->dm.dc->current_state, dc_state);
+
+- if (dc_enable_dmub_notifications(adev->dm.dc))
+- amdgpu_dm_outbox_init(adev);
+-
+ r = dm_dmub_hw_init(adev);
+ if (r)
+ DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r);
+@@ -2721,6 +2725,11 @@ static int dm_resume(void *handle)
+ }
+ }
+
++ if (dc_is_dmub_outbox_supported(adev->dm.dc)) {
++ amdgpu_dm_outbox_init(adev);
++ dc_enable_dmub_outbox(adev->dm.dc);
++ }
++
+ WARN_ON(!dc_commit_state(dm->dc, dc_state));
+
+ dm_gpureset_commit_state(dm->cached_dc_state, dm);
+@@ -2742,13 +2751,15 @@ static int dm_resume(void *handle)
+ /* TODO: Remove dc_state->dccg, use dc->dccg directly. */
+ dc_resource_state_construct(dm->dc, dm_state->context);
+
+- /* Re-enable outbox interrupts for DPIA. */
+- if (dc_enable_dmub_notifications(adev->dm.dc))
+- amdgpu_dm_outbox_init(adev);
+-
+ /* Before powering on DC we need to re-initialize DMUB. */
+ dm_dmub_hw_resume(adev);
+
++ /* Re-enable outbox interrupts for DPIA. */
++ if (dc_is_dmub_outbox_supported(adev->dm.dc)) {
++ amdgpu_dm_outbox_init(adev);
++ dc_enable_dmub_outbox(adev->dm.dc);
++ }
++
+ /* power on hardware */
+ dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0);
+
+diff --git a/drivers/gpu/drm/drm_gem_ttm_helper.c b/drivers/gpu/drm/drm_gem_ttm_helper.c
+index d5962a34c01d5..e5fc875990c4f 100644
+--- a/drivers/gpu/drm/drm_gem_ttm_helper.c
++++ b/drivers/gpu/drm/drm_gem_ttm_helper.c
+@@ -64,8 +64,13 @@ int drm_gem_ttm_vmap(struct drm_gem_object *gem,
+ struct iosys_map *map)
+ {
+ struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gem);
++ int ret;
++
++ dma_resv_lock(gem->resv, NULL);
++ ret = ttm_bo_vmap(bo, map);
++ dma_resv_unlock(gem->resv);
+
+- return ttm_bo_vmap(bo, map);
++ return ret;
+ }
+ EXPORT_SYMBOL(drm_gem_ttm_vmap);
+
+@@ -82,7 +87,9 @@ void drm_gem_ttm_vunmap(struct drm_gem_object *gem,
+ {
+ struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gem);
+
++ dma_resv_lock(gem->resv, NULL);
+ ttm_bo_vunmap(bo, map);
++ dma_resv_unlock(gem->resv);
+ }
+ EXPORT_SYMBOL(drm_gem_ttm_vunmap);
+
+diff --git a/drivers/gpu/drm/imx/dcss/dcss-dev.c b/drivers/gpu/drm/imx/dcss/dcss-dev.c
+index c849533ca83e3..3f5750cc2673e 100644
+--- a/drivers/gpu/drm/imx/dcss/dcss-dev.c
++++ b/drivers/gpu/drm/imx/dcss/dcss-dev.c
+@@ -207,6 +207,7 @@ struct dcss_dev *dcss_dev_create(struct device *dev, bool hdmi_output)
+
+ ret = dcss_submodules_init(dcss);
+ if (ret) {
++ of_node_put(dcss->of_port);
+ dev_err(dev, "submodules initialization failed\n");
+ goto clks_err;
+ }
+@@ -237,6 +238,8 @@ void dcss_dev_destroy(struct dcss_dev *dcss)
+ dcss_clocks_disable(dcss);
+ }
+
++ of_node_put(dcss->of_port);
++
+ pm_runtime_disable(dcss->dev);
+
+ dcss_submodules_stop(dcss);
+diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c
+index f7bfcf63d48ee..701a258d2e111 100644
+--- a/drivers/gpu/drm/panel/panel-edp.c
++++ b/drivers/gpu/drm/panel/panel-edp.c
+@@ -713,7 +713,7 @@ static int generic_edp_panel_probe(struct device *dev, struct panel_edp *panel)
+ of_property_read_u32(dev->of_node, "hpd-reliable-delay-ms", &reliable_ms);
+ desc->delay.hpd_reliable = reliable_ms;
+ of_property_read_u32(dev->of_node, "hpd-absent-delay-ms", &absent_ms);
+- desc->delay.hpd_reliable = absent_ms;
++ desc->delay.hpd_absent = absent_ms;
+
+ /* Power the panel on so we can read the EDID */
+ ret = pm_runtime_get_sync(dev);
+diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c
+index 191c56064f196..6b25b2f4f5a30 100644
+--- a/drivers/gpu/drm/scheduler/sched_entity.c
++++ b/drivers/gpu/drm/scheduler/sched_entity.c
+@@ -190,7 +190,7 @@ long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout)
+ }
+ EXPORT_SYMBOL(drm_sched_entity_flush);
+
+-static void drm_sched_entity_kill_jobs_irq_work(struct irq_work *wrk)
++static void drm_sched_entity_kill_jobs_work(struct work_struct *wrk)
+ {
+ struct drm_sched_job *job = container_of(wrk, typeof(*job), work);
+
+@@ -207,8 +207,8 @@ static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,
+ struct drm_sched_job *job = container_of(cb, struct drm_sched_job,
+ finish_cb);
+
+- init_irq_work(&job->work, drm_sched_entity_kill_jobs_irq_work);
+- irq_work_queue(&job->work);
++ INIT_WORK(&job->work, drm_sched_entity_kill_jobs_work);
++ schedule_work(&job->work);
+ }
+
+ static struct dma_fence *
+diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c
+index 3d6f8ee355bfc..630cfa4ddd468 100644
+--- a/drivers/i2c/busses/i2c-cadence.c
++++ b/drivers/i2c/busses/i2c-cadence.c
+@@ -388,9 +388,9 @@ static irqreturn_t cdns_i2c_slave_isr(void *ptr)
+ */
+ static irqreturn_t cdns_i2c_master_isr(void *ptr)
+ {
+- unsigned int isr_status, avail_bytes, updatetx;
++ unsigned int isr_status, avail_bytes;
+ unsigned int bytes_to_send;
+- bool hold_quirk;
++ bool updatetx;
+ struct cdns_i2c *id = ptr;
+ /* Signal completion only after everything is updated */
+ int done_flag = 0;
+@@ -410,11 +410,7 @@ static irqreturn_t cdns_i2c_master_isr(void *ptr)
+ * Check if transfer size register needs to be updated again for a
+ * large data receive operation.
+ */
+- updatetx = 0;
+- if (id->recv_count > id->curr_recv_count)
+- updatetx = 1;
+-
+- hold_quirk = (id->quirks & CDNS_I2C_BROKEN_HOLD_BIT) && updatetx;
++ updatetx = id->recv_count > id->curr_recv_count;
+
+ /* When receiving, handle data interrupt and completion interrupt */
+ if (id->p_recv_buf &&
+@@ -445,7 +441,7 @@ static irqreturn_t cdns_i2c_master_isr(void *ptr)
+ break;
+ }
+
+- if (cdns_is_holdquirk(id, hold_quirk))
++ if (cdns_is_holdquirk(id, updatetx))
+ break;
+ }
+
+@@ -456,7 +452,7 @@ static irqreturn_t cdns_i2c_master_isr(void *ptr)
+ * maintain transfer size non-zero while performing a large
+ * receive operation.
+ */
+- if (cdns_is_holdquirk(id, hold_quirk)) {
++ if (cdns_is_holdquirk(id, updatetx)) {
+ /* wait while fifo is full */
+ while (cdns_i2c_readreg(CDNS_I2C_XFER_SIZE_OFFSET) !=
+ (id->curr_recv_count - CDNS_I2C_FIFO_DEPTH))
+@@ -478,22 +474,6 @@ static irqreturn_t cdns_i2c_master_isr(void *ptr)
+ CDNS_I2C_XFER_SIZE_OFFSET);
+ id->curr_recv_count = id->recv_count;
+ }
+- } else if (id->recv_count && !hold_quirk &&
+- !id->curr_recv_count) {
+-
+- /* Set the slave address in address register*/
+- cdns_i2c_writereg(id->p_msg->addr & CDNS_I2C_ADDR_MASK,
+- CDNS_I2C_ADDR_OFFSET);
+-
+- if (id->recv_count > CDNS_I2C_TRANSFER_SIZE) {
+- cdns_i2c_writereg(CDNS_I2C_TRANSFER_SIZE,
+- CDNS_I2C_XFER_SIZE_OFFSET);
+- id->curr_recv_count = CDNS_I2C_TRANSFER_SIZE;
+- } else {
+- cdns_i2c_writereg(id->recv_count,
+- CDNS_I2C_XFER_SIZE_OFFSET);
+- id->curr_recv_count = id->recv_count;
+- }
+ }
+
+ /* Clear hold (if not repeated start) and signal completion */
+diff --git a/drivers/i2c/busses/i2c-mlxcpld.c b/drivers/i2c/busses/i2c-mlxcpld.c
+index 56aa424fd71d5..815cc561386b0 100644
+--- a/drivers/i2c/busses/i2c-mlxcpld.c
++++ b/drivers/i2c/busses/i2c-mlxcpld.c
+@@ -49,7 +49,7 @@
+ #define MLXCPLD_LPCI2C_NACK_IND 2
+
+ #define MLXCPLD_I2C_FREQ_1000KHZ_SET 0x04
+-#define MLXCPLD_I2C_FREQ_400KHZ_SET 0x0c
++#define MLXCPLD_I2C_FREQ_400KHZ_SET 0x0e
+ #define MLXCPLD_I2C_FREQ_100KHZ_SET 0x42
+
+ enum mlxcpld_i2c_frequency {
+diff --git a/drivers/infiniband/hw/irdma/cm.c b/drivers/infiniband/hw/irdma/cm.c
+index 638bf4a1ed946..646fa86774909 100644
+--- a/drivers/infiniband/hw/irdma/cm.c
++++ b/drivers/infiniband/hw/irdma/cm.c
+@@ -4231,10 +4231,6 @@ void irdma_cm_teardown_connections(struct irdma_device *iwdev, u32 *ipaddr,
+ struct irdma_cm_node *cm_node;
+ struct list_head teardown_list;
+ struct ib_qp_attr attr;
+- struct irdma_sc_vsi *vsi = &iwdev->vsi;
+- struct irdma_sc_qp *sc_qp;
+- struct irdma_qp *qp;
+- int i;
+
+ INIT_LIST_HEAD(&teardown_list);
+
+@@ -4251,52 +4247,6 @@ void irdma_cm_teardown_connections(struct irdma_device *iwdev, u32 *ipaddr,
+ irdma_cm_disconn(cm_node->iwqp);
+ irdma_rem_ref_cm_node(cm_node);
+ }
+- if (!iwdev->roce_mode)
+- return;
+-
+- INIT_LIST_HEAD(&teardown_list);
+- for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++) {
+- mutex_lock(&vsi->qos[i].qos_mutex);
+- list_for_each_safe (list_node, list_core_temp,
+- &vsi->qos[i].qplist) {
+- u32 qp_ip[4];
+-
+- sc_qp = container_of(list_node, struct irdma_sc_qp,
+- list);
+- if (sc_qp->qp_uk.qp_type != IRDMA_QP_TYPE_ROCE_RC)
+- continue;
+-
+- qp = sc_qp->qp_uk.back_qp;
+- if (!disconnect_all) {
+- if (nfo->ipv4)
+- qp_ip[0] = qp->udp_info.local_ipaddr[3];
+- else
+- memcpy(qp_ip,
+- &qp->udp_info.local_ipaddr[0],
+- sizeof(qp_ip));
+- }
+-
+- if (disconnect_all ||
+- (nfo->vlan_id == (qp->udp_info.vlan_tag & VLAN_VID_MASK) &&
+- !memcmp(qp_ip, ipaddr, nfo->ipv4 ? 4 : 16))) {
+- spin_lock(&iwdev->rf->qptable_lock);
+- if (iwdev->rf->qp_table[sc_qp->qp_uk.qp_id]) {
+- irdma_qp_add_ref(&qp->ibqp);
+- list_add(&qp->teardown_entry,
+- &teardown_list);
+- }
+- spin_unlock(&iwdev->rf->qptable_lock);
+- }
+- }
+- mutex_unlock(&vsi->qos[i].qos_mutex);
+- }
+-
+- list_for_each_safe (list_node, list_core_temp, &teardown_list) {
+- qp = container_of(list_node, struct irdma_qp, teardown_entry);
+- attr.qp_state = IB_QPS_ERR;
+- irdma_modify_qp_roce(&qp->ibqp, &attr, IB_QP_STATE, NULL);
+- irdma_qp_rem_ref(&qp->ibqp);
+- }
+ }
+
+ /**
+diff --git a/drivers/infiniband/hw/irdma/i40iw_hw.c b/drivers/infiniband/hw/irdma/i40iw_hw.c
+index e46fc110004d0..50299f58b6b31 100644
+--- a/drivers/infiniband/hw/irdma/i40iw_hw.c
++++ b/drivers/infiniband/hw/irdma/i40iw_hw.c
+@@ -201,6 +201,7 @@ void i40iw_init_hw(struct irdma_sc_dev *dev)
+ dev->hw_attrs.uk_attrs.max_hw_read_sges = I40IW_MAX_SGE_RD;
+ dev->hw_attrs.max_hw_device_pages = I40IW_MAX_PUSH_PAGE_COUNT;
+ dev->hw_attrs.uk_attrs.max_hw_inline = I40IW_MAX_INLINE_DATA_SIZE;
++ dev->hw_attrs.page_size_cap = SZ_4K | SZ_2M;
+ dev->hw_attrs.max_hw_ird = I40IW_MAX_IRD_SIZE;
+ dev->hw_attrs.max_hw_ord = I40IW_MAX_ORD_SIZE;
+ dev->hw_attrs.max_hw_wqes = I40IW_MAX_WQ_ENTRIES;
+diff --git a/drivers/infiniband/hw/irdma/icrdma_hw.c b/drivers/infiniband/hw/irdma/icrdma_hw.c
+index cf53b17510cdb..5986fd906308c 100644
+--- a/drivers/infiniband/hw/irdma/icrdma_hw.c
++++ b/drivers/infiniband/hw/irdma/icrdma_hw.c
+@@ -139,6 +139,7 @@ void icrdma_init_hw(struct irdma_sc_dev *dev)
+ dev->cqp_db = dev->hw_regs[IRDMA_CQPDB];
+ dev->cq_ack_db = dev->hw_regs[IRDMA_CQACK];
+ dev->irq_ops = &icrdma_irq_ops;
++ dev->hw_attrs.page_size_cap = SZ_4K | SZ_2M | SZ_1G;
+ dev->hw_attrs.max_hw_ird = ICRDMA_MAX_IRD_SIZE;
+ dev->hw_attrs.max_hw_ord = ICRDMA_MAX_ORD_SIZE;
+ dev->hw_attrs.max_stat_inst = ICRDMA_MAX_STATS_COUNT;
+diff --git a/drivers/infiniband/hw/irdma/irdma.h b/drivers/infiniband/hw/irdma/irdma.h
+index 46c12334c7354..4789e85d717b3 100644
+--- a/drivers/infiniband/hw/irdma/irdma.h
++++ b/drivers/infiniband/hw/irdma/irdma.h
+@@ -127,6 +127,7 @@ struct irdma_hw_attrs {
+ u64 max_hw_outbound_msg_size;
+ u64 max_hw_inbound_msg_size;
+ u64 max_mr_size;
++ u64 page_size_cap;
+ u32 min_hw_qp_id;
+ u32 min_hw_aeq_size;
+ u32 max_hw_aeq_size;
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index 52f3e88f85695..6daa149dcbda2 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -30,7 +30,7 @@ static int irdma_query_device(struct ib_device *ibdev,
+ props->vendor_part_id = pcidev->device;
+
+ props->hw_ver = rf->pcidev->revision;
+- props->page_size_cap = SZ_4K | SZ_2M | SZ_1G;
++ props->page_size_cap = hw_attrs->page_size_cap;
+ props->max_mr_size = hw_attrs->max_mr_size;
+ props->max_qp = rf->max_qp - rf->used_qps;
+ props->max_qp_wr = hw_attrs->max_qp_wr;
+@@ -2764,7 +2764,7 @@ static struct ib_mr *irdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 len,
+
+ if (req.reg_type == IRDMA_MEMREG_TYPE_MEM) {
+ iwmr->page_size = ib_umem_find_best_pgsz(region,
+- SZ_4K | SZ_2M | SZ_1G,
++ iwdev->rf->sc_dev.hw_attrs.page_size_cap,
+ virt);
+ if (unlikely(!iwmr->page_size)) {
+ kfree(iwmr);
+diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c
+index 64e27c2821f99..ada23040cb654 100644
+--- a/drivers/mmc/host/sdhci-omap.c
++++ b/drivers/mmc/host/sdhci-omap.c
+@@ -1303,8 +1303,9 @@ static int sdhci_omap_probe(struct platform_device *pdev)
+ /*
+ * omap_device_pm_domain has callbacks to enable the main
+ * functional clock, interface clock and also configure the
+- * SYSCONFIG register of omap devices. The callback will be invoked
+- * as part of pm_runtime_get_sync.
++ * SYSCONFIG register to clear any boot loader set voltage
++ * capabilities before calling sdhci_setup_host(). The
++ * callback will be invoked as part of pm_runtime_get_sync.
+ */
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_set_autosuspend_delay(dev, 50);
+@@ -1446,7 +1447,8 @@ static int __maybe_unused sdhci_omap_runtime_suspend(struct device *dev)
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
+
+- sdhci_runtime_suspend_host(host);
++ if (omap_host->con != -EINVAL)
++ sdhci_runtime_suspend_host(host);
+
+ sdhci_omap_context_save(omap_host);
+
+@@ -1463,10 +1465,10 @@ static int __maybe_unused sdhci_omap_runtime_resume(struct device *dev)
+
+ pinctrl_pm_select_default_state(dev);
+
+- if (omap_host->con != -EINVAL)
++ if (omap_host->con != -EINVAL) {
+ sdhci_omap_context_restore(omap_host);
+-
+- sdhci_runtime_resume_host(host, 0);
++ sdhci_runtime_resume_host(host, 0);
++ }
+
+ return 0;
+ }
+diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
+index 44b14c9dc9a73..a626028336d3f 100644
+--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
++++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
+@@ -655,9 +655,10 @@ static int gpmi_nfc_compute_timings(struct gpmi_nand_data *this,
+ unsigned int tRP_ps;
+ bool use_half_period;
+ int sample_delay_ps, sample_delay_factor;
+- u16 busy_timeout_cycles;
++ unsigned int busy_timeout_cycles;
+ u8 wrn_dly_sel;
+ unsigned long clk_rate, min_rate;
++ u64 busy_timeout_ps;
+
+ if (sdr->tRC_min >= 30000) {
+ /* ONFI non-EDO modes [0-3] */
+@@ -690,7 +691,8 @@ static int gpmi_nfc_compute_timings(struct gpmi_nand_data *this,
+ addr_setup_cycles = TO_CYCLES(sdr->tALS_min, period_ps);
+ data_setup_cycles = TO_CYCLES(sdr->tDS_min, period_ps);
+ data_hold_cycles = TO_CYCLES(sdr->tDH_min, period_ps);
+- busy_timeout_cycles = TO_CYCLES(sdr->tWB_max + sdr->tR_max, period_ps);
++ busy_timeout_ps = max(sdr->tBERS_max, sdr->tPROG_max);
++ busy_timeout_cycles = TO_CYCLES(busy_timeout_ps, period_ps);
+
+ hw->timing0 = BF_GPMI_TIMING0_ADDRESS_SETUP(addr_setup_cycles) |
+ BF_GPMI_TIMING0_DATA_HOLD(data_hold_cycles) |
+diff --git a/drivers/net/amt.c b/drivers/net/amt.c
+index 14fe03dbd9b1d..acf5ea96652f8 100644
+--- a/drivers/net/amt.c
++++ b/drivers/net/amt.c
+@@ -563,7 +563,7 @@ static struct sk_buff *amt_build_igmp_gq(struct amt_dev *amt)
+ ihv3->nsrcs = 0;
+ ihv3->resv = 0;
+ ihv3->suppress = false;
+- ihv3->qrv = amt->net->ipv4.sysctl_igmp_qrv;
++ ihv3->qrv = READ_ONCE(amt->net->ipv4.sysctl_igmp_qrv);
+ ihv3->csum = 0;
+ csum = &ihv3->csum;
+ csum_start = (void *)ihv3;
+@@ -577,14 +577,14 @@ static struct sk_buff *amt_build_igmp_gq(struct amt_dev *amt)
+ return skb;
+ }
+
+-static void __amt_update_gw_status(struct amt_dev *amt, enum amt_status status,
+- bool validate)
++static void amt_update_gw_status(struct amt_dev *amt, enum amt_status status,
++ bool validate)
+ {
+ if (validate && amt->status >= status)
+ return;
+ netdev_dbg(amt->dev, "Update GW status %s -> %s",
+ status_str[amt->status], status_str[status]);
+- amt->status = status;
++ WRITE_ONCE(amt->status, status);
+ }
+
+ static void __amt_update_relay_status(struct amt_tunnel_list *tunnel,
+@@ -600,14 +600,6 @@ static void __amt_update_relay_status(struct amt_tunnel_list *tunnel,
+ tunnel->status = status;
+ }
+
+-static void amt_update_gw_status(struct amt_dev *amt, enum amt_status status,
+- bool validate)
+-{
+- spin_lock_bh(&amt->lock);
+- __amt_update_gw_status(amt, status, validate);
+- spin_unlock_bh(&amt->lock);
+-}
+-
+ static void amt_update_relay_status(struct amt_tunnel_list *tunnel,
+ enum amt_status status, bool validate)
+ {
+@@ -700,9 +692,7 @@ static void amt_send_discovery(struct amt_dev *amt)
+ if (unlikely(net_xmit_eval(err)))
+ amt->dev->stats.tx_errors++;
+
+- spin_lock_bh(&amt->lock);
+- __amt_update_gw_status(amt, AMT_STATUS_SENT_DISCOVERY, true);
+- spin_unlock_bh(&amt->lock);
++ amt_update_gw_status(amt, AMT_STATUS_SENT_DISCOVERY, true);
+ out:
+ rcu_read_unlock();
+ }
+@@ -900,6 +890,28 @@ static void amt_send_mld_gq(struct amt_dev *amt, struct amt_tunnel_list *tunnel)
+ }
+ #endif
+
++static bool amt_queue_event(struct amt_dev *amt, enum amt_event event,
++ struct sk_buff *skb)
++{
++ int index;
++
++ spin_lock_bh(&amt->lock);
++ if (amt->nr_events >= AMT_MAX_EVENTS) {
++ spin_unlock_bh(&amt->lock);
++ return 1;
++ }
++
++ index = (amt->event_idx + amt->nr_events) % AMT_MAX_EVENTS;
++ amt->events[index].event = event;
++ amt->events[index].skb = skb;
++ amt->nr_events++;
++ amt->event_idx %= AMT_MAX_EVENTS;
++ queue_work(amt_wq, &amt->event_wq);
++ spin_unlock_bh(&amt->lock);
++
++ return 0;
++}
++
+ static void amt_secret_work(struct work_struct *work)
+ {
+ struct amt_dev *amt = container_of(to_delayed_work(work),
+@@ -913,58 +925,72 @@ static void amt_secret_work(struct work_struct *work)
+ msecs_to_jiffies(AMT_SECRET_TIMEOUT));
+ }
+
+-static void amt_discovery_work(struct work_struct *work)
++static void amt_event_send_discovery(struct amt_dev *amt)
+ {
+- struct amt_dev *amt = container_of(to_delayed_work(work),
+- struct amt_dev,
+- discovery_wq);
+-
+- spin_lock_bh(&amt->lock);
+ if (amt->status > AMT_STATUS_SENT_DISCOVERY)
+ goto out;
+ get_random_bytes(&amt->nonce, sizeof(__be32));
+- spin_unlock_bh(&amt->lock);
+
+ amt_send_discovery(amt);
+- spin_lock_bh(&amt->lock);
+ out:
+ mod_delayed_work(amt_wq, &amt->discovery_wq,
+ msecs_to_jiffies(AMT_DISCOVERY_TIMEOUT));
+- spin_unlock_bh(&amt->lock);
+ }
+
+-static void amt_req_work(struct work_struct *work)
++static void amt_discovery_work(struct work_struct *work)
+ {
+ struct amt_dev *amt = container_of(to_delayed_work(work),
+ struct amt_dev,
+- req_wq);
++ discovery_wq);
++
++ if (amt_queue_event(amt, AMT_EVENT_SEND_DISCOVERY, NULL))
++ mod_delayed_work(amt_wq, &amt->discovery_wq,
++ msecs_to_jiffies(AMT_DISCOVERY_TIMEOUT));
++}
++
++static void amt_event_send_request(struct amt_dev *amt)
++{
+ u32 exp;
+
+- spin_lock_bh(&amt->lock);
+ if (amt->status < AMT_STATUS_RECEIVED_ADVERTISEMENT)
+ goto out;
+
+ if (amt->req_cnt > AMT_MAX_REQ_COUNT) {
+ netdev_dbg(amt->dev, "Gateway is not ready");
+ amt->qi = AMT_INIT_REQ_TIMEOUT;
+- amt->ready4 = false;
+- amt->ready6 = false;
++ WRITE_ONCE(amt->ready4, false);
++ WRITE_ONCE(amt->ready6, false);
+ amt->remote_ip = 0;
+- __amt_update_gw_status(amt, AMT_STATUS_INIT, false);
++ amt_update_gw_status(amt, AMT_STATUS_INIT, false);
+ amt->req_cnt = 0;
++ amt->nonce = 0;
+ goto out;
+ }
+- spin_unlock_bh(&amt->lock);
++
++ if (!amt->req_cnt) {
++ WRITE_ONCE(amt->ready4, false);
++ WRITE_ONCE(amt->ready6, false);
++ get_random_bytes(&amt->nonce, sizeof(__be32));
++ }
+
+ amt_send_request(amt, false);
+ amt_send_request(amt, true);
+- spin_lock_bh(&amt->lock);
+- __amt_update_gw_status(amt, AMT_STATUS_SENT_REQUEST, true);
++ amt_update_gw_status(amt, AMT_STATUS_SENT_REQUEST, true);
+ amt->req_cnt++;
+ out:
+ exp = min_t(u32, (1 * (1 << amt->req_cnt)), AMT_MAX_REQ_TIMEOUT);
+ mod_delayed_work(amt_wq, &amt->req_wq, msecs_to_jiffies(exp * 1000));
+- spin_unlock_bh(&amt->lock);
++}
++
++static void amt_req_work(struct work_struct *work)
++{
++ struct amt_dev *amt = container_of(to_delayed_work(work),
++ struct amt_dev,
++ req_wq);
++
++ if (amt_queue_event(amt, AMT_EVENT_SEND_REQUEST, NULL))
++ mod_delayed_work(amt_wq, &amt->req_wq,
++ msecs_to_jiffies(100));
+ }
+
+ static bool amt_send_membership_update(struct amt_dev *amt,
+@@ -1220,7 +1246,8 @@ static netdev_tx_t amt_dev_xmit(struct sk_buff *skb, struct net_device *dev)
+ /* Gateway only passes IGMP/MLD packets */
+ if (!report)
+ goto free;
+- if ((!v6 && !amt->ready4) || (v6 && !amt->ready6))
++ if ((!v6 && !READ_ONCE(amt->ready4)) ||
++ (v6 && !READ_ONCE(amt->ready6)))
+ goto free;
+ if (amt_send_membership_update(amt, skb, v6))
+ goto free;
+@@ -2236,6 +2263,10 @@ static bool amt_advertisement_handler(struct amt_dev *amt, struct sk_buff *skb)
+ ipv4_is_zeronet(amta->ip4))
+ return true;
+
++ if (amt->status != AMT_STATUS_SENT_DISCOVERY ||
++ amt->nonce != amta->nonce)
++ return true;
++
+ amt->remote_ip = amta->ip4;
+ netdev_dbg(amt->dev, "advertised remote ip = %pI4\n", &amt->remote_ip);
+ mod_delayed_work(amt_wq, &amt->req_wq, 0);
+@@ -2251,6 +2282,9 @@ static bool amt_multicast_data_handler(struct amt_dev *amt, struct sk_buff *skb)
+ struct ethhdr *eth;
+ struct iphdr *iph;
+
++ if (READ_ONCE(amt->status) != AMT_STATUS_SENT_UPDATE)
++ return true;
++
+ hdr_size = sizeof(*amtmd) + sizeof(struct udphdr);
+ if (!pskb_may_pull(skb, hdr_size))
+ return true;
+@@ -2325,6 +2359,9 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
+ if (amtmq->reserved || amtmq->version)
+ return true;
+
++ if (amtmq->nonce != amt->nonce)
++ return true;
++
+ hdr_size -= sizeof(*eth);
+ if (iptunnel_pull_header(skb, hdr_size, htons(ETH_P_TEB), false))
+ return true;
+@@ -2339,6 +2376,9 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
+
+ iph = ip_hdr(skb);
+ if (iph->version == 4) {
++ if (READ_ONCE(amt->ready4))
++ return true;
++
+ if (!pskb_may_pull(skb, sizeof(*iph) + AMT_IPHDR_OPTS +
+ sizeof(*ihv3)))
+ return true;
+@@ -2349,12 +2389,10 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
+ ihv3 = skb_pull(skb, sizeof(*iph) + AMT_IPHDR_OPTS);
+ skb_reset_transport_header(skb);
+ skb_push(skb, sizeof(*iph) + AMT_IPHDR_OPTS);
+- spin_lock_bh(&amt->lock);
+- amt->ready4 = true;
++ WRITE_ONCE(amt->ready4, true);
+ amt->mac = amtmq->response_mac;
+ amt->req_cnt = 0;
+ amt->qi = ihv3->qqic;
+- spin_unlock_bh(&amt->lock);
+ skb->protocol = htons(ETH_P_IP);
+ eth->h_proto = htons(ETH_P_IP);
+ ip_eth_mc_map(iph->daddr, eth->h_dest);
+@@ -2363,6 +2401,9 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
+ struct mld2_query *mld2q;
+ struct ipv6hdr *ip6h;
+
++ if (READ_ONCE(amt->ready6))
++ return true;
++
+ if (!pskb_may_pull(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS +
+ sizeof(*mld2q)))
+ return true;
+@@ -2374,12 +2415,10 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
+ mld2q = skb_pull(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS);
+ skb_reset_transport_header(skb);
+ skb_push(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS);
+- spin_lock_bh(&amt->lock);
+- amt->ready6 = true;
++ WRITE_ONCE(amt->ready6, true);
+ amt->mac = amtmq->response_mac;
+ amt->req_cnt = 0;
+ amt->qi = mld2q->mld2q_qqic;
+- spin_unlock_bh(&amt->lock);
+ skb->protocol = htons(ETH_P_IPV6);
+ eth->h_proto = htons(ETH_P_IPV6);
+ ipv6_eth_mc_map(&ip6h->daddr, eth->h_dest);
+@@ -2392,12 +2431,14 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
+ skb->pkt_type = PACKET_MULTICAST;
+ skb->ip_summed = CHECKSUM_NONE;
+ len = skb->len;
++ local_bh_disable();
+ if (__netif_rx(skb) == NET_RX_SUCCESS) {
+ amt_update_gw_status(amt, AMT_STATUS_RECEIVED_QUERY, true);
+ dev_sw_netstats_rx_add(amt->dev, len);
+ } else {
+ amt->dev->stats.rx_dropped++;
+ }
++ local_bh_enable();
+
+ return false;
+ }
+@@ -2638,7 +2679,9 @@ static bool amt_request_handler(struct amt_dev *amt, struct sk_buff *skb)
+ if (tunnel->ip4 == iph->saddr)
+ goto send;
+
++ spin_lock_bh(&amt->lock);
+ if (amt->nr_tunnels >= amt->max_tunnels) {
++ spin_unlock_bh(&amt->lock);
+ icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
+ return true;
+ }
+@@ -2646,8 +2689,10 @@ static bool amt_request_handler(struct amt_dev *amt, struct sk_buff *skb)
+ tunnel = kzalloc(sizeof(*tunnel) +
+ (sizeof(struct hlist_head) * amt->hash_buckets),
+ GFP_ATOMIC);
+- if (!tunnel)
++ if (!tunnel) {
++ spin_unlock_bh(&amt->lock);
+ return true;
++ }
+
+ tunnel->source_port = udph->source;
+ tunnel->ip4 = iph->saddr;
+@@ -2660,10 +2705,9 @@ static bool amt_request_handler(struct amt_dev *amt, struct sk_buff *skb)
+
+ INIT_DELAYED_WORK(&tunnel->gc_wq, amt_tunnel_expire);
+
+- spin_lock_bh(&amt->lock);
+ list_add_tail_rcu(&tunnel->list, &amt->tunnel_list);
+ tunnel->key = amt->key;
+- amt_update_relay_status(tunnel, AMT_STATUS_RECEIVED_REQUEST, true);
++ __amt_update_relay_status(tunnel, AMT_STATUS_RECEIVED_REQUEST, true);
+ amt->nr_tunnels++;
+ mod_delayed_work(amt_wq, &tunnel->gc_wq,
+ msecs_to_jiffies(amt_gmi(amt)));
+@@ -2688,6 +2732,38 @@ send:
+ return false;
+ }
+
++static void amt_gw_rcv(struct amt_dev *amt, struct sk_buff *skb)
++{
++ int type = amt_parse_type(skb);
++ int err = 1;
++
++ if (type == -1)
++ goto drop;
++
++ if (amt->mode == AMT_MODE_GATEWAY) {
++ switch (type) {
++ case AMT_MSG_ADVERTISEMENT:
++ err = amt_advertisement_handler(amt, skb);
++ break;
++ case AMT_MSG_MEMBERSHIP_QUERY:
++ err = amt_membership_query_handler(amt, skb);
++ if (!err)
++ return;
++ break;
++ default:
++ netdev_dbg(amt->dev, "Invalid type of Gateway\n");
++ break;
++ }
++ }
++drop:
++ if (err) {
++ amt->dev->stats.rx_dropped++;
++ kfree_skb(skb);
++ } else {
++ consume_skb(skb);
++ }
++}
++
+ static int amt_rcv(struct sock *sk, struct sk_buff *skb)
+ {
+ struct amt_dev *amt;
+@@ -2719,8 +2795,12 @@ static int amt_rcv(struct sock *sk, struct sk_buff *skb)
+ err = true;
+ goto drop;
+ }
+- err = amt_advertisement_handler(amt, skb);
+- break;
++ if (amt_queue_event(amt, AMT_EVENT_RECEIVE, skb)) {
++ netdev_dbg(amt->dev, "AMT Event queue full\n");
++ err = true;
++ goto drop;
++ }
++ goto out;
+ case AMT_MSG_MULTICAST_DATA:
+ if (iph->saddr != amt->remote_ip) {
+ netdev_dbg(amt->dev, "Invalid Relay IP\n");
+@@ -2738,11 +2818,12 @@ static int amt_rcv(struct sock *sk, struct sk_buff *skb)
+ err = true;
+ goto drop;
+ }
+- err = amt_membership_query_handler(amt, skb);
+- if (err)
++ if (amt_queue_event(amt, AMT_EVENT_RECEIVE, skb)) {
++ netdev_dbg(amt->dev, "AMT Event queue full\n");
++ err = true;
+ goto drop;
+- else
+- goto out;
++ }
++ goto out;
+ default:
+ err = true;
+ netdev_dbg(amt->dev, "Invalid type of Gateway\n");
+@@ -2780,6 +2861,46 @@ out:
+ return 0;
+ }
+
++static void amt_event_work(struct work_struct *work)
++{
++ struct amt_dev *amt = container_of(work, struct amt_dev, event_wq);
++ struct sk_buff *skb;
++ u8 event;
++ int i;
++
++ for (i = 0; i < AMT_MAX_EVENTS; i++) {
++ spin_lock_bh(&amt->lock);
++ if (amt->nr_events == 0) {
++ spin_unlock_bh(&amt->lock);
++ return;
++ }
++ event = amt->events[amt->event_idx].event;
++ skb = amt->events[amt->event_idx].skb;
++ amt->events[amt->event_idx].event = AMT_EVENT_NONE;
++ amt->events[amt->event_idx].skb = NULL;
++ amt->nr_events--;
++ amt->event_idx++;
++ amt->event_idx %= AMT_MAX_EVENTS;
++ spin_unlock_bh(&amt->lock);
++
++ switch (event) {
++ case AMT_EVENT_RECEIVE:
++ amt_gw_rcv(amt, skb);
++ break;
++ case AMT_EVENT_SEND_DISCOVERY:
++ amt_event_send_discovery(amt);
++ break;
++ case AMT_EVENT_SEND_REQUEST:
++ amt_event_send_request(amt);
++ break;
++ default:
++ if (skb)
++ kfree_skb(skb);
++ break;
++ }
++ }
++}
++
+ static int amt_err_lookup(struct sock *sk, struct sk_buff *skb)
+ {
+ struct amt_dev *amt;
+@@ -2804,7 +2925,7 @@ static int amt_err_lookup(struct sock *sk, struct sk_buff *skb)
+ break;
+ case AMT_MSG_REQUEST:
+ case AMT_MSG_MEMBERSHIP_UPDATE:
+- if (amt->status >= AMT_STATUS_RECEIVED_ADVERTISEMENT)
++ if (READ_ONCE(amt->status) >= AMT_STATUS_RECEIVED_ADVERTISEMENT)
+ mod_delayed_work(amt_wq, &amt->req_wq, 0);
+ break;
+ default:
+@@ -2867,6 +2988,8 @@ static int amt_dev_open(struct net_device *dev)
+
+ amt->ready4 = false;
+ amt->ready6 = false;
++ amt->event_idx = 0;
++ amt->nr_events = 0;
+
+ err = amt_socket_create(amt);
+ if (err)
+@@ -2874,6 +2997,7 @@ static int amt_dev_open(struct net_device *dev)
+
+ amt->req_cnt = 0;
+ amt->remote_ip = 0;
++ amt->nonce = 0;
+ get_random_bytes(&amt->key, sizeof(siphash_key_t));
+
+ amt->status = AMT_STATUS_INIT;
+@@ -2892,6 +3016,8 @@ static int amt_dev_stop(struct net_device *dev)
+ struct amt_dev *amt = netdev_priv(dev);
+ struct amt_tunnel_list *tunnel, *tmp;
+ struct socket *sock;
++ struct sk_buff *skb;
++ int i;
+
+ cancel_delayed_work_sync(&amt->req_wq);
+ cancel_delayed_work_sync(&amt->discovery_wq);
+@@ -2904,6 +3030,15 @@ static int amt_dev_stop(struct net_device *dev)
+ if (sock)
+ udp_tunnel_sock_release(sock);
+
++ cancel_work_sync(&amt->event_wq);
++ for (i = 0; i < AMT_MAX_EVENTS; i++) {
++ skb = amt->events[i].skb;
++ if (skb)
++ kfree_skb(skb);
++ amt->events[i].event = AMT_EVENT_NONE;
++ amt->events[i].skb = NULL;
++ }
++
+ amt->ready4 = false;
+ amt->ready6 = false;
+ amt->req_cnt = 0;
+@@ -3095,7 +3230,7 @@ static int amt_newlink(struct net *net, struct net_device *dev,
+ goto err;
+ }
+ if (amt->mode == AMT_MODE_RELAY) {
+- amt->qrv = amt->net->ipv4.sysctl_igmp_qrv;
++ amt->qrv = READ_ONCE(amt->net->ipv4.sysctl_igmp_qrv);
+ amt->qri = 10;
+ dev->needed_headroom = amt->stream_dev->needed_headroom +
+ AMT_RELAY_HLEN;
+@@ -3146,8 +3281,8 @@ static int amt_newlink(struct net *net, struct net_device *dev,
+ INIT_DELAYED_WORK(&amt->discovery_wq, amt_discovery_work);
+ INIT_DELAYED_WORK(&amt->req_wq, amt_req_work);
+ INIT_DELAYED_WORK(&amt->secret_wq, amt_secret_work);
++ INIT_WORK(&amt->event_wq, amt_event_work);
+ INIT_LIST_HEAD(&amt->tunnel_list);
+-
+ return 0;
+ err:
+ dev_put(amt->stream_dev);
+@@ -3280,7 +3415,7 @@ static int __init amt_init(void)
+ if (err < 0)
+ goto unregister_notifier;
+
+- amt_wq = alloc_workqueue("amt", WQ_UNBOUND, 1);
++ amt_wq = alloc_workqueue("amt", WQ_UNBOUND, 0);
+ if (!amt_wq) {
+ err = -ENOMEM;
+ goto rtnl_unregister;
+diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
+index 589996cef5db3..8d457d2c3bccb 100644
+--- a/drivers/net/can/rcar/rcar_canfd.c
++++ b/drivers/net/can/rcar/rcar_canfd.c
+@@ -1850,6 +1850,7 @@ static int rcar_canfd_probe(struct platform_device *pdev)
+ of_child = of_get_child_by_name(pdev->dev.of_node, name);
+ if (of_child && of_device_is_available(of_child))
+ channels_mask |= BIT(i);
++ of_node_put(of_child);
+ }
+
+ if (chip_id != RENESAS_RZG2L) {
+diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
+index 8014b18d93914..aa0bcf01e20ac 100644
+--- a/drivers/net/dsa/microchip/ksz_common.c
++++ b/drivers/net/dsa/microchip/ksz_common.c
+@@ -447,18 +447,21 @@ int ksz_switch_register(struct ksz_device *dev,
+ ports = of_get_child_by_name(dev->dev->of_node, "ethernet-ports");
+ if (!ports)
+ ports = of_get_child_by_name(dev->dev->of_node, "ports");
+- if (ports)
++ if (ports) {
+ for_each_available_child_of_node(ports, port) {
+ if (of_property_read_u32(port, "reg",
+ &port_num))
+ continue;
+ if (!(dev->port_mask & BIT(port_num))) {
+ of_node_put(port);
++ of_node_put(ports);
+ return -EINVAL;
+ }
+ of_get_phy_mode(port,
+ &dev->ports[port_num].interface);
+ }
++ of_node_put(ports);
++ }
+ dev->synclko_125 = of_property_read_bool(dev->dev->of_node,
+ "microchip,synclko-125");
+ dev->synclko_disable = of_property_read_bool(dev->dev->of_node,
+diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
+index b33841c6507ae..7734c6b1bacae 100644
+--- a/drivers/net/dsa/sja1105/sja1105_main.c
++++ b/drivers/net/dsa/sja1105/sja1105_main.c
+@@ -3383,12 +3383,28 @@ static const struct of_device_id sja1105_dt_ids[] = {
+ };
+ MODULE_DEVICE_TABLE(of, sja1105_dt_ids);
+
++static const struct spi_device_id sja1105_spi_ids[] = {
++ { "sja1105e" },
++ { "sja1105t" },
++ { "sja1105p" },
++ { "sja1105q" },
++ { "sja1105r" },
++ { "sja1105s" },
++ { "sja1110a" },
++ { "sja1110b" },
++ { "sja1110c" },
++ { "sja1110d" },
++ { },
++};
++MODULE_DEVICE_TABLE(spi, sja1105_spi_ids);
++
+ static struct spi_driver sja1105_driver = {
+ .driver = {
+ .name = "sja1105",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(sja1105_dt_ids),
+ },
++ .id_table = sja1105_spi_ids,
+ .probe = sja1105_probe,
+ .remove = sja1105_remove,
+ .shutdown = sja1105_shutdown,
+diff --git a/drivers/net/dsa/vitesse-vsc73xx-spi.c b/drivers/net/dsa/vitesse-vsc73xx-spi.c
+index 3110895358d8d..97a92e6da60d8 100644
+--- a/drivers/net/dsa/vitesse-vsc73xx-spi.c
++++ b/drivers/net/dsa/vitesse-vsc73xx-spi.c
+@@ -205,10 +205,20 @@ static const struct of_device_id vsc73xx_of_match[] = {
+ };
+ MODULE_DEVICE_TABLE(of, vsc73xx_of_match);
+
++static const struct spi_device_id vsc73xx_spi_ids[] = {
++ { "vsc7385" },
++ { "vsc7388" },
++ { "vsc7395" },
++ { "vsc7398" },
++ { },
++};
++MODULE_DEVICE_TABLE(spi, vsc73xx_spi_ids);
++
+ static struct spi_driver vsc73xx_spi_driver = {
+ .probe = vsc73xx_spi_probe,
+ .remove = vsc73xx_spi_remove,
+ .shutdown = vsc73xx_spi_shutdown,
++ .id_table = vsc73xx_spi_ids,
+ .driver = {
+ .name = "vsc73xx-spi",
+ .of_match_table = vsc73xx_of_match,
+diff --git a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c
+index 7c760aa655404..ddfe9208529a5 100644
+--- a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c
++++ b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c
+@@ -1236,8 +1236,8 @@ static struct sock *chtls_recv_sock(struct sock *lsk,
+ csk->sndbuf = newsk->sk_sndbuf;
+ csk->smac_idx = ((struct port_info *)netdev_priv(ndev))->smt_idx;
+ RCV_WSCALE(tp) = select_rcv_wscale(tcp_full_space(newsk),
+- sock_net(newsk)->
+- ipv4.sysctl_tcp_window_scaling,
++ READ_ONCE(sock_net(newsk)->
++ ipv4.sysctl_tcp_window_scaling),
+ tp->window_clamp);
+ neigh_release(n);
+ inet_inherit_port(&tcp_hashinfo, lsk, newsk);
+@@ -1384,7 +1384,7 @@ static void chtls_pass_accept_request(struct sock *sk,
+ #endif
+ }
+ if (req->tcpopt.wsf <= 14 &&
+- sock_net(sk)->ipv4.sysctl_tcp_window_scaling) {
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_window_scaling)) {
+ inet_rsk(oreq)->wscale_ok = 1;
+ inet_rsk(oreq)->snd_wscale = req->tcpopt.wsf;
+ }
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index 528eb0f223b17..b4f5e57d0285c 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -2287,7 +2287,7 @@ err:
+
+ /* Uses sync mcc */
+ int be_cmd_read_port_transceiver_data(struct be_adapter *adapter,
+- u8 page_num, u8 *data)
++ u8 page_num, u32 off, u32 len, u8 *data)
+ {
+ struct be_dma_mem cmd;
+ struct be_mcc_wrb *wrb;
+@@ -2321,10 +2321,10 @@ int be_cmd_read_port_transceiver_data(struct be_adapter *adapter,
+ req->port = cpu_to_le32(adapter->hba_port_num);
+ req->page_num = cpu_to_le32(page_num);
+ status = be_mcc_notify_wait(adapter);
+- if (!status) {
++ if (!status && len > 0) {
+ struct be_cmd_resp_port_type *resp = cmd.va;
+
+- memcpy(data, resp->page_data, PAGE_DATA_LEN);
++ memcpy(data, resp->page_data + off, len);
+ }
+ err:
+ mutex_unlock(&adapter->mcc_lock);
+@@ -2415,7 +2415,7 @@ int be_cmd_query_cable_type(struct be_adapter *adapter)
+ int status;
+
+ status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
+- page_data);
++ 0, PAGE_DATA_LEN, page_data);
+ if (!status) {
+ switch (adapter->phy.interface_type) {
+ case PHY_TYPE_QSFP:
+@@ -2440,7 +2440,7 @@ int be_cmd_query_sfp_info(struct be_adapter *adapter)
+ int status;
+
+ status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
+- page_data);
++ 0, PAGE_DATA_LEN, page_data);
+ if (!status) {
+ strlcpy(adapter->phy.vendor_name, page_data +
+ SFP_VENDOR_NAME_OFFSET, SFP_VENDOR_NAME_LEN - 1);
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
+index db1f3b908582e..e2085c68c0ee7 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
+@@ -2427,7 +2427,7 @@ int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num, u8 beacon,
+ int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num,
+ u32 *state);
+ int be_cmd_read_port_transceiver_data(struct be_adapter *adapter,
+- u8 page_num, u8 *data);
++ u8 page_num, u32 off, u32 len, u8 *data);
+ int be_cmd_query_cable_type(struct be_adapter *adapter);
+ int be_cmd_query_sfp_info(struct be_adapter *adapter);
+ int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
+diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+index dfa784339781d..bd0df189d8719 100644
+--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
++++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+@@ -1344,7 +1344,7 @@ static int be_get_module_info(struct net_device *netdev,
+ return -EOPNOTSUPP;
+
+ status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
+- page_data);
++ 0, PAGE_DATA_LEN, page_data);
+ if (!status) {
+ if (!page_data[SFP_PLUS_SFF_8472_COMP]) {
+ modinfo->type = ETH_MODULE_SFF_8079;
+@@ -1362,25 +1362,32 @@ static int be_get_module_eeprom(struct net_device *netdev,
+ {
+ struct be_adapter *adapter = netdev_priv(netdev);
+ int status;
++ u32 begin, end;
+
+ if (!check_privilege(adapter, MAX_PRIVILEGES))
+ return -EOPNOTSUPP;
+
+- status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
+- data);
+- if (status)
+- goto err;
++ begin = eeprom->offset;
++ end = eeprom->offset + eeprom->len;
++
++ if (begin < PAGE_DATA_LEN) {
++ status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0, begin,
++ min_t(u32, end, PAGE_DATA_LEN) - begin,
++ data);
++ if (status)
++ goto err;
++
++ data += PAGE_DATA_LEN - begin;
++ begin = PAGE_DATA_LEN;
++ }
+
+- if (eeprom->offset + eeprom->len > PAGE_DATA_LEN) {
+- status = be_cmd_read_port_transceiver_data(adapter,
+- TR_PAGE_A2,
+- data +
+- PAGE_DATA_LEN);
++ if (end > PAGE_DATA_LEN) {
++ status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A2,
++ begin - PAGE_DATA_LEN,
++ end - begin, data);
+ if (status)
+ goto err;
+ }
+- if (eeprom->offset)
+- memcpy(data, data + eeprom->offset, eeprom->len);
+ err:
+ return be_cmd_status(status);
+ }
+diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h
+index 13382df2f2eff..bcf680e838113 100644
+--- a/drivers/net/ethernet/intel/e1000e/hw.h
++++ b/drivers/net/ethernet/intel/e1000e/hw.h
+@@ -630,7 +630,6 @@ struct e1000_phy_info {
+ bool disable_polarity_correction;
+ bool is_mdix;
+ bool polarity_correction;
+- bool reset_disable;
+ bool speed_downgraded;
+ bool autoneg_wait_to_complete;
+ };
+diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c
+index e6c8e6d5234f8..9466f65a6da77 100644
+--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
++++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
+@@ -2050,10 +2050,6 @@ static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw)
+ bool blocked = false;
+ int i = 0;
+
+- /* Check the PHY (LCD) reset flag */
+- if (hw->phy.reset_disable)
+- return true;
+-
+ while ((blocked = !(er32(FWSM) & E1000_ICH_FWSM_RSPCIPHY)) &&
+ (i++ < 30))
+ usleep_range(10000, 11000);
+diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.h b/drivers/net/ethernet/intel/e1000e/ich8lan.h
+index 638a3ddd7ada8..2504b11c3169f 100644
+--- a/drivers/net/ethernet/intel/e1000e/ich8lan.h
++++ b/drivers/net/ethernet/intel/e1000e/ich8lan.h
+@@ -271,7 +271,6 @@
+ #define I217_CGFREG_ENABLE_MTA_RESET 0x0002
+ #define I217_MEMPWR PHY_REG(772, 26)
+ #define I217_MEMPWR_DISABLE_SMB_RELEASE 0x0010
+-#define I217_MEMPWR_MOEM 0x1000
+
+ /* Receive Address Initial CRC Calculation */
+ #define E1000_PCH_RAICC(_n) (0x05F50 + ((_n) * 4))
+diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
+index fa06f68c8c803..f1729940e46ce 100644
+--- a/drivers/net/ethernet/intel/e1000e/netdev.c
++++ b/drivers/net/ethernet/intel/e1000e/netdev.c
+@@ -6494,6 +6494,10 @@ static void e1000e_s0ix_exit_flow(struct e1000_adapter *adapter)
+
+ if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID &&
+ hw->mac.type >= e1000_pch_adp) {
++ /* Keep the GPT clock enabled for CSME */
++ mac_data = er32(FEXTNVM);
++ mac_data |= BIT(3);
++ ew32(FEXTNVM, mac_data);
+ /* Request ME unconfigure the device from S0ix */
+ mac_data = er32(H2ME);
+ mac_data &= ~E1000_H2ME_START_DPG;
+@@ -6987,21 +6991,8 @@ static __maybe_unused int e1000e_pm_suspend(struct device *dev)
+ struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
+ struct e1000_adapter *adapter = netdev_priv(netdev);
+ struct pci_dev *pdev = to_pci_dev(dev);
+- struct e1000_hw *hw = &adapter->hw;
+- u16 phy_data;
+ int rc;
+
+- if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID &&
+- hw->mac.type >= e1000_pch_adp) {
+- /* Mask OEM Bits / Gig Disable / Restart AN (772_26[12] = 1) */
+- e1e_rphy(hw, I217_MEMPWR, &phy_data);
+- phy_data |= I217_MEMPWR_MOEM;
+- e1e_wphy(hw, I217_MEMPWR, phy_data);
+-
+- /* Disable LCD reset */
+- hw->phy.reset_disable = true;
+- }
+-
+ e1000e_flush_lpic(pdev);
+
+ e1000e_pm_freeze(dev);
+@@ -7023,8 +7014,6 @@ static __maybe_unused int e1000e_pm_resume(struct device *dev)
+ struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
+ struct e1000_adapter *adapter = netdev_priv(netdev);
+ struct pci_dev *pdev = to_pci_dev(dev);
+- struct e1000_hw *hw = &adapter->hw;
+- u16 phy_data;
+ int rc;
+
+ /* Introduce S0ix implementation */
+@@ -7035,17 +7024,6 @@ static __maybe_unused int e1000e_pm_resume(struct device *dev)
+ if (rc)
+ return rc;
+
+- if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID &&
+- hw->mac.type >= e1000_pch_adp) {
+- /* Unmask OEM Bits / Gig Disable / Restart AN 772_26[12] = 0 */
+- e1e_rphy(hw, I217_MEMPWR, &phy_data);
+- phy_data &= ~I217_MEMPWR_MOEM;
+- e1e_wphy(hw, I217_MEMPWR, phy_data);
+-
+- /* Enable LCD reset */
+- hw->phy.reset_disable = false;
+- }
+-
+ return e1000e_pm_thaw(dev);
+ }
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index 77eb9c7262053..6f01bffd7e5c2 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -10645,7 +10645,7 @@ static int i40e_reset(struct i40e_pf *pf)
+ **/
+ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
+ {
+- int old_recovery_mode_bit = test_bit(__I40E_RECOVERY_MODE, pf->state);
++ const bool is_recovery_mode_reported = i40e_check_recovery_mode(pf);
+ struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
+ struct i40e_hw *hw = &pf->hw;
+ i40e_status ret;
+@@ -10653,13 +10653,11 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
+ int v;
+
+ if (test_bit(__I40E_EMP_RESET_INTR_RECEIVED, pf->state) &&
+- i40e_check_recovery_mode(pf)) {
++ is_recovery_mode_reported)
+ i40e_set_ethtool_ops(pf->vsi[pf->lan_vsi]->netdev);
+- }
+
+ if (test_bit(__I40E_DOWN, pf->state) &&
+- !test_bit(__I40E_RECOVERY_MODE, pf->state) &&
+- !old_recovery_mode_bit)
++ !test_bit(__I40E_RECOVERY_MODE, pf->state))
+ goto clear_recovery;
+ dev_dbg(&pf->pdev->dev, "Rebuilding internal switch\n");
+
+@@ -10686,13 +10684,12 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
+ * accordingly with regard to resources initialization
+ * and deinitialization
+ */
+- if (test_bit(__I40E_RECOVERY_MODE, pf->state) ||
+- old_recovery_mode_bit) {
++ if (test_bit(__I40E_RECOVERY_MODE, pf->state)) {
+ if (i40e_get_capabilities(pf,
+ i40e_aqc_opc_list_func_capabilities))
+ goto end_unlock;
+
+- if (test_bit(__I40E_RECOVERY_MODE, pf->state)) {
++ if (is_recovery_mode_reported) {
+ /* we're staying in recovery mode so we'll reinitialize
+ * misc vector here
+ */
+diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h
+index 49aed3e506a66..0ea0361cd86b1 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf.h
++++ b/drivers/net/ethernet/intel/iavf/iavf.h
+@@ -64,7 +64,6 @@ struct iavf_vsi {
+ u16 id;
+ DECLARE_BITMAP(state, __IAVF_VSI_STATE_SIZE__);
+ int base_vector;
+- u16 work_limit;
+ u16 qs_handle;
+ void *priv; /* client driver data reference. */
+ };
+@@ -159,8 +158,12 @@ struct iavf_vlan {
+ struct iavf_vlan_filter {
+ struct list_head list;
+ struct iavf_vlan vlan;
+- bool remove; /* filter needs to be removed */
+- bool add; /* filter needs to be added */
++ struct {
++ u8 is_new_vlan:1; /* filter is new, wait for PF answer */
++ u8 remove:1; /* filter needs to be removed */
++ u8 add:1; /* filter needs to be added */
++ u8 padding:5;
++ };
+ };
+
+ #define IAVF_MAX_TRAFFIC_CLASS 4
+@@ -461,6 +464,10 @@ static inline const char *iavf_state_str(enum iavf_state_t state)
+ return "__IAVF_INIT_VERSION_CHECK";
+ case __IAVF_INIT_GET_RESOURCES:
+ return "__IAVF_INIT_GET_RESOURCES";
++ case __IAVF_INIT_EXTENDED_CAPS:
++ return "__IAVF_INIT_EXTENDED_CAPS";
++ case __IAVF_INIT_CONFIG_ADAPTER:
++ return "__IAVF_INIT_CONFIG_ADAPTER";
+ case __IAVF_INIT_SW:
+ return "__IAVF_INIT_SW";
+ case __IAVF_INIT_FAILED:
+@@ -520,6 +527,7 @@ int iavf_get_vf_config(struct iavf_adapter *adapter);
+ int iavf_get_vf_vlan_v2_caps(struct iavf_adapter *adapter);
+ int iavf_send_vf_offload_vlan_v2_msg(struct iavf_adapter *adapter);
+ void iavf_set_queue_vlan_tag_loc(struct iavf_adapter *adapter);
++u16 iavf_get_num_vlans_added(struct iavf_adapter *adapter);
+ void iavf_irq_enable(struct iavf_adapter *adapter, bool flush);
+ void iavf_configure_queues(struct iavf_adapter *adapter);
+ void iavf_deconfigure_queues(struct iavf_adapter *adapter);
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
+index 3bb56714beb03..e535d4c3da49d 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
+@@ -692,12 +692,8 @@ static int __iavf_get_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *ec, int queue)
+ {
+ struct iavf_adapter *adapter = netdev_priv(netdev);
+- struct iavf_vsi *vsi = &adapter->vsi;
+ struct iavf_ring *rx_ring, *tx_ring;
+
+- ec->tx_max_coalesced_frames = vsi->work_limit;
+- ec->rx_max_coalesced_frames = vsi->work_limit;
+-
+ /* Rx and Tx usecs per queue value. If user doesn't specify the
+ * queue, return queue 0's value to represent.
+ */
+@@ -825,12 +821,8 @@ static int __iavf_set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *ec, int queue)
+ {
+ struct iavf_adapter *adapter = netdev_priv(netdev);
+- struct iavf_vsi *vsi = &adapter->vsi;
+ int i;
+
+- if (ec->tx_max_coalesced_frames_irq || ec->rx_max_coalesced_frames_irq)
+- vsi->work_limit = ec->tx_max_coalesced_frames_irq;
+-
+ if (ec->rx_coalesce_usecs == 0) {
+ if (ec->use_adaptive_rx_coalesce)
+ netif_info(adapter, drv, netdev, "rx-usecs=0, need to disable adaptive-rx for a complete disable\n");
+@@ -1969,8 +1961,6 @@ static int iavf_set_rxfh(struct net_device *netdev, const u32 *indir,
+
+ static const struct ethtool_ops iavf_ethtool_ops = {
+ .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
+- ETHTOOL_COALESCE_MAX_FRAMES |
+- ETHTOOL_COALESCE_MAX_FRAMES_IRQ |
+ ETHTOOL_COALESCE_USE_ADAPTIVE,
+ .get_drvinfo = iavf_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index f3ecb3bca33dd..2e2c153ce46a3 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -843,7 +843,7 @@ static void iavf_restore_filters(struct iavf_adapter *adapter)
+ * iavf_get_num_vlans_added - get number of VLANs added
+ * @adapter: board private structure
+ */
+-static u16 iavf_get_num_vlans_added(struct iavf_adapter *adapter)
++u16 iavf_get_num_vlans_added(struct iavf_adapter *adapter)
+ {
+ return bitmap_weight(adapter->vsi.active_cvlans, VLAN_N_VID) +
+ bitmap_weight(adapter->vsi.active_svlans, VLAN_N_VID);
+@@ -906,11 +906,6 @@ static int iavf_vlan_rx_add_vid(struct net_device *netdev,
+ if (!iavf_add_vlan(adapter, IAVF_VLAN(vid, be16_to_cpu(proto))))
+ return -ENOMEM;
+
+- if (proto == cpu_to_be16(ETH_P_8021Q))
+- set_bit(vid, adapter->vsi.active_cvlans);
+- else
+- set_bit(vid, adapter->vsi.active_svlans);
+-
+ return 0;
+ }
+
+@@ -2245,7 +2240,6 @@ int iavf_parse_vf_resource_msg(struct iavf_adapter *adapter)
+
+ adapter->vsi.back = adapter;
+ adapter->vsi.base_vector = 1;
+- adapter->vsi.work_limit = IAVF_DEFAULT_IRQ_WORK;
+ vsi->netdev = adapter->netdev;
+ vsi->qs_handle = adapter->vsi_res->qset_handle;
+ if (adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF) {
+@@ -2956,6 +2950,9 @@ continue_reset:
+ adapter->aq_required |= IAVF_FLAG_AQ_ADD_CLOUD_FILTER;
+ iavf_misc_irq_enable(adapter);
+
++ bitmap_clear(adapter->vsi.active_cvlans, 0, VLAN_N_VID);
++ bitmap_clear(adapter->vsi.active_svlans, 0, VLAN_N_VID);
++
+ mod_delayed_work(iavf_wq, &adapter->watchdog_task, 2);
+
+ /* We were running when the reset started, so we need to restore some
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_txrx.c b/drivers/net/ethernet/intel/iavf/iavf_txrx.c
+index 978f651c6b093..06d18797d25a2 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_txrx.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_txrx.c
+@@ -194,7 +194,7 @@ static bool iavf_clean_tx_irq(struct iavf_vsi *vsi,
+ struct iavf_tx_buffer *tx_buf;
+ struct iavf_tx_desc *tx_desc;
+ unsigned int total_bytes = 0, total_packets = 0;
+- unsigned int budget = vsi->work_limit;
++ unsigned int budget = IAVF_DEFAULT_IRQ_WORK;
+
+ tx_buf = &tx_ring->tx_bi[i];
+ tx_desc = IAVF_TX_DESC(tx_ring, i);
+@@ -1285,11 +1285,10 @@ static struct iavf_rx_buffer *iavf_get_rx_buffer(struct iavf_ring *rx_ring,
+ {
+ struct iavf_rx_buffer *rx_buffer;
+
+- if (!size)
+- return NULL;
+-
+ rx_buffer = &rx_ring->rx_bi[rx_ring->next_to_clean];
+ prefetchw(rx_buffer->page);
++ if (!size)
++ return rx_buffer;
+
+ /* we are reusing so sync this buffer for CPU use */
+ dma_sync_single_range_for_cpu(rx_ring->dev,
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
+index 782450d5c12fc..1603e99bae4af 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
+@@ -626,6 +626,33 @@ static void iavf_mac_add_reject(struct iavf_adapter *adapter)
+ spin_unlock_bh(&adapter->mac_vlan_list_lock);
+ }
+
++/**
++ * iavf_vlan_add_reject
++ * @adapter: adapter structure
++ *
++ * Remove VLAN filters from list based on PF response.
++ **/
++static void iavf_vlan_add_reject(struct iavf_adapter *adapter)
++{
++ struct iavf_vlan_filter *f, *ftmp;
++
++ spin_lock_bh(&adapter->mac_vlan_list_lock);
++ list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
++ if (f->is_new_vlan) {
++ if (f->vlan.tpid == ETH_P_8021Q)
++ clear_bit(f->vlan.vid,
++ adapter->vsi.active_cvlans);
++ else
++ clear_bit(f->vlan.vid,
++ adapter->vsi.active_svlans);
++
++ list_del(&f->list);
++ kfree(f);
++ }
++ }
++ spin_unlock_bh(&adapter->mac_vlan_list_lock);
++}
++
+ /**
+ * iavf_add_vlans
+ * @adapter: adapter structure
+@@ -683,6 +710,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
+ vvfl->vlan_id[i] = f->vlan.vid;
+ i++;
+ f->add = false;
++ f->is_new_vlan = true;
+ if (i == count)
+ break;
+ }
+@@ -695,10 +723,18 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
+ iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_VLAN, (u8 *)vvfl, len);
+ kfree(vvfl);
+ } else {
++ u16 max_vlans = adapter->vlan_v2_caps.filtering.max_filters;
++ u16 current_vlans = iavf_get_num_vlans_added(adapter);
+ struct virtchnl_vlan_filter_list_v2 *vvfl_v2;
+
+ adapter->current_op = VIRTCHNL_OP_ADD_VLAN_V2;
+
++ if ((count + current_vlans) > max_vlans &&
++ current_vlans < max_vlans) {
++ count = max_vlans - iavf_get_num_vlans_added(adapter);
++ more = true;
++ }
++
+ len = sizeof(*vvfl_v2) + ((count - 1) *
+ sizeof(struct virtchnl_vlan_filter));
+ if (len > IAVF_MAX_AQ_BUF_SIZE) {
+@@ -725,6 +761,9 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
+ &adapter->vlan_v2_caps.filtering.filtering_support;
+ struct virtchnl_vlan *vlan;
+
++ if (i == count)
++ break;
++
+ /* give priority over outer if it's enabled */
+ if (filtering_support->outer)
+ vlan = &vvfl_v2->filters[i].outer;
+@@ -736,8 +775,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
+
+ i++;
+ f->add = false;
+- if (i == count)
+- break;
++ f->is_new_vlan = true;
+ }
+ }
+
+@@ -2080,6 +2118,11 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
+ */
+ iavf_netdev_features_vlan_strip_set(netdev, true);
+ break;
++ case VIRTCHNL_OP_ADD_VLAN_V2:
++ iavf_vlan_add_reject(adapter);
++ dev_warn(&adapter->pdev->dev, "Failed to add VLAN filter, error %s\n",
++ iavf_stat_str(&adapter->hw, v_retval));
++ break;
+ default:
+ dev_err(&adapter->pdev->dev, "PF returned error %d (%s) to our request %d\n",
+ v_retval, iavf_stat_str(&adapter->hw, v_retval),
+@@ -2332,6 +2375,24 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
+ spin_unlock_bh(&adapter->adv_rss_lock);
+ }
+ break;
++ case VIRTCHNL_OP_ADD_VLAN_V2: {
++ struct iavf_vlan_filter *f;
++
++ spin_lock_bh(&adapter->mac_vlan_list_lock);
++ list_for_each_entry(f, &adapter->vlan_filter_list, list) {
++ if (f->is_new_vlan) {
++ f->is_new_vlan = false;
++ if (f->vlan.tpid == ETH_P_8021Q)
++ set_bit(f->vlan.vid,
++ adapter->vsi.active_cvlans);
++ else
++ set_bit(f->vlan.vid,
++ adapter->vsi.active_svlans);
++ }
++ }
++ spin_unlock_bh(&adapter->mac_vlan_list_lock);
++ }
++ break;
+ case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:
+ /* PF enabled vlan strip on this VF.
+ * Update netdev->features if needed to be in sync with ethtool.
+diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
+index 74b2c590ed5d0..38e46e9ba8bb8 100644
+--- a/drivers/net/ethernet/intel/igc/igc_main.c
++++ b/drivers/net/ethernet/intel/igc/igc_main.c
+@@ -6171,6 +6171,9 @@ u32 igc_rd32(struct igc_hw *hw, u32 reg)
+ u8 __iomem *hw_addr = READ_ONCE(hw->hw_addr);
+ u32 value = 0;
+
++ if (IGC_REMOVED(hw_addr))
++ return ~value;
++
+ value = readl(&hw_addr[reg]);
+
+ /* reads should not return all F's */
+diff --git a/drivers/net/ethernet/intel/igc/igc_regs.h b/drivers/net/ethernet/intel/igc/igc_regs.h
+index e197a33d93a03..026c3b65fc37a 100644
+--- a/drivers/net/ethernet/intel/igc/igc_regs.h
++++ b/drivers/net/ethernet/intel/igc/igc_regs.h
+@@ -306,7 +306,8 @@ u32 igc_rd32(struct igc_hw *hw, u32 reg);
+ #define wr32(reg, val) \
+ do { \
+ u8 __iomem *hw_addr = READ_ONCE((hw)->hw_addr); \
+- writel((val), &hw_addr[(reg)]); \
++ if (!IGC_REMOVED(hw_addr)) \
++ writel((val), &hw_addr[(reg)]); \
+ } while (0)
+
+ #define rd32(reg) (igc_rd32(hw, reg))
+@@ -318,4 +319,6 @@ do { \
+
+ #define array_rd32(reg, offset) (igc_rd32(hw, (reg) + ((offset) << 2)))
+
++#define IGC_REMOVED(h) unlikely(!(h))
++
+ #endif
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+index 921a4d977d651..8813b4dd6872f 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+@@ -779,6 +779,7 @@ struct ixgbe_adapter {
+ #ifdef CONFIG_IXGBE_IPSEC
+ struct ixgbe_ipsec *ipsec;
+ #endif /* CONFIG_IXGBE_IPSEC */
++ spinlock_t vfs_lock;
+ };
+
+ static inline int ixgbe_determine_xdp_q_idx(int cpu)
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+index c4a4954aa3177..6c403f112d294 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+@@ -6402,6 +6402,9 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter,
+ /* n-tuple support exists, always init our spinlock */
+ spin_lock_init(&adapter->fdir_perfect_lock);
+
++ /* init spinlock to avoid concurrency of VF resources */
++ spin_lock_init(&adapter->vfs_lock);
++
+ #ifdef CONFIG_IXGBE_DCB
+ ixgbe_init_dcb(adapter);
+ #endif
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+index d4e63f0644c36..a1e69c7348632 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+@@ -205,10 +205,13 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, unsigned int max_vfs)
+ int ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
+ {
+ unsigned int num_vfs = adapter->num_vfs, vf;
++ unsigned long flags;
+ int rss;
+
++ spin_lock_irqsave(&adapter->vfs_lock, flags);
+ /* set num VFs to 0 to prevent access to vfinfo */
+ adapter->num_vfs = 0;
++ spin_unlock_irqrestore(&adapter->vfs_lock, flags);
+
+ /* put the reference to all of the vf devices */
+ for (vf = 0; vf < num_vfs; ++vf) {
+@@ -1355,8 +1358,10 @@ static void ixgbe_rcv_ack_from_vf(struct ixgbe_adapter *adapter, u32 vf)
+ void ixgbe_msg_task(struct ixgbe_adapter *adapter)
+ {
+ struct ixgbe_hw *hw = &adapter->hw;
++ unsigned long flags;
+ u32 vf;
+
++ spin_lock_irqsave(&adapter->vfs_lock, flags);
+ for (vf = 0; vf < adapter->num_vfs; vf++) {
+ /* process any reset requests */
+ if (!ixgbe_check_for_rst(hw, vf))
+@@ -1370,6 +1375,7 @@ void ixgbe_msg_task(struct ixgbe_adapter *adapter)
+ if (!ixgbe_check_for_ack(hw, vf))
+ ixgbe_rcv_ack_from_vf(adapter, vf);
+ }
++ spin_unlock_irqrestore(&adapter->vfs_lock, flags);
+ }
+
+ static inline void ixgbe_ping_vf(struct ixgbe_adapter *adapter, int vf)
+diff --git a/drivers/net/ethernet/marvell/prestera/prestera_flower.c b/drivers/net/ethernet/marvell/prestera/prestera_flower.c
+index 921959a980ee4..d8cfa4a7de0f2 100644
+--- a/drivers/net/ethernet/marvell/prestera/prestera_flower.c
++++ b/drivers/net/ethernet/marvell/prestera/prestera_flower.c
+@@ -139,12 +139,12 @@ static int prestera_flower_parse_meta(struct prestera_acl_rule *rule,
+ }
+ port = netdev_priv(ingress_dev);
+
+- mask = htons(0x1FFF);
+- key = htons(port->hw_id);
++ mask = htons(0x1FFF << 3);
++ key = htons(port->hw_id << 3);
+ rule_match_set(r_match->key, SYS_PORT, key);
+ rule_match_set(r_match->mask, SYS_PORT, mask);
+
+- mask = htons(0x1FF);
++ mask = htons(0x3FF);
+ key = htons(port->dev_id);
+ rule_match_set(r_match->key, SYS_DEV, key);
+ rule_match_set(r_match->mask, SYS_DEV, mask);
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+index 7ad663c5b1ab7..c00d6c4ed37c3 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+@@ -5387,7 +5387,7 @@ static bool mlxsw_sp_fi_is_gateway(const struct mlxsw_sp *mlxsw_sp,
+ {
+ const struct fib_nh *nh = fib_info_nh(fi, 0);
+
+- return nh->fib_nh_scope == RT_SCOPE_LINK ||
++ return nh->fib_nh_gw_family ||
+ mlxsw_sp_nexthop4_ipip_type(mlxsw_sp, nh, NULL);
+ }
+
+@@ -10263,7 +10263,7 @@ static void mlxsw_sp_mp4_hash_init(struct mlxsw_sp *mlxsw_sp,
+ unsigned long *fields = config->fields;
+ u32 hash_fields;
+
+- switch (net->ipv4.sysctl_fib_multipath_hash_policy) {
++ switch (READ_ONCE(net->ipv4.sysctl_fib_multipath_hash_policy)) {
+ case 0:
+ mlxsw_sp_mp4_hash_outer_addr(config);
+ break;
+@@ -10281,7 +10281,7 @@ static void mlxsw_sp_mp4_hash_init(struct mlxsw_sp *mlxsw_sp,
+ mlxsw_sp_mp_hash_inner_l3(config);
+ break;
+ case 3:
+- hash_fields = net->ipv4.sysctl_fib_multipath_hash_fields;
++ hash_fields = READ_ONCE(net->ipv4.sysctl_fib_multipath_hash_fields);
+ /* Outer */
+ MLXSW_SP_MP_HASH_HEADER_SET(headers, IPV4_EN_NOT_TCP_NOT_UDP);
+ MLXSW_SP_MP_HASH_HEADER_SET(headers, IPV4_EN_TCP_UDP);
+@@ -10462,13 +10462,14 @@ static int mlxsw_sp_dscp_init(struct mlxsw_sp *mlxsw_sp)
+ static int __mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp)
+ {
+ struct net *net = mlxsw_sp_net(mlxsw_sp);
+- bool usp = net->ipv4.sysctl_ip_fwd_update_priority;
+ char rgcr_pl[MLXSW_REG_RGCR_LEN];
+ u64 max_rifs;
++ bool usp;
+
+ if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_RIFS))
+ return -EIO;
+ max_rifs = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS);
++ usp = READ_ONCE(net->ipv4.sysctl_ip_fwd_update_priority);
+
+ mlxsw_reg_rgcr_pack(rgcr_pl, true, true);
+ mlxsw_reg_rgcr_max_router_interfaces_set(rgcr_pl, max_rifs);
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c b/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c
+index 005e56ea5da12..5893770bfd946 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c
+@@ -75,6 +75,9 @@ static int __lan966x_mac_learn(struct lan966x *lan966x, int pgid,
+ unsigned int vid,
+ enum macaccess_entry_type type)
+ {
++ int ret;
++
++ spin_lock(&lan966x->mac_lock);
+ lan966x_mac_select(lan966x, mac, vid);
+
+ /* Issue a write command */
+@@ -86,7 +89,10 @@ static int __lan966x_mac_learn(struct lan966x *lan966x, int pgid,
+ ANA_MACACCESS_MAC_TABLE_CMD_SET(MACACCESS_CMD_LEARN),
+ lan966x, ANA_MACACCESS);
+
+- return lan966x_mac_wait_for_completion(lan966x);
++ ret = lan966x_mac_wait_for_completion(lan966x);
++ spin_unlock(&lan966x->mac_lock);
++
++ return ret;
+ }
+
+ /* The mask of the front ports is encoded inside the mac parameter via a call
+@@ -113,11 +119,13 @@ int lan966x_mac_learn(struct lan966x *lan966x, int port,
+ return __lan966x_mac_learn(lan966x, port, false, mac, vid, type);
+ }
+
+-int lan966x_mac_forget(struct lan966x *lan966x,
+- const unsigned char mac[ETH_ALEN],
+- unsigned int vid,
+- enum macaccess_entry_type type)
++static int lan966x_mac_forget_locked(struct lan966x *lan966x,
++ const unsigned char mac[ETH_ALEN],
++ unsigned int vid,
++ enum macaccess_entry_type type)
+ {
++ lockdep_assert_held(&lan966x->mac_lock);
++
+ lan966x_mac_select(lan966x, mac, vid);
+
+ /* Issue a forget command */
+@@ -128,6 +136,20 @@ int lan966x_mac_forget(struct lan966x *lan966x,
+ return lan966x_mac_wait_for_completion(lan966x);
+ }
+
++int lan966x_mac_forget(struct lan966x *lan966x,
++ const unsigned char mac[ETH_ALEN],
++ unsigned int vid,
++ enum macaccess_entry_type type)
++{
++ int ret;
++
++ spin_lock(&lan966x->mac_lock);
++ ret = lan966x_mac_forget_locked(lan966x, mac, vid, type);
++ spin_unlock(&lan966x->mac_lock);
++
++ return ret;
++}
++
+ int lan966x_mac_cpu_learn(struct lan966x *lan966x, const char *addr, u16 vid)
+ {
+ return lan966x_mac_learn(lan966x, PGID_CPU, addr, vid, ENTRYTYPE_LOCKED);
+@@ -161,7 +183,7 @@ static struct lan966x_mac_entry *lan966x_mac_alloc_entry(const unsigned char *ma
+ {
+ struct lan966x_mac_entry *mac_entry;
+
+- mac_entry = kzalloc(sizeof(*mac_entry), GFP_KERNEL);
++ mac_entry = kzalloc(sizeof(*mac_entry), GFP_ATOMIC);
+ if (!mac_entry)
+ return NULL;
+
+@@ -179,7 +201,6 @@ static struct lan966x_mac_entry *lan966x_mac_find_entry(struct lan966x *lan966x,
+ struct lan966x_mac_entry *res = NULL;
+ struct lan966x_mac_entry *mac_entry;
+
+- spin_lock(&lan966x->mac_lock);
+ list_for_each_entry(mac_entry, &lan966x->mac_entries, list) {
+ if (mac_entry->vid == vid &&
+ ether_addr_equal(mac, mac_entry->mac) &&
+@@ -188,7 +209,6 @@ static struct lan966x_mac_entry *lan966x_mac_find_entry(struct lan966x *lan966x,
+ break;
+ }
+ }
+- spin_unlock(&lan966x->mac_lock);
+
+ return res;
+ }
+@@ -231,8 +251,11 @@ int lan966x_mac_add_entry(struct lan966x *lan966x, struct lan966x_port *port,
+ {
+ struct lan966x_mac_entry *mac_entry;
+
+- if (lan966x_mac_lookup(lan966x, addr, vid, ENTRYTYPE_NORMAL))
++ spin_lock(&lan966x->mac_lock);
++ if (lan966x_mac_lookup(lan966x, addr, vid, ENTRYTYPE_NORMAL)) {
++ spin_unlock(&lan966x->mac_lock);
+ return 0;
++ }
+
+ /* In case the entry already exists, don't add it again to SW,
+ * just update HW, but we need to look in the actual HW because
+@@ -241,21 +264,25 @@ int lan966x_mac_add_entry(struct lan966x *lan966x, struct lan966x_port *port,
+ * add the entry but without the extern_learn flag.
+ */
+ mac_entry = lan966x_mac_find_entry(lan966x, addr, vid, port->chip_port);
+- if (mac_entry)
+- return lan966x_mac_learn(lan966x, port->chip_port,
+- addr, vid, ENTRYTYPE_LOCKED);
++ if (mac_entry) {
++ spin_unlock(&lan966x->mac_lock);
++ goto mac_learn;
++ }
+
+ mac_entry = lan966x_mac_alloc_entry(addr, vid, port->chip_port);
+- if (!mac_entry)
++ if (!mac_entry) {
++ spin_unlock(&lan966x->mac_lock);
+ return -ENOMEM;
++ }
+
+- spin_lock(&lan966x->mac_lock);
+ list_add_tail(&mac_entry->list, &lan966x->mac_entries);
+ spin_unlock(&lan966x->mac_lock);
+
+- lan966x_mac_learn(lan966x, port->chip_port, addr, vid, ENTRYTYPE_LOCKED);
+ lan966x_fdb_call_notifiers(SWITCHDEV_FDB_OFFLOADED, addr, vid, port->dev);
+
++mac_learn:
++ lan966x_mac_learn(lan966x, port->chip_port, addr, vid, ENTRYTYPE_LOCKED);
++
+ return 0;
+ }
+
+@@ -269,8 +296,9 @@ int lan966x_mac_del_entry(struct lan966x *lan966x, const unsigned char *addr,
+ list) {
+ if (mac_entry->vid == vid &&
+ ether_addr_equal(addr, mac_entry->mac)) {
+- lan966x_mac_forget(lan966x, mac_entry->mac, mac_entry->vid,
+- ENTRYTYPE_LOCKED);
++ lan966x_mac_forget_locked(lan966x, mac_entry->mac,
++ mac_entry->vid,
++ ENTRYTYPE_LOCKED);
+
+ list_del(&mac_entry->list);
+ kfree(mac_entry);
+@@ -288,8 +316,8 @@ void lan966x_mac_purge_entries(struct lan966x *lan966x)
+ spin_lock(&lan966x->mac_lock);
+ list_for_each_entry_safe(mac_entry, tmp, &lan966x->mac_entries,
+ list) {
+- lan966x_mac_forget(lan966x, mac_entry->mac, mac_entry->vid,
+- ENTRYTYPE_LOCKED);
++ lan966x_mac_forget_locked(lan966x, mac_entry->mac,
++ mac_entry->vid, ENTRYTYPE_LOCKED);
+
+ list_del(&mac_entry->list);
+ kfree(mac_entry);
+@@ -325,10 +353,13 @@ static void lan966x_mac_irq_process(struct lan966x *lan966x, u32 row,
+ {
+ struct lan966x_mac_entry *mac_entry, *tmp;
+ unsigned char mac[ETH_ALEN] __aligned(2);
++ struct list_head mac_deleted_entries;
+ u32 dest_idx;
+ u32 column;
+ u16 vid;
+
++ INIT_LIST_HEAD(&mac_deleted_entries);
++
+ spin_lock(&lan966x->mac_lock);
+ list_for_each_entry_safe(mac_entry, tmp, &lan966x->mac_entries, list) {
+ bool found = false;
+@@ -362,20 +393,26 @@ static void lan966x_mac_irq_process(struct lan966x *lan966x, u32 row,
+ }
+
+ if (!found) {
+- /* Notify the bridge that the entry doesn't exist
+- * anymore in the HW and remove the entry from the SW
+- * list
+- */
+- lan966x_mac_notifiers(SWITCHDEV_FDB_DEL_TO_BRIDGE,
+- mac_entry->mac, mac_entry->vid,
+- lan966x->ports[mac_entry->port_index]->dev);
+-
+ list_del(&mac_entry->list);
+- kfree(mac_entry);
++ /* Move the entry from SW list to a tmp list such that
++ * it would be deleted later
++ */
++ list_add_tail(&mac_entry->list, &mac_deleted_entries);
+ }
+ }
+ spin_unlock(&lan966x->mac_lock);
+
++ list_for_each_entry_safe(mac_entry, tmp, &mac_deleted_entries, list) {
++ /* Notify the bridge that the entry doesn't exist
++ * anymore in the HW
++ */
++ lan966x_mac_notifiers(SWITCHDEV_FDB_DEL_TO_BRIDGE,
++ mac_entry->mac, mac_entry->vid,
++ lan966x->ports[mac_entry->port_index]->dev);
++ list_del(&mac_entry->list);
++ kfree(mac_entry);
++ }
++
+ /* Now go to the list of columns and see if any entry was not in the SW
+ * list, then that means that the entry is new so it needs to notify the
+ * bridge.
+@@ -396,13 +433,20 @@ static void lan966x_mac_irq_process(struct lan966x *lan966x, u32 row,
+ if (WARN_ON(dest_idx >= lan966x->num_phys_ports))
+ continue;
+
++ spin_lock(&lan966x->mac_lock);
++ mac_entry = lan966x_mac_find_entry(lan966x, mac, vid, dest_idx);
++ if (mac_entry) {
++ spin_unlock(&lan966x->mac_lock);
++ continue;
++ }
++
+ mac_entry = lan966x_mac_alloc_entry(mac, vid, dest_idx);
+- if (!mac_entry)
++ if (!mac_entry) {
++ spin_unlock(&lan966x->mac_lock);
+ return;
++ }
+
+ mac_entry->row = row;
+-
+- spin_lock(&lan966x->mac_lock);
+ list_add_tail(&mac_entry->list, &lan966x->mac_entries);
+ spin_unlock(&lan966x->mac_lock);
+
+@@ -424,6 +468,7 @@ irqreturn_t lan966x_mac_irq_handler(struct lan966x *lan966x)
+ lan966x, ANA_MACTINDX);
+
+ while (1) {
++ spin_lock(&lan966x->mac_lock);
+ lan_rmw(ANA_MACACCESS_MAC_TABLE_CMD_SET(MACACCESS_CMD_SYNC_GET_NEXT),
+ ANA_MACACCESS_MAC_TABLE_CMD,
+ lan966x, ANA_MACACCESS);
+@@ -447,12 +492,15 @@ irqreturn_t lan966x_mac_irq_handler(struct lan966x *lan966x)
+ stop = false;
+
+ if (column == LAN966X_MAC_COLUMNS - 1 &&
+- index == 0 && stop)
++ index == 0 && stop) {
++ spin_unlock(&lan966x->mac_lock);
+ break;
++ }
+
+ entry[column].mach = lan_rd(lan966x, ANA_MACHDATA);
+ entry[column].macl = lan_rd(lan966x, ANA_MACLDATA);
+ entry[column].maca = lan_rd(lan966x, ANA_MACACCESS);
++ spin_unlock(&lan966x->mac_lock);
+
+ /* Once all the columns are read process them */
+ if (column == LAN966X_MAC_COLUMNS - 1) {
+diff --git a/drivers/net/ethernet/netronome/nfp/flower/action.c b/drivers/net/ethernet/netronome/nfp/flower/action.c
+index 1b9421e844a95..79036767c99d1 100644
+--- a/drivers/net/ethernet/netronome/nfp/flower/action.c
++++ b/drivers/net/ethernet/netronome/nfp/flower/action.c
+@@ -473,7 +473,7 @@ nfp_fl_set_tun(struct nfp_app *app, struct nfp_fl_set_tun *set_tun,
+ set_tun->ttl = ip4_dst_hoplimit(&rt->dst);
+ ip_rt_put(rt);
+ } else {
+- set_tun->ttl = net->ipv4.sysctl_ip_default_ttl;
++ set_tun->ttl = READ_ONCE(net->ipv4.sysctl_ip_default_ttl);
+ }
+ }
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
+index 6ff88df587673..ca8ab290013ce 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
+@@ -576,32 +576,7 @@ static int mediatek_dwmac_init(struct platform_device *pdev, void *priv)
+ }
+ }
+
+- ret = clk_bulk_prepare_enable(variant->num_clks, plat->clks);
+- if (ret) {
+- dev_err(plat->dev, "failed to enable clks, err = %d\n", ret);
+- return ret;
+- }
+-
+- ret = clk_prepare_enable(plat->rmii_internal_clk);
+- if (ret) {
+- dev_err(plat->dev, "failed to enable rmii internal clk, err = %d\n", ret);
+- goto err_clk;
+- }
+-
+ return 0;
+-
+-err_clk:
+- clk_bulk_disable_unprepare(variant->num_clks, plat->clks);
+- return ret;
+-}
+-
+-static void mediatek_dwmac_exit(struct platform_device *pdev, void *priv)
+-{
+- struct mediatek_dwmac_plat_data *plat = priv;
+- const struct mediatek_dwmac_variant *variant = plat->variant;
+-
+- clk_disable_unprepare(plat->rmii_internal_clk);
+- clk_bulk_disable_unprepare(variant->num_clks, plat->clks);
+ }
+
+ static int mediatek_dwmac_clks_config(void *priv, bool enabled)
+@@ -643,7 +618,6 @@ static int mediatek_dwmac_common_data(struct platform_device *pdev,
+ plat->addr64 = priv_plat->variant->dma_bit_mask;
+ plat->bsp_priv = priv_plat;
+ plat->init = mediatek_dwmac_init;
+- plat->exit = mediatek_dwmac_exit;
+ plat->clks_config = mediatek_dwmac_clks_config;
+ if (priv_plat->variant->dwmac_fix_mac_speed)
+ plat->fix_mac_speed = priv_plat->variant->dwmac_fix_mac_speed;
+@@ -712,13 +686,32 @@ static int mediatek_dwmac_probe(struct platform_device *pdev)
+ mediatek_dwmac_common_data(pdev, plat_dat, priv_plat);
+ mediatek_dwmac_init(pdev, priv_plat);
+
++ ret = mediatek_dwmac_clks_config(priv_plat, true);
++ if (ret)
++ return ret;
++
+ ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+ if (ret) {
+ stmmac_remove_config_dt(pdev, plat_dat);
+- return ret;
++ goto err_drv_probe;
+ }
+
+ return 0;
++
++err_drv_probe:
++ mediatek_dwmac_clks_config(priv_plat, false);
++ return ret;
++}
++
++static int mediatek_dwmac_remove(struct platform_device *pdev)
++{
++ struct mediatek_dwmac_plat_data *priv_plat = get_stmmac_bsp_priv(&pdev->dev);
++ int ret;
++
++ ret = stmmac_pltfr_remove(pdev);
++ mediatek_dwmac_clks_config(priv_plat, false);
++
++ return ret;
+ }
+
+ static const struct of_device_id mediatek_dwmac_match[] = {
+@@ -733,7 +726,7 @@ MODULE_DEVICE_TABLE(of, mediatek_dwmac_match);
+
+ static struct platform_driver mediatek_dwmac_driver = {
+ .probe = mediatek_dwmac_probe,
+- .remove = stmmac_pltfr_remove,
++ .remove = mediatek_dwmac_remove,
+ .driver = {
+ .name = "dwmac-mediatek",
+ .pm = &stmmac_pltfr_pm_ops,
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+index fd41db65fe1df..af33390411346 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+@@ -219,6 +219,9 @@ static void dwmac4_map_mtl_dma(struct mac_device_info *hw, u32 queue, u32 chan)
+ if (queue == 0 || queue == 4) {
+ value &= ~MTL_RXQ_DMA_Q04MDMACH_MASK;
+ value |= MTL_RXQ_DMA_Q04MDMACH(chan);
++ } else if (queue > 4) {
++ value &= ~MTL_RXQ_DMA_QXMDMACH_MASK(queue - 4);
++ value |= MTL_RXQ_DMA_QXMDMACH(chan, queue - 4);
+ } else {
+ value &= ~MTL_RXQ_DMA_QXMDMACH_MASK(queue);
+ value |= MTL_RXQ_DMA_QXMDMACH(chan, queue);
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+index abfb3cd5958df..9c3055ee26085 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+@@ -803,14 +803,6 @@ static int stmmac_ethtool_op_set_eee(struct net_device *dev,
+ netdev_warn(priv->dev,
+ "Setting EEE tx-lpi is not supported\n");
+
+- if (priv->hw->xpcs) {
+- ret = xpcs_config_eee(priv->hw->xpcs,
+- priv->plat->mult_fact_100ns,
+- edata->eee_enabled);
+- if (ret)
+- return ret;
+- }
+-
+ if (!edata->eee_enabled)
+ stmmac_disable_eee_mode(priv);
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 2525a80353b70..6a7f63a58aef8 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -834,19 +834,10 @@ int stmmac_init_tstamp_counter(struct stmmac_priv *priv, u32 systime_flags)
+ struct timespec64 now;
+ u32 sec_inc = 0;
+ u64 temp = 0;
+- int ret;
+
+ if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp))
+ return -EOPNOTSUPP;
+
+- ret = clk_prepare_enable(priv->plat->clk_ptp_ref);
+- if (ret < 0) {
+- netdev_warn(priv->dev,
+- "failed to enable PTP reference clock: %pe\n",
+- ERR_PTR(ret));
+- return ret;
+- }
+-
+ stmmac_config_hw_tstamping(priv, priv->ptpaddr, systime_flags);
+ priv->systime_flags = systime_flags;
+
+@@ -3270,6 +3261,14 @@ static int stmmac_hw_setup(struct net_device *dev, bool ptp_register)
+
+ stmmac_mmc_setup(priv);
+
++ if (ptp_register) {
++ ret = clk_prepare_enable(priv->plat->clk_ptp_ref);
++ if (ret < 0)
++ netdev_warn(priv->dev,
++ "failed to enable PTP reference clock: %pe\n",
++ ERR_PTR(ret));
++ }
++
+ ret = stmmac_init_ptp(priv);
+ if (ret == -EOPNOTSUPP)
+ netdev_info(priv->dev, "PTP not supported by HW\n");
+@@ -7220,8 +7219,6 @@ int stmmac_dvr_remove(struct device *dev)
+ netdev_info(priv->dev, "%s: removing driver", __func__);
+
+ pm_runtime_get_sync(dev);
+- pm_runtime_disable(dev);
+- pm_runtime_put_noidle(dev);
+
+ stmmac_stop_all_dma(priv);
+ stmmac_mac_set(priv, priv->ioaddr, false);
+@@ -7248,6 +7245,9 @@ int stmmac_dvr_remove(struct device *dev)
+ mutex_destroy(&priv->lock);
+ bitmap_free(priv->af_xdp_zc_qps);
+
++ pm_runtime_disable(dev);
++ pm_runtime_put_noidle(dev);
++
+ return 0;
+ }
+ EXPORT_SYMBOL_GPL(stmmac_dvr_remove);
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+index 11e1055e8260f..9f5cac4000da6 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -815,7 +815,13 @@ static int __maybe_unused stmmac_pltfr_noirq_resume(struct device *dev)
+ if (ret)
+ return ret;
+
+- stmmac_init_tstamp_counter(priv, priv->systime_flags);
++ ret = clk_prepare_enable(priv->plat->clk_ptp_ref);
++ if (ret < 0) {
++ netdev_warn(priv->dev,
++ "failed to enable PTP reference clock: %pe\n",
++ ERR_PTR(ret));
++ return ret;
++ }
+ }
+
+ return 0;
+diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
+index 873f6deabbd1a..dc1f6d8444ad0 100644
+--- a/drivers/net/usb/ax88179_178a.c
++++ b/drivers/net/usb/ax88179_178a.c
+@@ -1801,7 +1801,7 @@ static const struct driver_info ax88179_info = {
+ .link_reset = ax88179_link_reset,
+ .reset = ax88179_reset,
+ .stop = ax88179_stop,
+- .flags = FLAG_ETHER | FLAG_FRAMING_AX,
++ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
+ .rx_fixup = ax88179_rx_fixup,
+ .tx_fixup = ax88179_tx_fixup,
+ };
+@@ -1814,7 +1814,7 @@ static const struct driver_info ax88178a_info = {
+ .link_reset = ax88179_link_reset,
+ .reset = ax88179_reset,
+ .stop = ax88179_stop,
+- .flags = FLAG_ETHER | FLAG_FRAMING_AX,
++ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
+ .rx_fixup = ax88179_rx_fixup,
+ .tx_fixup = ax88179_tx_fixup,
+ };
+@@ -1827,7 +1827,7 @@ static const struct driver_info cypress_GX3_info = {
+ .link_reset = ax88179_link_reset,
+ .reset = ax88179_reset,
+ .stop = ax88179_stop,
+- .flags = FLAG_ETHER | FLAG_FRAMING_AX,
++ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
+ .rx_fixup = ax88179_rx_fixup,
+ .tx_fixup = ax88179_tx_fixup,
+ };
+@@ -1840,7 +1840,7 @@ static const struct driver_info dlink_dub1312_info = {
+ .link_reset = ax88179_link_reset,
+ .reset = ax88179_reset,
+ .stop = ax88179_stop,
+- .flags = FLAG_ETHER | FLAG_FRAMING_AX,
++ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
+ .rx_fixup = ax88179_rx_fixup,
+ .tx_fixup = ax88179_tx_fixup,
+ };
+@@ -1853,7 +1853,7 @@ static const struct driver_info sitecom_info = {
+ .link_reset = ax88179_link_reset,
+ .reset = ax88179_reset,
+ .stop = ax88179_stop,
+- .flags = FLAG_ETHER | FLAG_FRAMING_AX,
++ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
+ .rx_fixup = ax88179_rx_fixup,
+ .tx_fixup = ax88179_tx_fixup,
+ };
+@@ -1866,7 +1866,7 @@ static const struct driver_info samsung_info = {
+ .link_reset = ax88179_link_reset,
+ .reset = ax88179_reset,
+ .stop = ax88179_stop,
+- .flags = FLAG_ETHER | FLAG_FRAMING_AX,
++ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
+ .rx_fixup = ax88179_rx_fixup,
+ .tx_fixup = ax88179_tx_fixup,
+ };
+@@ -1879,7 +1879,7 @@ static const struct driver_info lenovo_info = {
+ .link_reset = ax88179_link_reset,
+ .reset = ax88179_reset,
+ .stop = ax88179_stop,
+- .flags = FLAG_ETHER | FLAG_FRAMING_AX,
++ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
+ .rx_fixup = ax88179_rx_fixup,
+ .tx_fixup = ax88179_tx_fixup,
+ };
+@@ -1892,7 +1892,7 @@ static const struct driver_info belkin_info = {
+ .link_reset = ax88179_link_reset,
+ .reset = ax88179_reset,
+ .stop = ax88179_stop,
+- .flags = FLAG_ETHER | FLAG_FRAMING_AX,
++ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
+ .rx_fixup = ax88179_rx_fixup,
+ .tx_fixup = ax88179_tx_fixup,
+ };
+@@ -1905,7 +1905,7 @@ static const struct driver_info toshiba_info = {
+ .link_reset = ax88179_link_reset,
+ .reset = ax88179_reset,
+ .stop = ax88179_stop,
+- .flags = FLAG_ETHER | FLAG_FRAMING_AX,
++ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
+ .rx_fixup = ax88179_rx_fixup,
+ .tx_fixup = ax88179_tx_fixup,
+ };
+@@ -1918,7 +1918,7 @@ static const struct driver_info mct_info = {
+ .link_reset = ax88179_link_reset,
+ .reset = ax88179_reset,
+ .stop = ax88179_stop,
+- .flags = FLAG_ETHER | FLAG_FRAMING_AX,
++ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
+ .rx_fixup = ax88179_rx_fixup,
+ .tx_fixup = ax88179_tx_fixup,
+ };
+@@ -1931,7 +1931,7 @@ static const struct driver_info at_umc2000_info = {
+ .link_reset = ax88179_link_reset,
+ .reset = ax88179_reset,
+ .stop = ax88179_stop,
+- .flags = FLAG_ETHER | FLAG_FRAMING_AX,
++ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
+ .rx_fixup = ax88179_rx_fixup,
+ .tx_fixup = ax88179_tx_fixup,
+ };
+@@ -1944,7 +1944,7 @@ static const struct driver_info at_umc200_info = {
+ .link_reset = ax88179_link_reset,
+ .reset = ax88179_reset,
+ .stop = ax88179_stop,
+- .flags = FLAG_ETHER | FLAG_FRAMING_AX,
++ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
+ .rx_fixup = ax88179_rx_fixup,
+ .tx_fixup = ax88179_tx_fixup,
+ };
+@@ -1957,7 +1957,7 @@ static const struct driver_info at_umc2000sp_info = {
+ .link_reset = ax88179_link_reset,
+ .reset = ax88179_reset,
+ .stop = ax88179_stop,
+- .flags = FLAG_ETHER | FLAG_FRAMING_AX,
++ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
+ .rx_fixup = ax88179_rx_fixup,
+ .tx_fixup = ax88179_tx_fixup,
+ };
+diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
+index ee41088c52518..6b4efae11e57c 100644
+--- a/drivers/net/usb/r8152.c
++++ b/drivers/net/usb/r8152.c
+@@ -32,7 +32,7 @@
+ #define NETNEXT_VERSION "12"
+
+ /* Information for net */
+-#define NET_VERSION "12"
++#define NET_VERSION "13"
+
+ #define DRIVER_VERSION "v1." NETNEXT_VERSION "." NET_VERSION
+ #define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>"
+@@ -5915,7 +5915,8 @@ static void r8153_enter_oob(struct r8152 *tp)
+
+ wait_oob_link_list_ready(tp);
+
+- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, mtu_to_size(tp->netdev->mtu));
++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, 1522);
++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, MTPS_DEFAULT);
+
+ switch (tp->version) {
+ case RTL_VER_03:
+@@ -5951,6 +5952,10 @@ static void r8153_enter_oob(struct r8152 *tp)
+ ocp_data |= NOW_IS_OOB | DIS_MCU_CLROOB;
+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data);
+
++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7);
++ ocp_data |= MCU_BORW_EN;
++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data);
++
+ rxdy_gated_en(tp, false);
+
+ ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
+@@ -6553,6 +6558,9 @@ static void rtl8156_down(struct r8152 *tp)
+ rtl_disable(tp);
+ rtl_reset_bmu(tp);
+
++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, 1522);
++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, MTPS_DEFAULT);
++
+ /* Clear teredo wake event. bit[15:8] is the teredo wakeup
+ * type. Set it to zero. bits[7:0] are the W1C bits about
+ * the events. Set them to all 1 to clear them.
+@@ -6563,6 +6571,10 @@ static void rtl8156_down(struct r8152 *tp)
+ ocp_data |= NOW_IS_OOB;
+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data);
+
++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7);
++ ocp_data |= MCU_BORW_EN;
++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data);
++
+ rtl_rx_vlan_en(tp, true);
+ rxdy_gated_en(tp, false);
+
+diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
+index d270a204324e9..fb185cb052583 100644
+--- a/drivers/pci/controller/pci-hyperv.c
++++ b/drivers/pci/controller/pci-hyperv.c
+@@ -604,17 +604,19 @@ static unsigned int hv_msi_get_int_vector(struct irq_data *data)
+ return cfg->vector;
+ }
+
+-static void hv_set_msi_entry_from_desc(union hv_msi_entry *msi_entry,
+- struct msi_desc *msi_desc)
+-{
+- msi_entry->address.as_uint32 = msi_desc->msg.address_lo;
+- msi_entry->data.as_uint32 = msi_desc->msg.data;
+-}
+-
+ static int hv_msi_prepare(struct irq_domain *domain, struct device *dev,
+ int nvec, msi_alloc_info_t *info)
+ {
+- return pci_msi_prepare(domain, dev, nvec, info);
++ int ret = pci_msi_prepare(domain, dev, nvec, info);
++
++ /*
++ * By using the interrupt remapper in the hypervisor IOMMU, contiguous
++ * CPU vectors is not needed for multi-MSI
++ */
++ if (info->type == X86_IRQ_ALLOC_TYPE_PCI_MSI)
++ info->flags &= ~X86_IRQ_ALLOC_CONTIGUOUS_VECTORS;
++
++ return ret;
+ }
+
+ /**
+@@ -631,6 +633,7 @@ static void hv_arch_irq_unmask(struct irq_data *data)
+ {
+ struct msi_desc *msi_desc = irq_data_get_msi_desc(data);
+ struct hv_retarget_device_interrupt *params;
++ struct tran_int_desc *int_desc;
+ struct hv_pcibus_device *hbus;
+ struct cpumask *dest;
+ cpumask_var_t tmp;
+@@ -645,6 +648,7 @@ static void hv_arch_irq_unmask(struct irq_data *data)
+ pdev = msi_desc_to_pci_dev(msi_desc);
+ pbus = pdev->bus;
+ hbus = container_of(pbus->sysdata, struct hv_pcibus_device, sysdata);
++ int_desc = data->chip_data;
+
+ spin_lock_irqsave(&hbus->retarget_msi_interrupt_lock, flags);
+
+@@ -652,7 +656,8 @@ static void hv_arch_irq_unmask(struct irq_data *data)
+ memset(params, 0, sizeof(*params));
+ params->partition_id = HV_PARTITION_ID_SELF;
+ params->int_entry.source = HV_INTERRUPT_SOURCE_MSI;
+- hv_set_msi_entry_from_desc(¶ms->int_entry.msi_entry, msi_desc);
++ params->int_entry.msi_entry.address.as_uint32 = int_desc->address & 0xffffffff;
++ params->int_entry.msi_entry.data.as_uint32 = int_desc->data;
+ params->device_id = (hbus->hdev->dev_instance.b[5] << 24) |
+ (hbus->hdev->dev_instance.b[4] << 16) |
+ (hbus->hdev->dev_instance.b[7] << 8) |
+@@ -1513,6 +1518,10 @@ static void hv_int_desc_free(struct hv_pci_dev *hpdev,
+ u8 buffer[sizeof(struct pci_delete_interrupt)];
+ } ctxt;
+
++ if (!int_desc->vector_count) {
++ kfree(int_desc);
++ return;
++ }
+ memset(&ctxt, 0, sizeof(ctxt));
+ int_pkt = (struct pci_delete_interrupt *)&ctxt.pkt.message;
+ int_pkt->message_type.type =
+@@ -1597,12 +1606,12 @@ static void hv_pci_compose_compl(void *context, struct pci_response *resp,
+
+ static u32 hv_compose_msi_req_v1(
+ struct pci_create_interrupt *int_pkt, struct cpumask *affinity,
+- u32 slot, u8 vector)
++ u32 slot, u8 vector, u8 vector_count)
+ {
+ int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE;
+ int_pkt->wslot.slot = slot;
+ int_pkt->int_desc.vector = vector;
+- int_pkt->int_desc.vector_count = 1;
++ int_pkt->int_desc.vector_count = vector_count;
+ int_pkt->int_desc.delivery_mode = DELIVERY_MODE;
+
+ /*
+@@ -1625,14 +1634,14 @@ static int hv_compose_msi_req_get_cpu(struct cpumask *affinity)
+
+ static u32 hv_compose_msi_req_v2(
+ struct pci_create_interrupt2 *int_pkt, struct cpumask *affinity,
+- u32 slot, u8 vector)
++ u32 slot, u8 vector, u8 vector_count)
+ {
+ int cpu;
+
+ int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE2;
+ int_pkt->wslot.slot = slot;
+ int_pkt->int_desc.vector = vector;
+- int_pkt->int_desc.vector_count = 1;
++ int_pkt->int_desc.vector_count = vector_count;
+ int_pkt->int_desc.delivery_mode = DELIVERY_MODE;
+ cpu = hv_compose_msi_req_get_cpu(affinity);
+ int_pkt->int_desc.processor_array[0] =
+@@ -1644,7 +1653,7 @@ static u32 hv_compose_msi_req_v2(
+
+ static u32 hv_compose_msi_req_v3(
+ struct pci_create_interrupt3 *int_pkt, struct cpumask *affinity,
+- u32 slot, u32 vector)
++ u32 slot, u32 vector, u8 vector_count)
+ {
+ int cpu;
+
+@@ -1652,7 +1661,7 @@ static u32 hv_compose_msi_req_v3(
+ int_pkt->wslot.slot = slot;
+ int_pkt->int_desc.vector = vector;
+ int_pkt->int_desc.reserved = 0;
+- int_pkt->int_desc.vector_count = 1;
++ int_pkt->int_desc.vector_count = vector_count;
+ int_pkt->int_desc.delivery_mode = DELIVERY_MODE;
+ cpu = hv_compose_msi_req_get_cpu(affinity);
+ int_pkt->int_desc.processor_array[0] =
+@@ -1683,6 +1692,8 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ struct cpumask *dest;
+ struct compose_comp_ctxt comp;
+ struct tran_int_desc *int_desc;
++ struct msi_desc *msi_desc;
++ u8 vector, vector_count;
+ struct {
+ struct pci_packet pci_pkt;
+ union {
+@@ -1695,7 +1706,17 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ u32 size;
+ int ret;
+
+- pdev = msi_desc_to_pci_dev(irq_data_get_msi_desc(data));
++ /* Reuse the previous allocation */
++ if (data->chip_data) {
++ int_desc = data->chip_data;
++ msg->address_hi = int_desc->address >> 32;
++ msg->address_lo = int_desc->address & 0xffffffff;
++ msg->data = int_desc->data;
++ return;
++ }
++
++ msi_desc = irq_data_get_msi_desc(data);
++ pdev = msi_desc_to_pci_dev(msi_desc);
+ dest = irq_data_get_effective_affinity_mask(data);
+ pbus = pdev->bus;
+ hbus = container_of(pbus->sysdata, struct hv_pcibus_device, sysdata);
+@@ -1704,17 +1725,40 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ if (!hpdev)
+ goto return_null_message;
+
+- /* Free any previous message that might have already been composed. */
+- if (data->chip_data) {
+- int_desc = data->chip_data;
+- data->chip_data = NULL;
+- hv_int_desc_free(hpdev, int_desc);
+- }
+-
+ int_desc = kzalloc(sizeof(*int_desc), GFP_ATOMIC);
+ if (!int_desc)
+ goto drop_reference;
+
++ if (!msi_desc->pci.msi_attrib.is_msix && msi_desc->nvec_used > 1) {
++ /*
++ * If this is not the first MSI of Multi MSI, we already have
++ * a mapping. Can exit early.
++ */
++ if (msi_desc->irq != data->irq) {
++ data->chip_data = int_desc;
++ int_desc->address = msi_desc->msg.address_lo |
++ (u64)msi_desc->msg.address_hi << 32;
++ int_desc->data = msi_desc->msg.data +
++ (data->irq - msi_desc->irq);
++ msg->address_hi = msi_desc->msg.address_hi;
++ msg->address_lo = msi_desc->msg.address_lo;
++ msg->data = int_desc->data;
++ put_pcichild(hpdev);
++ return;
++ }
++ /*
++ * The vector we select here is a dummy value. The correct
++ * value gets sent to the hypervisor in unmask(). This needs
++ * to be aligned with the count, and also not zero. Multi-msi
++ * is powers of 2 up to 32, so 32 will always work here.
++ */
++ vector = 32;
++ vector_count = msi_desc->nvec_used;
++ } else {
++ vector = hv_msi_get_int_vector(data);
++ vector_count = 1;
++ }
++
+ memset(&ctxt, 0, sizeof(ctxt));
+ init_completion(&comp.comp_pkt.host_event);
+ ctxt.pci_pkt.completion_func = hv_pci_compose_compl;
+@@ -1725,7 +1769,8 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ size = hv_compose_msi_req_v1(&ctxt.int_pkts.v1,
+ dest,
+ hpdev->desc.win_slot.slot,
+- hv_msi_get_int_vector(data));
++ vector,
++ vector_count);
+ break;
+
+ case PCI_PROTOCOL_VERSION_1_2:
+@@ -1733,14 +1778,16 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ size = hv_compose_msi_req_v2(&ctxt.int_pkts.v2,
+ dest,
+ hpdev->desc.win_slot.slot,
+- hv_msi_get_int_vector(data));
++ vector,
++ vector_count);
+ break;
+
+ case PCI_PROTOCOL_VERSION_1_4:
+ size = hv_compose_msi_req_v3(&ctxt.int_pkts.v3,
+ dest,
+ hpdev->desc.win_slot.slot,
+- hv_msi_get_int_vector(data));
++ vector,
++ vector_count);
+ break;
+
+ default:
+diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
+index adccf03b3e5af..b920dd5237c75 100644
+--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
++++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
+@@ -101,7 +101,7 @@ struct armada_37xx_pinctrl {
+ struct device *dev;
+ struct gpio_chip gpio_chip;
+ struct irq_chip irq_chip;
+- spinlock_t irq_lock;
++ raw_spinlock_t irq_lock;
+ struct pinctrl_desc pctl;
+ struct pinctrl_dev *pctl_dev;
+ struct armada_37xx_pin_group *groups;
+@@ -522,9 +522,9 @@ static void armada_37xx_irq_ack(struct irq_data *d)
+ unsigned long flags;
+
+ armada_37xx_irq_update_reg(®, d);
+- spin_lock_irqsave(&info->irq_lock, flags);
++ raw_spin_lock_irqsave(&info->irq_lock, flags);
+ writel(d->mask, info->base + reg);
+- spin_unlock_irqrestore(&info->irq_lock, flags);
++ raw_spin_unlock_irqrestore(&info->irq_lock, flags);
+ }
+
+ static void armada_37xx_irq_mask(struct irq_data *d)
+@@ -535,10 +535,10 @@ static void armada_37xx_irq_mask(struct irq_data *d)
+ unsigned long flags;
+
+ armada_37xx_irq_update_reg(®, d);
+- spin_lock_irqsave(&info->irq_lock, flags);
++ raw_spin_lock_irqsave(&info->irq_lock, flags);
+ val = readl(info->base + reg);
+ writel(val & ~d->mask, info->base + reg);
+- spin_unlock_irqrestore(&info->irq_lock, flags);
++ raw_spin_unlock_irqrestore(&info->irq_lock, flags);
+ }
+
+ static void armada_37xx_irq_unmask(struct irq_data *d)
+@@ -549,10 +549,10 @@ static void armada_37xx_irq_unmask(struct irq_data *d)
+ unsigned long flags;
+
+ armada_37xx_irq_update_reg(®, d);
+- spin_lock_irqsave(&info->irq_lock, flags);
++ raw_spin_lock_irqsave(&info->irq_lock, flags);
+ val = readl(info->base + reg);
+ writel(val | d->mask, info->base + reg);
+- spin_unlock_irqrestore(&info->irq_lock, flags);
++ raw_spin_unlock_irqrestore(&info->irq_lock, flags);
+ }
+
+ static int armada_37xx_irq_set_wake(struct irq_data *d, unsigned int on)
+@@ -563,14 +563,14 @@ static int armada_37xx_irq_set_wake(struct irq_data *d, unsigned int on)
+ unsigned long flags;
+
+ armada_37xx_irq_update_reg(®, d);
+- spin_lock_irqsave(&info->irq_lock, flags);
++ raw_spin_lock_irqsave(&info->irq_lock, flags);
+ val = readl(info->base + reg);
+ if (on)
+ val |= (BIT(d->hwirq % GPIO_PER_REG));
+ else
+ val &= ~(BIT(d->hwirq % GPIO_PER_REG));
+ writel(val, info->base + reg);
+- spin_unlock_irqrestore(&info->irq_lock, flags);
++ raw_spin_unlock_irqrestore(&info->irq_lock, flags);
+
+ return 0;
+ }
+@@ -582,7 +582,7 @@ static int armada_37xx_irq_set_type(struct irq_data *d, unsigned int type)
+ u32 val, reg = IRQ_POL;
+ unsigned long flags;
+
+- spin_lock_irqsave(&info->irq_lock, flags);
++ raw_spin_lock_irqsave(&info->irq_lock, flags);
+ armada_37xx_irq_update_reg(®, d);
+ val = readl(info->base + reg);
+ switch (type) {
+@@ -606,11 +606,11 @@ static int armada_37xx_irq_set_type(struct irq_data *d, unsigned int type)
+ break;
+ }
+ default:
+- spin_unlock_irqrestore(&info->irq_lock, flags);
++ raw_spin_unlock_irqrestore(&info->irq_lock, flags);
+ return -EINVAL;
+ }
+ writel(val, info->base + reg);
+- spin_unlock_irqrestore(&info->irq_lock, flags);
++ raw_spin_unlock_irqrestore(&info->irq_lock, flags);
+
+ return 0;
+ }
+@@ -625,7 +625,7 @@ static int armada_37xx_edge_both_irq_swap_pol(struct armada_37xx_pinctrl *info,
+
+ regmap_read(info->regmap, INPUT_VAL + 4*reg_idx, &l);
+
+- spin_lock_irqsave(&info->irq_lock, flags);
++ raw_spin_lock_irqsave(&info->irq_lock, flags);
+ p = readl(info->base + IRQ_POL + 4 * reg_idx);
+ if ((p ^ l) & (1 << bit_num)) {
+ /*
+@@ -646,7 +646,7 @@ static int armada_37xx_edge_both_irq_swap_pol(struct armada_37xx_pinctrl *info,
+ ret = -1;
+ }
+
+- spin_unlock_irqrestore(&info->irq_lock, flags);
++ raw_spin_unlock_irqrestore(&info->irq_lock, flags);
+ return ret;
+ }
+
+@@ -663,11 +663,11 @@ static void armada_37xx_irq_handler(struct irq_desc *desc)
+ u32 status;
+ unsigned long flags;
+
+- spin_lock_irqsave(&info->irq_lock, flags);
++ raw_spin_lock_irqsave(&info->irq_lock, flags);
+ status = readl_relaxed(info->base + IRQ_STATUS + 4 * i);
+ /* Manage only the interrupt that was enabled */
+ status &= readl_relaxed(info->base + IRQ_EN + 4 * i);
+- spin_unlock_irqrestore(&info->irq_lock, flags);
++ raw_spin_unlock_irqrestore(&info->irq_lock, flags);
+ while (status) {
+ u32 hwirq = ffs(status) - 1;
+ u32 virq = irq_find_mapping(d, hwirq +
+@@ -694,12 +694,12 @@ static void armada_37xx_irq_handler(struct irq_desc *desc)
+
+ update_status:
+ /* Update status in case a new IRQ appears */
+- spin_lock_irqsave(&info->irq_lock, flags);
++ raw_spin_lock_irqsave(&info->irq_lock, flags);
+ status = readl_relaxed(info->base +
+ IRQ_STATUS + 4 * i);
+ /* Manage only the interrupt that was enabled */
+ status &= readl_relaxed(info->base + IRQ_EN + 4 * i);
+- spin_unlock_irqrestore(&info->irq_lock, flags);
++ raw_spin_unlock_irqrestore(&info->irq_lock, flags);
+ }
+ }
+ chained_irq_exit(chip, desc);
+@@ -726,23 +726,13 @@ static int armada_37xx_irqchip_register(struct platform_device *pdev,
+ struct gpio_chip *gc = &info->gpio_chip;
+ struct irq_chip *irqchip = &info->irq_chip;
+ struct gpio_irq_chip *girq = &gc->irq;
++ struct device_node *np = to_of_node(gc->fwnode);
+ struct device *dev = &pdev->dev;
+- struct device_node *np;
+- int ret = -ENODEV, i, nr_irq_parent;
++ unsigned int i, nr_irq_parent;
+
+- /* Check if we have at least one gpio-controller child node */
+- for_each_child_of_node(dev->of_node, np) {
+- if (of_property_read_bool(np, "gpio-controller")) {
+- ret = 0;
+- break;
+- }
+- }
+- if (ret)
+- return dev_err_probe(dev, ret, "no gpio-controller child node\n");
++ raw_spin_lock_init(&info->irq_lock);
+
+ nr_irq_parent = of_irq_count(np);
+- spin_lock_init(&info->irq_lock);
+-
+ if (!nr_irq_parent) {
+ dev_err(dev, "invalid or no IRQ\n");
+ return 0;
+@@ -1121,25 +1111,40 @@ static const struct of_device_id armada_37xx_pinctrl_of_match[] = {
+ { },
+ };
+
++static const struct regmap_config armada_37xx_pinctrl_regmap_config = {
++ .reg_bits = 32,
++ .val_bits = 32,
++ .reg_stride = 4,
++ .use_raw_spinlock = true,
++};
++
+ static int __init armada_37xx_pinctrl_probe(struct platform_device *pdev)
+ {
+ struct armada_37xx_pinctrl *info;
+ struct device *dev = &pdev->dev;
+- struct device_node *np = dev->of_node;
+ struct regmap *regmap;
++ void __iomem *base;
+ int ret;
+
++ base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
++ if (IS_ERR(base)) {
++ dev_err(dev, "failed to ioremap base address: %pe\n", base);
++ return PTR_ERR(base);
++ }
++
++ regmap = devm_regmap_init_mmio(dev, base,
++ &armada_37xx_pinctrl_regmap_config);
++ if (IS_ERR(regmap)) {
++ dev_err(dev, "failed to create regmap: %pe\n", regmap);
++ return PTR_ERR(regmap);
++ }
++
+ info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ info->dev = dev;
+-
+- regmap = syscon_node_to_regmap(np);
+- if (IS_ERR(regmap))
+- return dev_err_probe(dev, PTR_ERR(regmap), "cannot get regmap\n");
+ info->regmap = regmap;
+-
+ info->data = of_device_get_match_data(dev);
+
+ ret = armada_37xx_pinctrl_register(pdev, info);
+diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c
+index 6a956ee94494f..6ee9f0de8ede3 100644
+--- a/drivers/pinctrl/pinctrl-ocelot.c
++++ b/drivers/pinctrl/pinctrl-ocelot.c
+@@ -28,19 +28,12 @@
+ #define ocelot_clrsetbits(addr, clear, set) \
+ writel((readl(addr) & ~(clear)) | (set), (addr))
+
+-/* PINCONFIG bits (sparx5 only) */
+ enum {
+ PINCONF_BIAS,
+ PINCONF_SCHMITT,
+ PINCONF_DRIVE_STRENGTH,
+ };
+
+-#define BIAS_PD_BIT BIT(4)
+-#define BIAS_PU_BIT BIT(3)
+-#define BIAS_BITS (BIAS_PD_BIT|BIAS_PU_BIT)
+-#define SCHMITT_BIT BIT(2)
+-#define DRIVE_BITS GENMASK(1, 0)
+-
+ /* GPIO standard registers */
+ #define OCELOT_GPIO_OUT_SET 0x0
+ #define OCELOT_GPIO_OUT_CLR 0x4
+@@ -314,6 +307,13 @@ struct ocelot_pin_caps {
+ unsigned char a_functions[OCELOT_FUNC_PER_PIN]; /* Additional functions */
+ };
+
++struct ocelot_pincfg_data {
++ u8 pd_bit;
++ u8 pu_bit;
++ u8 drive_bits;
++ u8 schmitt_bit;
++};
++
+ struct ocelot_pinctrl {
+ struct device *dev;
+ struct pinctrl_dev *pctl;
+@@ -321,10 +321,16 @@ struct ocelot_pinctrl {
+ struct regmap *map;
+ struct regmap *pincfg;
+ struct pinctrl_desc *desc;
++ const struct ocelot_pincfg_data *pincfg_data;
+ struct ocelot_pmx_func func[FUNC_MAX];
+ u8 stride;
+ };
+
++struct ocelot_match_data {
++ struct pinctrl_desc desc;
++ struct ocelot_pincfg_data pincfg_data;
++};
++
+ #define LUTON_P(p, f0, f1) \
+ static struct ocelot_pin_caps luton_pin_##p = { \
+ .pin = p, \
+@@ -1318,24 +1324,27 @@ static int ocelot_hw_get_value(struct ocelot_pinctrl *info,
+ int ret = -EOPNOTSUPP;
+
+ if (info->pincfg) {
++ const struct ocelot_pincfg_data *opd = info->pincfg_data;
+ u32 regcfg;
+
+- ret = regmap_read(info->pincfg, pin, ®cfg);
++ ret = regmap_read(info->pincfg,
++ pin * regmap_get_reg_stride(info->pincfg),
++ ®cfg);
+ if (ret)
+ return ret;
+
+ ret = 0;
+ switch (reg) {
+ case PINCONF_BIAS:
+- *val = regcfg & BIAS_BITS;
++ *val = regcfg & (opd->pd_bit | opd->pu_bit);
+ break;
+
+ case PINCONF_SCHMITT:
+- *val = regcfg & SCHMITT_BIT;
++ *val = regcfg & opd->schmitt_bit;
+ break;
+
+ case PINCONF_DRIVE_STRENGTH:
+- *val = regcfg & DRIVE_BITS;
++ *val = regcfg & opd->drive_bits;
+ break;
+
+ default:
+@@ -1352,14 +1361,18 @@ static int ocelot_pincfg_clrsetbits(struct ocelot_pinctrl *info, u32 regaddr,
+ u32 val;
+ int ret;
+
+- ret = regmap_read(info->pincfg, regaddr, &val);
++ ret = regmap_read(info->pincfg,
++ regaddr * regmap_get_reg_stride(info->pincfg),
++ &val);
+ if (ret)
+ return ret;
+
+ val &= ~clrbits;
+ val |= setbits;
+
+- ret = regmap_write(info->pincfg, regaddr, val);
++ ret = regmap_write(info->pincfg,
++ regaddr * regmap_get_reg_stride(info->pincfg),
++ val);
+
+ return ret;
+ }
+@@ -1372,23 +1385,27 @@ static int ocelot_hw_set_value(struct ocelot_pinctrl *info,
+ int ret = -EOPNOTSUPP;
+
+ if (info->pincfg) {
++ const struct ocelot_pincfg_data *opd = info->pincfg_data;
+
+ ret = 0;
+ switch (reg) {
+ case PINCONF_BIAS:
+- ret = ocelot_pincfg_clrsetbits(info, pin, BIAS_BITS,
++ ret = ocelot_pincfg_clrsetbits(info, pin,
++ opd->pd_bit | opd->pu_bit,
+ val);
+ break;
+
+ case PINCONF_SCHMITT:
+- ret = ocelot_pincfg_clrsetbits(info, pin, SCHMITT_BIT,
++ ret = ocelot_pincfg_clrsetbits(info, pin,
++ opd->schmitt_bit,
+ val);
+ break;
+
+ case PINCONF_DRIVE_STRENGTH:
+ if (val <= 3)
+ ret = ocelot_pincfg_clrsetbits(info, pin,
+- DRIVE_BITS, val);
++ opd->drive_bits,
++ val);
+ else
+ ret = -EINVAL;
+ break;
+@@ -1418,17 +1435,20 @@ static int ocelot_pinconf_get(struct pinctrl_dev *pctldev,
+ if (param == PIN_CONFIG_BIAS_DISABLE)
+ val = (val == 0);
+ else if (param == PIN_CONFIG_BIAS_PULL_DOWN)
+- val = (val & BIAS_PD_BIT ? true : false);
++ val = !!(val & info->pincfg_data->pd_bit);
+ else /* PIN_CONFIG_BIAS_PULL_UP */
+- val = (val & BIAS_PU_BIT ? true : false);
++ val = !!(val & info->pincfg_data->pu_bit);
+ break;
+
+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
++ if (!info->pincfg_data->schmitt_bit)
++ return -EOPNOTSUPP;
++
+ err = ocelot_hw_get_value(info, pin, PINCONF_SCHMITT, &val);
+ if (err)
+ return err;
+
+- val = (val & SCHMITT_BIT ? true : false);
++ val = !!(val & info->pincfg_data->schmitt_bit);
+ break;
+
+ case PIN_CONFIG_DRIVE_STRENGTH:
+@@ -1472,6 +1492,7 @@ static int ocelot_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+ unsigned long *configs, unsigned int num_configs)
+ {
+ struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
++ const struct ocelot_pincfg_data *opd = info->pincfg_data;
+ u32 param, arg, p;
+ int cfg, err = 0;
+
+@@ -1484,8 +1505,8 @@ static int ocelot_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+ case PIN_CONFIG_BIAS_PULL_UP:
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ arg = (param == PIN_CONFIG_BIAS_DISABLE) ? 0 :
+- (param == PIN_CONFIG_BIAS_PULL_UP) ? BIAS_PU_BIT :
+- BIAS_PD_BIT;
++ (param == PIN_CONFIG_BIAS_PULL_UP) ?
++ opd->pu_bit : opd->pd_bit;
+
+ err = ocelot_hw_set_value(info, pin, PINCONF_BIAS, arg);
+ if (err)
+@@ -1494,7 +1515,10 @@ static int ocelot_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+ break;
+
+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+- arg = arg ? SCHMITT_BIT : 0;
++ if (!opd->schmitt_bit)
++ return -EOPNOTSUPP;
++
++ arg = arg ? opd->schmitt_bit : 0;
+ err = ocelot_hw_set_value(info, pin, PINCONF_SCHMITT,
+ arg);
+ if (err)
+@@ -1555,69 +1579,94 @@ static const struct pinctrl_ops ocelot_pctl_ops = {
+ .dt_free_map = pinconf_generic_dt_free_map,
+ };
+
+-static struct pinctrl_desc luton_desc = {
+- .name = "luton-pinctrl",
+- .pins = luton_pins,
+- .npins = ARRAY_SIZE(luton_pins),
+- .pctlops = &ocelot_pctl_ops,
+- .pmxops = &ocelot_pmx_ops,
+- .owner = THIS_MODULE,
++static struct ocelot_match_data luton_desc = {
++ .desc = {
++ .name = "luton-pinctrl",
++ .pins = luton_pins,
++ .npins = ARRAY_SIZE(luton_pins),
++ .pctlops = &ocelot_pctl_ops,
++ .pmxops = &ocelot_pmx_ops,
++ .owner = THIS_MODULE,
++ },
+ };
+
+-static struct pinctrl_desc serval_desc = {
+- .name = "serval-pinctrl",
+- .pins = serval_pins,
+- .npins = ARRAY_SIZE(serval_pins),
+- .pctlops = &ocelot_pctl_ops,
+- .pmxops = &ocelot_pmx_ops,
+- .owner = THIS_MODULE,
++static struct ocelot_match_data serval_desc = {
++ .desc = {
++ .name = "serval-pinctrl",
++ .pins = serval_pins,
++ .npins = ARRAY_SIZE(serval_pins),
++ .pctlops = &ocelot_pctl_ops,
++ .pmxops = &ocelot_pmx_ops,
++ .owner = THIS_MODULE,
++ },
+ };
+
+-static struct pinctrl_desc ocelot_desc = {
+- .name = "ocelot-pinctrl",
+- .pins = ocelot_pins,
+- .npins = ARRAY_SIZE(ocelot_pins),
+- .pctlops = &ocelot_pctl_ops,
+- .pmxops = &ocelot_pmx_ops,
+- .owner = THIS_MODULE,
++static struct ocelot_match_data ocelot_desc = {
++ .desc = {
++ .name = "ocelot-pinctrl",
++ .pins = ocelot_pins,
++ .npins = ARRAY_SIZE(ocelot_pins),
++ .pctlops = &ocelot_pctl_ops,
++ .pmxops = &ocelot_pmx_ops,
++ .owner = THIS_MODULE,
++ },
+ };
+
+-static struct pinctrl_desc jaguar2_desc = {
+- .name = "jaguar2-pinctrl",
+- .pins = jaguar2_pins,
+- .npins = ARRAY_SIZE(jaguar2_pins),
+- .pctlops = &ocelot_pctl_ops,
+- .pmxops = &ocelot_pmx_ops,
+- .owner = THIS_MODULE,
++static struct ocelot_match_data jaguar2_desc = {
++ .desc = {
++ .name = "jaguar2-pinctrl",
++ .pins = jaguar2_pins,
++ .npins = ARRAY_SIZE(jaguar2_pins),
++ .pctlops = &ocelot_pctl_ops,
++ .pmxops = &ocelot_pmx_ops,
++ .owner = THIS_MODULE,
++ },
+ };
+
+-static struct pinctrl_desc servalt_desc = {
+- .name = "servalt-pinctrl",
+- .pins = servalt_pins,
+- .npins = ARRAY_SIZE(servalt_pins),
+- .pctlops = &ocelot_pctl_ops,
+- .pmxops = &ocelot_pmx_ops,
+- .owner = THIS_MODULE,
++static struct ocelot_match_data servalt_desc = {
++ .desc = {
++ .name = "servalt-pinctrl",
++ .pins = servalt_pins,
++ .npins = ARRAY_SIZE(servalt_pins),
++ .pctlops = &ocelot_pctl_ops,
++ .pmxops = &ocelot_pmx_ops,
++ .owner = THIS_MODULE,
++ },
+ };
+
+-static struct pinctrl_desc sparx5_desc = {
+- .name = "sparx5-pinctrl",
+- .pins = sparx5_pins,
+- .npins = ARRAY_SIZE(sparx5_pins),
+- .pctlops = &ocelot_pctl_ops,
+- .pmxops = &ocelot_pmx_ops,
+- .confops = &ocelot_confops,
+- .owner = THIS_MODULE,
++static struct ocelot_match_data sparx5_desc = {
++ .desc = {
++ .name = "sparx5-pinctrl",
++ .pins = sparx5_pins,
++ .npins = ARRAY_SIZE(sparx5_pins),
++ .pctlops = &ocelot_pctl_ops,
++ .pmxops = &ocelot_pmx_ops,
++ .confops = &ocelot_confops,
++ .owner = THIS_MODULE,
++ },
++ .pincfg_data = {
++ .pd_bit = BIT(4),
++ .pu_bit = BIT(3),
++ .drive_bits = GENMASK(1, 0),
++ .schmitt_bit = BIT(2),
++ },
+ };
+
+-static struct pinctrl_desc lan966x_desc = {
+- .name = "lan966x-pinctrl",
+- .pins = lan966x_pins,
+- .npins = ARRAY_SIZE(lan966x_pins),
+- .pctlops = &ocelot_pctl_ops,
+- .pmxops = &lan966x_pmx_ops,
+- .confops = &ocelot_confops,
+- .owner = THIS_MODULE,
++static struct ocelot_match_data lan966x_desc = {
++ .desc = {
++ .name = "lan966x-pinctrl",
++ .pins = lan966x_pins,
++ .npins = ARRAY_SIZE(lan966x_pins),
++ .pctlops = &ocelot_pctl_ops,
++ .pmxops = &lan966x_pmx_ops,
++ .confops = &ocelot_confops,
++ .owner = THIS_MODULE,
++ },
++ .pincfg_data = {
++ .pd_bit = BIT(3),
++ .pu_bit = BIT(2),
++ .drive_bits = GENMASK(1, 0),
++ },
+ };
+
+ static int ocelot_create_group_func_map(struct device *dev,
+@@ -1883,7 +1932,8 @@ static const struct of_device_id ocelot_pinctrl_of_match[] = {
+ {},
+ };
+
+-static struct regmap *ocelot_pinctrl_create_pincfg(struct platform_device *pdev)
++static struct regmap *ocelot_pinctrl_create_pincfg(struct platform_device *pdev,
++ const struct ocelot_pinctrl *info)
+ {
+ void __iomem *base;
+
+@@ -1891,7 +1941,7 @@ static struct regmap *ocelot_pinctrl_create_pincfg(struct platform_device *pdev)
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+- .max_register = 32,
++ .max_register = info->desc->npins * 4,
+ .name = "pincfg",
+ };
+
+@@ -1906,6 +1956,7 @@ static struct regmap *ocelot_pinctrl_create_pincfg(struct platform_device *pdev)
+
+ static int ocelot_pinctrl_probe(struct platform_device *pdev)
+ {
++ const struct ocelot_match_data *data;
+ struct device *dev = &pdev->dev;
+ struct ocelot_pinctrl *info;
+ struct regmap *pincfg;
+@@ -1921,7 +1972,16 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
+ if (!info)
+ return -ENOMEM;
+
+- info->desc = (struct pinctrl_desc *)device_get_match_data(dev);
++ data = device_get_match_data(dev);
++ if (!data)
++ return -EINVAL;
++
++ info->desc = devm_kmemdup(dev, &data->desc, sizeof(*info->desc),
++ GFP_KERNEL);
++ if (!info->desc)
++ return -ENOMEM;
++
++ info->pincfg_data = &data->pincfg_data;
+
+ base = devm_ioremap_resource(dev,
+ platform_get_resource(pdev, IORESOURCE_MEM, 0));
+@@ -1942,7 +2002,7 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
+
+ /* Pinconf registers */
+ if (info->desc->confops) {
+- pincfg = ocelot_pinctrl_create_pincfg(pdev);
++ pincfg = ocelot_pinctrl_create_pincfg(pdev, info);
+ if (IS_ERR(pincfg))
+ dev_dbg(dev, "Failed to create pincfg regmap\n");
+ else
+diff --git a/drivers/pinctrl/ralink/Kconfig b/drivers/pinctrl/ralink/Kconfig
+index a76ee3deb8c31..d0f0a8f2b9b7d 100644
+--- a/drivers/pinctrl/ralink/Kconfig
++++ b/drivers/pinctrl/ralink/Kconfig
+@@ -3,37 +3,33 @@ menu "Ralink pinctrl drivers"
+ depends on RALINK
+
+ config PINCTRL_RALINK
+- bool "Ralink pin control support"
+- default y if RALINK
+-
+-config PINCTRL_RT2880
+- bool "RT2880 pinctrl driver for RALINK/Mediatek SOCs"
++ bool "Ralink pinctrl driver"
+ select PINMUX
+ select GENERIC_PINCONF
+
+ config PINCTRL_MT7620
+ bool "mt7620 pinctrl driver for RALINK/Mediatek SOCs"
+ depends on RALINK && SOC_MT7620
+- select PINCTRL_RT2880
++ select PINCTRL_RALINK
+
+ config PINCTRL_MT7621
+ bool "mt7621 pinctrl driver for RALINK/Mediatek SOCs"
+ depends on RALINK && SOC_MT7621
+- select PINCTRL_RT2880
++ select PINCTRL_RALINK
+
+ config PINCTRL_RT288X
+ bool "RT288X pinctrl driver for RALINK/Mediatek SOCs"
+ depends on RALINK && SOC_RT288X
+- select PINCTRL_RT2880
++ select PINCTRL_RALINK
+
+ config PINCTRL_RT305X
+ bool "RT305X pinctrl driver for RALINK/Mediatek SOCs"
+ depends on RALINK && SOC_RT305X
+- select PINCTRL_RT2880
++ select PINCTRL_RALINK
+
+ config PINCTRL_RT3883
+ bool "RT3883 pinctrl driver for RALINK/Mediatek SOCs"
+ depends on RALINK && SOC_RT3883
+- select PINCTRL_RT2880
++ select PINCTRL_RALINK
+
+ endmenu
+diff --git a/drivers/pinctrl/ralink/Makefile b/drivers/pinctrl/ralink/Makefile
+index a15610206ced4..2c1323b74e96f 100644
+--- a/drivers/pinctrl/ralink/Makefile
++++ b/drivers/pinctrl/ralink/Makefile
+@@ -1,5 +1,5 @@
+ # SPDX-License-Identifier: GPL-2.0
+-obj-$(CONFIG_PINCTRL_RT2880) += pinctrl-rt2880.o
++obj-$(CONFIG_PINCTRL_RALINK) += pinctrl-ralink.o
+
+ obj-$(CONFIG_PINCTRL_MT7620) += pinctrl-mt7620.o
+ obj-$(CONFIG_PINCTRL_MT7621) += pinctrl-mt7621.o
+diff --git a/drivers/pinctrl/ralink/pinctrl-mt7620.c b/drivers/pinctrl/ralink/pinctrl-mt7620.c
+index 6853b5b8b0fe7..51b863d85c51e 100644
+--- a/drivers/pinctrl/ralink/pinctrl-mt7620.c
++++ b/drivers/pinctrl/ralink/pinctrl-mt7620.c
+@@ -5,7 +5,7 @@
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/of.h>
+-#include "pinmux.h"
++#include "pinctrl-ralink.h"
+
+ #define MT7620_GPIO_MODE_UART0_SHIFT 2
+ #define MT7620_GPIO_MODE_UART0_MASK 0x7
+@@ -54,20 +54,20 @@
+ #define MT7620_GPIO_MODE_EPHY 15
+ #define MT7620_GPIO_MODE_PA 20
+
+-static struct rt2880_pmx_func i2c_grp[] = { FUNC("i2c", 0, 1, 2) };
+-static struct rt2880_pmx_func spi_grp[] = { FUNC("spi", 0, 3, 4) };
+-static struct rt2880_pmx_func uartlite_grp[] = { FUNC("uartlite", 0, 15, 2) };
+-static struct rt2880_pmx_func mdio_grp[] = {
++static struct ralink_pmx_func i2c_grp[] = { FUNC("i2c", 0, 1, 2) };
++static struct ralink_pmx_func spi_grp[] = { FUNC("spi", 0, 3, 4) };
++static struct ralink_pmx_func uartlite_grp[] = { FUNC("uartlite", 0, 15, 2) };
++static struct ralink_pmx_func mdio_grp[] = {
+ FUNC("mdio", MT7620_GPIO_MODE_MDIO, 22, 2),
+ FUNC("refclk", MT7620_GPIO_MODE_MDIO_REFCLK, 22, 2),
+ };
+-static struct rt2880_pmx_func rgmii1_grp[] = { FUNC("rgmii1", 0, 24, 12) };
+-static struct rt2880_pmx_func refclk_grp[] = { FUNC("spi refclk", 0, 37, 3) };
+-static struct rt2880_pmx_func ephy_grp[] = { FUNC("ephy", 0, 40, 5) };
+-static struct rt2880_pmx_func rgmii2_grp[] = { FUNC("rgmii2", 0, 60, 12) };
+-static struct rt2880_pmx_func wled_grp[] = { FUNC("wled", 0, 72, 1) };
+-static struct rt2880_pmx_func pa_grp[] = { FUNC("pa", 0, 18, 4) };
+-static struct rt2880_pmx_func uartf_grp[] = {
++static struct ralink_pmx_func rgmii1_grp[] = { FUNC("rgmii1", 0, 24, 12) };
++static struct ralink_pmx_func refclk_grp[] = { FUNC("spi refclk", 0, 37, 3) };
++static struct ralink_pmx_func ephy_grp[] = { FUNC("ephy", 0, 40, 5) };
++static struct ralink_pmx_func rgmii2_grp[] = { FUNC("rgmii2", 0, 60, 12) };
++static struct ralink_pmx_func wled_grp[] = { FUNC("wled", 0, 72, 1) };
++static struct ralink_pmx_func pa_grp[] = { FUNC("pa", 0, 18, 4) };
++static struct ralink_pmx_func uartf_grp[] = {
+ FUNC("uartf", MT7620_GPIO_MODE_UARTF, 7, 8),
+ FUNC("pcm uartf", MT7620_GPIO_MODE_PCM_UARTF, 7, 8),
+ FUNC("pcm i2s", MT7620_GPIO_MODE_PCM_I2S, 7, 8),
+@@ -76,20 +76,20 @@ static struct rt2880_pmx_func uartf_grp[] = {
+ FUNC("gpio uartf", MT7620_GPIO_MODE_GPIO_UARTF, 7, 4),
+ FUNC("gpio i2s", MT7620_GPIO_MODE_GPIO_I2S, 7, 4),
+ };
+-static struct rt2880_pmx_func wdt_grp[] = {
++static struct ralink_pmx_func wdt_grp[] = {
+ FUNC("wdt rst", 0, 17, 1),
+ FUNC("wdt refclk", 0, 17, 1),
+ };
+-static struct rt2880_pmx_func pcie_rst_grp[] = {
++static struct ralink_pmx_func pcie_rst_grp[] = {
+ FUNC("pcie rst", MT7620_GPIO_MODE_PCIE_RST, 36, 1),
+ FUNC("pcie refclk", MT7620_GPIO_MODE_PCIE_REF, 36, 1)
+ };
+-static struct rt2880_pmx_func nd_sd_grp[] = {
++static struct ralink_pmx_func nd_sd_grp[] = {
+ FUNC("nand", MT7620_GPIO_MODE_NAND, 45, 15),
+ FUNC("sd", MT7620_GPIO_MODE_SD, 47, 13)
+ };
+
+-static struct rt2880_pmx_group mt7620a_pinmux_data[] = {
++static struct ralink_pmx_group mt7620a_pinmux_data[] = {
+ GRP("i2c", i2c_grp, 1, MT7620_GPIO_MODE_I2C),
+ GRP("uartf", uartf_grp, MT7620_GPIO_MODE_UART0_MASK,
+ MT7620_GPIO_MODE_UART0_SHIFT),
+@@ -112,262 +112,262 @@ static struct rt2880_pmx_group mt7620a_pinmux_data[] = {
+ { 0 }
+ };
+
+-static struct rt2880_pmx_func pwm1_grp_mt7628[] = {
++static struct ralink_pmx_func pwm1_grp_mt76x8[] = {
+ FUNC("sdxc d6", 3, 19, 1),
+ FUNC("utif", 2, 19, 1),
+ FUNC("gpio", 1, 19, 1),
+ FUNC("pwm1", 0, 19, 1),
+ };
+
+-static struct rt2880_pmx_func pwm0_grp_mt7628[] = {
++static struct ralink_pmx_func pwm0_grp_mt76x8[] = {
+ FUNC("sdxc d7", 3, 18, 1),
+ FUNC("utif", 2, 18, 1),
+ FUNC("gpio", 1, 18, 1),
+ FUNC("pwm0", 0, 18, 1),
+ };
+
+-static struct rt2880_pmx_func uart2_grp_mt7628[] = {
++static struct ralink_pmx_func uart2_grp_mt76x8[] = {
+ FUNC("sdxc d5 d4", 3, 20, 2),
+ FUNC("pwm", 2, 20, 2),
+ FUNC("gpio", 1, 20, 2),
+ FUNC("uart2", 0, 20, 2),
+ };
+
+-static struct rt2880_pmx_func uart1_grp_mt7628[] = {
++static struct ralink_pmx_func uart1_grp_mt76x8[] = {
+ FUNC("sw_r", 3, 45, 2),
+ FUNC("pwm", 2, 45, 2),
+ FUNC("gpio", 1, 45, 2),
+ FUNC("uart1", 0, 45, 2),
+ };
+
+-static struct rt2880_pmx_func i2c_grp_mt7628[] = {
++static struct ralink_pmx_func i2c_grp_mt76x8[] = {
+ FUNC("-", 3, 4, 2),
+ FUNC("debug", 2, 4, 2),
+ FUNC("gpio", 1, 4, 2),
+ FUNC("i2c", 0, 4, 2),
+ };
+
+-static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("refclk", 0, 37, 1) };
+-static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 36, 1) };
+-static struct rt2880_pmx_func wdt_grp_mt7628[] = { FUNC("wdt", 0, 38, 1) };
+-static struct rt2880_pmx_func spi_grp_mt7628[] = { FUNC("spi", 0, 7, 4) };
++static struct ralink_pmx_func refclk_grp_mt76x8[] = { FUNC("refclk", 0, 37, 1) };
++static struct ralink_pmx_func perst_grp_mt76x8[] = { FUNC("perst", 0, 36, 1) };
++static struct ralink_pmx_func wdt_grp_mt76x8[] = { FUNC("wdt", 0, 38, 1) };
++static struct ralink_pmx_func spi_grp_mt76x8[] = { FUNC("spi", 0, 7, 4) };
+
+-static struct rt2880_pmx_func sd_mode_grp_mt7628[] = {
++static struct ralink_pmx_func sd_mode_grp_mt76x8[] = {
+ FUNC("jtag", 3, 22, 8),
+ FUNC("utif", 2, 22, 8),
+ FUNC("gpio", 1, 22, 8),
+ FUNC("sdxc", 0, 22, 8),
+ };
+
+-static struct rt2880_pmx_func uart0_grp_mt7628[] = {
++static struct ralink_pmx_func uart0_grp_mt76x8[] = {
+ FUNC("-", 3, 12, 2),
+ FUNC("-", 2, 12, 2),
+ FUNC("gpio", 1, 12, 2),
+ FUNC("uart0", 0, 12, 2),
+ };
+
+-static struct rt2880_pmx_func i2s_grp_mt7628[] = {
++static struct ralink_pmx_func i2s_grp_mt76x8[] = {
+ FUNC("antenna", 3, 0, 4),
+ FUNC("pcm", 2, 0, 4),
+ FUNC("gpio", 1, 0, 4),
+ FUNC("i2s", 0, 0, 4),
+ };
+
+-static struct rt2880_pmx_func spi_cs1_grp_mt7628[] = {
++static struct ralink_pmx_func spi_cs1_grp_mt76x8[] = {
+ FUNC("-", 3, 6, 1),
+ FUNC("refclk", 2, 6, 1),
+ FUNC("gpio", 1, 6, 1),
+ FUNC("spi cs1", 0, 6, 1),
+ };
+
+-static struct rt2880_pmx_func spis_grp_mt7628[] = {
++static struct ralink_pmx_func spis_grp_mt76x8[] = {
+ FUNC("pwm_uart2", 3, 14, 4),
+ FUNC("utif", 2, 14, 4),
+ FUNC("gpio", 1, 14, 4),
+ FUNC("spis", 0, 14, 4),
+ };
+
+-static struct rt2880_pmx_func gpio_grp_mt7628[] = {
++static struct ralink_pmx_func gpio_grp_mt76x8[] = {
+ FUNC("pcie", 3, 11, 1),
+ FUNC("refclk", 2, 11, 1),
+ FUNC("gpio", 1, 11, 1),
+ FUNC("gpio", 0, 11, 1),
+ };
+
+-static struct rt2880_pmx_func p4led_kn_grp_mt7628[] = {
++static struct ralink_pmx_func p4led_kn_grp_mt76x8[] = {
+ FUNC("jtag", 3, 30, 1),
+ FUNC("utif", 2, 30, 1),
+ FUNC("gpio", 1, 30, 1),
+ FUNC("p4led_kn", 0, 30, 1),
+ };
+
+-static struct rt2880_pmx_func p3led_kn_grp_mt7628[] = {
++static struct ralink_pmx_func p3led_kn_grp_mt76x8[] = {
+ FUNC("jtag", 3, 31, 1),
+ FUNC("utif", 2, 31, 1),
+ FUNC("gpio", 1, 31, 1),
+ FUNC("p3led_kn", 0, 31, 1),
+ };
+
+-static struct rt2880_pmx_func p2led_kn_grp_mt7628[] = {
++static struct ralink_pmx_func p2led_kn_grp_mt76x8[] = {
+ FUNC("jtag", 3, 32, 1),
+ FUNC("utif", 2, 32, 1),
+ FUNC("gpio", 1, 32, 1),
+ FUNC("p2led_kn", 0, 32, 1),
+ };
+
+-static struct rt2880_pmx_func p1led_kn_grp_mt7628[] = {
++static struct ralink_pmx_func p1led_kn_grp_mt76x8[] = {
+ FUNC("jtag", 3, 33, 1),
+ FUNC("utif", 2, 33, 1),
+ FUNC("gpio", 1, 33, 1),
+ FUNC("p1led_kn", 0, 33, 1),
+ };
+
+-static struct rt2880_pmx_func p0led_kn_grp_mt7628[] = {
++static struct ralink_pmx_func p0led_kn_grp_mt76x8[] = {
+ FUNC("jtag", 3, 34, 1),
+ FUNC("rsvd", 2, 34, 1),
+ FUNC("gpio", 1, 34, 1),
+ FUNC("p0led_kn", 0, 34, 1),
+ };
+
+-static struct rt2880_pmx_func wled_kn_grp_mt7628[] = {
++static struct ralink_pmx_func wled_kn_grp_mt76x8[] = {
+ FUNC("rsvd", 3, 35, 1),
+ FUNC("rsvd", 2, 35, 1),
+ FUNC("gpio", 1, 35, 1),
+ FUNC("wled_kn", 0, 35, 1),
+ };
+
+-static struct rt2880_pmx_func p4led_an_grp_mt7628[] = {
++static struct ralink_pmx_func p4led_an_grp_mt76x8[] = {
+ FUNC("jtag", 3, 39, 1),
+ FUNC("utif", 2, 39, 1),
+ FUNC("gpio", 1, 39, 1),
+ FUNC("p4led_an", 0, 39, 1),
+ };
+
+-static struct rt2880_pmx_func p3led_an_grp_mt7628[] = {
++static struct ralink_pmx_func p3led_an_grp_mt76x8[] = {
+ FUNC("jtag", 3, 40, 1),
+ FUNC("utif", 2, 40, 1),
+ FUNC("gpio", 1, 40, 1),
+ FUNC("p3led_an", 0, 40, 1),
+ };
+
+-static struct rt2880_pmx_func p2led_an_grp_mt7628[] = {
++static struct ralink_pmx_func p2led_an_grp_mt76x8[] = {
+ FUNC("jtag", 3, 41, 1),
+ FUNC("utif", 2, 41, 1),
+ FUNC("gpio", 1, 41, 1),
+ FUNC("p2led_an", 0, 41, 1),
+ };
+
+-static struct rt2880_pmx_func p1led_an_grp_mt7628[] = {
++static struct ralink_pmx_func p1led_an_grp_mt76x8[] = {
+ FUNC("jtag", 3, 42, 1),
+ FUNC("utif", 2, 42, 1),
+ FUNC("gpio", 1, 42, 1),
+ FUNC("p1led_an", 0, 42, 1),
+ };
+
+-static struct rt2880_pmx_func p0led_an_grp_mt7628[] = {
++static struct ralink_pmx_func p0led_an_grp_mt76x8[] = {
+ FUNC("jtag", 3, 43, 1),
+ FUNC("rsvd", 2, 43, 1),
+ FUNC("gpio", 1, 43, 1),
+ FUNC("p0led_an", 0, 43, 1),
+ };
+
+-static struct rt2880_pmx_func wled_an_grp_mt7628[] = {
++static struct ralink_pmx_func wled_an_grp_mt76x8[] = {
+ FUNC("rsvd", 3, 44, 1),
+ FUNC("rsvd", 2, 44, 1),
+ FUNC("gpio", 1, 44, 1),
+ FUNC("wled_an", 0, 44, 1),
+ };
+
+-#define MT7628_GPIO_MODE_MASK 0x3
+-
+-#define MT7628_GPIO_MODE_P4LED_KN 58
+-#define MT7628_GPIO_MODE_P3LED_KN 56
+-#define MT7628_GPIO_MODE_P2LED_KN 54
+-#define MT7628_GPIO_MODE_P1LED_KN 52
+-#define MT7628_GPIO_MODE_P0LED_KN 50
+-#define MT7628_GPIO_MODE_WLED_KN 48
+-#define MT7628_GPIO_MODE_P4LED_AN 42
+-#define MT7628_GPIO_MODE_P3LED_AN 40
+-#define MT7628_GPIO_MODE_P2LED_AN 38
+-#define MT7628_GPIO_MODE_P1LED_AN 36
+-#define MT7628_GPIO_MODE_P0LED_AN 34
+-#define MT7628_GPIO_MODE_WLED_AN 32
+-#define MT7628_GPIO_MODE_PWM1 30
+-#define MT7628_GPIO_MODE_PWM0 28
+-#define MT7628_GPIO_MODE_UART2 26
+-#define MT7628_GPIO_MODE_UART1 24
+-#define MT7628_GPIO_MODE_I2C 20
+-#define MT7628_GPIO_MODE_REFCLK 18
+-#define MT7628_GPIO_MODE_PERST 16
+-#define MT7628_GPIO_MODE_WDT 14
+-#define MT7628_GPIO_MODE_SPI 12
+-#define MT7628_GPIO_MODE_SDMODE 10
+-#define MT7628_GPIO_MODE_UART0 8
+-#define MT7628_GPIO_MODE_I2S 6
+-#define MT7628_GPIO_MODE_CS1 4
+-#define MT7628_GPIO_MODE_SPIS 2
+-#define MT7628_GPIO_MODE_GPIO 0
+-
+-static struct rt2880_pmx_group mt7628an_pinmux_data[] = {
+- GRP_G("pwm1", pwm1_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_PWM1),
+- GRP_G("pwm0", pwm0_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_PWM0),
+- GRP_G("uart2", uart2_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_UART2),
+- GRP_G("uart1", uart1_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_UART1),
+- GRP_G("i2c", i2c_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_I2C),
+- GRP("refclk", refclk_grp_mt7628, 1, MT7628_GPIO_MODE_REFCLK),
+- GRP("perst", perst_grp_mt7628, 1, MT7628_GPIO_MODE_PERST),
+- GRP("wdt", wdt_grp_mt7628, 1, MT7628_GPIO_MODE_WDT),
+- GRP("spi", spi_grp_mt7628, 1, MT7628_GPIO_MODE_SPI),
+- GRP_G("sdmode", sd_mode_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_SDMODE),
+- GRP_G("uart0", uart0_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_UART0),
+- GRP_G("i2s", i2s_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_I2S),
+- GRP_G("spi cs1", spi_cs1_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_CS1),
+- GRP_G("spis", spis_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_SPIS),
+- GRP_G("gpio", gpio_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_GPIO),
+- GRP_G("wled_an", wled_an_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_WLED_AN),
+- GRP_G("p0led_an", p0led_an_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_P0LED_AN),
+- GRP_G("p1led_an", p1led_an_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_P1LED_AN),
+- GRP_G("p2led_an", p2led_an_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_P2LED_AN),
+- GRP_G("p3led_an", p3led_an_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_P3LED_AN),
+- GRP_G("p4led_an", p4led_an_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_P4LED_AN),
+- GRP_G("wled_kn", wled_kn_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_WLED_KN),
+- GRP_G("p0led_kn", p0led_kn_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_P0LED_KN),
+- GRP_G("p1led_kn", p1led_kn_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_P1LED_KN),
+- GRP_G("p2led_kn", p2led_kn_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_P2LED_KN),
+- GRP_G("p3led_kn", p3led_kn_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_P3LED_KN),
+- GRP_G("p4led_kn", p4led_kn_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_P4LED_KN),
++#define MT76X8_GPIO_MODE_MASK 0x3
++
++#define MT76X8_GPIO_MODE_P4LED_KN 58
++#define MT76X8_GPIO_MODE_P3LED_KN 56
++#define MT76X8_GPIO_MODE_P2LED_KN 54
++#define MT76X8_GPIO_MODE_P1LED_KN 52
++#define MT76X8_GPIO_MODE_P0LED_KN 50
++#define MT76X8_GPIO_MODE_WLED_KN 48
++#define MT76X8_GPIO_MODE_P4LED_AN 42
++#define MT76X8_GPIO_MODE_P3LED_AN 40
++#define MT76X8_GPIO_MODE_P2LED_AN 38
++#define MT76X8_GPIO_MODE_P1LED_AN 36
++#define MT76X8_GPIO_MODE_P0LED_AN 34
++#define MT76X8_GPIO_MODE_WLED_AN 32
++#define MT76X8_GPIO_MODE_PWM1 30
++#define MT76X8_GPIO_MODE_PWM0 28
++#define MT76X8_GPIO_MODE_UART2 26
++#define MT76X8_GPIO_MODE_UART1 24
++#define MT76X8_GPIO_MODE_I2C 20
++#define MT76X8_GPIO_MODE_REFCLK 18
++#define MT76X8_GPIO_MODE_PERST 16
++#define MT76X8_GPIO_MODE_WDT 14
++#define MT76X8_GPIO_MODE_SPI 12
++#define MT76X8_GPIO_MODE_SDMODE 10
++#define MT76X8_GPIO_MODE_UART0 8
++#define MT76X8_GPIO_MODE_I2S 6
++#define MT76X8_GPIO_MODE_CS1 4
++#define MT76X8_GPIO_MODE_SPIS 2
++#define MT76X8_GPIO_MODE_GPIO 0
++
++static struct ralink_pmx_group mt76x8_pinmux_data[] = {
++ GRP_G("pwm1", pwm1_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_PWM1),
++ GRP_G("pwm0", pwm0_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_PWM0),
++ GRP_G("uart2", uart2_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_UART2),
++ GRP_G("uart1", uart1_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_UART1),
++ GRP_G("i2c", i2c_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_I2C),
++ GRP("refclk", refclk_grp_mt76x8, 1, MT76X8_GPIO_MODE_REFCLK),
++ GRP("perst", perst_grp_mt76x8, 1, MT76X8_GPIO_MODE_PERST),
++ GRP("wdt", wdt_grp_mt76x8, 1, MT76X8_GPIO_MODE_WDT),
++ GRP("spi", spi_grp_mt76x8, 1, MT76X8_GPIO_MODE_SPI),
++ GRP_G("sdmode", sd_mode_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_SDMODE),
++ GRP_G("uart0", uart0_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_UART0),
++ GRP_G("i2s", i2s_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_I2S),
++ GRP_G("spi cs1", spi_cs1_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_CS1),
++ GRP_G("spis", spis_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_SPIS),
++ GRP_G("gpio", gpio_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_GPIO),
++ GRP_G("wled_an", wled_an_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_WLED_AN),
++ GRP_G("p0led_an", p0led_an_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_P0LED_AN),
++ GRP_G("p1led_an", p1led_an_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_P1LED_AN),
++ GRP_G("p2led_an", p2led_an_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_P2LED_AN),
++ GRP_G("p3led_an", p3led_an_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_P3LED_AN),
++ GRP_G("p4led_an", p4led_an_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_P4LED_AN),
++ GRP_G("wled_kn", wled_kn_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_WLED_KN),
++ GRP_G("p0led_kn", p0led_kn_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_P0LED_KN),
++ GRP_G("p1led_kn", p1led_kn_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_P1LED_KN),
++ GRP_G("p2led_kn", p2led_kn_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_P2LED_KN),
++ GRP_G("p3led_kn", p3led_kn_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_P3LED_KN),
++ GRP_G("p4led_kn", p4led_kn_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_P4LED_KN),
+ { 0 }
+ };
+
+ static int mt7620_pinmux_probe(struct platform_device *pdev)
+ {
+ if (is_mt76x8())
+- return rt2880_pinmux_init(pdev, mt7628an_pinmux_data);
++ return ralink_pinmux_init(pdev, mt76x8_pinmux_data);
+ else
+- return rt2880_pinmux_init(pdev, mt7620a_pinmux_data);
++ return ralink_pinmux_init(pdev, mt7620a_pinmux_data);
+ }
+
+ static const struct of_device_id mt7620_pinmux_match[] = {
+diff --git a/drivers/pinctrl/ralink/pinctrl-mt7621.c b/drivers/pinctrl/ralink/pinctrl-mt7621.c
+index 7d96144c474e7..14b89cb43d4cb 100644
+--- a/drivers/pinctrl/ralink/pinctrl-mt7621.c
++++ b/drivers/pinctrl/ralink/pinctrl-mt7621.c
+@@ -3,7 +3,7 @@
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/of.h>
+-#include "pinmux.h"
++#include "pinctrl-ralink.h"
+
+ #define MT7621_GPIO_MODE_UART1 1
+ #define MT7621_GPIO_MODE_I2C 2
+@@ -34,40 +34,40 @@
+ #define MT7621_GPIO_MODE_SDHCI_SHIFT 18
+ #define MT7621_GPIO_MODE_SDHCI_GPIO 1
+
+-static struct rt2880_pmx_func uart1_grp[] = { FUNC("uart1", 0, 1, 2) };
+-static struct rt2880_pmx_func i2c_grp[] = { FUNC("i2c", 0, 3, 2) };
+-static struct rt2880_pmx_func uart3_grp[] = {
++static struct ralink_pmx_func uart1_grp[] = { FUNC("uart1", 0, 1, 2) };
++static struct ralink_pmx_func i2c_grp[] = { FUNC("i2c", 0, 3, 2) };
++static struct ralink_pmx_func uart3_grp[] = {
+ FUNC("uart3", 0, 5, 4),
+ FUNC("i2s", 2, 5, 4),
+ FUNC("spdif3", 3, 5, 4),
+ };
+-static struct rt2880_pmx_func uart2_grp[] = {
++static struct ralink_pmx_func uart2_grp[] = {
+ FUNC("uart2", 0, 9, 4),
+ FUNC("pcm", 2, 9, 4),
+ FUNC("spdif2", 3, 9, 4),
+ };
+-static struct rt2880_pmx_func jtag_grp[] = { FUNC("jtag", 0, 13, 5) };
+-static struct rt2880_pmx_func wdt_grp[] = {
++static struct ralink_pmx_func jtag_grp[] = { FUNC("jtag", 0, 13, 5) };
++static struct ralink_pmx_func wdt_grp[] = {
+ FUNC("wdt rst", 0, 18, 1),
+ FUNC("wdt refclk", 2, 18, 1),
+ };
+-static struct rt2880_pmx_func pcie_rst_grp[] = {
++static struct ralink_pmx_func pcie_rst_grp[] = {
+ FUNC("pcie rst", MT7621_GPIO_MODE_PCIE_RST, 19, 1),
+ FUNC("pcie refclk", MT7621_GPIO_MODE_PCIE_REF, 19, 1)
+ };
+-static struct rt2880_pmx_func mdio_grp[] = { FUNC("mdio", 0, 20, 2) };
+-static struct rt2880_pmx_func rgmii2_grp[] = { FUNC("rgmii2", 0, 22, 12) };
+-static struct rt2880_pmx_func spi_grp[] = {
++static struct ralink_pmx_func mdio_grp[] = { FUNC("mdio", 0, 20, 2) };
++static struct ralink_pmx_func rgmii2_grp[] = { FUNC("rgmii2", 0, 22, 12) };
++static struct ralink_pmx_func spi_grp[] = {
+ FUNC("spi", 0, 34, 7),
+ FUNC("nand1", 2, 34, 7),
+ };
+-static struct rt2880_pmx_func sdhci_grp[] = {
++static struct ralink_pmx_func sdhci_grp[] = {
+ FUNC("sdhci", 0, 41, 8),
+ FUNC("nand2", 2, 41, 8),
+ };
+-static struct rt2880_pmx_func rgmii1_grp[] = { FUNC("rgmii1", 0, 49, 12) };
++static struct ralink_pmx_func rgmii1_grp[] = { FUNC("rgmii1", 0, 49, 12) };
+
+-static struct rt2880_pmx_group mt7621_pinmux_data[] = {
++static struct ralink_pmx_group mt7621_pinmux_data[] = {
+ GRP("uart1", uart1_grp, 1, MT7621_GPIO_MODE_UART1),
+ GRP("i2c", i2c_grp, 1, MT7621_GPIO_MODE_I2C),
+ GRP_G("uart3", uart3_grp, MT7621_GPIO_MODE_UART3_MASK,
+@@ -92,7 +92,7 @@ static struct rt2880_pmx_group mt7621_pinmux_data[] = {
+
+ static int mt7621_pinmux_probe(struct platform_device *pdev)
+ {
+- return rt2880_pinmux_init(pdev, mt7621_pinmux_data);
++ return ralink_pinmux_init(pdev, mt7621_pinmux_data);
+ }
+
+ static const struct of_device_id mt7621_pinmux_match[] = {
+diff --git a/drivers/pinctrl/ralink/pinctrl-ralink.c b/drivers/pinctrl/ralink/pinctrl-ralink.c
+new file mode 100644
+index 0000000000000..3a8268a43d74a
+--- /dev/null
++++ b/drivers/pinctrl/ralink/pinctrl-ralink.c
+@@ -0,0 +1,351 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
++ */
++
++#include <linux/module.h>
++#include <linux/device.h>
++#include <linux/io.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <linux/of.h>
++#include <linux/pinctrl/pinctrl.h>
++#include <linux/pinctrl/pinconf.h>
++#include <linux/pinctrl/pinconf-generic.h>
++#include <linux/pinctrl/pinmux.h>
++#include <linux/pinctrl/consumer.h>
++#include <linux/pinctrl/machine.h>
++
++#include <asm/mach-ralink/ralink_regs.h>
++#include <asm/mach-ralink/mt7620.h>
++
++#include "pinctrl-ralink.h"
++#include "../core.h"
++#include "../pinctrl-utils.h"
++
++#define SYSC_REG_GPIO_MODE 0x60
++#define SYSC_REG_GPIO_MODE2 0x64
++
++struct ralink_priv {
++ struct device *dev;
++
++ struct pinctrl_pin_desc *pads;
++ struct pinctrl_desc *desc;
++
++ struct ralink_pmx_func **func;
++ int func_count;
++
++ struct ralink_pmx_group *groups;
++ const char **group_names;
++ int group_count;
++
++ u8 *gpio;
++ int max_pins;
++};
++
++static int ralink_get_group_count(struct pinctrl_dev *pctrldev)
++{
++ struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++
++ return p->group_count;
++}
++
++static const char *ralink_get_group_name(struct pinctrl_dev *pctrldev,
++ unsigned int group)
++{
++ struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++
++ return (group >= p->group_count) ? NULL : p->group_names[group];
++}
++
++static int ralink_get_group_pins(struct pinctrl_dev *pctrldev,
++ unsigned int group,
++ const unsigned int **pins,
++ unsigned int *num_pins)
++{
++ struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++
++ if (group >= p->group_count)
++ return -EINVAL;
++
++ *pins = p->groups[group].func[0].pins;
++ *num_pins = p->groups[group].func[0].pin_count;
++
++ return 0;
++}
++
++static const struct pinctrl_ops ralink_pctrl_ops = {
++ .get_groups_count = ralink_get_group_count,
++ .get_group_name = ralink_get_group_name,
++ .get_group_pins = ralink_get_group_pins,
++ .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
++ .dt_free_map = pinconf_generic_dt_free_map,
++};
++
++static int ralink_pmx_func_count(struct pinctrl_dev *pctrldev)
++{
++ struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++
++ return p->func_count;
++}
++
++static const char *ralink_pmx_func_name(struct pinctrl_dev *pctrldev,
++ unsigned int func)
++{
++ struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++
++ return p->func[func]->name;
++}
++
++static int ralink_pmx_group_get_groups(struct pinctrl_dev *pctrldev,
++ unsigned int func,
++ const char * const **groups,
++ unsigned int * const num_groups)
++{
++ struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++
++ if (p->func[func]->group_count == 1)
++ *groups = &p->group_names[p->func[func]->groups[0]];
++ else
++ *groups = p->group_names;
++
++ *num_groups = p->func[func]->group_count;
++
++ return 0;
++}
++
++static int ralink_pmx_group_enable(struct pinctrl_dev *pctrldev,
++ unsigned int func, unsigned int group)
++{
++ struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++ u32 mode = 0;
++ u32 reg = SYSC_REG_GPIO_MODE;
++ int i;
++ int shift;
++
++ /* dont allow double use */
++ if (p->groups[group].enabled) {
++ dev_err(p->dev, "%s is already enabled\n",
++ p->groups[group].name);
++ return 0;
++ }
++
++ p->groups[group].enabled = 1;
++ p->func[func]->enabled = 1;
++
++ shift = p->groups[group].shift;
++ if (shift >= 32) {
++ shift -= 32;
++ reg = SYSC_REG_GPIO_MODE2;
++ }
++ mode = rt_sysc_r32(reg);
++ mode &= ~(p->groups[group].mask << shift);
++
++ /* mark the pins as gpio */
++ for (i = 0; i < p->groups[group].func[0].pin_count; i++)
++ p->gpio[p->groups[group].func[0].pins[i]] = 1;
++
++ /* function 0 is gpio and needs special handling */
++ if (func == 0) {
++ mode |= p->groups[group].gpio << shift;
++ } else {
++ for (i = 0; i < p->func[func]->pin_count; i++)
++ p->gpio[p->func[func]->pins[i]] = 0;
++ mode |= p->func[func]->value << shift;
++ }
++ rt_sysc_w32(mode, reg);
++
++ return 0;
++}
++
++static int ralink_pmx_group_gpio_request_enable(struct pinctrl_dev *pctrldev,
++ struct pinctrl_gpio_range *range,
++ unsigned int pin)
++{
++ struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++
++ if (!p->gpio[pin]) {
++ dev_err(p->dev, "pin %d is not set to gpio mux\n", pin);
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static const struct pinmux_ops ralink_pmx_group_ops = {
++ .get_functions_count = ralink_pmx_func_count,
++ .get_function_name = ralink_pmx_func_name,
++ .get_function_groups = ralink_pmx_group_get_groups,
++ .set_mux = ralink_pmx_group_enable,
++ .gpio_request_enable = ralink_pmx_group_gpio_request_enable,
++};
++
++static struct pinctrl_desc ralink_pctrl_desc = {
++ .owner = THIS_MODULE,
++ .name = "ralink-pinmux",
++ .pctlops = &ralink_pctrl_ops,
++ .pmxops = &ralink_pmx_group_ops,
++};
++
++static struct ralink_pmx_func gpio_func = {
++ .name = "gpio",
++};
++
++static int ralink_pinmux_index(struct ralink_priv *p)
++{
++ struct ralink_pmx_group *mux = p->groups;
++ int i, j, c = 0;
++
++ /* count the mux functions */
++ while (mux->name) {
++ p->group_count++;
++ mux++;
++ }
++
++ /* allocate the group names array needed by the gpio function */
++ p->group_names = devm_kcalloc(p->dev, p->group_count,
++ sizeof(char *), GFP_KERNEL);
++ if (!p->group_names)
++ return -ENOMEM;
++
++ for (i = 0; i < p->group_count; i++) {
++ p->group_names[i] = p->groups[i].name;
++ p->func_count += p->groups[i].func_count;
++ }
++
++ /* we have a dummy function[0] for gpio */
++ p->func_count++;
++
++ /* allocate our function and group mapping index buffers */
++ p->func = devm_kcalloc(p->dev, p->func_count,
++ sizeof(*p->func), GFP_KERNEL);
++ gpio_func.groups = devm_kcalloc(p->dev, p->group_count, sizeof(int),
++ GFP_KERNEL);
++ if (!p->func || !gpio_func.groups)
++ return -ENOMEM;
++
++ /* add a backpointer to the function so it knows its group */
++ gpio_func.group_count = p->group_count;
++ for (i = 0; i < gpio_func.group_count; i++)
++ gpio_func.groups[i] = i;
++
++ p->func[c] = &gpio_func;
++ c++;
++
++ /* add remaining functions */
++ for (i = 0; i < p->group_count; i++) {
++ for (j = 0; j < p->groups[i].func_count; j++) {
++ p->func[c] = &p->groups[i].func[j];
++ p->func[c]->groups = devm_kzalloc(p->dev, sizeof(int),
++ GFP_KERNEL);
++ if (!p->func[c]->groups)
++ return -ENOMEM;
++ p->func[c]->groups[0] = i;
++ p->func[c]->group_count = 1;
++ c++;
++ }
++ }
++ return 0;
++}
++
++static int ralink_pinmux_pins(struct ralink_priv *p)
++{
++ int i, j;
++
++ /*
++ * loop over the functions and initialize the pins array.
++ * also work out the highest pin used.
++ */
++ for (i = 0; i < p->func_count; i++) {
++ int pin;
++
++ if (!p->func[i]->pin_count)
++ continue;
++
++ p->func[i]->pins = devm_kcalloc(p->dev,
++ p->func[i]->pin_count,
++ sizeof(int),
++ GFP_KERNEL);
++ if (!p->func[i]->pins)
++ return -ENOMEM;
++ for (j = 0; j < p->func[i]->pin_count; j++)
++ p->func[i]->pins[j] = p->func[i]->pin_first + j;
++
++ pin = p->func[i]->pin_first + p->func[i]->pin_count;
++ if (pin > p->max_pins)
++ p->max_pins = pin;
++ }
++
++ /* the buffer that tells us which pins are gpio */
++ p->gpio = devm_kcalloc(p->dev, p->max_pins, sizeof(u8), GFP_KERNEL);
++ /* the pads needed to tell pinctrl about our pins */
++ p->pads = devm_kcalloc(p->dev, p->max_pins,
++ sizeof(struct pinctrl_pin_desc), GFP_KERNEL);
++ if (!p->pads || !p->gpio)
++ return -ENOMEM;
++
++ memset(p->gpio, 1, sizeof(u8) * p->max_pins);
++ for (i = 0; i < p->func_count; i++) {
++ if (!p->func[i]->pin_count)
++ continue;
++
++ for (j = 0; j < p->func[i]->pin_count; j++)
++ p->gpio[p->func[i]->pins[j]] = 0;
++ }
++
++ /* pin 0 is always a gpio */
++ p->gpio[0] = 1;
++
++ /* set the pads */
++ for (i = 0; i < p->max_pins; i++) {
++ /* strlen("ioXY") + 1 = 5 */
++ char *name = devm_kzalloc(p->dev, 5, GFP_KERNEL);
++
++ if (!name)
++ return -ENOMEM;
++ snprintf(name, 5, "io%d", i);
++ p->pads[i].number = i;
++ p->pads[i].name = name;
++ }
++ p->desc->pins = p->pads;
++ p->desc->npins = p->max_pins;
++
++ return 0;
++}
++
++int ralink_pinmux_init(struct platform_device *pdev,
++ struct ralink_pmx_group *data)
++{
++ struct ralink_priv *p;
++ struct pinctrl_dev *dev;
++ int err;
++
++ if (!data)
++ return -ENOTSUPP;
++
++ /* setup the private data */
++ p = devm_kzalloc(&pdev->dev, sizeof(struct ralink_priv), GFP_KERNEL);
++ if (!p)
++ return -ENOMEM;
++
++ p->dev = &pdev->dev;
++ p->desc = &ralink_pctrl_desc;
++ p->groups = data;
++ platform_set_drvdata(pdev, p);
++
++ /* init the device */
++ err = ralink_pinmux_index(p);
++ if (err) {
++ dev_err(&pdev->dev, "failed to load index\n");
++ return err;
++ }
++
++ err = ralink_pinmux_pins(p);
++ if (err) {
++ dev_err(&pdev->dev, "failed to load pins\n");
++ return err;
++ }
++ dev = pinctrl_register(p->desc, &pdev->dev, p);
++
++ return PTR_ERR_OR_ZERO(dev);
++}
+diff --git a/drivers/pinctrl/ralink/pinctrl-ralink.h b/drivers/pinctrl/ralink/pinctrl-ralink.h
+new file mode 100644
+index 0000000000000..1349694095852
+--- /dev/null
++++ b/drivers/pinctrl/ralink/pinctrl-ralink.h
+@@ -0,0 +1,53 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Copyright (C) 2012 John Crispin <john@phrozen.org>
++ */
++
++#ifndef _PINCTRL_RALINK_H__
++#define _PINCTRL_RALINK_H__
++
++#define FUNC(name, value, pin_first, pin_count) \
++ { name, value, pin_first, pin_count }
++
++#define GRP(_name, _func, _mask, _shift) \
++ { .name = _name, .mask = _mask, .shift = _shift, \
++ .func = _func, .gpio = _mask, \
++ .func_count = ARRAY_SIZE(_func) }
++
++#define GRP_G(_name, _func, _mask, _gpio, _shift) \
++ { .name = _name, .mask = _mask, .shift = _shift, \
++ .func = _func, .gpio = _gpio, \
++ .func_count = ARRAY_SIZE(_func) }
++
++struct ralink_pmx_group;
++
++struct ralink_pmx_func {
++ const char *name;
++ const char value;
++
++ int pin_first;
++ int pin_count;
++ int *pins;
++
++ int *groups;
++ int group_count;
++
++ int enabled;
++};
++
++struct ralink_pmx_group {
++ const char *name;
++ int enabled;
++
++ const u32 shift;
++ const char mask;
++ const char gpio;
++
++ struct ralink_pmx_func *func;
++ int func_count;
++};
++
++int ralink_pinmux_init(struct platform_device *pdev,
++ struct ralink_pmx_group *data);
++
++#endif
+diff --git a/drivers/pinctrl/ralink/pinctrl-rt2880.c b/drivers/pinctrl/ralink/pinctrl-rt2880.c
+deleted file mode 100644
+index 96fc06d1b8b92..0000000000000
+--- a/drivers/pinctrl/ralink/pinctrl-rt2880.c
++++ /dev/null
+@@ -1,349 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-/*
+- * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+- */
+-
+-#include <linux/module.h>
+-#include <linux/device.h>
+-#include <linux/io.h>
+-#include <linux/platform_device.h>
+-#include <linux/slab.h>
+-#include <linux/of.h>
+-#include <linux/pinctrl/pinctrl.h>
+-#include <linux/pinctrl/pinconf.h>
+-#include <linux/pinctrl/pinconf-generic.h>
+-#include <linux/pinctrl/pinmux.h>
+-#include <linux/pinctrl/consumer.h>
+-#include <linux/pinctrl/machine.h>
+-
+-#include <asm/mach-ralink/ralink_regs.h>
+-#include <asm/mach-ralink/mt7620.h>
+-
+-#include "pinmux.h"
+-#include "../core.h"
+-#include "../pinctrl-utils.h"
+-
+-#define SYSC_REG_GPIO_MODE 0x60
+-#define SYSC_REG_GPIO_MODE2 0x64
+-
+-struct rt2880_priv {
+- struct device *dev;
+-
+- struct pinctrl_pin_desc *pads;
+- struct pinctrl_desc *desc;
+-
+- struct rt2880_pmx_func **func;
+- int func_count;
+-
+- struct rt2880_pmx_group *groups;
+- const char **group_names;
+- int group_count;
+-
+- u8 *gpio;
+- int max_pins;
+-};
+-
+-static int rt2880_get_group_count(struct pinctrl_dev *pctrldev)
+-{
+- struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
+-
+- return p->group_count;
+-}
+-
+-static const char *rt2880_get_group_name(struct pinctrl_dev *pctrldev,
+- unsigned int group)
+-{
+- struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
+-
+- return (group >= p->group_count) ? NULL : p->group_names[group];
+-}
+-
+-static int rt2880_get_group_pins(struct pinctrl_dev *pctrldev,
+- unsigned int group,
+- const unsigned int **pins,
+- unsigned int *num_pins)
+-{
+- struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
+-
+- if (group >= p->group_count)
+- return -EINVAL;
+-
+- *pins = p->groups[group].func[0].pins;
+- *num_pins = p->groups[group].func[0].pin_count;
+-
+- return 0;
+-}
+-
+-static const struct pinctrl_ops rt2880_pctrl_ops = {
+- .get_groups_count = rt2880_get_group_count,
+- .get_group_name = rt2880_get_group_name,
+- .get_group_pins = rt2880_get_group_pins,
+- .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
+- .dt_free_map = pinconf_generic_dt_free_map,
+-};
+-
+-static int rt2880_pmx_func_count(struct pinctrl_dev *pctrldev)
+-{
+- struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
+-
+- return p->func_count;
+-}
+-
+-static const char *rt2880_pmx_func_name(struct pinctrl_dev *pctrldev,
+- unsigned int func)
+-{
+- struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
+-
+- return p->func[func]->name;
+-}
+-
+-static int rt2880_pmx_group_get_groups(struct pinctrl_dev *pctrldev,
+- unsigned int func,
+- const char * const **groups,
+- unsigned int * const num_groups)
+-{
+- struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
+-
+- if (p->func[func]->group_count == 1)
+- *groups = &p->group_names[p->func[func]->groups[0]];
+- else
+- *groups = p->group_names;
+-
+- *num_groups = p->func[func]->group_count;
+-
+- return 0;
+-}
+-
+-static int rt2880_pmx_group_enable(struct pinctrl_dev *pctrldev,
+- unsigned int func, unsigned int group)
+-{
+- struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
+- u32 mode = 0;
+- u32 reg = SYSC_REG_GPIO_MODE;
+- int i;
+- int shift;
+-
+- /* dont allow double use */
+- if (p->groups[group].enabled) {
+- dev_err(p->dev, "%s is already enabled\n",
+- p->groups[group].name);
+- return 0;
+- }
+-
+- p->groups[group].enabled = 1;
+- p->func[func]->enabled = 1;
+-
+- shift = p->groups[group].shift;
+- if (shift >= 32) {
+- shift -= 32;
+- reg = SYSC_REG_GPIO_MODE2;
+- }
+- mode = rt_sysc_r32(reg);
+- mode &= ~(p->groups[group].mask << shift);
+-
+- /* mark the pins as gpio */
+- for (i = 0; i < p->groups[group].func[0].pin_count; i++)
+- p->gpio[p->groups[group].func[0].pins[i]] = 1;
+-
+- /* function 0 is gpio and needs special handling */
+- if (func == 0) {
+- mode |= p->groups[group].gpio << shift;
+- } else {
+- for (i = 0; i < p->func[func]->pin_count; i++)
+- p->gpio[p->func[func]->pins[i]] = 0;
+- mode |= p->func[func]->value << shift;
+- }
+- rt_sysc_w32(mode, reg);
+-
+- return 0;
+-}
+-
+-static int rt2880_pmx_group_gpio_request_enable(struct pinctrl_dev *pctrldev,
+- struct pinctrl_gpio_range *range,
+- unsigned int pin)
+-{
+- struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
+-
+- if (!p->gpio[pin]) {
+- dev_err(p->dev, "pin %d is not set to gpio mux\n", pin);
+- return -EINVAL;
+- }
+-
+- return 0;
+-}
+-
+-static const struct pinmux_ops rt2880_pmx_group_ops = {
+- .get_functions_count = rt2880_pmx_func_count,
+- .get_function_name = rt2880_pmx_func_name,
+- .get_function_groups = rt2880_pmx_group_get_groups,
+- .set_mux = rt2880_pmx_group_enable,
+- .gpio_request_enable = rt2880_pmx_group_gpio_request_enable,
+-};
+-
+-static struct pinctrl_desc rt2880_pctrl_desc = {
+- .owner = THIS_MODULE,
+- .name = "rt2880-pinmux",
+- .pctlops = &rt2880_pctrl_ops,
+- .pmxops = &rt2880_pmx_group_ops,
+-};
+-
+-static struct rt2880_pmx_func gpio_func = {
+- .name = "gpio",
+-};
+-
+-static int rt2880_pinmux_index(struct rt2880_priv *p)
+-{
+- struct rt2880_pmx_group *mux = p->groups;
+- int i, j, c = 0;
+-
+- /* count the mux functions */
+- while (mux->name) {
+- p->group_count++;
+- mux++;
+- }
+-
+- /* allocate the group names array needed by the gpio function */
+- p->group_names = devm_kcalloc(p->dev, p->group_count,
+- sizeof(char *), GFP_KERNEL);
+- if (!p->group_names)
+- return -ENOMEM;
+-
+- for (i = 0; i < p->group_count; i++) {
+- p->group_names[i] = p->groups[i].name;
+- p->func_count += p->groups[i].func_count;
+- }
+-
+- /* we have a dummy function[0] for gpio */
+- p->func_count++;
+-
+- /* allocate our function and group mapping index buffers */
+- p->func = devm_kcalloc(p->dev, p->func_count,
+- sizeof(*p->func), GFP_KERNEL);
+- gpio_func.groups = devm_kcalloc(p->dev, p->group_count, sizeof(int),
+- GFP_KERNEL);
+- if (!p->func || !gpio_func.groups)
+- return -ENOMEM;
+-
+- /* add a backpointer to the function so it knows its group */
+- gpio_func.group_count = p->group_count;
+- for (i = 0; i < gpio_func.group_count; i++)
+- gpio_func.groups[i] = i;
+-
+- p->func[c] = &gpio_func;
+- c++;
+-
+- /* add remaining functions */
+- for (i = 0; i < p->group_count; i++) {
+- for (j = 0; j < p->groups[i].func_count; j++) {
+- p->func[c] = &p->groups[i].func[j];
+- p->func[c]->groups = devm_kzalloc(p->dev, sizeof(int),
+- GFP_KERNEL);
+- if (!p->func[c]->groups)
+- return -ENOMEM;
+- p->func[c]->groups[0] = i;
+- p->func[c]->group_count = 1;
+- c++;
+- }
+- }
+- return 0;
+-}
+-
+-static int rt2880_pinmux_pins(struct rt2880_priv *p)
+-{
+- int i, j;
+-
+- /*
+- * loop over the functions and initialize the pins array.
+- * also work out the highest pin used.
+- */
+- for (i = 0; i < p->func_count; i++) {
+- int pin;
+-
+- if (!p->func[i]->pin_count)
+- continue;
+-
+- p->func[i]->pins = devm_kcalloc(p->dev,
+- p->func[i]->pin_count,
+- sizeof(int),
+- GFP_KERNEL);
+- for (j = 0; j < p->func[i]->pin_count; j++)
+- p->func[i]->pins[j] = p->func[i]->pin_first + j;
+-
+- pin = p->func[i]->pin_first + p->func[i]->pin_count;
+- if (pin > p->max_pins)
+- p->max_pins = pin;
+- }
+-
+- /* the buffer that tells us which pins are gpio */
+- p->gpio = devm_kcalloc(p->dev, p->max_pins, sizeof(u8), GFP_KERNEL);
+- /* the pads needed to tell pinctrl about our pins */
+- p->pads = devm_kcalloc(p->dev, p->max_pins,
+- sizeof(struct pinctrl_pin_desc), GFP_KERNEL);
+- if (!p->pads || !p->gpio)
+- return -ENOMEM;
+-
+- memset(p->gpio, 1, sizeof(u8) * p->max_pins);
+- for (i = 0; i < p->func_count; i++) {
+- if (!p->func[i]->pin_count)
+- continue;
+-
+- for (j = 0; j < p->func[i]->pin_count; j++)
+- p->gpio[p->func[i]->pins[j]] = 0;
+- }
+-
+- /* pin 0 is always a gpio */
+- p->gpio[0] = 1;
+-
+- /* set the pads */
+- for (i = 0; i < p->max_pins; i++) {
+- /* strlen("ioXY") + 1 = 5 */
+- char *name = devm_kzalloc(p->dev, 5, GFP_KERNEL);
+-
+- if (!name)
+- return -ENOMEM;
+- snprintf(name, 5, "io%d", i);
+- p->pads[i].number = i;
+- p->pads[i].name = name;
+- }
+- p->desc->pins = p->pads;
+- p->desc->npins = p->max_pins;
+-
+- return 0;
+-}
+-
+-int rt2880_pinmux_init(struct platform_device *pdev,
+- struct rt2880_pmx_group *data)
+-{
+- struct rt2880_priv *p;
+- struct pinctrl_dev *dev;
+- int err;
+-
+- if (!data)
+- return -ENOTSUPP;
+-
+- /* setup the private data */
+- p = devm_kzalloc(&pdev->dev, sizeof(struct rt2880_priv), GFP_KERNEL);
+- if (!p)
+- return -ENOMEM;
+-
+- p->dev = &pdev->dev;
+- p->desc = &rt2880_pctrl_desc;
+- p->groups = data;
+- platform_set_drvdata(pdev, p);
+-
+- /* init the device */
+- err = rt2880_pinmux_index(p);
+- if (err) {
+- dev_err(&pdev->dev, "failed to load index\n");
+- return err;
+- }
+-
+- err = rt2880_pinmux_pins(p);
+- if (err) {
+- dev_err(&pdev->dev, "failed to load pins\n");
+- return err;
+- }
+- dev = pinctrl_register(p->desc, &pdev->dev, p);
+-
+- return PTR_ERR_OR_ZERO(dev);
+-}
+diff --git a/drivers/pinctrl/ralink/pinctrl-rt288x.c b/drivers/pinctrl/ralink/pinctrl-rt288x.c
+index 0744aebbace52..40c45140ff8a3 100644
+--- a/drivers/pinctrl/ralink/pinctrl-rt288x.c
++++ b/drivers/pinctrl/ralink/pinctrl-rt288x.c
+@@ -4,7 +4,7 @@
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/of.h>
+-#include "pinmux.h"
++#include "pinctrl-ralink.h"
+
+ #define RT2880_GPIO_MODE_I2C BIT(0)
+ #define RT2880_GPIO_MODE_UART0 BIT(1)
+@@ -15,15 +15,15 @@
+ #define RT2880_GPIO_MODE_SDRAM BIT(6)
+ #define RT2880_GPIO_MODE_PCI BIT(7)
+
+-static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) };
+-static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
+-static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 7, 8) };
+-static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) };
+-static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) };
+-static struct rt2880_pmx_func sdram_func[] = { FUNC("sdram", 0, 24, 16) };
+-static struct rt2880_pmx_func pci_func[] = { FUNC("pci", 0, 40, 32) };
++static struct ralink_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) };
++static struct ralink_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
++static struct ralink_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 7, 8) };
++static struct ralink_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) };
++static struct ralink_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) };
++static struct ralink_pmx_func sdram_func[] = { FUNC("sdram", 0, 24, 16) };
++static struct ralink_pmx_func pci_func[] = { FUNC("pci", 0, 40, 32) };
+
+-static struct rt2880_pmx_group rt2880_pinmux_data_act[] = {
++static struct ralink_pmx_group rt2880_pinmux_data_act[] = {
+ GRP("i2c", i2c_func, 1, RT2880_GPIO_MODE_I2C),
+ GRP("spi", spi_func, 1, RT2880_GPIO_MODE_SPI),
+ GRP("uartlite", uartlite_func, 1, RT2880_GPIO_MODE_UART0),
+@@ -36,7 +36,7 @@ static struct rt2880_pmx_group rt2880_pinmux_data_act[] = {
+
+ static int rt288x_pinmux_probe(struct platform_device *pdev)
+ {
+- return rt2880_pinmux_init(pdev, rt2880_pinmux_data_act);
++ return ralink_pinmux_init(pdev, rt2880_pinmux_data_act);
+ }
+
+ static const struct of_device_id rt288x_pinmux_match[] = {
+diff --git a/drivers/pinctrl/ralink/pinctrl-rt305x.c b/drivers/pinctrl/ralink/pinctrl-rt305x.c
+index 5d8fa156c0037..25527ca1ccaae 100644
+--- a/drivers/pinctrl/ralink/pinctrl-rt305x.c
++++ b/drivers/pinctrl/ralink/pinctrl-rt305x.c
+@@ -5,7 +5,7 @@
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/of.h>
+-#include "pinmux.h"
++#include "pinctrl-ralink.h"
+
+ #define RT305X_GPIO_MODE_UART0_SHIFT 2
+ #define RT305X_GPIO_MODE_UART0_MASK 0x7
+@@ -31,9 +31,9 @@
+ #define RT3352_GPIO_MODE_LNA 18
+ #define RT3352_GPIO_MODE_PA 20
+
+-static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) };
+-static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
+-static struct rt2880_pmx_func uartf_func[] = {
++static struct ralink_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) };
++static struct ralink_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
++static struct ralink_pmx_func uartf_func[] = {
+ FUNC("uartf", RT305X_GPIO_MODE_UARTF, 7, 8),
+ FUNC("pcm uartf", RT305X_GPIO_MODE_PCM_UARTF, 7, 8),
+ FUNC("pcm i2s", RT305X_GPIO_MODE_PCM_I2S, 7, 8),
+@@ -42,28 +42,28 @@ static struct rt2880_pmx_func uartf_func[] = {
+ FUNC("gpio uartf", RT305X_GPIO_MODE_GPIO_UARTF, 7, 4),
+ FUNC("gpio i2s", RT305X_GPIO_MODE_GPIO_I2S, 7, 4),
+ };
+-static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) };
+-static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) };
+-static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) };
+-static struct rt2880_pmx_func rt5350_led_func[] = { FUNC("led", 0, 22, 5) };
+-static struct rt2880_pmx_func rt5350_cs1_func[] = {
++static struct ralink_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) };
++static struct ralink_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) };
++static struct ralink_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) };
++static struct ralink_pmx_func rt5350_led_func[] = { FUNC("led", 0, 22, 5) };
++static struct ralink_pmx_func rt5350_cs1_func[] = {
+ FUNC("spi_cs1", 0, 27, 1),
+ FUNC("wdg_cs1", 1, 27, 1),
+ };
+-static struct rt2880_pmx_func sdram_func[] = { FUNC("sdram", 0, 24, 16) };
+-static struct rt2880_pmx_func rt3352_rgmii_func[] = {
++static struct ralink_pmx_func sdram_func[] = { FUNC("sdram", 0, 24, 16) };
++static struct ralink_pmx_func rt3352_rgmii_func[] = {
+ FUNC("rgmii", 0, 24, 12)
+ };
+-static struct rt2880_pmx_func rgmii_func[] = { FUNC("rgmii", 0, 40, 12) };
+-static struct rt2880_pmx_func rt3352_lna_func[] = { FUNC("lna", 0, 36, 2) };
+-static struct rt2880_pmx_func rt3352_pa_func[] = { FUNC("pa", 0, 38, 2) };
+-static struct rt2880_pmx_func rt3352_led_func[] = { FUNC("led", 0, 40, 5) };
+-static struct rt2880_pmx_func rt3352_cs1_func[] = {
++static struct ralink_pmx_func rgmii_func[] = { FUNC("rgmii", 0, 40, 12) };
++static struct ralink_pmx_func rt3352_lna_func[] = { FUNC("lna", 0, 36, 2) };
++static struct ralink_pmx_func rt3352_pa_func[] = { FUNC("pa", 0, 38, 2) };
++static struct ralink_pmx_func rt3352_led_func[] = { FUNC("led", 0, 40, 5) };
++static struct ralink_pmx_func rt3352_cs1_func[] = {
+ FUNC("spi_cs1", 0, 45, 1),
+ FUNC("wdg_cs1", 1, 45, 1),
+ };
+
+-static struct rt2880_pmx_group rt3050_pinmux_data[] = {
++static struct ralink_pmx_group rt3050_pinmux_data[] = {
+ GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C),
+ GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI),
+ GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK,
+@@ -76,7 +76,7 @@ static struct rt2880_pmx_group rt3050_pinmux_data[] = {
+ { 0 }
+ };
+
+-static struct rt2880_pmx_group rt3352_pinmux_data[] = {
++static struct ralink_pmx_group rt3352_pinmux_data[] = {
+ GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C),
+ GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI),
+ GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK,
+@@ -92,7 +92,7 @@ static struct rt2880_pmx_group rt3352_pinmux_data[] = {
+ { 0 }
+ };
+
+-static struct rt2880_pmx_group rt5350_pinmux_data[] = {
++static struct ralink_pmx_group rt5350_pinmux_data[] = {
+ GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C),
+ GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI),
+ GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK,
+@@ -107,11 +107,11 @@ static struct rt2880_pmx_group rt5350_pinmux_data[] = {
+ static int rt305x_pinmux_probe(struct platform_device *pdev)
+ {
+ if (soc_is_rt5350())
+- return rt2880_pinmux_init(pdev, rt5350_pinmux_data);
++ return ralink_pinmux_init(pdev, rt5350_pinmux_data);
+ else if (soc_is_rt305x() || soc_is_rt3350())
+- return rt2880_pinmux_init(pdev, rt3050_pinmux_data);
++ return ralink_pinmux_init(pdev, rt3050_pinmux_data);
+ else if (soc_is_rt3352())
+- return rt2880_pinmux_init(pdev, rt3352_pinmux_data);
++ return ralink_pinmux_init(pdev, rt3352_pinmux_data);
+ else
+ return -EINVAL;
+ }
+diff --git a/drivers/pinctrl/ralink/pinctrl-rt3883.c b/drivers/pinctrl/ralink/pinctrl-rt3883.c
+index 3e0e1b4caa647..0b8674dbe1880 100644
+--- a/drivers/pinctrl/ralink/pinctrl-rt3883.c
++++ b/drivers/pinctrl/ralink/pinctrl-rt3883.c
+@@ -3,7 +3,7 @@
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/of.h>
+-#include "pinmux.h"
++#include "pinctrl-ralink.h"
+
+ #define RT3883_GPIO_MODE_UART0_SHIFT 2
+ #define RT3883_GPIO_MODE_UART0_MASK 0x7
+@@ -39,9 +39,9 @@
+ #define RT3883_GPIO_MODE_LNA_G_GPIO 0x3
+ #define RT3883_GPIO_MODE_LNA_G _RT3883_GPIO_MODE_LNA_G(RT3883_GPIO_MODE_LNA_G_MASK)
+
+-static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) };
+-static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
+-static struct rt2880_pmx_func uartf_func[] = {
++static struct ralink_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) };
++static struct ralink_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
++static struct ralink_pmx_func uartf_func[] = {
+ FUNC("uartf", RT3883_GPIO_MODE_UARTF, 7, 8),
+ FUNC("pcm uartf", RT3883_GPIO_MODE_PCM_UARTF, 7, 8),
+ FUNC("pcm i2s", RT3883_GPIO_MODE_PCM_I2S, 7, 8),
+@@ -50,21 +50,21 @@ static struct rt2880_pmx_func uartf_func[] = {
+ FUNC("gpio uartf", RT3883_GPIO_MODE_GPIO_UARTF, 7, 4),
+ FUNC("gpio i2s", RT3883_GPIO_MODE_GPIO_I2S, 7, 4),
+ };
+-static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) };
+-static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) };
+-static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) };
+-static struct rt2880_pmx_func lna_a_func[] = { FUNC("lna a", 0, 32, 3) };
+-static struct rt2880_pmx_func lna_g_func[] = { FUNC("lna g", 0, 35, 3) };
+-static struct rt2880_pmx_func pci_func[] = {
++static struct ralink_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) };
++static struct ralink_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) };
++static struct ralink_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) };
++static struct ralink_pmx_func lna_a_func[] = { FUNC("lna a", 0, 32, 3) };
++static struct ralink_pmx_func lna_g_func[] = { FUNC("lna g", 0, 35, 3) };
++static struct ralink_pmx_func pci_func[] = {
+ FUNC("pci-dev", 0, 40, 32),
+ FUNC("pci-host2", 1, 40, 32),
+ FUNC("pci-host1", 2, 40, 32),
+ FUNC("pci-fnc", 3, 40, 32)
+ };
+-static struct rt2880_pmx_func ge1_func[] = { FUNC("ge1", 0, 72, 12) };
+-static struct rt2880_pmx_func ge2_func[] = { FUNC("ge2", 0, 84, 12) };
++static struct ralink_pmx_func ge1_func[] = { FUNC("ge1", 0, 72, 12) };
++static struct ralink_pmx_func ge2_func[] = { FUNC("ge2", 0, 84, 12) };
+
+-static struct rt2880_pmx_group rt3883_pinmux_data[] = {
++static struct ralink_pmx_group rt3883_pinmux_data[] = {
+ GRP("i2c", i2c_func, 1, RT3883_GPIO_MODE_I2C),
+ GRP("spi", spi_func, 1, RT3883_GPIO_MODE_SPI),
+ GRP("uartf", uartf_func, RT3883_GPIO_MODE_UART0_MASK,
+@@ -83,7 +83,7 @@ static struct rt2880_pmx_group rt3883_pinmux_data[] = {
+
+ static int rt3883_pinmux_probe(struct platform_device *pdev)
+ {
+- return rt2880_pinmux_init(pdev, rt3883_pinmux_data);
++ return ralink_pinmux_init(pdev, rt3883_pinmux_data);
+ }
+
+ static const struct of_device_id rt3883_pinmux_match[] = {
+diff --git a/drivers/pinctrl/ralink/pinmux.h b/drivers/pinctrl/ralink/pinmux.h
+deleted file mode 100644
+index 0046abe3bcc79..0000000000000
+--- a/drivers/pinctrl/ralink/pinmux.h
++++ /dev/null
+@@ -1,53 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0-only */
+-/*
+- * Copyright (C) 2012 John Crispin <john@phrozen.org>
+- */
+-
+-#ifndef _RT288X_PINMUX_H__
+-#define _RT288X_PINMUX_H__
+-
+-#define FUNC(name, value, pin_first, pin_count) \
+- { name, value, pin_first, pin_count }
+-
+-#define GRP(_name, _func, _mask, _shift) \
+- { .name = _name, .mask = _mask, .shift = _shift, \
+- .func = _func, .gpio = _mask, \
+- .func_count = ARRAY_SIZE(_func) }
+-
+-#define GRP_G(_name, _func, _mask, _gpio, _shift) \
+- { .name = _name, .mask = _mask, .shift = _shift, \
+- .func = _func, .gpio = _gpio, \
+- .func_count = ARRAY_SIZE(_func) }
+-
+-struct rt2880_pmx_group;
+-
+-struct rt2880_pmx_func {
+- const char *name;
+- const char value;
+-
+- int pin_first;
+- int pin_count;
+- int *pins;
+-
+- int *groups;
+- int group_count;
+-
+- int enabled;
+-};
+-
+-struct rt2880_pmx_group {
+- const char *name;
+- int enabled;
+-
+- const u32 shift;
+- const char mask;
+- const char gpio;
+-
+- struct rt2880_pmx_func *func;
+- int func_count;
+-};
+-
+-int rt2880_pinmux_init(struct platform_device *pdev,
+- struct rt2880_pmx_group *data);
+-
+-#endif
+diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c
+index f7c9459f66283..edd0d0af5c147 100644
+--- a/drivers/pinctrl/stm32/pinctrl-stm32.c
++++ b/drivers/pinctrl/stm32/pinctrl-stm32.c
+@@ -1299,15 +1299,17 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl,
+ bank->bank_ioport_nr = bank_ioport_nr;
+ spin_lock_init(&bank->lock);
+
+- /* create irq hierarchical domain */
+- bank->fwnode = of_node_to_fwnode(np);
++ if (pctl->domain) {
++ /* create irq hierarchical domain */
++ bank->fwnode = of_node_to_fwnode(np);
+
+- bank->domain = irq_domain_create_hierarchy(pctl->domain, 0,
+- STM32_GPIO_IRQ_LINE, bank->fwnode,
+- &stm32_gpio_domain_ops, bank);
++ bank->domain = irq_domain_create_hierarchy(pctl->domain, 0, STM32_GPIO_IRQ_LINE,
++ bank->fwnode, &stm32_gpio_domain_ops,
++ bank);
+
+- if (!bank->domain)
+- return -ENODEV;
++ if (!bank->domain)
++ return -ENODEV;
++ }
+
+ err = gpiochip_add_data(&bank->gpio_chip, bank);
+ if (err) {
+@@ -1466,6 +1468,8 @@ int stm32_pctl_probe(struct platform_device *pdev)
+ pctl->domain = stm32_pctrl_get_irq_domain(np);
+ if (IS_ERR(pctl->domain))
+ return PTR_ERR(pctl->domain);
++ if (!pctl->domain)
++ dev_warn(dev, "pinctrl without interrupt support\n");
+
+ /* hwspinlock is optional */
+ hwlock_id = of_hwspin_lock_get_id(pdev->dev.of_node, 0);
+diff --git a/drivers/pinctrl/sunplus/sppctl.c b/drivers/pinctrl/sunplus/sppctl.c
+index 3ba47040ac423..2b3335ab56c66 100644
+--- a/drivers/pinctrl/sunplus/sppctl.c
++++ b/drivers/pinctrl/sunplus/sppctl.c
+@@ -871,6 +871,9 @@ static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node
+ }
+
+ *map = kcalloc(*num_maps + nmG, sizeof(**map), GFP_KERNEL);
++ if (*map == NULL)
++ return -ENOMEM;
++
+ for (i = 0; i < (*num_maps); i++) {
+ dt_pin = be32_to_cpu(list[i]);
+ pin_num = FIELD_GET(GENMASK(31, 24), dt_pin);
+diff --git a/drivers/power/reset/arm-versatile-reboot.c b/drivers/power/reset/arm-versatile-reboot.c
+index 08d0a07b58ef2..c7624d7611a7e 100644
+--- a/drivers/power/reset/arm-versatile-reboot.c
++++ b/drivers/power/reset/arm-versatile-reboot.c
+@@ -146,6 +146,7 @@ static int __init versatile_reboot_probe(void)
+ versatile_reboot_type = (enum versatile_reboot)reboot_id->data;
+
+ syscon_regmap = syscon_node_to_regmap(np);
++ of_node_put(np);
+ if (IS_ERR(syscon_regmap))
+ return PTR_ERR(syscon_regmap);
+
+diff --git a/drivers/power/supply/ab8500_fg.c b/drivers/power/supply/ab8500_fg.c
+index ec8a404d71b44..4339fa9ff0099 100644
+--- a/drivers/power/supply/ab8500_fg.c
++++ b/drivers/power/supply/ab8500_fg.c
+@@ -3148,6 +3148,7 @@ static int ab8500_fg_probe(struct platform_device *pdev)
+ ret = ab8500_fg_init_hw_registers(di);
+ if (ret) {
+ dev_err(dev, "failed to initialize registers\n");
++ destroy_workqueue(di->fg_wq);
+ return ret;
+ }
+
+@@ -3159,6 +3160,7 @@ static int ab8500_fg_probe(struct platform_device *pdev)
+ di->fg_psy = devm_power_supply_register(dev, &ab8500_fg_desc, &psy_cfg);
+ if (IS_ERR(di->fg_psy)) {
+ dev_err(dev, "failed to register FG psy\n");
++ destroy_workqueue(di->fg_wq);
+ return PTR_ERR(di->fg_psy);
+ }
+
+@@ -3174,8 +3176,10 @@ static int ab8500_fg_probe(struct platform_device *pdev)
+ /* Register primary interrupt handlers */
+ for (i = 0; i < ARRAY_SIZE(ab8500_fg_irq); i++) {
+ irq = platform_get_irq_byname(pdev, ab8500_fg_irq[i].name);
+- if (irq < 0)
++ if (irq < 0) {
++ destroy_workqueue(di->fg_wq);
+ return irq;
++ }
+
+ ret = devm_request_threaded_irq(dev, irq, NULL,
+ ab8500_fg_irq[i].isr,
+@@ -3185,6 +3189,7 @@ static int ab8500_fg_probe(struct platform_device *pdev)
+ if (ret != 0) {
+ dev_err(dev, "failed to request %s IRQ %d: %d\n",
+ ab8500_fg_irq[i].name, irq, ret);
++ destroy_workqueue(di->fg_wq);
+ return ret;
+ }
+ dev_dbg(dev, "Requested %s IRQ %d: %d\n",
+@@ -3200,6 +3205,7 @@ static int ab8500_fg_probe(struct platform_device *pdev)
+ ret = ab8500_fg_sysfs_init(di);
+ if (ret) {
+ dev_err(dev, "failed to create sysfs entry\n");
++ destroy_workqueue(di->fg_wq);
+ return ret;
+ }
+
+@@ -3207,6 +3213,7 @@ static int ab8500_fg_probe(struct platform_device *pdev)
+ if (ret) {
+ dev_err(dev, "failed to create FG psy\n");
+ ab8500_fg_sysfs_exit(di);
++ destroy_workqueue(di->fg_wq);
+ return ret;
+ }
+
+diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c
+index 775c0bf2f923d..0933948d7df3d 100644
+--- a/drivers/spi/spi-bcm2835.c
++++ b/drivers/spi/spi-bcm2835.c
+@@ -1138,10 +1138,14 @@ static void bcm2835_spi_handle_err(struct spi_controller *ctlr,
+ struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
+
+ /* if an error occurred and we have an active dma, then terminate */
+- dmaengine_terminate_sync(ctlr->dma_tx);
+- bs->tx_dma_active = false;
+- dmaengine_terminate_sync(ctlr->dma_rx);
+- bs->rx_dma_active = false;
++ if (ctlr->dma_tx) {
++ dmaengine_terminate_sync(ctlr->dma_tx);
++ bs->tx_dma_active = false;
++ }
++ if (ctlr->dma_rx) {
++ dmaengine_terminate_sync(ctlr->dma_rx);
++ bs->rx_dma_active = false;
++ }
+ bcm2835_spi_undo_prologue(bs);
+
+ /* and reset */
+diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
+index 5b485cd96c931..5298a3a43bc71 100644
+--- a/fs/dlm/lock.c
++++ b/fs/dlm/lock.c
+@@ -4085,13 +4085,14 @@ static void send_repeat_remove(struct dlm_ls *ls, char *ms_name, int len)
+ rv = _create_message(ls, sizeof(struct dlm_message) + len,
+ dir_nodeid, DLM_MSG_REMOVE, &ms, &mh);
+ if (rv)
+- return;
++ goto out;
+
+ memcpy(ms->m_extra, name, len);
+ ms->m_hash = hash;
+
+ send_message(mh, ms);
+
++out:
+ spin_lock(&ls->ls_remove_spin);
+ ls->ls_remove_len = 0;
+ memset(ls->ls_remove_name, 0, DLM_RESNAME_MAXLEN);
+diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c
+index a02a04a993bfa..c6eaf7e9ea743 100644
+--- a/fs/exfat/namei.c
++++ b/fs/exfat/namei.c
+@@ -1080,6 +1080,7 @@ static int exfat_rename_file(struct inode *inode, struct exfat_chain *p_dir,
+
+ exfat_remove_entries(inode, p_dir, oldentry, 0,
+ num_old_entries);
++ ei->dir = *p_dir;
+ ei->entry = newentry;
+ } else {
+ if (exfat_get_entry_type(epold) == TYPE_FILE) {
+@@ -1167,28 +1168,6 @@ static int exfat_move_file(struct inode *inode, struct exfat_chain *p_olddir,
+ return 0;
+ }
+
+-static void exfat_update_parent_info(struct exfat_inode_info *ei,
+- struct inode *parent_inode)
+-{
+- struct exfat_sb_info *sbi = EXFAT_SB(parent_inode->i_sb);
+- struct exfat_inode_info *parent_ei = EXFAT_I(parent_inode);
+- loff_t parent_isize = i_size_read(parent_inode);
+-
+- /*
+- * the problem that struct exfat_inode_info caches wrong parent info.
+- *
+- * because of flag-mismatch of ei->dir,
+- * there is abnormal traversing cluster chain.
+- */
+- if (unlikely(parent_ei->flags != ei->dir.flags ||
+- parent_isize != EXFAT_CLU_TO_B(ei->dir.size, sbi) ||
+- parent_ei->start_clu != ei->dir.dir)) {
+- exfat_chain_set(&ei->dir, parent_ei->start_clu,
+- EXFAT_B_TO_CLU_ROUND_UP(parent_isize, sbi),
+- parent_ei->flags);
+- }
+-}
+-
+ /* rename or move a old file into a new file */
+ static int __exfat_rename(struct inode *old_parent_inode,
+ struct exfat_inode_info *ei, struct inode *new_parent_inode,
+@@ -1219,9 +1198,9 @@ static int __exfat_rename(struct inode *old_parent_inode,
+ return -ENOENT;
+ }
+
+- exfat_update_parent_info(ei, old_parent_inode);
+-
+- exfat_chain_dup(&olddir, &ei->dir);
++ exfat_chain_set(&olddir, EXFAT_I(old_parent_inode)->start_clu,
++ EXFAT_B_TO_CLU_ROUND_UP(i_size_read(old_parent_inode), sbi),
++ EXFAT_I(old_parent_inode)->flags);
+ dentry = ei->entry;
+
+ ep = exfat_get_dentry(sb, &olddir, dentry, &old_bh);
+@@ -1241,8 +1220,6 @@ static int __exfat_rename(struct inode *old_parent_inode,
+ goto out;
+ }
+
+- exfat_update_parent_info(new_ei, new_parent_inode);
+-
+ p_dir = &(new_ei->dir);
+ new_entry = new_ei->entry;
+ ep = exfat_get_dentry(sb, p_dir, new_entry, &new_bh);
+diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
+index 944f83ef9f2ef..dcd15e0249767 100644
+--- a/include/drm/gpu_scheduler.h
++++ b/include/drm/gpu_scheduler.h
+@@ -28,7 +28,7 @@
+ #include <linux/dma-fence.h>
+ #include <linux/completion.h>
+ #include <linux/xarray.h>
+-#include <linux/irq_work.h>
++#include <linux/workqueue.h>
+
+ #define MAX_WAIT_SCHED_ENTITY_Q_EMPTY msecs_to_jiffies(1000)
+
+@@ -294,7 +294,7 @@ struct drm_sched_job {
+ */
+ union {
+ struct dma_fence_cb finish_cb;
+- struct irq_work work;
++ struct work_struct work;
+ };
+
+ uint64_t id;
+diff --git a/include/net/amt.h b/include/net/amt.h
+index 7a4db8b903eed..44acadf3a69e3 100644
+--- a/include/net/amt.h
++++ b/include/net/amt.h
+@@ -78,6 +78,15 @@ enum amt_status {
+
+ #define AMT_STATUS_MAX (__AMT_STATUS_MAX - 1)
+
++/* Gateway events only */
++enum amt_event {
++ AMT_EVENT_NONE,
++ AMT_EVENT_RECEIVE,
++ AMT_EVENT_SEND_DISCOVERY,
++ AMT_EVENT_SEND_REQUEST,
++ __AMT_EVENT_MAX,
++};
++
+ struct amt_header {
+ #if defined(__LITTLE_ENDIAN_BITFIELD)
+ u8 type:4,
+@@ -292,6 +301,12 @@ struct amt_group_node {
+ struct hlist_head sources[];
+ };
+
++#define AMT_MAX_EVENTS 16
++struct amt_events {
++ enum amt_event event;
++ struct sk_buff *skb;
++};
++
+ struct amt_dev {
+ struct net_device *dev;
+ struct net_device *stream_dev;
+@@ -308,6 +323,7 @@ struct amt_dev {
+ struct delayed_work req_wq;
+ /* Protected by RTNL */
+ struct delayed_work secret_wq;
++ struct work_struct event_wq;
+ /* AMT status */
+ enum amt_status status;
+ /* Generated key */
+@@ -345,6 +361,10 @@ struct amt_dev {
+ /* Used only in gateway mode */
+ u64 mac:48,
+ reserved:16;
++ /* AMT gateway side message handler queue */
++ struct amt_events events[AMT_MAX_EVENTS];
++ u8 event_idx;
++ u8 nr_events;
+ };
+
+ #define AMT_TOS 0xc0
+diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
+index 98e1ec1a14f03..749bb1e460871 100644
+--- a/include/net/inet_hashtables.h
++++ b/include/net/inet_hashtables.h
+@@ -207,7 +207,7 @@ static inline bool inet_sk_bound_dev_eq(struct net *net, int bound_dev_if,
+ int dif, int sdif)
+ {
+ #if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
+- return inet_bound_dev_eq(!!net->ipv4.sysctl_tcp_l3mdev_accept,
++ return inet_bound_dev_eq(!!READ_ONCE(net->ipv4.sysctl_tcp_l3mdev_accept),
+ bound_dev_if, dif, sdif);
+ #else
+ return inet_bound_dev_eq(true, bound_dev_if, dif, sdif);
+diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
+index 48e4c59d85e24..6395f6b9a5d29 100644
+--- a/include/net/inet_sock.h
++++ b/include/net/inet_sock.h
+@@ -107,7 +107,8 @@ static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk)
+
+ static inline u32 inet_request_mark(const struct sock *sk, struct sk_buff *skb)
+ {
+- if (!sk->sk_mark && sock_net(sk)->ipv4.sysctl_tcp_fwmark_accept)
++ if (!sk->sk_mark &&
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fwmark_accept))
+ return skb->mark;
+
+ return sk->sk_mark;
+@@ -116,14 +117,15 @@ static inline u32 inet_request_mark(const struct sock *sk, struct sk_buff *skb)
+ static inline int inet_request_bound_dev_if(const struct sock *sk,
+ struct sk_buff *skb)
+ {
++ int bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
+ #ifdef CONFIG_NET_L3_MASTER_DEV
+ struct net *net = sock_net(sk);
+
+- if (!sk->sk_bound_dev_if && net->ipv4.sysctl_tcp_l3mdev_accept)
++ if (!bound_dev_if && READ_ONCE(net->ipv4.sysctl_tcp_l3mdev_accept))
+ return l3mdev_master_ifindex_by_index(net, skb->skb_iif);
+ #endif
+
+- return sk->sk_bound_dev_if;
++ return bound_dev_if;
+ }
+
+ static inline int inet_sk_bound_l3mdev(const struct sock *sk)
+@@ -131,7 +133,7 @@ static inline int inet_sk_bound_l3mdev(const struct sock *sk)
+ #ifdef CONFIG_NET_L3_MASTER_DEV
+ struct net *net = sock_net(sk);
+
+- if (!net->ipv4.sysctl_tcp_l3mdev_accept)
++ if (!READ_ONCE(net->ipv4.sysctl_tcp_l3mdev_accept))
+ return l3mdev_master_ifindex_by_index(net,
+ sk->sk_bound_dev_if);
+ #endif
+@@ -373,7 +375,7 @@ static inline bool inet_get_convert_csum(struct sock *sk)
+ static inline bool inet_can_nonlocal_bind(struct net *net,
+ struct inet_sock *inet)
+ {
+- return net->ipv4.sysctl_ip_nonlocal_bind ||
++ return READ_ONCE(net->ipv4.sysctl_ip_nonlocal_bind) ||
+ inet->freebind || inet->transparent;
+ }
+
+diff --git a/include/net/ip.h b/include/net/ip.h
+index 26fffda78cca4..1c979fd1904ce 100644
+--- a/include/net/ip.h
++++ b/include/net/ip.h
+@@ -357,7 +357,7 @@ static inline bool sysctl_dev_name_is_allowed(const char *name)
+
+ static inline bool inet_port_requires_bind_service(struct net *net, unsigned short port)
+ {
+- return port < net->ipv4.sysctl_ip_prot_sock;
++ return port < READ_ONCE(net->ipv4.sysctl_ip_prot_sock);
+ }
+
+ #else
+@@ -384,7 +384,7 @@ void ipfrag_init(void);
+ void ip_static_sysctl_init(void);
+
+ #define IP4_REPLY_MARK(net, mark) \
+- ((net)->ipv4.sysctl_fwmark_reflect ? (mark) : 0)
++ (READ_ONCE((net)->ipv4.sysctl_fwmark_reflect) ? (mark) : 0)
+
+ static inline bool ip_is_fragment(const struct iphdr *iph)
+ {
+@@ -446,7 +446,7 @@ static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst,
+ struct net *net = dev_net(dst->dev);
+ unsigned int mtu;
+
+- if (net->ipv4.sysctl_ip_fwd_use_pmtu ||
++ if (READ_ONCE(net->ipv4.sysctl_ip_fwd_use_pmtu) ||
+ ip_mtu_locked(dst) ||
+ !forwarding) {
+ mtu = rt->rt_pmtu;
+diff --git a/include/net/protocol.h b/include/net/protocol.h
+index f51c06ae365f5..6aef8cb11cc8c 100644
+--- a/include/net/protocol.h
++++ b/include/net/protocol.h
+@@ -35,8 +35,6 @@
+
+ /* This is used to register protocols. */
+ struct net_protocol {
+- int (*early_demux)(struct sk_buff *skb);
+- int (*early_demux_handler)(struct sk_buff *skb);
+ int (*handler)(struct sk_buff *skb);
+
+ /* This returns an error if we weren't able to handle the error. */
+@@ -52,8 +50,6 @@ struct net_protocol {
+
+ #if IS_ENABLED(CONFIG_IPV6)
+ struct inet6_protocol {
+- void (*early_demux)(struct sk_buff *skb);
+- void (*early_demux_handler)(struct sk_buff *skb);
+ int (*handler)(struct sk_buff *skb);
+
+ /* This returns an error if we weren't able to handle the error. */
+diff --git a/include/net/route.h b/include/net/route.h
+index 25404fc2b4837..08df794364853 100644
+--- a/include/net/route.h
++++ b/include/net/route.h
+@@ -361,7 +361,7 @@ static inline int ip4_dst_hoplimit(const struct dst_entry *dst)
+ struct net *net = dev_net(dst->dev);
+
+ if (hoplimit == 0)
+- hoplimit = net->ipv4.sysctl_ip_default_ttl;
++ hoplimit = READ_ONCE(net->ipv4.sysctl_ip_default_ttl);
+ return hoplimit;
+ }
+
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index 2d9a78b3beaa9..4f5de382e1927 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -932,7 +932,7 @@ extern const struct inet_connection_sock_af_ops ipv6_specific;
+
+ INDIRECT_CALLABLE_DECLARE(void tcp_v6_send_check(struct sock *sk, struct sk_buff *skb));
+ INDIRECT_CALLABLE_DECLARE(int tcp_v6_rcv(struct sk_buff *skb));
+-INDIRECT_CALLABLE_DECLARE(void tcp_v6_early_demux(struct sk_buff *skb));
++void tcp_v6_early_demux(struct sk_buff *skb);
+
+ #endif
+
+@@ -1421,8 +1421,8 @@ static inline void tcp_slow_start_after_idle_check(struct sock *sk)
+ struct tcp_sock *tp = tcp_sk(sk);
+ s32 delta;
+
+- if (!sock_net(sk)->ipv4.sysctl_tcp_slow_start_after_idle || tp->packets_out ||
+- ca_ops->cong_control)
++ if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_slow_start_after_idle) ||
++ tp->packets_out || ca_ops->cong_control)
+ return;
+ delta = tcp_jiffies32 - tp->lsndtime;
+ if (delta > inet_csk(sk)->icsk_rto)
+@@ -1511,21 +1511,24 @@ static inline int keepalive_intvl_when(const struct tcp_sock *tp)
+ {
+ struct net *net = sock_net((struct sock *)tp);
+
+- return tp->keepalive_intvl ? : net->ipv4.sysctl_tcp_keepalive_intvl;
++ return tp->keepalive_intvl ? :
++ READ_ONCE(net->ipv4.sysctl_tcp_keepalive_intvl);
+ }
+
+ static inline int keepalive_time_when(const struct tcp_sock *tp)
+ {
+ struct net *net = sock_net((struct sock *)tp);
+
+- return tp->keepalive_time ? : net->ipv4.sysctl_tcp_keepalive_time;
++ return tp->keepalive_time ? :
++ READ_ONCE(net->ipv4.sysctl_tcp_keepalive_time);
+ }
+
+ static inline int keepalive_probes(const struct tcp_sock *tp)
+ {
+ struct net *net = sock_net((struct sock *)tp);
+
+- return tp->keepalive_probes ? : net->ipv4.sysctl_tcp_keepalive_probes;
++ return tp->keepalive_probes ? :
++ READ_ONCE(net->ipv4.sysctl_tcp_keepalive_probes);
+ }
+
+ static inline u32 keepalive_time_elapsed(const struct tcp_sock *tp)
+@@ -1538,7 +1541,8 @@ static inline u32 keepalive_time_elapsed(const struct tcp_sock *tp)
+
+ static inline int tcp_fin_time(const struct sock *sk)
+ {
+- int fin_timeout = tcp_sk(sk)->linger2 ? : sock_net(sk)->ipv4.sysctl_tcp_fin_timeout;
++ int fin_timeout = tcp_sk(sk)->linger2 ? :
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fin_timeout);
+ const int rto = inet_csk(sk)->icsk_rto;
+
+ if (fin_timeout < (rto << 2) - (rto >> 1))
+@@ -2041,7 +2045,7 @@ void __tcp_v4_send_check(struct sk_buff *skb, __be32 saddr, __be32 daddr);
+ static inline u32 tcp_notsent_lowat(const struct tcp_sock *tp)
+ {
+ struct net *net = sock_net((struct sock *)tp);
+- return tp->notsent_lowat ?: net->ipv4.sysctl_tcp_notsent_lowat;
++ return tp->notsent_lowat ?: READ_ONCE(net->ipv4.sysctl_tcp_notsent_lowat);
+ }
+
+ bool tcp_stream_memory_free(const struct sock *sk, int wake);
+diff --git a/include/net/udp.h b/include/net/udp.h
+index f1c2a88c9005a..abe91ab9030df 100644
+--- a/include/net/udp.h
++++ b/include/net/udp.h
+@@ -167,7 +167,7 @@ static inline void udp_csum_pull_header(struct sk_buff *skb)
+ typedef struct sock *(*udp_lookup_t)(const struct sk_buff *skb, __be16 sport,
+ __be16 dport);
+
+-INDIRECT_CALLABLE_DECLARE(void udp_v6_early_demux(struct sk_buff *));
++void udp_v6_early_demux(struct sk_buff *skb);
+ INDIRECT_CALLABLE_DECLARE(int udpv6_rcv(struct sk_buff *));
+
+ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
+@@ -238,7 +238,7 @@ static inline bool udp_sk_bound_dev_eq(struct net *net, int bound_dev_if,
+ int dif, int sdif)
+ {
+ #if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
+- return inet_bound_dev_eq(!!net->ipv4.sysctl_udp_l3mdev_accept,
++ return inet_bound_dev_eq(!!READ_ONCE(net->ipv4.sysctl_udp_l3mdev_accept),
+ bound_dev_if, dif, sdif);
+ #else
+ return inet_bound_dev_eq(true, bound_dev_if, dif, sdif);
+diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
+index 1e92b52fc8146..3adff3831c047 100644
+--- a/kernel/bpf/core.c
++++ b/kernel/bpf/core.c
+@@ -68,11 +68,13 @@ void *bpf_internal_load_pointer_neg_helper(const struct sk_buff *skb, int k, uns
+ {
+ u8 *ptr = NULL;
+
+- if (k >= SKF_NET_OFF)
++ if (k >= SKF_NET_OFF) {
+ ptr = skb_network_header(skb) + k - SKF_NET_OFF;
+- else if (k >= SKF_LL_OFF)
++ } else if (k >= SKF_LL_OFF) {
++ if (unlikely(!skb_mac_header_was_set(skb)))
++ return NULL;
+ ptr = skb_mac_header(skb) + k - SKF_LL_OFF;
+-
++ }
+ if (ptr >= skb->head && ptr + size <= skb_tail_pointer(skb))
+ return ptr;
+
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index 950b25c3f2103..82238406f5f55 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -6254,10 +6254,10 @@ again:
+
+ if (!atomic_inc_not_zero(&event->rb->mmap_count)) {
+ /*
+- * Raced against perf_mmap_close() through
+- * perf_event_set_output(). Try again, hope for better
+- * luck.
++ * Raced against perf_mmap_close(); remove the
++ * event and try again.
+ */
++ ring_buffer_attach(event, NULL);
+ mutex_unlock(&event->mmap_mutex);
+ goto again;
+ }
+@@ -11826,14 +11826,25 @@ err_size:
+ goto out;
+ }
+
++static void mutex_lock_double(struct mutex *a, struct mutex *b)
++{
++ if (b < a)
++ swap(a, b);
++
++ mutex_lock(a);
++ mutex_lock_nested(b, SINGLE_DEPTH_NESTING);
++}
++
+ static int
+ perf_event_set_output(struct perf_event *event, struct perf_event *output_event)
+ {
+ struct perf_buffer *rb = NULL;
+ int ret = -EINVAL;
+
+- if (!output_event)
++ if (!output_event) {
++ mutex_lock(&event->mmap_mutex);
+ goto set;
++ }
+
+ /* don't allow circular references */
+ if (event == output_event)
+@@ -11871,8 +11882,15 @@ perf_event_set_output(struct perf_event *event, struct perf_event *output_event)
+ event->pmu != output_event->pmu)
+ goto out;
+
++ /*
++ * Hold both mmap_mutex to serialize against perf_mmap_close(). Since
++ * output_event is already on rb->event_list, and the list iteration
++ * restarts after every removal, it is guaranteed this new event is
++ * observed *OR* if output_event is already removed, it's guaranteed we
++ * observe !rb->mmap_count.
++ */
++ mutex_lock_double(&event->mmap_mutex, &output_event->mmap_mutex);
+ set:
+- mutex_lock(&event->mmap_mutex);
+ /* Can't redirect output if we've got an active mmap() */
+ if (atomic_read(&event->mmap_count))
+ goto unlock;
+@@ -11882,6 +11900,12 @@ set:
+ rb = ring_buffer_get(output_event);
+ if (!rb)
+ goto unlock;
++
++ /* did we race against perf_mmap_close() */
++ if (!atomic_read(&rb->mmap_count)) {
++ ring_buffer_put(rb);
++ goto unlock;
++ }
+ }
+
+ ring_buffer_attach(event, rb);
+@@ -11889,20 +11913,13 @@ set:
+ ret = 0;
+ unlock:
+ mutex_unlock(&event->mmap_mutex);
++ if (output_event)
++ mutex_unlock(&output_event->mmap_mutex);
+
+ out:
+ return ret;
+ }
+
+-static void mutex_lock_double(struct mutex *a, struct mutex *b)
+-{
+- if (b < a)
+- swap(a, b);
+-
+- mutex_lock(a);
+- mutex_lock_nested(b, SINGLE_DEPTH_NESTING);
+-}
+-
+ static int perf_event_set_clock(struct perf_event *event, clockid_t clk_id)
+ {
+ bool nmi_safe = false;
+diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
+index b61281d104584..10a916ec64826 100644
+--- a/kernel/sched/deadline.c
++++ b/kernel/sched/deadline.c
+@@ -1669,7 +1669,10 @@ static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags)
+ * the throttle.
+ */
+ p->dl.dl_throttled = 0;
+- BUG_ON(!is_dl_boosted(&p->dl) || flags != ENQUEUE_REPLENISH);
++ if (!(flags & ENQUEUE_REPLENISH))
++ printk_deferred_once("sched: DL de-boosted task PID %d: REPLENISH flag missing\n",
++ task_pid_nr(p));
++
+ return;
+ }
+
+diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c
+index 230038d4f9081..bb9962b33f95c 100644
+--- a/kernel/watch_queue.c
++++ b/kernel/watch_queue.c
+@@ -34,6 +34,27 @@ MODULE_LICENSE("GPL");
+ #define WATCH_QUEUE_NOTE_SIZE 128
+ #define WATCH_QUEUE_NOTES_PER_PAGE (PAGE_SIZE / WATCH_QUEUE_NOTE_SIZE)
+
++/*
++ * This must be called under the RCU read-lock, which makes
++ * sure that the wqueue still exists. It can then take the lock,
++ * and check that the wqueue hasn't been destroyed, which in
++ * turn makes sure that the notification pipe still exists.
++ */
++static inline bool lock_wqueue(struct watch_queue *wqueue)
++{
++ spin_lock_bh(&wqueue->lock);
++ if (unlikely(wqueue->defunct)) {
++ spin_unlock_bh(&wqueue->lock);
++ return false;
++ }
++ return true;
++}
++
++static inline void unlock_wqueue(struct watch_queue *wqueue)
++{
++ spin_unlock_bh(&wqueue->lock);
++}
++
+ static void watch_queue_pipe_buf_release(struct pipe_inode_info *pipe,
+ struct pipe_buffer *buf)
+ {
+@@ -69,6 +90,10 @@ static const struct pipe_buf_operations watch_queue_pipe_buf_ops = {
+
+ /*
+ * Post a notification to a watch queue.
++ *
++ * Must be called with the RCU lock for reading, and the
++ * watch_queue lock held, which guarantees that the pipe
++ * hasn't been released.
+ */
+ static bool post_one_notification(struct watch_queue *wqueue,
+ struct watch_notification *n)
+@@ -85,9 +110,6 @@ static bool post_one_notification(struct watch_queue *wqueue,
+
+ spin_lock_irq(&pipe->rd_wait.lock);
+
+- if (wqueue->defunct)
+- goto out;
+-
+ mask = pipe->ring_size - 1;
+ head = pipe->head;
+ tail = pipe->tail;
+@@ -203,7 +225,10 @@ void __post_watch_notification(struct watch_list *wlist,
+ if (security_post_notification(watch->cred, cred, n) < 0)
+ continue;
+
+- post_one_notification(wqueue, n);
++ if (lock_wqueue(wqueue)) {
++ post_one_notification(wqueue, n);
++ unlock_wqueue(wqueue);
++ }
+ }
+
+ rcu_read_unlock();
+@@ -462,11 +487,12 @@ int add_watch_to_object(struct watch *watch, struct watch_list *wlist)
+ return -EAGAIN;
+ }
+
+- spin_lock_bh(&wqueue->lock);
+- kref_get(&wqueue->usage);
+- kref_get(&watch->usage);
+- hlist_add_head(&watch->queue_node, &wqueue->watches);
+- spin_unlock_bh(&wqueue->lock);
++ if (lock_wqueue(wqueue)) {
++ kref_get(&wqueue->usage);
++ kref_get(&watch->usage);
++ hlist_add_head(&watch->queue_node, &wqueue->watches);
++ unlock_wqueue(wqueue);
++ }
+
+ hlist_add_head(&watch->list_node, &wlist->watchers);
+ return 0;
+@@ -520,20 +546,15 @@ found:
+
+ wqueue = rcu_dereference(watch->queue);
+
+- /* We don't need the watch list lock for the next bit as RCU is
+- * protecting *wqueue from deallocation.
+- */
+- if (wqueue) {
++ if (lock_wqueue(wqueue)) {
+ post_one_notification(wqueue, &n.watch);
+
+- spin_lock_bh(&wqueue->lock);
+-
+ if (!hlist_unhashed(&watch->queue_node)) {
+ hlist_del_init_rcu(&watch->queue_node);
+ put_watch(watch);
+ }
+
+- spin_unlock_bh(&wqueue->lock);
++ unlock_wqueue(wqueue);
+ }
+
+ if (wlist->release_watch) {
+diff --git a/mm/mempolicy.c b/mm/mempolicy.c
+index 8c74107a2b15e..ea6dee61bc9dc 100644
+--- a/mm/mempolicy.c
++++ b/mm/mempolicy.c
+@@ -350,7 +350,7 @@ static void mpol_rebind_preferred(struct mempolicy *pol,
+ */
+ static void mpol_rebind_policy(struct mempolicy *pol, const nodemask_t *newmask)
+ {
+- if (!pol)
++ if (!pol || pol->mode == MPOL_LOCAL)
+ return;
+ if (!mpol_store_user_nodemask(pol) &&
+ nodes_equal(pol->w.cpuset_mems_allowed, *newmask))
+diff --git a/net/core/filter.c b/net/core/filter.c
+index 6391c1885bca8..d0b0c163d3f34 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -7031,7 +7031,7 @@ BPF_CALL_5(bpf_tcp_check_syncookie, struct sock *, sk, void *, iph, u32, iph_len
+ if (sk->sk_protocol != IPPROTO_TCP || sk->sk_state != TCP_LISTEN)
+ return -EINVAL;
+
+- if (!sock_net(sk)->ipv4.sysctl_tcp_syncookies)
++ if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_syncookies))
+ return -EINVAL;
+
+ if (!th->ack || th->rst || th->syn)
+@@ -7106,7 +7106,7 @@ BPF_CALL_5(bpf_tcp_gen_syncookie, struct sock *, sk, void *, iph, u32, iph_len,
+ if (sk->sk_protocol != IPPROTO_TCP || sk->sk_state != TCP_LISTEN)
+ return -EINVAL;
+
+- if (!sock_net(sk)->ipv4.sysctl_tcp_syncookies)
++ if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_syncookies))
+ return -ENOENT;
+
+ if (!th->syn || th->ack || th->fin || th->rst)
+diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c
+index 5f85e01d4093b..b0ff6153be623 100644
+--- a/net/core/secure_seq.c
++++ b/net/core/secure_seq.c
+@@ -64,7 +64,7 @@ u32 secure_tcpv6_ts_off(const struct net *net,
+ .daddr = *(struct in6_addr *)daddr,
+ };
+
+- if (net->ipv4.sysctl_tcp_timestamps != 1)
++ if (READ_ONCE(net->ipv4.sysctl_tcp_timestamps) != 1)
+ return 0;
+
+ ts_secret_init();
+@@ -120,7 +120,7 @@ EXPORT_SYMBOL(secure_ipv6_port_ephemeral);
+ #ifdef CONFIG_INET
+ u32 secure_tcp_ts_off(const struct net *net, __be32 saddr, __be32 daddr)
+ {
+- if (net->ipv4.sysctl_tcp_timestamps != 1)
++ if (READ_ONCE(net->ipv4.sysctl_tcp_timestamps) != 1)
+ return 0;
+
+ ts_secret_init();
+diff --git a/net/core/sock_reuseport.c b/net/core/sock_reuseport.c
+index 3f00a28fe762a..5daa1fa542490 100644
+--- a/net/core/sock_reuseport.c
++++ b/net/core/sock_reuseport.c
+@@ -387,7 +387,7 @@ void reuseport_stop_listen_sock(struct sock *sk)
+ prog = rcu_dereference_protected(reuse->prog,
+ lockdep_is_held(&reuseport_lock));
+
+- if (sock_net(sk)->ipv4.sysctl_tcp_migrate_req ||
++ if (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_migrate_req) ||
+ (prog && prog->expected_attach_type == BPF_SK_REUSEPORT_SELECT_OR_MIGRATE)) {
+ /* Migration capable, move sk from the listening section
+ * to the closed section.
+@@ -545,7 +545,7 @@ struct sock *reuseport_migrate_sock(struct sock *sk,
+ hash = migrating_sk->sk_hash;
+ prog = rcu_dereference(reuse->prog);
+ if (!prog || prog->expected_attach_type != BPF_SK_REUSEPORT_SELECT_OR_MIGRATE) {
+- if (sock_net(sk)->ipv4.sysctl_tcp_migrate_req)
++ if (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_migrate_req))
+ goto select_by_hash;
+ goto failure;
+ }
+diff --git a/net/dsa/port.c b/net/dsa/port.c
+index bdccb613285db..7bc79e28d48ee 100644
+--- a/net/dsa/port.c
++++ b/net/dsa/port.c
+@@ -242,6 +242,60 @@ void dsa_port_disable(struct dsa_port *dp)
+ rtnl_unlock();
+ }
+
++static void dsa_port_reset_vlan_filtering(struct dsa_port *dp,
++ struct dsa_bridge bridge)
++{
++ struct netlink_ext_ack extack = {0};
++ bool change_vlan_filtering = false;
++ struct dsa_switch *ds = dp->ds;
++ struct dsa_port *other_dp;
++ bool vlan_filtering;
++ int err;
++
++ if (ds->needs_standalone_vlan_filtering &&
++ !br_vlan_enabled(bridge.dev)) {
++ change_vlan_filtering = true;
++ vlan_filtering = true;
++ } else if (!ds->needs_standalone_vlan_filtering &&
++ br_vlan_enabled(bridge.dev)) {
++ change_vlan_filtering = true;
++ vlan_filtering = false;
++ }
++
++ /* If the bridge was vlan_filtering, the bridge core doesn't trigger an
++ * event for changing vlan_filtering setting upon slave ports leaving
++ * it. That is a good thing, because that lets us handle it and also
++ * handle the case where the switch's vlan_filtering setting is global
++ * (not per port). When that happens, the correct moment to trigger the
++ * vlan_filtering callback is only when the last port leaves the last
++ * VLAN-aware bridge.
++ */
++ if (change_vlan_filtering && ds->vlan_filtering_is_global) {
++ dsa_switch_for_each_port(other_dp, ds) {
++ struct net_device *br = dsa_port_bridge_dev_get(other_dp);
++
++ if (br && br_vlan_enabled(br)) {
++ change_vlan_filtering = false;
++ break;
++ }
++ }
++ }
++
++ if (!change_vlan_filtering)
++ return;
++
++ err = dsa_port_vlan_filtering(dp, vlan_filtering, &extack);
++ if (extack._msg) {
++ dev_err(ds->dev, "port %d: %s\n", dp->index,
++ extack._msg);
++ }
++ if (err && err != -EOPNOTSUPP) {
++ dev_err(ds->dev,
++ "port %d failed to reset VLAN filtering to %d: %pe\n",
++ dp->index, vlan_filtering, ERR_PTR(err));
++ }
++}
++
+ static int dsa_port_inherit_brport_flags(struct dsa_port *dp,
+ struct netlink_ext_ack *extack)
+ {
+@@ -313,7 +367,8 @@ static int dsa_port_switchdev_sync_attrs(struct dsa_port *dp,
+ return 0;
+ }
+
+-static void dsa_port_switchdev_unsync_attrs(struct dsa_port *dp)
++static void dsa_port_switchdev_unsync_attrs(struct dsa_port *dp,
++ struct dsa_bridge bridge)
+ {
+ /* Configure the port for standalone mode (no address learning,
+ * flood everything).
+@@ -333,7 +388,7 @@ static void dsa_port_switchdev_unsync_attrs(struct dsa_port *dp)
+ */
+ dsa_port_set_state_now(dp, BR_STATE_FORWARDING, true);
+
+- /* VLAN filtering is handled by dsa_switch_bridge_leave */
++ dsa_port_reset_vlan_filtering(dp, bridge);
+
+ /* Ageing time may be global to the switch chip, so don't change it
+ * here because we have no good reason (or value) to change it to.
+@@ -502,7 +557,7 @@ void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br)
+ "port %d failed to notify DSA_NOTIFIER_BRIDGE_LEAVE: %pe\n",
+ dp->index, ERR_PTR(err));
+
+- dsa_port_switchdev_unsync_attrs(dp);
++ dsa_port_switchdev_unsync_attrs(dp, info.bridge);
+ }
+
+ int dsa_port_lag_change(struct dsa_port *dp,
+@@ -752,7 +807,7 @@ int dsa_port_vlan_filtering(struct dsa_port *dp, bool vlan_filtering,
+ ds->vlan_filtering = vlan_filtering;
+
+ dsa_switch_for_each_user_port(other_dp, ds) {
+- struct net_device *slave = dp->slave;
++ struct net_device *slave = other_dp->slave;
+
+ /* We might be called in the unbind path, so not
+ * all slave devices might still be registered.
+diff --git a/net/dsa/switch.c b/net/dsa/switch.c
+index d25cd1da3eb35..d8a80cf9742c0 100644
+--- a/net/dsa/switch.c
++++ b/net/dsa/switch.c
+@@ -115,62 +115,10 @@ static int dsa_switch_bridge_join(struct dsa_switch *ds,
+ return 0;
+ }
+
+-static int dsa_switch_sync_vlan_filtering(struct dsa_switch *ds,
+- struct dsa_notifier_bridge_info *info)
+-{
+- struct netlink_ext_ack extack = {0};
+- bool change_vlan_filtering = false;
+- bool vlan_filtering;
+- struct dsa_port *dp;
+- int err;
+-
+- if (ds->needs_standalone_vlan_filtering &&
+- !br_vlan_enabled(info->bridge.dev)) {
+- change_vlan_filtering = true;
+- vlan_filtering = true;
+- } else if (!ds->needs_standalone_vlan_filtering &&
+- br_vlan_enabled(info->bridge.dev)) {
+- change_vlan_filtering = true;
+- vlan_filtering = false;
+- }
+-
+- /* If the bridge was vlan_filtering, the bridge core doesn't trigger an
+- * event for changing vlan_filtering setting upon slave ports leaving
+- * it. That is a good thing, because that lets us handle it and also
+- * handle the case where the switch's vlan_filtering setting is global
+- * (not per port). When that happens, the correct moment to trigger the
+- * vlan_filtering callback is only when the last port leaves the last
+- * VLAN-aware bridge.
+- */
+- if (change_vlan_filtering && ds->vlan_filtering_is_global) {
+- dsa_switch_for_each_port(dp, ds) {
+- struct net_device *br = dsa_port_bridge_dev_get(dp);
+-
+- if (br && br_vlan_enabled(br)) {
+- change_vlan_filtering = false;
+- break;
+- }
+- }
+- }
+-
+- if (change_vlan_filtering) {
+- err = dsa_port_vlan_filtering(dsa_to_port(ds, info->port),
+- vlan_filtering, &extack);
+- if (extack._msg)
+- dev_err(ds->dev, "port %d: %s\n", info->port,
+- extack._msg);
+- if (err && err != -EOPNOTSUPP)
+- return err;
+- }
+-
+- return 0;
+-}
+-
+ static int dsa_switch_bridge_leave(struct dsa_switch *ds,
+ struct dsa_notifier_bridge_info *info)
+ {
+ struct dsa_switch_tree *dst = ds->dst;
+- int err;
+
+ if (dst->index == info->tree_index && ds->index == info->sw_index &&
+ ds->ops->port_bridge_leave)
+@@ -182,12 +130,6 @@ static int dsa_switch_bridge_leave(struct dsa_switch *ds,
+ info->sw_index, info->port,
+ info->bridge);
+
+- if (ds->dst->index == info->tree_index && ds->index == info->sw_index) {
+- err = dsa_switch_sync_vlan_filtering(ds, info);
+- if (err)
+- return err;
+- }
+-
+ return 0;
+ }
+
+diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
+index 98bc180563d16..5c207367b3b4f 100644
+--- a/net/ipv4/af_inet.c
++++ b/net/ipv4/af_inet.c
+@@ -217,7 +217,7 @@ int inet_listen(struct socket *sock, int backlog)
+ * because the socket was in TCP_LISTEN state previously but
+ * was shutdown() rather than close().
+ */
+- tcp_fastopen = sock_net(sk)->ipv4.sysctl_tcp_fastopen;
++ tcp_fastopen = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fastopen);
+ if ((tcp_fastopen & TFO_SERVER_WO_SOCKOPT1) &&
+ (tcp_fastopen & TFO_SERVER_ENABLE) &&
+ !inet_csk(sk)->icsk_accept_queue.fastopenq.max_qlen) {
+@@ -335,7 +335,7 @@ lookup_protocol:
+ inet->hdrincl = 1;
+ }
+
+- if (net->ipv4.sysctl_ip_no_pmtu_disc)
++ if (READ_ONCE(net->ipv4.sysctl_ip_no_pmtu_disc))
+ inet->pmtudisc = IP_PMTUDISC_DONT;
+ else
+ inet->pmtudisc = IP_PMTUDISC_WANT;
+@@ -1711,24 +1711,14 @@ static const struct net_protocol igmp_protocol = {
+ };
+ #endif
+
+-/* thinking of making this const? Don't.
+- * early_demux can change based on sysctl.
+- */
+-static struct net_protocol tcp_protocol = {
+- .early_demux = tcp_v4_early_demux,
+- .early_demux_handler = tcp_v4_early_demux,
++static const struct net_protocol tcp_protocol = {
+ .handler = tcp_v4_rcv,
+ .err_handler = tcp_v4_err,
+ .no_policy = 1,
+ .icmp_strict_tag_validation = 1,
+ };
+
+-/* thinking of making this const? Don't.
+- * early_demux can change based on sysctl.
+- */
+-static struct net_protocol udp_protocol = {
+- .early_demux = udp_v4_early_demux,
+- .early_demux_handler = udp_v4_early_demux,
++static const struct net_protocol udp_protocol = {
+ .handler = udp_rcv,
+ .err_handler = udp_err,
+ .no_policy = 1,
+diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
+index 720f65f7bd0b0..9f5c1c26c8f26 100644
+--- a/net/ipv4/fib_semantics.c
++++ b/net/ipv4/fib_semantics.c
+@@ -2216,7 +2216,7 @@ void fib_select_multipath(struct fib_result *res, int hash)
+ }
+
+ change_nexthops(fi) {
+- if (net->ipv4.sysctl_fib_multipath_use_neigh) {
++ if (READ_ONCE(net->ipv4.sysctl_fib_multipath_use_neigh)) {
+ if (!fib_good_nh(nexthop_nh))
+ continue;
+ if (!first) {
+diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
+index c13ceda9ce5d8..d8cfa6241c04b 100644
+--- a/net/ipv4/icmp.c
++++ b/net/ipv4/icmp.c
+@@ -878,7 +878,7 @@ static bool icmp_unreach(struct sk_buff *skb)
+ * values please see
+ * Documentation/networking/ip-sysctl.rst
+ */
+- switch (net->ipv4.sysctl_ip_no_pmtu_disc) {
++ switch (READ_ONCE(net->ipv4.sysctl_ip_no_pmtu_disc)) {
+ default:
+ net_dbg_ratelimited("%pI4: fragmentation needed and DF set\n",
+ &iph->daddr);
+diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
+index 1d9e6d5e9a76c..0a0010f896274 100644
+--- a/net/ipv4/igmp.c
++++ b/net/ipv4/igmp.c
+@@ -467,7 +467,8 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
+
+ if (pmc->multiaddr == IGMP_ALL_HOSTS)
+ return skb;
+- if (ipv4_is_local_multicast(pmc->multiaddr) && !net->ipv4.sysctl_igmp_llm_reports)
++ if (ipv4_is_local_multicast(pmc->multiaddr) &&
++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
+ return skb;
+
+ mtu = READ_ONCE(dev->mtu);
+@@ -593,7 +594,7 @@ static int igmpv3_send_report(struct in_device *in_dev, struct ip_mc_list *pmc)
+ if (pmc->multiaddr == IGMP_ALL_HOSTS)
+ continue;
+ if (ipv4_is_local_multicast(pmc->multiaddr) &&
+- !net->ipv4.sysctl_igmp_llm_reports)
++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
+ continue;
+ spin_lock_bh(&pmc->lock);
+ if (pmc->sfcount[MCAST_EXCLUDE])
+@@ -736,7 +737,8 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
+ if (type == IGMPV3_HOST_MEMBERSHIP_REPORT)
+ return igmpv3_send_report(in_dev, pmc);
+
+- if (ipv4_is_local_multicast(group) && !net->ipv4.sysctl_igmp_llm_reports)
++ if (ipv4_is_local_multicast(group) &&
++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
+ return 0;
+
+ if (type == IGMP_HOST_LEAVE_MESSAGE)
+@@ -825,7 +827,7 @@ static void igmp_ifc_event(struct in_device *in_dev)
+ struct net *net = dev_net(in_dev->dev);
+ if (IGMP_V1_SEEN(in_dev) || IGMP_V2_SEEN(in_dev))
+ return;
+- WRITE_ONCE(in_dev->mr_ifc_count, in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv);
++ WRITE_ONCE(in_dev->mr_ifc_count, in_dev->mr_qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv));
+ igmp_ifc_start_timer(in_dev, 1);
+ }
+
+@@ -920,7 +922,8 @@ static bool igmp_heard_report(struct in_device *in_dev, __be32 group)
+
+ if (group == IGMP_ALL_HOSTS)
+ return false;
+- if (ipv4_is_local_multicast(group) && !net->ipv4.sysctl_igmp_llm_reports)
++ if (ipv4_is_local_multicast(group) &&
++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
+ return false;
+
+ rcu_read_lock();
+@@ -1006,7 +1009,7 @@ static bool igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
+ * received value was zero, use the default or statically
+ * configured value.
+ */
+- in_dev->mr_qrv = ih3->qrv ?: net->ipv4.sysctl_igmp_qrv;
++ in_dev->mr_qrv = ih3->qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv);
+ in_dev->mr_qi = IGMPV3_QQIC(ih3->qqic)*HZ ?: IGMP_QUERY_INTERVAL;
+
+ /* RFC3376, 8.3. Query Response Interval:
+@@ -1045,7 +1048,7 @@ static bool igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
+ if (im->multiaddr == IGMP_ALL_HOSTS)
+ continue;
+ if (ipv4_is_local_multicast(im->multiaddr) &&
+- !net->ipv4.sysctl_igmp_llm_reports)
++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
+ continue;
+ spin_lock_bh(&im->lock);
+ if (im->tm_running)
+@@ -1186,7 +1189,7 @@ static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im,
+ pmc->interface = im->interface;
+ in_dev_hold(in_dev);
+ pmc->multiaddr = im->multiaddr;
+- pmc->crcount = in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv;
++ pmc->crcount = in_dev->mr_qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv);
+ pmc->sfmode = im->sfmode;
+ if (pmc->sfmode == MCAST_INCLUDE) {
+ struct ip_sf_list *psf;
+@@ -1237,9 +1240,11 @@ static void igmpv3_del_delrec(struct in_device *in_dev, struct ip_mc_list *im)
+ swap(im->tomb, pmc->tomb);
+ swap(im->sources, pmc->sources);
+ for (psf = im->sources; psf; psf = psf->sf_next)
+- psf->sf_crcount = in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv;
++ psf->sf_crcount = in_dev->mr_qrv ?:
++ READ_ONCE(net->ipv4.sysctl_igmp_qrv);
+ } else {
+- im->crcount = in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv;
++ im->crcount = in_dev->mr_qrv ?:
++ READ_ONCE(net->ipv4.sysctl_igmp_qrv);
+ }
+ in_dev_put(pmc->interface);
+ kfree_pmc(pmc);
+@@ -1296,7 +1301,8 @@ static void __igmp_group_dropped(struct ip_mc_list *im, gfp_t gfp)
+ #ifdef CONFIG_IP_MULTICAST
+ if (im->multiaddr == IGMP_ALL_HOSTS)
+ return;
+- if (ipv4_is_local_multicast(im->multiaddr) && !net->ipv4.sysctl_igmp_llm_reports)
++ if (ipv4_is_local_multicast(im->multiaddr) &&
++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
+ return;
+
+ reporter = im->reporter;
+@@ -1338,13 +1344,14 @@ static void igmp_group_added(struct ip_mc_list *im)
+ #ifdef CONFIG_IP_MULTICAST
+ if (im->multiaddr == IGMP_ALL_HOSTS)
+ return;
+- if (ipv4_is_local_multicast(im->multiaddr) && !net->ipv4.sysctl_igmp_llm_reports)
++ if (ipv4_is_local_multicast(im->multiaddr) &&
++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
+ return;
+
+ if (in_dev->dead)
+ return;
+
+- im->unsolicit_count = net->ipv4.sysctl_igmp_qrv;
++ im->unsolicit_count = READ_ONCE(net->ipv4.sysctl_igmp_qrv);
+ if (IGMP_V1_SEEN(in_dev) || IGMP_V2_SEEN(in_dev)) {
+ spin_lock_bh(&im->lock);
+ igmp_start_timer(im, IGMP_INITIAL_REPORT_DELAY);
+@@ -1358,7 +1365,7 @@ static void igmp_group_added(struct ip_mc_list *im)
+ * IN() to IN(A).
+ */
+ if (im->sfmode == MCAST_EXCLUDE)
+- im->crcount = in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv;
++ im->crcount = in_dev->mr_qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv);
+
+ igmp_ifc_event(in_dev);
+ #endif
+@@ -1642,7 +1649,7 @@ static void ip_mc_rejoin_groups(struct in_device *in_dev)
+ if (im->multiaddr == IGMP_ALL_HOSTS)
+ continue;
+ if (ipv4_is_local_multicast(im->multiaddr) &&
+- !net->ipv4.sysctl_igmp_llm_reports)
++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
+ continue;
+
+ /* a failover is happening and switches
+@@ -1749,7 +1756,7 @@ static void ip_mc_reset(struct in_device *in_dev)
+
+ in_dev->mr_qi = IGMP_QUERY_INTERVAL;
+ in_dev->mr_qri = IGMP_QUERY_RESPONSE_INTERVAL;
+- in_dev->mr_qrv = net->ipv4.sysctl_igmp_qrv;
++ in_dev->mr_qrv = READ_ONCE(net->ipv4.sysctl_igmp_qrv);
+ }
+ #else
+ static void ip_mc_reset(struct in_device *in_dev)
+@@ -1883,7 +1890,7 @@ static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode,
+ #ifdef CONFIG_IP_MULTICAST
+ if (psf->sf_oldin &&
+ !IGMP_V1_SEEN(in_dev) && !IGMP_V2_SEEN(in_dev)) {
+- psf->sf_crcount = in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv;
++ psf->sf_crcount = in_dev->mr_qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv);
+ psf->sf_next = pmc->tomb;
+ pmc->tomb = psf;
+ rv = 1;
+@@ -1947,7 +1954,7 @@ static int ip_mc_del_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
+ /* filter mode change */
+ pmc->sfmode = MCAST_INCLUDE;
+ #ifdef CONFIG_IP_MULTICAST
+- pmc->crcount = in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv;
++ pmc->crcount = in_dev->mr_qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv);
+ WRITE_ONCE(in_dev->mr_ifc_count, pmc->crcount);
+ for (psf = pmc->sources; psf; psf = psf->sf_next)
+ psf->sf_crcount = 0;
+@@ -2126,7 +2133,7 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
+ #ifdef CONFIG_IP_MULTICAST
+ /* else no filters; keep old mode for reports */
+
+- pmc->crcount = in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv;
++ pmc->crcount = in_dev->mr_qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv);
+ WRITE_ONCE(in_dev->mr_ifc_count, pmc->crcount);
+ for (psf = pmc->sources; psf; psf = psf->sf_next)
+ psf->sf_crcount = 0;
+@@ -2192,7 +2199,7 @@ static int __ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr,
+ count++;
+ }
+ err = -ENOBUFS;
+- if (count >= net->ipv4.sysctl_igmp_max_memberships)
++ if (count >= READ_ONCE(net->ipv4.sysctl_igmp_max_memberships))
+ goto done;
+ iml = sock_kmalloc(sk, sizeof(*iml), GFP_KERNEL);
+ if (!iml)
+@@ -2379,7 +2386,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
+ }
+ /* else, add a new source to the filter */
+
+- if (psl && psl->sl_count >= net->ipv4.sysctl_igmp_max_msf) {
++ if (psl && psl->sl_count >= READ_ONCE(net->ipv4.sysctl_igmp_max_msf)) {
+ err = -ENOBUFS;
+ goto done;
+ }
+diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
+index 1e5b53c2bb267..cdc750ced5255 100644
+--- a/net/ipv4/inet_connection_sock.c
++++ b/net/ipv4/inet_connection_sock.c
+@@ -259,7 +259,7 @@ next_port:
+ goto other_half_scan;
+ }
+
+- if (net->ipv4.sysctl_ip_autobind_reuse && !relax) {
++ if (READ_ONCE(net->ipv4.sysctl_ip_autobind_reuse) && !relax) {
+ /* We still have a chance to connect to different destinations */
+ relax = true;
+ goto ports_exhausted;
+@@ -829,7 +829,8 @@ static void reqsk_timer_handler(struct timer_list *t)
+
+ icsk = inet_csk(sk_listener);
+ net = sock_net(sk_listener);
+- max_syn_ack_retries = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_synack_retries;
++ max_syn_ack_retries = icsk->icsk_syn_retries ? :
++ READ_ONCE(net->ipv4.sysctl_tcp_synack_retries);
+ /* Normally all the openreqs are young and become mature
+ * (i.e. converted to established socket) for first timeout.
+ * If synack was not acknowledged for 1 second, it means
+diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c
+index 92ba3350274bc..03bb7c51b6182 100644
+--- a/net/ipv4/ip_forward.c
++++ b/net/ipv4/ip_forward.c
+@@ -151,7 +151,7 @@ int ip_forward(struct sk_buff *skb)
+ !skb_sec_path(skb))
+ ip_rt_send_redirect(skb);
+
+- if (net->ipv4.sysctl_ip_fwd_update_priority)
++ if (READ_ONCE(net->ipv4.sysctl_ip_fwd_update_priority))
+ skb->priority = rt_tos2priority(iph->tos);
+
+ return NF_HOOK(NFPROTO_IPV4, NF_INET_FORWARD,
+diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
+index 95f7bb052784e..f3fd6c3983090 100644
+--- a/net/ipv4/ip_input.c
++++ b/net/ipv4/ip_input.c
+@@ -312,14 +312,13 @@ static bool ip_can_use_hint(const struct sk_buff *skb, const struct iphdr *iph,
+ ip_hdr(hint)->tos == iph->tos;
+ }
+
+-INDIRECT_CALLABLE_DECLARE(int udp_v4_early_demux(struct sk_buff *));
+-INDIRECT_CALLABLE_DECLARE(int tcp_v4_early_demux(struct sk_buff *));
++int tcp_v4_early_demux(struct sk_buff *skb);
++int udp_v4_early_demux(struct sk_buff *skb);
+ static int ip_rcv_finish_core(struct net *net, struct sock *sk,
+ struct sk_buff *skb, struct net_device *dev,
+ const struct sk_buff *hint)
+ {
+ const struct iphdr *iph = ip_hdr(skb);
+- int (*edemux)(struct sk_buff *skb);
+ int err, drop_reason;
+ struct rtable *rt;
+
+@@ -332,21 +331,29 @@ static int ip_rcv_finish_core(struct net *net, struct sock *sk,
+ goto drop_error;
+ }
+
+- if (net->ipv4.sysctl_ip_early_demux &&
++ if (READ_ONCE(net->ipv4.sysctl_ip_early_demux) &&
+ !skb_dst(skb) &&
+ !skb->sk &&
+ !ip_is_fragment(iph)) {
+- const struct net_protocol *ipprot;
+- int protocol = iph->protocol;
+-
+- ipprot = rcu_dereference(inet_protos[protocol]);
+- if (ipprot && (edemux = READ_ONCE(ipprot->early_demux))) {
+- err = INDIRECT_CALL_2(edemux, tcp_v4_early_demux,
+- udp_v4_early_demux, skb);
+- if (unlikely(err))
+- goto drop_error;
+- /* must reload iph, skb->head might have changed */
+- iph = ip_hdr(skb);
++ switch (iph->protocol) {
++ case IPPROTO_TCP:
++ if (READ_ONCE(net->ipv4.sysctl_tcp_early_demux)) {
++ tcp_v4_early_demux(skb);
++
++ /* must reload iph, skb->head might have changed */
++ iph = ip_hdr(skb);
++ }
++ break;
++ case IPPROTO_UDP:
++ if (READ_ONCE(net->ipv4.sysctl_udp_early_demux)) {
++ err = udp_v4_early_demux(skb);
++ if (unlikely(err))
++ goto drop_error;
++
++ /* must reload iph, skb->head might have changed */
++ iph = ip_hdr(skb);
++ }
++ break;
+ }
+ }
+
+diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
+index 445a9ecaefa19..a8a323ecbb54b 100644
+--- a/net/ipv4/ip_sockglue.c
++++ b/net/ipv4/ip_sockglue.c
+@@ -782,7 +782,7 @@ static int ip_set_mcast_msfilter(struct sock *sk, sockptr_t optval, int optlen)
+ /* numsrc >= (4G-140)/128 overflow in 32 bits */
+ err = -ENOBUFS;
+ if (gsf->gf_numsrc >= 0x1ffffff ||
+- gsf->gf_numsrc > sock_net(sk)->ipv4.sysctl_igmp_max_msf)
++ gsf->gf_numsrc > READ_ONCE(sock_net(sk)->ipv4.sysctl_igmp_max_msf))
+ goto out_free_gsf;
+
+ err = -EINVAL;
+@@ -832,7 +832,7 @@ static int compat_ip_set_mcast_msfilter(struct sock *sk, sockptr_t optval,
+
+ /* numsrc >= (4G-140)/128 overflow in 32 bits */
+ err = -ENOBUFS;
+- if (n > sock_net(sk)->ipv4.sysctl_igmp_max_msf)
++ if (n > READ_ONCE(sock_net(sk)->ipv4.sysctl_igmp_max_msf))
+ goto out_free_gsf;
+ err = set_mcast_msfilter(sk, gf32->gf_interface, n, gf32->gf_fmode,
+ &gf32->gf_group, gf32->gf_slist_flex);
+@@ -1244,7 +1244,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, int optname,
+ }
+ /* numsrc >= (1G-4) overflow in 32 bits */
+ if (msf->imsf_numsrc >= 0x3ffffffcU ||
+- msf->imsf_numsrc > net->ipv4.sysctl_igmp_max_msf) {
++ msf->imsf_numsrc > READ_ONCE(net->ipv4.sysctl_igmp_max_msf)) {
+ kfree(msf);
+ err = -ENOBUFS;
+ break;
+@@ -1606,7 +1606,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
+ {
+ struct net *net = sock_net(sk);
+ val = (inet->uc_ttl == -1 ?
+- net->ipv4.sysctl_ip_default_ttl :
++ READ_ONCE(net->ipv4.sysctl_ip_default_ttl) :
+ inet->uc_ttl);
+ break;
+ }
+diff --git a/net/ipv4/netfilter/nf_reject_ipv4.c b/net/ipv4/netfilter/nf_reject_ipv4.c
+index 4eed5afca392e..f2edb40c0db00 100644
+--- a/net/ipv4/netfilter/nf_reject_ipv4.c
++++ b/net/ipv4/netfilter/nf_reject_ipv4.c
+@@ -62,7 +62,7 @@ struct sk_buff *nf_reject_skb_v4_tcp_reset(struct net *net,
+
+ skb_reserve(nskb, LL_MAX_HEADER);
+ niph = nf_reject_iphdr_put(nskb, oldskb, IPPROTO_TCP,
+- net->ipv4.sysctl_ip_default_ttl);
++ READ_ONCE(net->ipv4.sysctl_ip_default_ttl));
+ nf_reject_ip_tcphdr_put(nskb, oldskb, oth);
+ niph->tot_len = htons(nskb->len);
+ ip_send_check(niph);
+@@ -115,7 +115,7 @@ struct sk_buff *nf_reject_skb_v4_unreach(struct net *net,
+
+ skb_reserve(nskb, LL_MAX_HEADER);
+ niph = nf_reject_iphdr_put(nskb, oldskb, IPPROTO_ICMP,
+- net->ipv4.sysctl_ip_default_ttl);
++ READ_ONCE(net->ipv4.sysctl_ip_default_ttl));
+
+ skb_reset_transport_header(nskb);
+ icmph = skb_put_zero(nskb, sizeof(struct icmphdr));
+diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
+index 28836071f0a69..0088a4c64d77e 100644
+--- a/net/ipv4/proc.c
++++ b/net/ipv4/proc.c
+@@ -387,7 +387,7 @@ static int snmp_seq_show_ipstats(struct seq_file *seq, void *v)
+
+ seq_printf(seq, "\nIp: %d %d",
+ IPV4_DEVCONF_ALL(net, FORWARDING) ? 1 : 2,
+- net->ipv4.sysctl_ip_default_ttl);
++ READ_ONCE(net->ipv4.sysctl_ip_default_ttl));
+
+ BUILD_BUG_ON(offsetof(struct ipstats_mib, mibs) != 0);
+ snmp_get_cpu_field64_batch(buff64, snmp4_ipstats_list,
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index ed01063d8f303..02a0a397a2f38 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -1397,7 +1397,7 @@ u32 ip_mtu_from_fib_result(struct fib_result *res, __be32 daddr)
+ struct fib_info *fi = res->fi;
+ u32 mtu = 0;
+
+- if (dev_net(dev)->ipv4.sysctl_ip_fwd_use_pmtu ||
++ if (READ_ONCE(dev_net(dev)->ipv4.sysctl_ip_fwd_use_pmtu) ||
+ fi->fib_metrics->metrics[RTAX_LOCK - 1] & (1 << RTAX_MTU))
+ mtu = fi->fib_mtu;
+
+@@ -1928,7 +1928,7 @@ static u32 fib_multipath_custom_hash_outer(const struct net *net,
+ const struct sk_buff *skb,
+ bool *p_has_inner)
+ {
+- u32 hash_fields = net->ipv4.sysctl_fib_multipath_hash_fields;
++ u32 hash_fields = READ_ONCE(net->ipv4.sysctl_fib_multipath_hash_fields);
+ struct flow_keys keys, hash_keys;
+
+ if (!(hash_fields & FIB_MULTIPATH_HASH_FIELD_OUTER_MASK))
+@@ -1957,7 +1957,7 @@ static u32 fib_multipath_custom_hash_inner(const struct net *net,
+ const struct sk_buff *skb,
+ bool has_inner)
+ {
+- u32 hash_fields = net->ipv4.sysctl_fib_multipath_hash_fields;
++ u32 hash_fields = READ_ONCE(net->ipv4.sysctl_fib_multipath_hash_fields);
+ struct flow_keys keys, hash_keys;
+
+ /* We assume the packet carries an encapsulation, but if none was
+@@ -2017,7 +2017,7 @@ static u32 fib_multipath_custom_hash_skb(const struct net *net,
+ static u32 fib_multipath_custom_hash_fl4(const struct net *net,
+ const struct flowi4 *fl4)
+ {
+- u32 hash_fields = net->ipv4.sysctl_fib_multipath_hash_fields;
++ u32 hash_fields = READ_ONCE(net->ipv4.sysctl_fib_multipath_hash_fields);
+ struct flow_keys hash_keys;
+
+ if (!(hash_fields & FIB_MULTIPATH_HASH_FIELD_OUTER_MASK))
+@@ -2047,7 +2047,7 @@ int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4,
+ struct flow_keys hash_keys;
+ u32 mhash = 0;
+
+- switch (net->ipv4.sysctl_fib_multipath_hash_policy) {
++ switch (READ_ONCE(net->ipv4.sysctl_fib_multipath_hash_policy)) {
+ case 0:
+ memset(&hash_keys, 0, sizeof(hash_keys));
+ hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
+diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
+index b387c48351559..942d2dfa11151 100644
+--- a/net/ipv4/syncookies.c
++++ b/net/ipv4/syncookies.c
+@@ -247,12 +247,12 @@ bool cookie_timestamp_decode(const struct net *net,
+ return true;
+ }
+
+- if (!net->ipv4.sysctl_tcp_timestamps)
++ if (!READ_ONCE(net->ipv4.sysctl_tcp_timestamps))
+ return false;
+
+ tcp_opt->sack_ok = (options & TS_OPT_SACK) ? TCP_SACK_SEEN : 0;
+
+- if (tcp_opt->sack_ok && !net->ipv4.sysctl_tcp_sack)
++ if (tcp_opt->sack_ok && !READ_ONCE(net->ipv4.sysctl_tcp_sack))
+ return false;
+
+ if ((options & TS_OPT_WSCALE_MASK) == TS_OPT_WSCALE_MASK)
+@@ -261,7 +261,7 @@ bool cookie_timestamp_decode(const struct net *net,
+ tcp_opt->wscale_ok = 1;
+ tcp_opt->snd_wscale = options & TS_OPT_WSCALE_MASK;
+
+- return net->ipv4.sysctl_tcp_window_scaling != 0;
++ return READ_ONCE(net->ipv4.sysctl_tcp_window_scaling) != 0;
+ }
+ EXPORT_SYMBOL(cookie_timestamp_decode);
+
+@@ -340,7 +340,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
+ struct flowi4 fl4;
+ u32 tsoff = 0;
+
+- if (!sock_net(sk)->ipv4.sysctl_tcp_syncookies || !th->ack || th->rst)
++ if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_syncookies) ||
++ !th->ack || th->rst)
+ goto out;
+
+ if (tcp_synq_no_recent_overflow(sk))
+diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
+index ffe0264a51b8c..344cdcd5a7d5c 100644
+--- a/net/ipv4/sysctl_net_ipv4.c
++++ b/net/ipv4/sysctl_net_ipv4.c
+@@ -88,7 +88,7 @@ static int ipv4_local_port_range(struct ctl_table *table, int write,
+ * port limit.
+ */
+ if ((range[1] < range[0]) ||
+- (range[0] < net->ipv4.sysctl_ip_prot_sock))
++ (range[0] < READ_ONCE(net->ipv4.sysctl_ip_prot_sock)))
+ ret = -EINVAL;
+ else
+ set_local_port_range(net, range);
+@@ -114,7 +114,7 @@ static int ipv4_privileged_ports(struct ctl_table *table, int write,
+ .extra2 = &ip_privileged_port_max,
+ };
+
+- pports = net->ipv4.sysctl_ip_prot_sock;
++ pports = READ_ONCE(net->ipv4.sysctl_ip_prot_sock);
+
+ ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
+
+@@ -126,7 +126,7 @@ static int ipv4_privileged_ports(struct ctl_table *table, int write,
+ if (range[0] < pports)
+ ret = -EINVAL;
+ else
+- net->ipv4.sysctl_ip_prot_sock = pports;
++ WRITE_ONCE(net->ipv4.sysctl_ip_prot_sock, pports);
+ }
+
+ return ret;
+@@ -354,61 +354,6 @@ bad_key:
+ return ret;
+ }
+
+-static void proc_configure_early_demux(int enabled, int protocol)
+-{
+- struct net_protocol *ipprot;
+-#if IS_ENABLED(CONFIG_IPV6)
+- struct inet6_protocol *ip6prot;
+-#endif
+-
+- rcu_read_lock();
+-
+- ipprot = rcu_dereference(inet_protos[protocol]);
+- if (ipprot)
+- ipprot->early_demux = enabled ? ipprot->early_demux_handler :
+- NULL;
+-
+-#if IS_ENABLED(CONFIG_IPV6)
+- ip6prot = rcu_dereference(inet6_protos[protocol]);
+- if (ip6prot)
+- ip6prot->early_demux = enabled ? ip6prot->early_demux_handler :
+- NULL;
+-#endif
+- rcu_read_unlock();
+-}
+-
+-static int proc_tcp_early_demux(struct ctl_table *table, int write,
+- void *buffer, size_t *lenp, loff_t *ppos)
+-{
+- int ret = 0;
+-
+- ret = proc_dou8vec_minmax(table, write, buffer, lenp, ppos);
+-
+- if (write && !ret) {
+- int enabled = init_net.ipv4.sysctl_tcp_early_demux;
+-
+- proc_configure_early_demux(enabled, IPPROTO_TCP);
+- }
+-
+- return ret;
+-}
+-
+-static int proc_udp_early_demux(struct ctl_table *table, int write,
+- void *buffer, size_t *lenp, loff_t *ppos)
+-{
+- int ret = 0;
+-
+- ret = proc_dou8vec_minmax(table, write, buffer, lenp, ppos);
+-
+- if (write && !ret) {
+- int enabled = init_net.ipv4.sysctl_udp_early_demux;
+-
+- proc_configure_early_demux(enabled, IPPROTO_UDP);
+- }
+-
+- return ret;
+-}
+-
+ static int proc_tfo_blackhole_detect_timeout(struct ctl_table *table,
+ int write, void *buffer,
+ size_t *lenp, loff_t *ppos)
+@@ -711,14 +656,14 @@ static struct ctl_table ipv4_net_table[] = {
+ .data = &init_net.ipv4.sysctl_udp_early_demux,
+ .maxlen = sizeof(u8),
+ .mode = 0644,
+- .proc_handler = proc_udp_early_demux
++ .proc_handler = proc_dou8vec_minmax,
+ },
+ {
+ .procname = "tcp_early_demux",
+ .data = &init_net.ipv4.sysctl_tcp_early_demux,
+ .maxlen = sizeof(u8),
+ .mode = 0644,
+- .proc_handler = proc_tcp_early_demux
++ .proc_handler = proc_dou8vec_minmax,
+ },
+ {
+ .procname = "nexthop_compat_mode",
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index f2fd1779d9251..28db838e604ad 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -441,7 +441,7 @@ void tcp_init_sock(struct sock *sk)
+ tp->snd_cwnd_clamp = ~0;
+ tp->mss_cache = TCP_MSS_DEFAULT;
+
+- tp->reordering = sock_net(sk)->ipv4.sysctl_tcp_reordering;
++ tp->reordering = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_reordering);
+ tcp_assign_congestion_control(sk);
+
+ tp->tsoffset = 0;
+@@ -1151,7 +1151,8 @@ static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
+ struct sockaddr *uaddr = msg->msg_name;
+ int err, flags;
+
+- if (!(sock_net(sk)->ipv4.sysctl_tcp_fastopen & TFO_CLIENT_ENABLE) ||
++ if (!(READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fastopen) &
++ TFO_CLIENT_ENABLE) ||
+ (uaddr && msg->msg_namelen >= sizeof(uaddr->sa_family) &&
+ uaddr->sa_family == AF_UNSPEC))
+ return -EOPNOTSUPP;
+@@ -3638,7 +3639,8 @@ static int do_tcp_setsockopt(struct sock *sk, int level, int optname,
+ case TCP_FASTOPEN_CONNECT:
+ if (val > 1 || val < 0) {
+ err = -EINVAL;
+- } else if (net->ipv4.sysctl_tcp_fastopen & TFO_CLIENT_ENABLE) {
++ } else if (READ_ONCE(net->ipv4.sysctl_tcp_fastopen) &
++ TFO_CLIENT_ENABLE) {
+ if (sk->sk_state == TCP_CLOSE)
+ tp->fastopen_connect = val;
+ else
+@@ -3988,12 +3990,13 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
+ val = keepalive_probes(tp);
+ break;
+ case TCP_SYNCNT:
+- val = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_syn_retries;
++ val = icsk->icsk_syn_retries ? :
++ READ_ONCE(net->ipv4.sysctl_tcp_syn_retries);
+ break;
+ case TCP_LINGER2:
+ val = tp->linger2;
+ if (val >= 0)
+- val = (val ? : net->ipv4.sysctl_tcp_fin_timeout) / HZ;
++ val = (val ? : READ_ONCE(net->ipv4.sysctl_tcp_fin_timeout)) / HZ;
+ break;
+ case TCP_DEFER_ACCEPT:
+ val = retrans_to_secs(icsk->icsk_accept_queue.rskq_defer_accept,
+diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
+index fdbcf2a6d08ef..825b216d11f52 100644
+--- a/net/ipv4/tcp_fastopen.c
++++ b/net/ipv4/tcp_fastopen.c
+@@ -332,7 +332,7 @@ static bool tcp_fastopen_no_cookie(const struct sock *sk,
+ const struct dst_entry *dst,
+ int flag)
+ {
+- return (sock_net(sk)->ipv4.sysctl_tcp_fastopen & flag) ||
++ return (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fastopen) & flag) ||
+ tcp_sk(sk)->fastopen_no_cookie ||
+ (dst && dst_metric(dst, RTAX_FASTOPEN_NO_COOKIE));
+ }
+@@ -347,7 +347,7 @@ struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
+ const struct dst_entry *dst)
+ {
+ bool syn_data = TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq + 1;
+- int tcp_fastopen = sock_net(sk)->ipv4.sysctl_tcp_fastopen;
++ int tcp_fastopen = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fastopen);
+ struct tcp_fastopen_cookie valid_foc = { .len = -1 };
+ struct sock *child;
+ int ret = 0;
+@@ -489,7 +489,7 @@ void tcp_fastopen_active_disable(struct sock *sk)
+ {
+ struct net *net = sock_net(sk);
+
+- if (!sock_net(sk)->ipv4.sysctl_tcp_fastopen_blackhole_timeout)
++ if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fastopen_blackhole_timeout))
+ return;
+
+ /* Paired with READ_ONCE() in tcp_fastopen_active_should_disable() */
+@@ -510,7 +510,8 @@ void tcp_fastopen_active_disable(struct sock *sk)
+ */
+ bool tcp_fastopen_active_should_disable(struct sock *sk)
+ {
+- unsigned int tfo_bh_timeout = sock_net(sk)->ipv4.sysctl_tcp_fastopen_blackhole_timeout;
++ unsigned int tfo_bh_timeout =
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fastopen_blackhole_timeout);
+ unsigned long timeout;
+ int tfo_da_times;
+ int multiplier;
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index 2d71bcfcc7592..19b186a4a8e8c 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -1051,7 +1051,7 @@ static void tcp_check_sack_reordering(struct sock *sk, const u32 low_seq,
+ tp->undo_marker ? tp->undo_retrans : 0);
+ #endif
+ tp->reordering = min_t(u32, (metric + mss - 1) / mss,
+- sock_net(sk)->ipv4.sysctl_tcp_max_reordering);
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_max_reordering));
+ }
+
+ /* This exciting event is worth to be remembered. 8) */
+@@ -2030,7 +2030,7 @@ static void tcp_check_reno_reordering(struct sock *sk, const int addend)
+ return;
+
+ tp->reordering = min_t(u32, tp->packets_out + addend,
+- sock_net(sk)->ipv4.sysctl_tcp_max_reordering);
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_max_reordering));
+ tp->reord_seen++;
+ NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPRENOREORDER);
+ }
+@@ -2095,7 +2095,8 @@ static inline void tcp_init_undo(struct tcp_sock *tp)
+
+ static bool tcp_is_rack(const struct sock *sk)
+ {
+- return sock_net(sk)->ipv4.sysctl_tcp_recovery & TCP_RACK_LOSS_DETECTION;
++ return READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_recovery) &
++ TCP_RACK_LOSS_DETECTION;
+ }
+
+ /* If we detect SACK reneging, forget all SACK information
+@@ -2139,6 +2140,7 @@ void tcp_enter_loss(struct sock *sk)
+ struct tcp_sock *tp = tcp_sk(sk);
+ struct net *net = sock_net(sk);
+ bool new_recovery = icsk->icsk_ca_state < TCP_CA_Recovery;
++ u8 reordering;
+
+ tcp_timeout_mark_lost(sk);
+
+@@ -2159,10 +2161,12 @@ void tcp_enter_loss(struct sock *sk)
+ /* Timeout in disordered state after receiving substantial DUPACKs
+ * suggests that the degree of reordering is over-estimated.
+ */
++ reordering = READ_ONCE(net->ipv4.sysctl_tcp_reordering);
+ if (icsk->icsk_ca_state <= TCP_CA_Disorder &&
+- tp->sacked_out >= net->ipv4.sysctl_tcp_reordering)
++ tp->sacked_out >= reordering)
+ tp->reordering = min_t(unsigned int, tp->reordering,
+- net->ipv4.sysctl_tcp_reordering);
++ reordering);
++
+ tcp_set_ca_state(sk, TCP_CA_Loss);
+ tp->high_seq = tp->snd_nxt;
+ tcp_ecn_queue_cwr(tp);
+@@ -3464,7 +3468,8 @@ static inline bool tcp_may_raise_cwnd(const struct sock *sk, const int flag)
+ * new SACK or ECE mark may first advance cwnd here and later reduce
+ * cwnd in tcp_fastretrans_alert() based on more states.
+ */
+- if (tcp_sk(sk)->reordering > sock_net(sk)->ipv4.sysctl_tcp_reordering)
++ if (tcp_sk(sk)->reordering >
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_reordering))
+ return flag & FLAG_FORWARD_PROGRESS;
+
+ return flag & FLAG_DATA_ACKED;
+@@ -4056,7 +4061,7 @@ void tcp_parse_options(const struct net *net,
+ break;
+ case TCPOPT_WINDOW:
+ if (opsize == TCPOLEN_WINDOW && th->syn &&
+- !estab && net->ipv4.sysctl_tcp_window_scaling) {
++ !estab && READ_ONCE(net->ipv4.sysctl_tcp_window_scaling)) {
+ __u8 snd_wscale = *(__u8 *)ptr;
+ opt_rx->wscale_ok = 1;
+ if (snd_wscale > TCP_MAX_WSCALE) {
+@@ -4072,7 +4077,7 @@ void tcp_parse_options(const struct net *net,
+ case TCPOPT_TIMESTAMP:
+ if ((opsize == TCPOLEN_TIMESTAMP) &&
+ ((estab && opt_rx->tstamp_ok) ||
+- (!estab && net->ipv4.sysctl_tcp_timestamps))) {
++ (!estab && READ_ONCE(net->ipv4.sysctl_tcp_timestamps)))) {
+ opt_rx->saw_tstamp = 1;
+ opt_rx->rcv_tsval = get_unaligned_be32(ptr);
+ opt_rx->rcv_tsecr = get_unaligned_be32(ptr + 4);
+@@ -4080,7 +4085,7 @@ void tcp_parse_options(const struct net *net,
+ break;
+ case TCPOPT_SACK_PERM:
+ if (opsize == TCPOLEN_SACK_PERM && th->syn &&
+- !estab && net->ipv4.sysctl_tcp_sack) {
++ !estab && READ_ONCE(net->ipv4.sysctl_tcp_sack)) {
+ opt_rx->sack_ok = TCP_SACK_SEEN;
+ tcp_sack_reset(opt_rx);
+ }
+@@ -5571,7 +5576,7 @@ static void tcp_check_urg(struct sock *sk, const struct tcphdr *th)
+ struct tcp_sock *tp = tcp_sk(sk);
+ u32 ptr = ntohs(th->urg_ptr);
+
+- if (ptr && !sock_net(sk)->ipv4.sysctl_tcp_stdurg)
++ if (ptr && !READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_stdurg))
+ ptr--;
+ ptr += ntohl(th->seq);
+
+@@ -6780,11 +6785,14 @@ static bool tcp_syn_flood_action(const struct sock *sk, const char *proto)
+ {
+ struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue;
+ const char *msg = "Dropping request";
+- bool want_cookie = false;
+ struct net *net = sock_net(sk);
++ bool want_cookie = false;
++ u8 syncookies;
++
++ syncookies = READ_ONCE(net->ipv4.sysctl_tcp_syncookies);
+
+ #ifdef CONFIG_SYN_COOKIES
+- if (net->ipv4.sysctl_tcp_syncookies) {
++ if (syncookies) {
+ msg = "Sending cookies";
+ want_cookie = true;
+ __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPREQQFULLDOCOOKIES);
+@@ -6792,8 +6800,7 @@ static bool tcp_syn_flood_action(const struct sock *sk, const char *proto)
+ #endif
+ __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPREQQFULLDROP);
+
+- if (!queue->synflood_warned &&
+- net->ipv4.sysctl_tcp_syncookies != 2 &&
++ if (!queue->synflood_warned && syncookies != 2 &&
+ xchg(&queue->synflood_warned, 1) == 0)
+ net_info_ratelimited("%s: Possible SYN flooding on port %d. %s. Check SNMP counters.\n",
+ proto, sk->sk_num, msg);
+@@ -6842,7 +6849,7 @@ u16 tcp_get_syncookie_mss(struct request_sock_ops *rsk_ops,
+ struct tcp_sock *tp = tcp_sk(sk);
+ u16 mss;
+
+- if (sock_net(sk)->ipv4.sysctl_tcp_syncookies != 2 &&
++ if (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_syncookies) != 2 &&
+ !inet_csk_reqsk_queue_is_full(sk))
+ return 0;
+
+@@ -6876,13 +6883,15 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
+ bool want_cookie = false;
+ struct dst_entry *dst;
+ struct flowi fl;
++ u8 syncookies;
++
++ syncookies = READ_ONCE(net->ipv4.sysctl_tcp_syncookies);
+
+ /* TW buckets are converted to open requests without
+ * limitations, they conserve resources and peer is
+ * evidently real one.
+ */
+- if ((net->ipv4.sysctl_tcp_syncookies == 2 ||
+- inet_csk_reqsk_queue_is_full(sk)) && !isn) {
++ if ((syncookies == 2 || inet_csk_reqsk_queue_is_full(sk)) && !isn) {
+ want_cookie = tcp_syn_flood_action(sk, rsk_ops->slab_name);
+ if (!want_cookie)
+ goto drop;
+@@ -6931,10 +6940,12 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
+ tcp_rsk(req)->ts_off = af_ops->init_ts_off(net, skb);
+
+ if (!want_cookie && !isn) {
++ int max_syn_backlog = READ_ONCE(net->ipv4.sysctl_max_syn_backlog);
++
+ /* Kill the following clause, if you dislike this way. */
+- if (!net->ipv4.sysctl_tcp_syncookies &&
+- (net->ipv4.sysctl_max_syn_backlog - inet_csk_reqsk_queue_len(sk) <
+- (net->ipv4.sysctl_max_syn_backlog >> 2)) &&
++ if (!syncookies &&
++ (max_syn_backlog - inet_csk_reqsk_queue_len(sk) <
++ (max_syn_backlog >> 2)) &&
+ !tcp_peer_is_proven(req, dst)) {
+ /* Without syncookies last quarter of
+ * backlog is filled with destinations,
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index cd78b4fc334f7..a57f96b868741 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -108,10 +108,10 @@ static u32 tcp_v4_init_ts_off(const struct net *net, const struct sk_buff *skb)
+
+ int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
+ {
++ int reuse = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_tw_reuse);
+ const struct inet_timewait_sock *tw = inet_twsk(sktw);
+ const struct tcp_timewait_sock *tcptw = tcp_twsk(sktw);
+ struct tcp_sock *tp = tcp_sk(sk);
+- int reuse = sock_net(sk)->ipv4.sysctl_tcp_tw_reuse;
+
+ if (reuse == 2) {
+ /* Still does not detect *everything* that goes through
+diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
+index 7029b0e98edb2..a501150deaa3b 100644
+--- a/net/ipv4/tcp_metrics.c
++++ b/net/ipv4/tcp_metrics.c
+@@ -428,7 +428,8 @@ void tcp_update_metrics(struct sock *sk)
+ if (!tcp_metric_locked(tm, TCP_METRIC_REORDERING)) {
+ val = tcp_metric_get(tm, TCP_METRIC_REORDERING);
+ if (val < tp->reordering &&
+- tp->reordering != net->ipv4.sysctl_tcp_reordering)
++ tp->reordering !=
++ READ_ONCE(net->ipv4.sysctl_tcp_reordering))
+ tcp_metric_set(tm, TCP_METRIC_REORDERING,
+ tp->reordering);
+ }
+diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
+index 6854bb1fb32b2..cb95d88497aea 100644
+--- a/net/ipv4/tcp_minisocks.c
++++ b/net/ipv4/tcp_minisocks.c
+@@ -173,7 +173,7 @@ tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb,
+ * Oh well... nobody has a sufficient solution to this
+ * protocol bug yet.
+ */
+- if (twsk_net(tw)->ipv4.sysctl_tcp_rfc1337 == 0) {
++ if (!READ_ONCE(twsk_net(tw)->ipv4.sysctl_tcp_rfc1337)) {
+ kill:
+ inet_twsk_deschedule_put(tw);
+ return TCP_TW_SUCCESS;
+@@ -781,7 +781,7 @@ listen_overflow:
+ if (sk != req->rsk_listener)
+ __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMIGRATEREQFAILURE);
+
+- if (!sock_net(sk)->ipv4.sysctl_tcp_abort_on_overflow) {
++ if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_abort_on_overflow)) {
+ inet_rsk(req)->acked = 1;
+ return NULL;
+ }
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 34249469e361f..3554a4c1e1b82 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -789,18 +789,18 @@ static unsigned int tcp_syn_options(struct sock *sk, struct sk_buff *skb,
+ opts->mss = tcp_advertise_mss(sk);
+ remaining -= TCPOLEN_MSS_ALIGNED;
+
+- if (likely(sock_net(sk)->ipv4.sysctl_tcp_timestamps && !*md5)) {
++ if (likely(READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_timestamps) && !*md5)) {
+ opts->options |= OPTION_TS;
+ opts->tsval = tcp_skb_timestamp(skb) + tp->tsoffset;
+ opts->tsecr = tp->rx_opt.ts_recent;
+ remaining -= TCPOLEN_TSTAMP_ALIGNED;
+ }
+- if (likely(sock_net(sk)->ipv4.sysctl_tcp_window_scaling)) {
++ if (likely(READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_window_scaling))) {
+ opts->ws = tp->rx_opt.rcv_wscale;
+ opts->options |= OPTION_WSCALE;
+ remaining -= TCPOLEN_WSCALE_ALIGNED;
+ }
+- if (likely(sock_net(sk)->ipv4.sysctl_tcp_sack)) {
++ if (likely(READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_sack))) {
+ opts->options |= OPTION_SACK_ADVERTISE;
+ if (unlikely(!(OPTION_TS & opts->options)))
+ remaining -= TCPOLEN_SACKPERM_ALIGNED;
+@@ -1717,7 +1717,8 @@ static inline int __tcp_mtu_to_mss(struct sock *sk, int pmtu)
+ mss_now -= icsk->icsk_ext_hdr_len;
+
+ /* Then reserve room for full set of TCP options and 8 bytes of data */
+- mss_now = max(mss_now, sock_net(sk)->ipv4.sysctl_tcp_min_snd_mss);
++ mss_now = max(mss_now,
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_min_snd_mss));
+ return mss_now;
+ }
+
+@@ -1760,10 +1761,10 @@ void tcp_mtup_init(struct sock *sk)
+ struct inet_connection_sock *icsk = inet_csk(sk);
+ struct net *net = sock_net(sk);
+
+- icsk->icsk_mtup.enabled = net->ipv4.sysctl_tcp_mtu_probing > 1;
++ icsk->icsk_mtup.enabled = READ_ONCE(net->ipv4.sysctl_tcp_mtu_probing) > 1;
+ icsk->icsk_mtup.search_high = tp->rx_opt.mss_clamp + sizeof(struct tcphdr) +
+ icsk->icsk_af_ops->net_header_len;
+- icsk->icsk_mtup.search_low = tcp_mss_to_mtu(sk, net->ipv4.sysctl_tcp_base_mss);
++ icsk->icsk_mtup.search_low = tcp_mss_to_mtu(sk, READ_ONCE(net->ipv4.sysctl_tcp_base_mss));
+ icsk->icsk_mtup.probe_size = 0;
+ if (icsk->icsk_mtup.enabled)
+ icsk->icsk_mtup.probe_timestamp = tcp_jiffies32;
+@@ -1895,7 +1896,7 @@ static void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited)
+ if (tp->packets_out > tp->snd_cwnd_used)
+ tp->snd_cwnd_used = tp->packets_out;
+
+- if (sock_net(sk)->ipv4.sysctl_tcp_slow_start_after_idle &&
++ if (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_slow_start_after_idle) &&
+ (s32)(tcp_jiffies32 - tp->snd_cwnd_stamp) >= inet_csk(sk)->icsk_rto &&
+ !ca_ops->cong_control)
+ tcp_cwnd_application_limited(sk);
+@@ -2280,7 +2281,7 @@ static inline void tcp_mtu_check_reprobe(struct sock *sk)
+ u32 interval;
+ s32 delta;
+
+- interval = net->ipv4.sysctl_tcp_probe_interval;
++ interval = READ_ONCE(net->ipv4.sysctl_tcp_probe_interval);
+ delta = tcp_jiffies32 - icsk->icsk_mtup.probe_timestamp;
+ if (unlikely(delta >= interval * HZ)) {
+ int mss = tcp_current_mss(sk);
+@@ -2364,7 +2365,7 @@ static int tcp_mtu_probe(struct sock *sk)
+ * probing process by not resetting search range to its orignal.
+ */
+ if (probe_size > tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_high) ||
+- interval < net->ipv4.sysctl_tcp_probe_threshold) {
++ interval < READ_ONCE(net->ipv4.sysctl_tcp_probe_threshold)) {
+ /* Check whether enough time has elaplased for
+ * another round of probing.
+ */
+@@ -2738,7 +2739,7 @@ bool tcp_schedule_loss_probe(struct sock *sk, bool advancing_rto)
+ if (rcu_access_pointer(tp->fastopen_rsk))
+ return false;
+
+- early_retrans = sock_net(sk)->ipv4.sysctl_tcp_early_retrans;
++ early_retrans = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_early_retrans);
+ /* Schedule a loss probe in 2*RTT for SACK capable connections
+ * not in loss recovery, that are either limited by cwnd or application.
+ */
+@@ -3102,7 +3103,7 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *to,
+ struct sk_buff *skb = to, *tmp;
+ bool first = true;
+
+- if (!sock_net(sk)->ipv4.sysctl_tcp_retrans_collapse)
++ if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_retrans_collapse))
+ return;
+ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN)
+ return;
+@@ -3644,7 +3645,7 @@ static void tcp_connect_init(struct sock *sk)
+ * See tcp_input.c:tcp_rcv_state_process case TCP_SYN_SENT.
+ */
+ tp->tcp_header_len = sizeof(struct tcphdr);
+- if (sock_net(sk)->ipv4.sysctl_tcp_timestamps)
++ if (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_timestamps))
+ tp->tcp_header_len += TCPOLEN_TSTAMP_ALIGNED;
+
+ #ifdef CONFIG_TCP_MD5SIG
+@@ -3680,7 +3681,7 @@ static void tcp_connect_init(struct sock *sk)
+ tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0),
+ &tp->rcv_wnd,
+ &tp->window_clamp,
+- sock_net(sk)->ipv4.sysctl_tcp_window_scaling,
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_window_scaling),
+ &rcv_wscale,
+ rcv_wnd);
+
+@@ -4087,7 +4088,7 @@ void tcp_send_probe0(struct sock *sk)
+
+ icsk->icsk_probes_out++;
+ if (err <= 0) {
+- if (icsk->icsk_backoff < net->ipv4.sysctl_tcp_retries2)
++ if (icsk->icsk_backoff < READ_ONCE(net->ipv4.sysctl_tcp_retries2))
+ icsk->icsk_backoff++;
+ timeout = tcp_probe0_when(sk, TCP_RTO_MAX);
+ } else {
+diff --git a/net/ipv4/tcp_recovery.c b/net/ipv4/tcp_recovery.c
+index fd113f6226efc..ac14216f6204f 100644
+--- a/net/ipv4/tcp_recovery.c
++++ b/net/ipv4/tcp_recovery.c
+@@ -19,7 +19,8 @@ static u32 tcp_rack_reo_wnd(const struct sock *sk)
+ return 0;
+
+ if (tp->sacked_out >= tp->reordering &&
+- !(sock_net(sk)->ipv4.sysctl_tcp_recovery & TCP_RACK_NO_DUPTHRESH))
++ !(READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_recovery) &
++ TCP_RACK_NO_DUPTHRESH))
+ return 0;
+ }
+
+@@ -192,7 +193,8 @@ void tcp_rack_update_reo_wnd(struct sock *sk, struct rate_sample *rs)
+ {
+ struct tcp_sock *tp = tcp_sk(sk);
+
+- if (sock_net(sk)->ipv4.sysctl_tcp_recovery & TCP_RACK_STATIC_REO_WND ||
++ if ((READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_recovery) &
++ TCP_RACK_STATIC_REO_WND) ||
+ !rs->prior_delivered)
+ return;
+
+diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
+index 20cf4a98c69d8..50bba370486e8 100644
+--- a/net/ipv4/tcp_timer.c
++++ b/net/ipv4/tcp_timer.c
+@@ -143,7 +143,7 @@ static int tcp_out_of_resources(struct sock *sk, bool do_reset)
+ */
+ static int tcp_orphan_retries(struct sock *sk, bool alive)
+ {
+- int retries = sock_net(sk)->ipv4.sysctl_tcp_orphan_retries; /* May be zero. */
++ int retries = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_orphan_retries); /* May be zero. */
+
+ /* We know from an ICMP that something is wrong. */
+ if (sk->sk_err_soft && !alive)
+@@ -163,7 +163,7 @@ static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk)
+ int mss;
+
+ /* Black hole detection */
+- if (!net->ipv4.sysctl_tcp_mtu_probing)
++ if (!READ_ONCE(net->ipv4.sysctl_tcp_mtu_probing))
+ return;
+
+ if (!icsk->icsk_mtup.enabled) {
+@@ -171,9 +171,9 @@ static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk)
+ icsk->icsk_mtup.probe_timestamp = tcp_jiffies32;
+ } else {
+ mss = tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_low) >> 1;
+- mss = min(net->ipv4.sysctl_tcp_base_mss, mss);
+- mss = max(mss, net->ipv4.sysctl_tcp_mtu_probe_floor);
+- mss = max(mss, net->ipv4.sysctl_tcp_min_snd_mss);
++ mss = min(READ_ONCE(net->ipv4.sysctl_tcp_base_mss), mss);
++ mss = max(mss, READ_ONCE(net->ipv4.sysctl_tcp_mtu_probe_floor));
++ mss = max(mss, READ_ONCE(net->ipv4.sysctl_tcp_min_snd_mss));
+ icsk->icsk_mtup.search_low = tcp_mss_to_mtu(sk, mss);
+ }
+ tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
+@@ -239,17 +239,18 @@ static int tcp_write_timeout(struct sock *sk)
+ if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
+ if (icsk->icsk_retransmits)
+ __dst_negative_advice(sk);
+- retry_until = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_syn_retries;
++ retry_until = icsk->icsk_syn_retries ? :
++ READ_ONCE(net->ipv4.sysctl_tcp_syn_retries);
+ expired = icsk->icsk_retransmits >= retry_until;
+ } else {
+- if (retransmits_timed_out(sk, net->ipv4.sysctl_tcp_retries1, 0)) {
++ if (retransmits_timed_out(sk, READ_ONCE(net->ipv4.sysctl_tcp_retries1), 0)) {
+ /* Black hole detection */
+ tcp_mtu_probing(icsk, sk);
+
+ __dst_negative_advice(sk);
+ }
+
+- retry_until = net->ipv4.sysctl_tcp_retries2;
++ retry_until = READ_ONCE(net->ipv4.sysctl_tcp_retries2);
+ if (sock_flag(sk, SOCK_DEAD)) {
+ const bool alive = icsk->icsk_rto < TCP_RTO_MAX;
+
+@@ -380,7 +381,7 @@ static void tcp_probe_timer(struct sock *sk)
+ msecs_to_jiffies(icsk->icsk_user_timeout))
+ goto abort;
+
+- max_probes = sock_net(sk)->ipv4.sysctl_tcp_retries2;
++ max_probes = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_retries2);
+ if (sock_flag(sk, SOCK_DEAD)) {
+ const bool alive = inet_csk_rto_backoff(icsk, TCP_RTO_MAX) < TCP_RTO_MAX;
+
+@@ -406,12 +407,15 @@ abort: tcp_write_err(sk);
+ static void tcp_fastopen_synack_timer(struct sock *sk, struct request_sock *req)
+ {
+ struct inet_connection_sock *icsk = inet_csk(sk);
+- int max_retries = icsk->icsk_syn_retries ? :
+- sock_net(sk)->ipv4.sysctl_tcp_synack_retries + 1; /* add one more retry for fastopen */
+ struct tcp_sock *tp = tcp_sk(sk);
++ int max_retries;
+
+ req->rsk_ops->syn_ack_timeout(req);
+
++ /* add one more retry for fastopen */
++ max_retries = icsk->icsk_syn_retries ? :
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_synack_retries) + 1;
++
+ if (req->num_timeout >= max_retries) {
+ tcp_write_err(sk);
+ return;
+@@ -574,7 +578,7 @@ out_reset_timer:
+ * linear-timeout retransmissions into a black hole
+ */
+ if (sk->sk_state == TCP_ESTABLISHED &&
+- (tp->thin_lto || net->ipv4.sysctl_tcp_thin_linear_timeouts) &&
++ (tp->thin_lto || READ_ONCE(net->ipv4.sysctl_tcp_thin_linear_timeouts)) &&
+ tcp_stream_is_thin(tp) &&
+ icsk->icsk_retransmits <= TCP_THIN_LINEAR_RETRIES) {
+ icsk->icsk_backoff = 0;
+@@ -585,7 +589,7 @@ out_reset_timer:
+ }
+ inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
+ tcp_clamp_rto_to_user_timeout(sk), TCP_RTO_MAX);
+- if (retransmits_timed_out(sk, net->ipv4.sysctl_tcp_retries1 + 1, 0))
++ if (retransmits_timed_out(sk, READ_ONCE(net->ipv4.sysctl_tcp_retries1) + 1, 0))
+ __sk_dst_reset(sk);
+
+ out:;
+diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
+index 7d7b7523d1265..ef1e6545d8690 100644
+--- a/net/ipv6/af_inet6.c
++++ b/net/ipv6/af_inet6.c
+@@ -226,7 +226,7 @@ lookup_protocol:
+ RCU_INIT_POINTER(inet->mc_list, NULL);
+ inet->rcv_tos = 0;
+
+- if (net->ipv4.sysctl_ip_no_pmtu_disc)
++ if (READ_ONCE(net->ipv4.sysctl_ip_no_pmtu_disc))
+ inet->pmtudisc = IP_PMTUDISC_DONT;
+ else
+ inet->pmtudisc = IP_PMTUDISC_WANT;
+diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
+index 5b5ea35635f9f..caba03e551ef6 100644
+--- a/net/ipv6/ip6_input.c
++++ b/net/ipv6/ip6_input.c
+@@ -45,20 +45,23 @@
+ #include <net/inet_ecn.h>
+ #include <net/dst_metadata.h>
+
+-INDIRECT_CALLABLE_DECLARE(void tcp_v6_early_demux(struct sk_buff *));
+ static void ip6_rcv_finish_core(struct net *net, struct sock *sk,
+ struct sk_buff *skb)
+ {
+- void (*edemux)(struct sk_buff *skb);
+-
+- if (net->ipv4.sysctl_ip_early_demux && !skb_dst(skb) && skb->sk == NULL) {
+- const struct inet6_protocol *ipprot;
+-
+- ipprot = rcu_dereference(inet6_protos[ipv6_hdr(skb)->nexthdr]);
+- if (ipprot && (edemux = READ_ONCE(ipprot->early_demux)))
+- INDIRECT_CALL_2(edemux, tcp_v6_early_demux,
+- udp_v6_early_demux, skb);
++ if (READ_ONCE(net->ipv4.sysctl_ip_early_demux) &&
++ !skb_dst(skb) && !skb->sk) {
++ switch (ipv6_hdr(skb)->nexthdr) {
++ case IPPROTO_TCP:
++ if (READ_ONCE(net->ipv4.sysctl_tcp_early_demux))
++ tcp_v6_early_demux(skb);
++ break;
++ case IPPROTO_UDP:
++ if (READ_ONCE(net->ipv4.sysctl_udp_early_demux))
++ udp_v6_early_demux(skb);
++ break;
++ }
+ }
++
+ if (!skb_valid_dst(skb))
+ ip6_route_input(skb);
+ }
+diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
+index 9cc123f000fbc..5014aa6634527 100644
+--- a/net/ipv6/syncookies.c
++++ b/net/ipv6/syncookies.c
+@@ -141,7 +141,8 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
+ __u8 rcv_wscale;
+ u32 tsoff = 0;
+
+- if (!sock_net(sk)->ipv4.sysctl_tcp_syncookies || !th->ack || th->rst)
++ if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_syncookies) ||
++ !th->ack || th->rst)
+ goto out;
+
+ if (tcp_synq_no_recent_overflow(sk))
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index cbc5fff3d8466..5185c11dc4447 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -1822,7 +1822,7 @@ do_time_wait:
+ goto discard_it;
+ }
+
+-INDIRECT_CALLABLE_SCOPE void tcp_v6_early_demux(struct sk_buff *skb)
++void tcp_v6_early_demux(struct sk_buff *skb)
+ {
+ const struct ipv6hdr *hdr;
+ const struct tcphdr *th;
+@@ -2176,12 +2176,7 @@ struct proto tcpv6_prot = {
+ };
+ EXPORT_SYMBOL_GPL(tcpv6_prot);
+
+-/* thinking of making this const? Don't.
+- * early_demux can change based on sysctl.
+- */
+-static struct inet6_protocol tcpv6_protocol = {
+- .early_demux = tcp_v6_early_demux,
+- .early_demux_handler = tcp_v6_early_demux,
++static const struct inet6_protocol tcpv6_protocol = {
+ .handler = tcp_v6_rcv,
+ .err_handler = tcp_v6_err,
+ .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
+index a535c3f2e4af4..aea28bf701be4 100644
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -1052,7 +1052,7 @@ static struct sock *__udp6_lib_demux_lookup(struct net *net,
+ return NULL;
+ }
+
+-INDIRECT_CALLABLE_SCOPE void udp_v6_early_demux(struct sk_buff *skb)
++void udp_v6_early_demux(struct sk_buff *skb)
+ {
+ struct net *net = dev_net(skb->dev);
+ const struct udphdr *uh;
+@@ -1660,12 +1660,7 @@ int udpv6_getsockopt(struct sock *sk, int level, int optname,
+ return ipv6_getsockopt(sk, level, optname, optval, optlen);
+ }
+
+-/* thinking of making this const? Don't.
+- * early_demux can change based on sysctl.
+- */
+-static struct inet6_protocol udpv6_protocol = {
+- .early_demux = udp_v6_early_demux,
+- .early_demux_handler = udp_v6_early_demux,
++static const struct inet6_protocol udpv6_protocol = {
+ .handler = udpv6_rcv,
+ .err_handler = udpv6_err,
+ .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
+diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c
+index e479dd0561c54..16915f8eef2b1 100644
+--- a/net/netfilter/nf_synproxy_core.c
++++ b/net/netfilter/nf_synproxy_core.c
+@@ -405,7 +405,7 @@ synproxy_build_ip(struct net *net, struct sk_buff *skb, __be32 saddr,
+ iph->tos = 0;
+ iph->id = 0;
+ iph->frag_off = htons(IP_DF);
+- iph->ttl = net->ipv4.sysctl_ip_default_ttl;
++ iph->ttl = READ_ONCE(net->ipv4.sysctl_ip_default_ttl);
+ iph->protocol = IPPROTO_TCP;
+ iph->check = 0;
+ iph->saddr = saddr;
+diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
+index 2d4dc1468a9a5..6fd33c75d6bb2 100644
+--- a/net/sched/cls_api.c
++++ b/net/sched/cls_api.c
+@@ -3531,7 +3531,7 @@ int tc_setup_action(struct flow_action *flow_action,
+ struct tc_action *actions[],
+ struct netlink_ext_ack *extack)
+ {
+- int i, j, index, err = 0;
++ int i, j, k, index, err = 0;
+ struct tc_action *act;
+
+ BUILD_BUG_ON(TCA_ACT_HW_STATS_ANY != FLOW_ACTION_HW_STATS_ANY);
+@@ -3551,14 +3551,18 @@ int tc_setup_action(struct flow_action *flow_action,
+ if (err)
+ goto err_out_locked;
+
+- entry->hw_stats = tc_act_hw_stats(act->hw_stats);
+- entry->hw_index = act->tcfa_index;
+ index = 0;
+ err = tc_setup_offload_act(act, entry, &index, extack);
+- if (!err)
+- j += index;
+- else
++ if (err)
+ goto err_out_locked;
++
++ for (k = 0; k < index ; k++) {
++ entry[k].hw_stats = tc_act_hw_stats(act->hw_stats);
++ entry[k].hw_index = act->tcfa_index;
++ }
++
++ j += index;
++
+ spin_unlock_bh(&act->tcfa_lock);
+ }
+
+diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
+index 35928fefae332..1a094b087d88b 100644
+--- a/net/sctp/protocol.c
++++ b/net/sctp/protocol.c
+@@ -358,7 +358,7 @@ static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp)
+ if (addr->v4.sin_addr.s_addr != htonl(INADDR_ANY) &&
+ ret != RTN_LOCAL &&
+ !sp->inet.freebind &&
+- !net->ipv4.sysctl_ip_nonlocal_bind)
++ !READ_ONCE(net->ipv4.sysctl_ip_nonlocal_bind))
+ return 0;
+
+ if (ipv6_only_sock(sctp_opt2sk(sp)))
+diff --git a/net/smc/smc_llc.c b/net/smc/smc_llc.c
+index c4d057b2941d5..0bde36b564727 100644
+--- a/net/smc/smc_llc.c
++++ b/net/smc/smc_llc.c
+@@ -2122,7 +2122,7 @@ void smc_llc_lgr_init(struct smc_link_group *lgr, struct smc_sock *smc)
+ init_waitqueue_head(&lgr->llc_flow_waiter);
+ init_waitqueue_head(&lgr->llc_msg_waiter);
+ mutex_init(&lgr->llc_conf_mutex);
+- lgr->llc_testlink_time = net->ipv4.sysctl_tcp_keepalive_time;
++ lgr->llc_testlink_time = READ_ONCE(net->ipv4.sysctl_tcp_keepalive_time);
+ }
+
+ /* called after lgr was removed from lgr_list */
+diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c
+index 3a61bb5945441..9c3933781ad47 100644
+--- a/net/tls/tls_device.c
++++ b/net/tls/tls_device.c
+@@ -97,13 +97,16 @@ static void tls_device_queue_ctx_destruction(struct tls_context *ctx)
+ unsigned long flags;
+
+ spin_lock_irqsave(&tls_device_lock, flags);
++ if (unlikely(!refcount_dec_and_test(&ctx->refcount)))
++ goto unlock;
++
+ list_move_tail(&ctx->list, &tls_device_gc_list);
+
+ /* schedule_work inside the spinlock
+ * to make sure tls_device_down waits for that work.
+ */
+ schedule_work(&tls_device_gc_work);
+-
++unlock:
+ spin_unlock_irqrestore(&tls_device_lock, flags);
+ }
+
+@@ -194,8 +197,7 @@ void tls_device_sk_destruct(struct sock *sk)
+ clean_acked_data_disable(inet_csk(sk));
+ }
+
+- if (refcount_dec_and_test(&tls_ctx->refcount))
+- tls_device_queue_ctx_destruction(tls_ctx);
++ tls_device_queue_ctx_destruction(tls_ctx);
+ }
+ EXPORT_SYMBOL_GPL(tls_device_sk_destruct);
+
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index f1876ea61fdce..f1a0bab920a55 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -2678,8 +2678,10 @@ static int xfrm_expand_policies(const struct flowi *fl, u16 family,
+ *num_xfrms = 0;
+ return 0;
+ }
+- if (IS_ERR(pols[0]))
++ if (IS_ERR(pols[0])) {
++ *num_pols = 0;
+ return PTR_ERR(pols[0]);
++ }
+
+ *num_xfrms = pols[0]->xfrm_nr;
+
+@@ -2694,6 +2696,7 @@ static int xfrm_expand_policies(const struct flowi *fl, u16 family,
+ if (pols[1]) {
+ if (IS_ERR(pols[1])) {
+ xfrm_pols_put(pols, *num_pols);
++ *num_pols = 0;
+ return PTR_ERR(pols[1]);
+ }
+ (*num_pols)++;
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+index b749935152ba5..b4ce16a934a28 100644
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -2620,7 +2620,7 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload)
+ int err;
+
+ if (family == AF_INET &&
+- xs_net(x)->ipv4.sysctl_ip_no_pmtu_disc)
++ READ_ONCE(xs_net(x)->ipv4.sysctl_ip_no_pmtu_disc))
+ x->props.flags |= XFRM_STATE_NOPMTUDISC;
+
+ err = -EPROTONOSUPPORT;
+diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
+index eea6e92500b8e..50ebad1e3abb1 100644
+--- a/security/integrity/ima/ima_policy.c
++++ b/security/integrity/ima/ima_policy.c
+@@ -2181,6 +2181,10 @@ bool ima_appraise_signature(enum kernel_read_file_id id)
+ if (id >= READING_MAX_ID)
+ return false;
+
++ if (id == READING_KEXEC_IMAGE && !(ima_appraise & IMA_APPRAISE_ENFORCE)
++ && security_locked_down(LOCKDOWN_KEXEC))
++ return false;
++
+ func = read_idmap[id] ?: FILE_CHECK;
+
+ rcu_read_lock();
+diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c
+index 88d23924e1bf2..87313145d14f9 100644
+--- a/sound/soc/sof/intel/hda-loader.c
++++ b/sound/soc/sof/intel/hda-loader.c
+@@ -397,7 +397,8 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
+ struct firmware stripped_firmware;
+ int ret, ret1, i;
+
+- if ((sdev->fw_ready.flags & SOF_IPC_INFO_D3_PERSISTENT) &&
++ if ((sdev->system_suspend_target < SOF_SUSPEND_S4) &&
++ (sdev->fw_ready.flags & SOF_IPC_INFO_D3_PERSISTENT) &&
+ !(sof_debug_check_flag(SOF_DBG_IGNORE_D3_PERSISTENT)) &&
+ !sdev->first_boot) {
+ dev_dbg(sdev->dev, "IMR restore supported, booting from IMR directly\n");
+diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c
+index 1c319582ca6f0..76351f7f3243d 100644
+--- a/sound/soc/sof/pm.c
++++ b/sound/soc/sof/pm.c
+@@ -23,6 +23,9 @@ static u32 snd_sof_dsp_power_target(struct snd_sof_dev *sdev)
+ u32 target_dsp_state;
+
+ switch (sdev->system_suspend_target) {
++ case SOF_SUSPEND_S5:
++ case SOF_SUSPEND_S4:
++ /* DSP should be in D3 if the system is suspending to S3+ */
+ case SOF_SUSPEND_S3:
+ /* DSP should be in D3 if the system is suspending to S3 */
+ target_dsp_state = SOF_DSP_PM_D3;
+@@ -327,8 +330,24 @@ int snd_sof_prepare(struct device *dev)
+ return 0;
+
+ #if defined(CONFIG_ACPI)
+- if (acpi_target_system_state() == ACPI_STATE_S0)
++ switch (acpi_target_system_state()) {
++ case ACPI_STATE_S0:
+ sdev->system_suspend_target = SOF_SUSPEND_S0IX;
++ break;
++ case ACPI_STATE_S1:
++ case ACPI_STATE_S2:
++ case ACPI_STATE_S3:
++ sdev->system_suspend_target = SOF_SUSPEND_S3;
++ break;
++ case ACPI_STATE_S4:
++ sdev->system_suspend_target = SOF_SUSPEND_S4;
++ break;
++ case ACPI_STATE_S5:
++ sdev->system_suspend_target = SOF_SUSPEND_S5;
++ break;
++ default:
++ break;
++ }
+ #endif
+
+ return 0;
+diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
+index 0d9b640ae24cd..c856f0d84e495 100644
+--- a/sound/soc/sof/sof-priv.h
++++ b/sound/soc/sof/sof-priv.h
+@@ -85,6 +85,8 @@ enum sof_system_suspend_state {
+ SOF_SUSPEND_NONE = 0,
+ SOF_SUSPEND_S0IX,
+ SOF_SUSPEND_S3,
++ SOF_SUSPEND_S4,
++ SOF_SUSPEND_S5,
+ };
+
+ enum sof_dfsentry_type {
+diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
+index 4ad0dfbc8b21f..7c7d20fc503ad 100644
+--- a/tools/perf/tests/perf-time-to-tsc.c
++++ b/tools/perf/tests/perf-time-to-tsc.c
+@@ -20,8 +20,6 @@
+ #include "tsc.h"
+ #include "mmap.h"
+ #include "tests.h"
+-#include "pmu.h"
+-#include "pmu-hybrid.h"
+
+ /*
+ * Except x86_64/i386 and Arm64, other archs don't support TSC in perf. Just
+@@ -106,28 +104,21 @@ static int test__perf_time_to_tsc(struct test_suite *test __maybe_unused, int su
+
+ evlist__config(evlist, &opts, NULL);
+
+- evsel = evlist__first(evlist);
+-
+- evsel->core.attr.comm = 1;
+- evsel->core.attr.disabled = 1;
+- evsel->core.attr.enable_on_exec = 0;
+-
+- /*
+- * For hybrid "cycles:u", it creates two events.
+- * Init the second evsel here.
+- */
+- if (perf_pmu__has_hybrid() && perf_pmu__hybrid_mounted("cpu_atom")) {
+- evsel = evsel__next(evsel);
++ /* For hybrid "cycles:u", it creates two events */
++ evlist__for_each_entry(evlist, evsel) {
+ evsel->core.attr.comm = 1;
+ evsel->core.attr.disabled = 1;
+ evsel->core.attr.enable_on_exec = 0;
+ }
+
+- if (evlist__open(evlist) == -ENOENT) {
+- err = TEST_SKIP;
++ ret = evlist__open(evlist);
++ if (ret < 0) {
++ if (ret == -ENOENT)
++ err = TEST_SKIP;
++ else
++ pr_debug("evlist__open() failed\n");
+ goto out_err;
+ }
+- CHECK__(evlist__open(evlist));
+
+ CHECK__(evlist__mmap(evlist, UINT_MAX));
+
+@@ -167,10 +158,12 @@ static int test__perf_time_to_tsc(struct test_suite *test __maybe_unused, int su
+ goto next_event;
+
+ if (strcmp(event->comm.comm, comm1) == 0) {
++ CHECK_NOT_NULL__(evsel = evlist__event2evsel(evlist, event));
+ CHECK__(evsel__parse_sample(evsel, event, &sample));
+ comm1_time = sample.time;
+ }
+ if (strcmp(event->comm.comm, comm2) == 0) {
++ CHECK_NOT_NULL__(evsel = evlist__event2evsel(evlist, event));
+ CHECK__(evsel__parse_sample(evsel, event, &sample));
+ comm2_time = sample.time;
+ }
+diff --git a/tools/testing/selftests/gpio/Makefile b/tools/testing/selftests/gpio/Makefile
+index 71b3066023685..616ed40196554 100644
+--- a/tools/testing/selftests/gpio/Makefile
++++ b/tools/testing/selftests/gpio/Makefile
+@@ -3,6 +3,6 @@
+ TEST_PROGS := gpio-mockup.sh gpio-sim.sh
+ TEST_FILES := gpio-mockup-sysfs.sh
+ TEST_GEN_PROGS_EXTENDED := gpio-mockup-cdev gpio-chip-info gpio-line-name
+-CFLAGS += -O2 -g -Wall -I../../../../usr/include/
++CFLAGS += -O2 -g -Wall -I../../../../usr/include/ $(KHDR_INCLUDES)
+
+ include ../lib.mk
+diff --git a/tools/testing/selftests/kvm/rseq_test.c b/tools/testing/selftests/kvm/rseq_test.c
+index 4158da0da2bba..2237d1aac8014 100644
+--- a/tools/testing/selftests/kvm/rseq_test.c
++++ b/tools/testing/selftests/kvm/rseq_test.c
+@@ -82,8 +82,9 @@ static int next_cpu(int cpu)
+ return cpu;
+ }
+
+-static void *migration_worker(void *ign)
++static void *migration_worker(void *__rseq_tid)
+ {
++ pid_t rseq_tid = (pid_t)(unsigned long)__rseq_tid;
+ cpu_set_t allowed_mask;
+ int r, i, cpu;
+
+@@ -106,7 +107,7 @@ static void *migration_worker(void *ign)
+ * stable, i.e. while changing affinity is in-progress.
+ */
+ smp_wmb();
+- r = sched_setaffinity(0, sizeof(allowed_mask), &allowed_mask);
++ r = sched_setaffinity(rseq_tid, sizeof(allowed_mask), &allowed_mask);
+ TEST_ASSERT(!r, "sched_setaffinity failed, errno = %d (%s)",
+ errno, strerror(errno));
+ smp_wmb();
+@@ -231,7 +232,8 @@ int main(int argc, char *argv[])
+ vm = vm_create_default(VCPU_ID, 0, guest_code);
+ ucall_init(vm, NULL);
+
+- pthread_create(&migration_thread, NULL, migration_worker, 0);
++ pthread_create(&migration_thread, NULL, migration_worker,
++ (void *)(unsigned long)gettid());
+
+ for (i = 0; !done; i++) {
+ vcpu_run(vm, VCPU_ID);
+diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
+index 5ab12214e18dd..24cb37d19c638 100644
+--- a/virt/kvm/kvm_main.c
++++ b/virt/kvm/kvm_main.c
+@@ -4299,8 +4299,11 @@ static int kvm_ioctl_create_device(struct kvm *kvm,
+ kvm_put_kvm_no_destroy(kvm);
+ mutex_lock(&kvm->lock);
+ list_del(&dev->vm_node);
++ if (ops->release)
++ ops->release(dev);
+ mutex_unlock(&kvm->lock);
+- ops->destroy(dev);
++ if (ops->destroy)
++ ops->destroy(dev);
+ return ret;
+ }
+
next reply other threads:[~2022-07-29 16:39 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-29 16:39 Mike Pagano [this message]
-- strict thread matches above, loose matches on Subject: below --
2022-08-21 19:59 [gentoo-commits] proj/linux-patches:5.18 commit in: / Mike Pagano
2022-08-21 16:54 Mike Pagano
2022-08-17 14:31 Mike Pagano
2022-08-11 12:32 Mike Pagano
2022-08-03 14:22 Alice Ferrazzi
2022-07-23 11:45 Alice Ferrazzi
2022-07-22 11:11 Mike Pagano
2022-07-22 11:06 Mike Pagano
2022-07-15 10:10 Alice Ferrazzi
2022-07-15 8:59 Alice Ferrazzi
2022-07-12 15:58 Mike Pagano
2022-07-07 17:29 Mike Pagano
2022-07-07 16:26 Mike Pagano
2022-07-02 16:12 Mike Pagano
2022-06-29 11:07 Mike Pagano
2022-06-26 21:52 Mike Pagano
2022-06-25 19:42 Mike Pagano
2022-06-22 12:53 Mike Pagano
2022-06-16 12:07 Mike Pagano
2022-06-14 17:29 Mike Pagano
2022-06-09 18:40 Mike Pagano
2022-06-09 11:25 Mike Pagano
2022-06-06 11:01 Mike Pagano
2022-05-30 21:42 Mike Pagano
2022-05-30 13:57 Mike Pagano
2022-05-24 21:02 Mike Pagano
2022-05-24 18:14 Mike Pagano
2022-05-11 17:39 Mike Pagano
2022-04-25 16:23 Mike Pagano
2022-04-25 16:15 Mike Pagano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1659112740.e3d4af682ac7e412f6f7e870493e0cbb2b17a0d2.mpagano@gentoo \
--to=mpagano@gentoo.org \
--cc=gentoo-commits@lists.gentoo.org \
--cc=gentoo-dev@lists.gentoo.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox