From 2087a8b012e86f8b827c16c45d3270c589412c74 Mon Sep 17 00:00:00 2001 From: Igor Pecovnik Date: Sat, 8 Feb 2025 17:56:44 +0100 Subject: [PATCH 01/33] Revert commit that breaks compilation This needs deeper anlysis and testing, so lets revert to known situation --- ...-rockchip-Fix-sdmmc-access-on-rk3308.patch | 64 +++++++++++++++++++ ...-rockchip-Fix-sdmmc-access-on-rk3308.patch | 64 +++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 patch/kernel/archive/rockchip64-6.12/board-rocks0-0001-Revert-arm64-dts-rockchip-Fix-sdmmc-access-on-rk3308.patch create mode 100644 patch/kernel/archive/rockchip64-6.13/board-rocks0-0001-Revert-arm64-dts-rockchip-Fix-sdmmc-access-on-rk3308.patch diff --git a/patch/kernel/archive/rockchip64-6.12/board-rocks0-0001-Revert-arm64-dts-rockchip-Fix-sdmmc-access-on-rk3308.patch b/patch/kernel/archive/rockchip64-6.12/board-rocks0-0001-Revert-arm64-dts-rockchip-Fix-sdmmc-access-on-rk3308.patch new file mode 100644 index 000000000000..2b1af580a105 --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.12/board-rocks0-0001-Revert-arm64-dts-rockchip-Fix-sdmmc-access-on-rk3308.patch @@ -0,0 +1,64 @@ +From 78c6d6c875dc82ab1f595dac580dcfe705923234 Mon Sep 17 00:00:00 2001 +From: Igor Pecovnik +Date: Sat, 8 Feb 2025 17:54:03 +0100 +Subject: [PATCH 1/1] Revert "arm64: dts: rockchip: Fix sdmmc access on + rk3308-rock-s0 v1.1 boards" + +This reverts commit 8810a8368b6075595715c4231322ca906a6b2f6f. +--- + .../boot/dts/rockchip/rk3308-rock-s0.dts | 25 +------------------ + 1 file changed, 1 insertion(+), 24 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-s0.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-s0.dts +index 8311af4c8689..bd6419a5c20a 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3308-rock-s0.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-s0.dts +@@ -74,23 +74,6 @@ vcc_io: regulator-3v3-vcc-io { + vin-supply = <&vcc5v0_sys>; + }; + +- /* +- * HW revision prior to v1.2 must pull GPIO4_D6 low to access sdmmc. +- * This is modeled as an always-on active low fixed regulator. +- */ +- vcc_sd: regulator-3v3-vcc-sd { +- compatible = "regulator-fixed"; +- gpios = <&gpio4 RK_PD6 GPIO_ACTIVE_LOW>; +- pinctrl-names = "default"; +- pinctrl-0 = <&sdmmc_2030>; +- regulator-name = "vcc_sd"; +- regulator-always-on; +- regulator-boot-on; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; +- vin-supply = <&vcc_io>; +- }; +- + vcc5v0_sys: regulator-5v0-vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; +@@ -198,12 +181,6 @@ pwr_led: pwr-led { + }; + }; + +- sdmmc { +- sdmmc_2030: sdmmc-2030 { +- rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; +- }; +- }; +- + wifi { + wifi_reg_on: wifi-reg-on { + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; +@@ -256,7 +233,7 @@ &sdmmc { + cap-mmc-highspeed; + cap-sd-highspeed; + disable-wp; +- vmmc-supply = <&vcc_sd>; ++ vmmc-supply = <&vcc_io>; + status = "okay"; + }; + +-- +2.43.0 + diff --git a/patch/kernel/archive/rockchip64-6.13/board-rocks0-0001-Revert-arm64-dts-rockchip-Fix-sdmmc-access-on-rk3308.patch b/patch/kernel/archive/rockchip64-6.13/board-rocks0-0001-Revert-arm64-dts-rockchip-Fix-sdmmc-access-on-rk3308.patch new file mode 100644 index 000000000000..2b1af580a105 --- /dev/null +++ b/patch/kernel/archive/rockchip64-6.13/board-rocks0-0001-Revert-arm64-dts-rockchip-Fix-sdmmc-access-on-rk3308.patch @@ -0,0 +1,64 @@ +From 78c6d6c875dc82ab1f595dac580dcfe705923234 Mon Sep 17 00:00:00 2001 +From: Igor Pecovnik +Date: Sat, 8 Feb 2025 17:54:03 +0100 +Subject: [PATCH 1/1] Revert "arm64: dts: rockchip: Fix sdmmc access on + rk3308-rock-s0 v1.1 boards" + +This reverts commit 8810a8368b6075595715c4231322ca906a6b2f6f. +--- + .../boot/dts/rockchip/rk3308-rock-s0.dts | 25 +------------------ + 1 file changed, 1 insertion(+), 24 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-s0.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-s0.dts +index 8311af4c8689..bd6419a5c20a 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3308-rock-s0.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-s0.dts +@@ -74,23 +74,6 @@ vcc_io: regulator-3v3-vcc-io { + vin-supply = <&vcc5v0_sys>; + }; + +- /* +- * HW revision prior to v1.2 must pull GPIO4_D6 low to access sdmmc. +- * This is modeled as an always-on active low fixed regulator. +- */ +- vcc_sd: regulator-3v3-vcc-sd { +- compatible = "regulator-fixed"; +- gpios = <&gpio4 RK_PD6 GPIO_ACTIVE_LOW>; +- pinctrl-names = "default"; +- pinctrl-0 = <&sdmmc_2030>; +- regulator-name = "vcc_sd"; +- regulator-always-on; +- regulator-boot-on; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; +- vin-supply = <&vcc_io>; +- }; +- + vcc5v0_sys: regulator-5v0-vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; +@@ -198,12 +181,6 @@ pwr_led: pwr-led { + }; + }; + +- sdmmc { +- sdmmc_2030: sdmmc-2030 { +- rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; +- }; +- }; +- + wifi { + wifi_reg_on: wifi-reg-on { + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; +@@ -256,7 +233,7 @@ &sdmmc { + cap-mmc-highspeed; + cap-sd-highspeed; + disable-wp; +- vmmc-supply = <&vcc_sd>; ++ vmmc-supply = <&vcc_io>; + status = "okay"; + }; + +-- +2.43.0 + From a8abed8d46a6b62265ede2c6fc0166744e533ecd Mon Sep 17 00:00:00 2001 From: Thorsten Maerz Date: Sat, 8 Feb 2025 15:23:41 +0100 Subject: [PATCH 02/33] firstlogin: bring up wifi device before scanning Scanning accesspoints requires an activated wifi device. Networkd does not activate it (only NetworkManager does so). As a result, firstlogin is not able to configure and use wifi on minimal images, as only Server and Desktop images have NetworkManeger installed. Activating the wifi device using "ip link set ${WIFI_DEVICE} up" before scanning fixes this. (And can safely be done - there is no problem activating it multiple times, as it is the case with NetworkManager installed.) --- packages/bsp/common/usr/lib/armbian/armbian-firstlogin | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/bsp/common/usr/lib/armbian/armbian-firstlogin b/packages/bsp/common/usr/lib/armbian/armbian-firstlogin index 8327c9fa830b..0a590a6eb139 100755 --- a/packages/bsp/common/usr/lib/armbian/armbian-firstlogin +++ b/packages/bsp/common/usr/lib/armbian/armbian-firstlogin @@ -304,6 +304,8 @@ set_timezone_and_locales() { WIFI_DEVICE=$(echo ${WIFI_DEVICES[$input-1]} | cut -d"," -f2) fi + # bring up wifi device (not done by networkd, only by NetworkManager) + ip link set ${WIFI_DEVICE} up # get list of wireless networks scanning=0 broken=1 From 222c875761d4ab28fe184cf2d4edfdbe2b009aee Mon Sep 17 00:00:00 2001 From: Julian Sikorski Date: Thu, 6 Feb 2025 11:57:44 +0000 Subject: [PATCH 03/33] Update odroidxu4-current to 6.6.75 --- .../odroidxu4-6.6/patch-6.6.68-69.patch | 3750 +++++ .../odroidxu4-6.6/patch-6.6.69-70.patch | 12214 ++++++++++++++++ .../odroidxu4-6.6/patch-6.6.70-71.patch | 227 + .../odroidxu4-6.6/patch-6.6.71-72.patch | 4467 ++++++ .../odroidxu4-6.6/patch-6.6.72-73.patch | 586 + .../odroidxu4-6.6/patch-6.6.73-74.patch | 2591 ++++ .../odroidxu4-6.6/patch-6.6.74-75.patch | 1630 +++ 7 files changed, 25465 insertions(+) create mode 100644 patch/kernel/archive/odroidxu4-6.6/patch-6.6.68-69.patch create mode 100644 patch/kernel/archive/odroidxu4-6.6/patch-6.6.69-70.patch create mode 100644 patch/kernel/archive/odroidxu4-6.6/patch-6.6.70-71.patch create mode 100644 patch/kernel/archive/odroidxu4-6.6/patch-6.6.71-72.patch create mode 100644 patch/kernel/archive/odroidxu4-6.6/patch-6.6.72-73.patch create mode 100644 patch/kernel/archive/odroidxu4-6.6/patch-6.6.73-74.patch create mode 100644 patch/kernel/archive/odroidxu4-6.6/patch-6.6.74-75.patch diff --git a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.68-69.patch b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.68-69.patch new file mode 100644 index 000000000000..781cb1f2369c --- /dev/null +++ b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.68-69.patch @@ -0,0 +1,3750 @@ +diff --git a/Makefile b/Makefile +index d57bf1b75593d8..ec4d9d1d9b7ae7 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 68 ++SUBLEVEL = 69 + EXTRAVERSION = + NAME = Pinguïn Aangedreven + +diff --git a/arch/loongarch/include/asm/inst.h b/arch/loongarch/include/asm/inst.h +index 71e1ed4165c80d..4fa53ad82efb32 100644 +--- a/arch/loongarch/include/asm/inst.h ++++ b/arch/loongarch/include/asm/inst.h +@@ -655,7 +655,17 @@ DEF_EMIT_REG2I16_FORMAT(blt, blt_op) + DEF_EMIT_REG2I16_FORMAT(bge, bge_op) + DEF_EMIT_REG2I16_FORMAT(bltu, bltu_op) + DEF_EMIT_REG2I16_FORMAT(bgeu, bgeu_op) +-DEF_EMIT_REG2I16_FORMAT(jirl, jirl_op) ++ ++static inline void emit_jirl(union loongarch_instruction *insn, ++ enum loongarch_gpr rd, ++ enum loongarch_gpr rj, ++ int offset) ++{ ++ insn->reg2i16_format.opcode = jirl_op; ++ insn->reg2i16_format.immediate = offset; ++ insn->reg2i16_format.rd = rd; ++ insn->reg2i16_format.rj = rj; ++} + + #define DEF_EMIT_REG2BSTRD_FORMAT(NAME, OP) \ + static inline void emit_##NAME(union loongarch_instruction *insn, \ +diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c +index de4f3def4af0b9..4ae77e9300d580 100644 +--- a/arch/loongarch/kernel/efi.c ++++ b/arch/loongarch/kernel/efi.c +@@ -90,7 +90,7 @@ static void __init init_screen_info(void) + memset(si, 0, sizeof(*si)); + early_memunmap(si, sizeof(*si)); + +- memblock_reserve(screen_info.lfb_base, screen_info.lfb_size); ++ memblock_reserve(__screen_info_lfb_base(&screen_info), screen_info.lfb_size); + } + + void __init efi_init(void) +diff --git a/arch/loongarch/kernel/inst.c b/arch/loongarch/kernel/inst.c +index 3050329556d118..14d7d700bcb98f 100644 +--- a/arch/loongarch/kernel/inst.c ++++ b/arch/loongarch/kernel/inst.c +@@ -332,7 +332,7 @@ u32 larch_insn_gen_jirl(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm) + return INSN_BREAK; + } + +- emit_jirl(&insn, rj, rd, imm >> 2); ++ emit_jirl(&insn, rd, rj, imm >> 2); + + return insn.word; + } +diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c +index 497f8b0a5f1efb..6595e992fda852 100644 +--- a/arch/loongarch/net/bpf_jit.c ++++ b/arch/loongarch/net/bpf_jit.c +@@ -181,13 +181,13 @@ static void __build_epilogue(struct jit_ctx *ctx, bool is_tail_call) + /* Set return value */ + emit_insn(ctx, addiw, LOONGARCH_GPR_A0, regmap[BPF_REG_0], 0); + /* Return to the caller */ +- emit_insn(ctx, jirl, LOONGARCH_GPR_RA, LOONGARCH_GPR_ZERO, 0); ++ emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_RA, 0); + } else { + /* + * Call the next bpf prog and skip the first instruction + * of TCC initialization. + */ +- emit_insn(ctx, jirl, LOONGARCH_GPR_T3, LOONGARCH_GPR_ZERO, 1); ++ emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_T3, 1); + } + } + +@@ -841,7 +841,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext + return ret; + + move_addr(ctx, t1, func_addr); +- emit_insn(ctx, jirl, t1, LOONGARCH_GPR_RA, 0); ++ emit_insn(ctx, jirl, LOONGARCH_GPR_RA, t1, 0); + move_reg(ctx, regmap[BPF_REG_0], LOONGARCH_GPR_A0); + break; + +diff --git a/arch/mips/Makefile b/arch/mips/Makefile +index f49807e1f19bc5..0888074f4dfef0 100644 +--- a/arch/mips/Makefile ++++ b/arch/mips/Makefile +@@ -299,7 +299,7 @@ drivers-$(CONFIG_PCI) += arch/mips/pci/ + ifdef CONFIG_64BIT + ifndef KBUILD_SYM32 + ifeq ($(shell expr $(load-y) \< 0xffffffff80000000), 0) +- KBUILD_SYM32 = y ++ KBUILD_SYM32 = $(call cc-option-yn, -msym32) + endif + endif + +diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h +index 2d53704d9f2461..e959a6b1a325ca 100644 +--- a/arch/mips/include/asm/mipsregs.h ++++ b/arch/mips/include/asm/mipsregs.h +@@ -2078,7 +2078,14 @@ do { \ + _ASM_INSN_IF_MIPS(0x4200000c) \ + _ASM_INSN32_IF_MM(0x0000517c) + #else /* !TOOLCHAIN_SUPPORTS_VIRT */ +-#define _ASM_SET_VIRT ".set\tvirt\n\t" ++#if MIPS_ISA_REV >= 5 ++#define _ASM_SET_VIRT_ISA ++#elif defined(CONFIG_64BIT) ++#define _ASM_SET_VIRT_ISA ".set\tmips64r5\n\t" ++#else ++#define _ASM_SET_VIRT_ISA ".set\tmips32r5\n\t" ++#endif ++#define _ASM_SET_VIRT _ASM_SET_VIRT_ISA ".set\tvirt\n\t" + #define _ASM_SET_MFGC0 _ASM_SET_VIRT + #define _ASM_SET_DMFGC0 _ASM_SET_VIRT + #define _ASM_SET_MTGC0 _ASM_SET_VIRT +@@ -2099,7 +2106,6 @@ do { \ + ({ int __res; \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ +- ".set\tmips32r5\n\t" \ + _ASM_SET_MFGC0 \ + "mfgc0\t%0, " #source ", %1\n\t" \ + _ASM_UNSET_MFGC0 \ +@@ -2113,7 +2119,6 @@ do { \ + ({ unsigned long long __res; \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ +- ".set\tmips64r5\n\t" \ + _ASM_SET_DMFGC0 \ + "dmfgc0\t%0, " #source ", %1\n\t" \ + _ASM_UNSET_DMFGC0 \ +@@ -2127,7 +2132,6 @@ do { \ + do { \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ +- ".set\tmips32r5\n\t" \ + _ASM_SET_MTGC0 \ + "mtgc0\t%z0, " #register ", %1\n\t" \ + _ASM_UNSET_MTGC0 \ +@@ -2140,7 +2144,6 @@ do { \ + do { \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ +- ".set\tmips64r5\n\t" \ + _ASM_SET_DMTGC0 \ + "dmtgc0\t%z0, " #register ", %1\n\t" \ + _ASM_UNSET_DMTGC0 \ +diff --git a/arch/powerpc/platforms/book3s/vas-api.c b/arch/powerpc/platforms/book3s/vas-api.c +index f381b177ea06ad..0b6365d85d1171 100644 +--- a/arch/powerpc/platforms/book3s/vas-api.c ++++ b/arch/powerpc/platforms/book3s/vas-api.c +@@ -464,7 +464,43 @@ static vm_fault_t vas_mmap_fault(struct vm_fault *vmf) + return VM_FAULT_SIGBUS; + } + ++/* ++ * During mmap() paste address, mapping VMA is saved in VAS window ++ * struct which is used to unmap during migration if the window is ++ * still open. But the user space can remove this mapping with ++ * munmap() before closing the window and the VMA address will ++ * be invalid. Set VAS window VMA to NULL in this function which ++ * is called before VMA free. ++ */ ++static void vas_mmap_close(struct vm_area_struct *vma) ++{ ++ struct file *fp = vma->vm_file; ++ struct coproc_instance *cp_inst = fp->private_data; ++ struct vas_window *txwin; ++ ++ /* Should not happen */ ++ if (!cp_inst || !cp_inst->txwin) { ++ pr_err("No attached VAS window for the paste address mmap\n"); ++ return; ++ } ++ ++ txwin = cp_inst->txwin; ++ /* ++ * task_ref.vma is set in coproc_mmap() during mmap paste ++ * address. So it has to be the same VMA that is getting freed. ++ */ ++ if (WARN_ON(txwin->task_ref.vma != vma)) { ++ pr_err("Invalid paste address mmaping\n"); ++ return; ++ } ++ ++ mutex_lock(&txwin->task_ref.mmap_mutex); ++ txwin->task_ref.vma = NULL; ++ mutex_unlock(&txwin->task_ref.mmap_mutex); ++} ++ + static const struct vm_operations_struct vas_vm_ops = { ++ .close = vas_mmap_close, + .fault = vas_mmap_fault, + }; + +diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h +index 197316121f04e1..f81a851c46dca5 100644 +--- a/arch/x86/include/asm/intel-family.h ++++ b/arch/x86/include/asm/intel-family.h +@@ -40,134 +40,221 @@ + * their own names :-( + */ + ++#define IFM(_fam, _model) VFM_MAKE(X86_VENDOR_INTEL, _fam, _model) ++ + /* Wildcard match for FAM6 so X86_MATCH_INTEL_FAM6_MODEL(ANY) works */ + #define INTEL_FAM6_ANY X86_MODEL_ANY ++/* Wildcard match for FAM6 so X86_MATCH_VFM(ANY) works */ ++#define INTEL_ANY IFM(X86_FAMILY_ANY, X86_MODEL_ANY) + + #define INTEL_FAM6_CORE_YONAH 0x0E ++#define INTEL_CORE_YONAH IFM(6, 0x0E) + + #define INTEL_FAM6_CORE2_MEROM 0x0F ++#define INTEL_CORE2_MEROM IFM(6, 0x0F) + #define INTEL_FAM6_CORE2_MEROM_L 0x16 ++#define INTEL_CORE2_MEROM_L IFM(6, 0x16) + #define INTEL_FAM6_CORE2_PENRYN 0x17 ++#define INTEL_CORE2_PENRYN IFM(6, 0x17) + #define INTEL_FAM6_CORE2_DUNNINGTON 0x1D ++#define INTEL_CORE2_DUNNINGTON IFM(6, 0x1D) + + #define INTEL_FAM6_NEHALEM 0x1E ++#define INTEL_NEHALEM IFM(6, 0x1E) + #define INTEL_FAM6_NEHALEM_G 0x1F /* Auburndale / Havendale */ ++#define INTEL_NEHALEM_G IFM(6, 0x1F) /* Auburndale / Havendale */ + #define INTEL_FAM6_NEHALEM_EP 0x1A ++#define INTEL_NEHALEM_EP IFM(6, 0x1A) + #define INTEL_FAM6_NEHALEM_EX 0x2E ++#define INTEL_NEHALEM_EX IFM(6, 0x2E) + + #define INTEL_FAM6_WESTMERE 0x25 ++#define INTEL_WESTMERE IFM(6, 0x25) + #define INTEL_FAM6_WESTMERE_EP 0x2C ++#define INTEL_WESTMERE_EP IFM(6, 0x2C) + #define INTEL_FAM6_WESTMERE_EX 0x2F ++#define INTEL_WESTMERE_EX IFM(6, 0x2F) + + #define INTEL_FAM6_SANDYBRIDGE 0x2A ++#define INTEL_SANDYBRIDGE IFM(6, 0x2A) + #define INTEL_FAM6_SANDYBRIDGE_X 0x2D ++#define INTEL_SANDYBRIDGE_X IFM(6, 0x2D) + #define INTEL_FAM6_IVYBRIDGE 0x3A ++#define INTEL_IVYBRIDGE IFM(6, 0x3A) + #define INTEL_FAM6_IVYBRIDGE_X 0x3E ++#define INTEL_IVYBRIDGE_X IFM(6, 0x3E) + + #define INTEL_FAM6_HASWELL 0x3C ++#define INTEL_HASWELL IFM(6, 0x3C) + #define INTEL_FAM6_HASWELL_X 0x3F ++#define INTEL_HASWELL_X IFM(6, 0x3F) + #define INTEL_FAM6_HASWELL_L 0x45 ++#define INTEL_HASWELL_L IFM(6, 0x45) + #define INTEL_FAM6_HASWELL_G 0x46 ++#define INTEL_HASWELL_G IFM(6, 0x46) + + #define INTEL_FAM6_BROADWELL 0x3D ++#define INTEL_BROADWELL IFM(6, 0x3D) + #define INTEL_FAM6_BROADWELL_G 0x47 ++#define INTEL_BROADWELL_G IFM(6, 0x47) + #define INTEL_FAM6_BROADWELL_X 0x4F ++#define INTEL_BROADWELL_X IFM(6, 0x4F) + #define INTEL_FAM6_BROADWELL_D 0x56 ++#define INTEL_BROADWELL_D IFM(6, 0x56) + + #define INTEL_FAM6_SKYLAKE_L 0x4E /* Sky Lake */ ++#define INTEL_SKYLAKE_L IFM(6, 0x4E) /* Sky Lake */ + #define INTEL_FAM6_SKYLAKE 0x5E /* Sky Lake */ ++#define INTEL_SKYLAKE IFM(6, 0x5E) /* Sky Lake */ + #define INTEL_FAM6_SKYLAKE_X 0x55 /* Sky Lake */ ++#define INTEL_SKYLAKE_X IFM(6, 0x55) /* Sky Lake */ + /* CASCADELAKE_X 0x55 Sky Lake -- s: 7 */ + /* COOPERLAKE_X 0x55 Sky Lake -- s: 11 */ + + #define INTEL_FAM6_KABYLAKE_L 0x8E /* Sky Lake */ ++#define INTEL_KABYLAKE_L IFM(6, 0x8E) /* Sky Lake */ + /* AMBERLAKE_L 0x8E Sky Lake -- s: 9 */ + /* COFFEELAKE_L 0x8E Sky Lake -- s: 10 */ + /* WHISKEYLAKE_L 0x8E Sky Lake -- s: 11,12 */ + + #define INTEL_FAM6_KABYLAKE 0x9E /* Sky Lake */ ++#define INTEL_KABYLAKE IFM(6, 0x9E) /* Sky Lake */ + /* COFFEELAKE 0x9E Sky Lake -- s: 10-13 */ + + #define INTEL_FAM6_COMETLAKE 0xA5 /* Sky Lake */ ++#define INTEL_COMETLAKE IFM(6, 0xA5) /* Sky Lake */ + #define INTEL_FAM6_COMETLAKE_L 0xA6 /* Sky Lake */ ++#define INTEL_COMETLAKE_L IFM(6, 0xA6) /* Sky Lake */ + + #define INTEL_FAM6_CANNONLAKE_L 0x66 /* Palm Cove */ ++#define INTEL_CANNONLAKE_L IFM(6, 0x66) /* Palm Cove */ + + #define INTEL_FAM6_ICELAKE_X 0x6A /* Sunny Cove */ ++#define INTEL_ICELAKE_X IFM(6, 0x6A) /* Sunny Cove */ + #define INTEL_FAM6_ICELAKE_D 0x6C /* Sunny Cove */ ++#define INTEL_ICELAKE_D IFM(6, 0x6C) /* Sunny Cove */ + #define INTEL_FAM6_ICELAKE 0x7D /* Sunny Cove */ ++#define INTEL_ICELAKE IFM(6, 0x7D) /* Sunny Cove */ + #define INTEL_FAM6_ICELAKE_L 0x7E /* Sunny Cove */ ++#define INTEL_ICELAKE_L IFM(6, 0x7E) /* Sunny Cove */ + #define INTEL_FAM6_ICELAKE_NNPI 0x9D /* Sunny Cove */ ++#define INTEL_ICELAKE_NNPI IFM(6, 0x9D) /* Sunny Cove */ + + #define INTEL_FAM6_ROCKETLAKE 0xA7 /* Cypress Cove */ ++#define INTEL_ROCKETLAKE IFM(6, 0xA7) /* Cypress Cove */ + + #define INTEL_FAM6_TIGERLAKE_L 0x8C /* Willow Cove */ ++#define INTEL_TIGERLAKE_L IFM(6, 0x8C) /* Willow Cove */ + #define INTEL_FAM6_TIGERLAKE 0x8D /* Willow Cove */ ++#define INTEL_TIGERLAKE IFM(6, 0x8D) /* Willow Cove */ + + #define INTEL_FAM6_SAPPHIRERAPIDS_X 0x8F /* Golden Cove */ ++#define INTEL_SAPPHIRERAPIDS_X IFM(6, 0x8F) /* Golden Cove */ + + #define INTEL_FAM6_EMERALDRAPIDS_X 0xCF ++#define INTEL_EMERALDRAPIDS_X IFM(6, 0xCF) + + #define INTEL_FAM6_GRANITERAPIDS_X 0xAD ++#define INTEL_GRANITERAPIDS_X IFM(6, 0xAD) + #define INTEL_FAM6_GRANITERAPIDS_D 0xAE ++#define INTEL_GRANITERAPIDS_D IFM(6, 0xAE) + + /* "Hybrid" Processors (P-Core/E-Core) */ + + #define INTEL_FAM6_LAKEFIELD 0x8A /* Sunny Cove / Tremont */ ++#define INTEL_LAKEFIELD IFM(6, 0x8A) /* Sunny Cove / Tremont */ + + #define INTEL_FAM6_ALDERLAKE 0x97 /* Golden Cove / Gracemont */ ++#define INTEL_ALDERLAKE IFM(6, 0x97) /* Golden Cove / Gracemont */ + #define INTEL_FAM6_ALDERLAKE_L 0x9A /* Golden Cove / Gracemont */ ++#define INTEL_ALDERLAKE_L IFM(6, 0x9A) /* Golden Cove / Gracemont */ + + #define INTEL_FAM6_RAPTORLAKE 0xB7 /* Raptor Cove / Enhanced Gracemont */ ++#define INTEL_RAPTORLAKE IFM(6, 0xB7) /* Raptor Cove / Enhanced Gracemont */ + #define INTEL_FAM6_RAPTORLAKE_P 0xBA ++#define INTEL_RAPTORLAKE_P IFM(6, 0xBA) + #define INTEL_FAM6_RAPTORLAKE_S 0xBF ++#define INTEL_RAPTORLAKE_S IFM(6, 0xBF) + + #define INTEL_FAM6_METEORLAKE 0xAC ++#define INTEL_METEORLAKE IFM(6, 0xAC) + #define INTEL_FAM6_METEORLAKE_L 0xAA ++#define INTEL_METEORLAKE_L IFM(6, 0xAA) + + #define INTEL_FAM6_ARROWLAKE_H 0xC5 ++#define INTEL_ARROWLAKE_H IFM(6, 0xC5) + #define INTEL_FAM6_ARROWLAKE 0xC6 ++#define INTEL_ARROWLAKE IFM(6, 0xC6) ++#define INTEL_FAM6_ARROWLAKE_U 0xB5 ++#define INTEL_ARROWLAKE_U IFM(6, 0xB5) + + #define INTEL_FAM6_LUNARLAKE_M 0xBD ++#define INTEL_LUNARLAKE_M IFM(6, 0xBD) + + /* "Small Core" Processors (Atom/E-Core) */ + + #define INTEL_FAM6_ATOM_BONNELL 0x1C /* Diamondville, Pineview */ ++#define INTEL_ATOM_BONNELL IFM(6, 0x1C) /* Diamondville, Pineview */ + #define INTEL_FAM6_ATOM_BONNELL_MID 0x26 /* Silverthorne, Lincroft */ ++#define INTEL_ATOM_BONNELL_MID IFM(6, 0x26) /* Silverthorne, Lincroft */ + + #define INTEL_FAM6_ATOM_SALTWELL 0x36 /* Cedarview */ ++#define INTEL_ATOM_SALTWELL IFM(6, 0x36) /* Cedarview */ + #define INTEL_FAM6_ATOM_SALTWELL_MID 0x27 /* Penwell */ ++#define INTEL_ATOM_SALTWELL_MID IFM(6, 0x27) /* Penwell */ + #define INTEL_FAM6_ATOM_SALTWELL_TABLET 0x35 /* Cloverview */ ++#define INTEL_ATOM_SALTWELL_TABLET IFM(6, 0x35) /* Cloverview */ + + #define INTEL_FAM6_ATOM_SILVERMONT 0x37 /* Bay Trail, Valleyview */ ++#define INTEL_ATOM_SILVERMONT IFM(6, 0x37) /* Bay Trail, Valleyview */ + #define INTEL_FAM6_ATOM_SILVERMONT_D 0x4D /* Avaton, Rangely */ ++#define INTEL_ATOM_SILVERMONT_D IFM(6, 0x4D) /* Avaton, Rangely */ + #define INTEL_FAM6_ATOM_SILVERMONT_MID 0x4A /* Merriefield */ ++#define INTEL_ATOM_SILVERMONT_MID IFM(6, 0x4A) /* Merriefield */ + + #define INTEL_FAM6_ATOM_AIRMONT 0x4C /* Cherry Trail, Braswell */ ++#define INTEL_ATOM_AIRMONT IFM(6, 0x4C) /* Cherry Trail, Braswell */ + #define INTEL_FAM6_ATOM_AIRMONT_MID 0x5A /* Moorefield */ ++#define INTEL_ATOM_AIRMONT_MID IFM(6, 0x5A) /* Moorefield */ + #define INTEL_FAM6_ATOM_AIRMONT_NP 0x75 /* Lightning Mountain */ ++#define INTEL_ATOM_AIRMONT_NP IFM(6, 0x75) /* Lightning Mountain */ + + #define INTEL_FAM6_ATOM_GOLDMONT 0x5C /* Apollo Lake */ ++#define INTEL_ATOM_GOLDMONT IFM(6, 0x5C) /* Apollo Lake */ + #define INTEL_FAM6_ATOM_GOLDMONT_D 0x5F /* Denverton */ ++#define INTEL_ATOM_GOLDMONT_D IFM(6, 0x5F) /* Denverton */ + + /* Note: the micro-architecture is "Goldmont Plus" */ + #define INTEL_FAM6_ATOM_GOLDMONT_PLUS 0x7A /* Gemini Lake */ ++#define INTEL_ATOM_GOLDMONT_PLUS IFM(6, 0x7A) /* Gemini Lake */ + + #define INTEL_FAM6_ATOM_TREMONT_D 0x86 /* Jacobsville */ ++#define INTEL_ATOM_TREMONT_D IFM(6, 0x86) /* Jacobsville */ + #define INTEL_FAM6_ATOM_TREMONT 0x96 /* Elkhart Lake */ ++#define INTEL_ATOM_TREMONT IFM(6, 0x96) /* Elkhart Lake */ + #define INTEL_FAM6_ATOM_TREMONT_L 0x9C /* Jasper Lake */ ++#define INTEL_ATOM_TREMONT_L IFM(6, 0x9C) /* Jasper Lake */ + + #define INTEL_FAM6_ATOM_GRACEMONT 0xBE /* Alderlake N */ ++#define INTEL_ATOM_GRACEMONT IFM(6, 0xBE) /* Alderlake N */ + + #define INTEL_FAM6_ATOM_CRESTMONT_X 0xAF /* Sierra Forest */ ++#define INTEL_ATOM_CRESTMONT_X IFM(6, 0xAF) /* Sierra Forest */ + #define INTEL_FAM6_ATOM_CRESTMONT 0xB6 /* Grand Ridge */ ++#define INTEL_ATOM_CRESTMONT IFM(6, 0xB6) /* Grand Ridge */ ++ ++#define INTEL_FAM6_ATOM_DARKMONT_X 0xDD /* Clearwater Forest */ ++#define INTEL_ATOM_DARKMONT_X IFM(6, 0xDD) /* Clearwater Forest */ + + /* Xeon Phi */ + + #define INTEL_FAM6_XEON_PHI_KNL 0x57 /* Knights Landing */ ++#define INTEL_XEON_PHI_KNL IFM(6, 0x57) /* Knights Landing */ + #define INTEL_FAM6_XEON_PHI_KNM 0x85 /* Knights Mill */ ++#define INTEL_XEON_PHI_KNM IFM(6, 0x85) /* Knights Mill */ + + /* Family 5 */ + #define INTEL_FAM5_QUARK_X1000 0x09 /* Quark X1000 SoC */ ++#define INTEL_QUARK_X1000 IFM(5, 0x09) /* Quark X1000 SoC */ + + #endif /* _ASM_X86_INTEL_FAMILY_H */ +diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h +index 6e775303d687dd..428348e7f06c3a 100644 +--- a/arch/x86/include/asm/processor.h ++++ b/arch/x86/include/asm/processor.h +@@ -81,9 +81,23 @@ extern u16 __read_mostly tlb_lld_1g[NR_INFO]; + */ + + struct cpuinfo_x86 { +- __u8 x86; /* CPU family */ +- __u8 x86_vendor; /* CPU vendor */ +- __u8 x86_model; ++ union { ++ /* ++ * The particular ordering (low-to-high) of (vendor, ++ * family, model) is done in case range of models, like ++ * it is usually done on AMD, need to be compared. ++ */ ++ struct { ++ __u8 x86_model; ++ /* CPU family */ ++ __u8 x86; ++ /* CPU vendor */ ++ __u8 x86_vendor; ++ __u8 x86_reserved; ++ }; ++ /* combined vendor, family, model */ ++ __u32 x86_vfm; ++ }; + __u8 x86_stepping; + #ifdef CONFIG_X86_64 + /* Number of 4K pages in DTLB/ITLB combined(in pages): */ +diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c +index aa3e7ed0eb3d7f..4752a9f17ef615 100644 +--- a/arch/x86/kernel/cpu/intel.c ++++ b/arch/x86/kernel/cpu/intel.c +@@ -72,19 +72,19 @@ static bool cpu_model_supports_sld __ro_after_init; + */ + static void check_memory_type_self_snoop_errata(struct cpuinfo_x86 *c) + { +- switch (c->x86_model) { +- case INTEL_FAM6_CORE_YONAH: +- case INTEL_FAM6_CORE2_MEROM: +- case INTEL_FAM6_CORE2_MEROM_L: +- case INTEL_FAM6_CORE2_PENRYN: +- case INTEL_FAM6_CORE2_DUNNINGTON: +- case INTEL_FAM6_NEHALEM: +- case INTEL_FAM6_NEHALEM_G: +- case INTEL_FAM6_NEHALEM_EP: +- case INTEL_FAM6_NEHALEM_EX: +- case INTEL_FAM6_WESTMERE: +- case INTEL_FAM6_WESTMERE_EP: +- case INTEL_FAM6_SANDYBRIDGE: ++ switch (c->x86_vfm) { ++ case INTEL_CORE_YONAH: ++ case INTEL_CORE2_MEROM: ++ case INTEL_CORE2_MEROM_L: ++ case INTEL_CORE2_PENRYN: ++ case INTEL_CORE2_DUNNINGTON: ++ case INTEL_NEHALEM: ++ case INTEL_NEHALEM_G: ++ case INTEL_NEHALEM_EP: ++ case INTEL_NEHALEM_EX: ++ case INTEL_WESTMERE: ++ case INTEL_WESTMERE_EP: ++ case INTEL_SANDYBRIDGE: + setup_clear_cpu_cap(X86_FEATURE_SELFSNOOP); + } + } +@@ -106,9 +106,9 @@ static void probe_xeon_phi_r3mwait(struct cpuinfo_x86 *c) + */ + if (c->x86 != 6) + return; +- switch (c->x86_model) { +- case INTEL_FAM6_XEON_PHI_KNL: +- case INTEL_FAM6_XEON_PHI_KNM: ++ switch (c->x86_vfm) { ++ case INTEL_XEON_PHI_KNL: ++ case INTEL_XEON_PHI_KNM: + break; + default: + return; +@@ -134,32 +134,32 @@ static void probe_xeon_phi_r3mwait(struct cpuinfo_x86 *c) + * - Release note from 20180108 microcode release + */ + struct sku_microcode { +- u8 model; ++ u32 vfm; + u8 stepping; + u32 microcode; + }; + static const struct sku_microcode spectre_bad_microcodes[] = { +- { INTEL_FAM6_KABYLAKE, 0x0B, 0x80 }, +- { INTEL_FAM6_KABYLAKE, 0x0A, 0x80 }, +- { INTEL_FAM6_KABYLAKE, 0x09, 0x80 }, +- { INTEL_FAM6_KABYLAKE_L, 0x0A, 0x80 }, +- { INTEL_FAM6_KABYLAKE_L, 0x09, 0x80 }, +- { INTEL_FAM6_SKYLAKE_X, 0x03, 0x0100013e }, +- { INTEL_FAM6_SKYLAKE_X, 0x04, 0x0200003c }, +- { INTEL_FAM6_BROADWELL, 0x04, 0x28 }, +- { INTEL_FAM6_BROADWELL_G, 0x01, 0x1b }, +- { INTEL_FAM6_BROADWELL_D, 0x02, 0x14 }, +- { INTEL_FAM6_BROADWELL_D, 0x03, 0x07000011 }, +- { INTEL_FAM6_BROADWELL_X, 0x01, 0x0b000025 }, +- { INTEL_FAM6_HASWELL_L, 0x01, 0x21 }, +- { INTEL_FAM6_HASWELL_G, 0x01, 0x18 }, +- { INTEL_FAM6_HASWELL, 0x03, 0x23 }, +- { INTEL_FAM6_HASWELL_X, 0x02, 0x3b }, +- { INTEL_FAM6_HASWELL_X, 0x04, 0x10 }, +- { INTEL_FAM6_IVYBRIDGE_X, 0x04, 0x42a }, ++ { INTEL_KABYLAKE, 0x0B, 0x80 }, ++ { INTEL_KABYLAKE, 0x0A, 0x80 }, ++ { INTEL_KABYLAKE, 0x09, 0x80 }, ++ { INTEL_KABYLAKE_L, 0x0A, 0x80 }, ++ { INTEL_KABYLAKE_L, 0x09, 0x80 }, ++ { INTEL_SKYLAKE_X, 0x03, 0x0100013e }, ++ { INTEL_SKYLAKE_X, 0x04, 0x0200003c }, ++ { INTEL_BROADWELL, 0x04, 0x28 }, ++ { INTEL_BROADWELL_G, 0x01, 0x1b }, ++ { INTEL_BROADWELL_D, 0x02, 0x14 }, ++ { INTEL_BROADWELL_D, 0x03, 0x07000011 }, ++ { INTEL_BROADWELL_X, 0x01, 0x0b000025 }, ++ { INTEL_HASWELL_L, 0x01, 0x21 }, ++ { INTEL_HASWELL_G, 0x01, 0x18 }, ++ { INTEL_HASWELL, 0x03, 0x23 }, ++ { INTEL_HASWELL_X, 0x02, 0x3b }, ++ { INTEL_HASWELL_X, 0x04, 0x10 }, ++ { INTEL_IVYBRIDGE_X, 0x04, 0x42a }, + /* Observed in the wild */ +- { INTEL_FAM6_SANDYBRIDGE_X, 0x06, 0x61b }, +- { INTEL_FAM6_SANDYBRIDGE_X, 0x07, 0x712 }, ++ { INTEL_SANDYBRIDGE_X, 0x06, 0x61b }, ++ { INTEL_SANDYBRIDGE_X, 0x07, 0x712 }, + }; + + static bool bad_spectre_microcode(struct cpuinfo_x86 *c) +@@ -173,11 +173,8 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *c) + if (cpu_has(c, X86_FEATURE_HYPERVISOR)) + return false; + +- if (c->x86 != 6) +- return false; +- + for (i = 0; i < ARRAY_SIZE(spectre_bad_microcodes); i++) { +- if (c->x86_model == spectre_bad_microcodes[i].model && ++ if (c->x86_vfm == spectre_bad_microcodes[i].vfm && + c->x86_stepping == spectre_bad_microcodes[i].stepping) + return (c->microcode <= spectre_bad_microcodes[i].microcode); + } +@@ -312,7 +309,7 @@ static void early_init_intel(struct cpuinfo_x86 *c) + * need the microcode to have already been loaded... so if it is + * not, recommend a BIOS update and disable large pages. + */ +- if (c->x86 == 6 && c->x86_model == 0x1c && c->x86_stepping <= 2 && ++ if (c->x86_vfm == INTEL_ATOM_BONNELL && c->x86_stepping <= 2 && + c->microcode < 0x20e) { + pr_warn("Atom PSE erratum detected, BIOS microcode update recommended\n"); + clear_cpu_cap(c, X86_FEATURE_PSE); +@@ -344,17 +341,13 @@ static void early_init_intel(struct cpuinfo_x86 *c) + } + + /* Penwell and Cloverview have the TSC which doesn't sleep on S3 */ +- if (c->x86 == 6) { +- switch (c->x86_model) { +- case INTEL_FAM6_ATOM_SALTWELL_MID: +- case INTEL_FAM6_ATOM_SALTWELL_TABLET: +- case INTEL_FAM6_ATOM_SILVERMONT_MID: +- case INTEL_FAM6_ATOM_AIRMONT_NP: +- set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC_S3); +- break; +- default: +- break; +- } ++ switch (c->x86_vfm) { ++ case INTEL_ATOM_SALTWELL_MID: ++ case INTEL_ATOM_SALTWELL_TABLET: ++ case INTEL_ATOM_SILVERMONT_MID: ++ case INTEL_ATOM_AIRMONT_NP: ++ set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC_S3); ++ break; + } + + /* +@@ -393,7 +386,7 @@ static void early_init_intel(struct cpuinfo_x86 *c) + * should be false so that __flush_tlb_all() causes CR3 instead of CR4.PGE + * to be modified. + */ +- if (c->x86 == 5 && c->x86_model == 9) { ++ if (c->x86_vfm == INTEL_QUARK_X1000) { + pr_info("Disabling PGE capability bit\n"); + setup_clear_cpu_cap(X86_FEATURE_PGE); + } +@@ -663,12 +656,15 @@ static void init_intel(struct cpuinfo_x86 *c) + set_cpu_cap(c, X86_FEATURE_PEBS); + } + +- if (c->x86 == 6 && boot_cpu_has(X86_FEATURE_CLFLUSH) && +- (c->x86_model == 29 || c->x86_model == 46 || c->x86_model == 47)) ++ if (boot_cpu_has(X86_FEATURE_CLFLUSH) && ++ (c->x86_vfm == INTEL_CORE2_DUNNINGTON || ++ c->x86_vfm == INTEL_NEHALEM_EX || ++ c->x86_vfm == INTEL_WESTMERE_EX)) + set_cpu_bug(c, X86_BUG_CLFLUSH_MONITOR); + +- if (c->x86 == 6 && boot_cpu_has(X86_FEATURE_MWAIT) && +- ((c->x86_model == INTEL_FAM6_ATOM_GOLDMONT))) ++ if (boot_cpu_has(X86_FEATURE_MWAIT) && ++ (c->x86_vfm == INTEL_ATOM_GOLDMONT || ++ c->x86_vfm == INTEL_LUNARLAKE_M)) + set_cpu_bug(c, X86_BUG_MONITOR); + + #ifdef CONFIG_X86_64 +@@ -1285,9 +1281,9 @@ void handle_bus_lock(struct pt_regs *regs) + * feature even though they do not enumerate IA32_CORE_CAPABILITIES. + */ + static const struct x86_cpu_id split_lock_cpu_ids[] __initconst = { +- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, 0), +- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L, 0), +- X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, 0), ++ X86_MATCH_VFM(INTEL_ICELAKE_X, 0), ++ X86_MATCH_VFM(INTEL_ICELAKE_L, 0), ++ X86_MATCH_VFM(INTEL_ICELAKE_D, 0), + {} + }; + +diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c +index ae71b8ef909c9a..978a3094e8ff73 100644 +--- a/arch/x86/kernel/cpu/match.c ++++ b/arch/x86/kernel/cpu/match.c +@@ -17,8 +17,7 @@ + * + * A typical table entry would be to match a specific CPU + * +- * X86_MATCH_VENDOR_FAM_MODEL_FEATURE(INTEL, 6, INTEL_FAM6_BROADWELL, +- * X86_FEATURE_ANY, NULL); ++ * X86_MATCH_VFM_FEATURE(INTEL_BROADWELL, X86_FEATURE_ANY, NULL); + * + * Fields can be wildcarded with %X86_VENDOR_ANY, %X86_FAMILY_ANY, + * %X86_MODEL_ANY, %X86_FEATURE_ANY (except for vendor) +diff --git a/block/blk-mq.c b/block/blk-mq.c +index 6c71add013bfc2..5da948b07058b4 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -43,6 +43,7 @@ + + static DEFINE_PER_CPU(struct llist_head, blk_cpu_done); + static DEFINE_PER_CPU(call_single_data_t, blk_cpu_csd); ++static DEFINE_MUTEX(blk_mq_cpuhp_lock); + + static void blk_mq_insert_request(struct request *rq, blk_insert_t flags); + static void blk_mq_request_bypass_insert(struct request *rq, +@@ -3623,13 +3624,91 @@ static int blk_mq_hctx_notify_dead(unsigned int cpu, struct hlist_node *node) + return 0; + } + +-static void blk_mq_remove_cpuhp(struct blk_mq_hw_ctx *hctx) ++static void __blk_mq_remove_cpuhp(struct blk_mq_hw_ctx *hctx) + { +- if (!(hctx->flags & BLK_MQ_F_STACKING)) ++ lockdep_assert_held(&blk_mq_cpuhp_lock); ++ ++ if (!(hctx->flags & BLK_MQ_F_STACKING) && ++ !hlist_unhashed(&hctx->cpuhp_online)) { + cpuhp_state_remove_instance_nocalls(CPUHP_AP_BLK_MQ_ONLINE, + &hctx->cpuhp_online); +- cpuhp_state_remove_instance_nocalls(CPUHP_BLK_MQ_DEAD, +- &hctx->cpuhp_dead); ++ INIT_HLIST_NODE(&hctx->cpuhp_online); ++ } ++ ++ if (!hlist_unhashed(&hctx->cpuhp_dead)) { ++ cpuhp_state_remove_instance_nocalls(CPUHP_BLK_MQ_DEAD, ++ &hctx->cpuhp_dead); ++ INIT_HLIST_NODE(&hctx->cpuhp_dead); ++ } ++} ++ ++static void blk_mq_remove_cpuhp(struct blk_mq_hw_ctx *hctx) ++{ ++ mutex_lock(&blk_mq_cpuhp_lock); ++ __blk_mq_remove_cpuhp(hctx); ++ mutex_unlock(&blk_mq_cpuhp_lock); ++} ++ ++static void __blk_mq_add_cpuhp(struct blk_mq_hw_ctx *hctx) ++{ ++ lockdep_assert_held(&blk_mq_cpuhp_lock); ++ ++ if (!(hctx->flags & BLK_MQ_F_STACKING) && ++ hlist_unhashed(&hctx->cpuhp_online)) ++ cpuhp_state_add_instance_nocalls(CPUHP_AP_BLK_MQ_ONLINE, ++ &hctx->cpuhp_online); ++ ++ if (hlist_unhashed(&hctx->cpuhp_dead)) ++ cpuhp_state_add_instance_nocalls(CPUHP_BLK_MQ_DEAD, ++ &hctx->cpuhp_dead); ++} ++ ++static void __blk_mq_remove_cpuhp_list(struct list_head *head) ++{ ++ struct blk_mq_hw_ctx *hctx; ++ ++ lockdep_assert_held(&blk_mq_cpuhp_lock); ++ ++ list_for_each_entry(hctx, head, hctx_list) ++ __blk_mq_remove_cpuhp(hctx); ++} ++ ++/* ++ * Unregister cpuhp callbacks from exited hw queues ++ * ++ * Safe to call if this `request_queue` is live ++ */ ++static void blk_mq_remove_hw_queues_cpuhp(struct request_queue *q) ++{ ++ LIST_HEAD(hctx_list); ++ ++ spin_lock(&q->unused_hctx_lock); ++ list_splice_init(&q->unused_hctx_list, &hctx_list); ++ spin_unlock(&q->unused_hctx_lock); ++ ++ mutex_lock(&blk_mq_cpuhp_lock); ++ __blk_mq_remove_cpuhp_list(&hctx_list); ++ mutex_unlock(&blk_mq_cpuhp_lock); ++ ++ spin_lock(&q->unused_hctx_lock); ++ list_splice(&hctx_list, &q->unused_hctx_list); ++ spin_unlock(&q->unused_hctx_lock); ++} ++ ++/* ++ * Register cpuhp callbacks from all hw queues ++ * ++ * Safe to call if this `request_queue` is live ++ */ ++static void blk_mq_add_hw_queues_cpuhp(struct request_queue *q) ++{ ++ struct blk_mq_hw_ctx *hctx; ++ unsigned long i; ++ ++ mutex_lock(&blk_mq_cpuhp_lock); ++ queue_for_each_hw_ctx(q, hctx, i) ++ __blk_mq_add_cpuhp(hctx); ++ mutex_unlock(&blk_mq_cpuhp_lock); + } + + /* +@@ -3680,8 +3759,6 @@ static void blk_mq_exit_hctx(struct request_queue *q, + if (set->ops->exit_hctx) + set->ops->exit_hctx(hctx, hctx_idx); + +- blk_mq_remove_cpuhp(hctx); +- + xa_erase(&q->hctx_table, hctx_idx); + + spin_lock(&q->unused_hctx_lock); +@@ -3698,6 +3775,7 @@ static void blk_mq_exit_hw_queues(struct request_queue *q, + queue_for_each_hw_ctx(q, hctx, i) { + if (i == nr_queue) + break; ++ blk_mq_remove_cpuhp(hctx); + blk_mq_exit_hctx(q, set, hctx, i); + } + } +@@ -3708,16 +3786,11 @@ static int blk_mq_init_hctx(struct request_queue *q, + { + hctx->queue_num = hctx_idx; + +- if (!(hctx->flags & BLK_MQ_F_STACKING)) +- cpuhp_state_add_instance_nocalls(CPUHP_AP_BLK_MQ_ONLINE, +- &hctx->cpuhp_online); +- cpuhp_state_add_instance_nocalls(CPUHP_BLK_MQ_DEAD, &hctx->cpuhp_dead); +- + hctx->tags = set->tags[hctx_idx]; + + if (set->ops->init_hctx && + set->ops->init_hctx(hctx, set->driver_data, hctx_idx)) +- goto unregister_cpu_notifier; ++ goto fail; + + if (blk_mq_init_request(set, hctx->fq->flush_rq, hctx_idx, + hctx->numa_node)) +@@ -3734,8 +3807,7 @@ static int blk_mq_init_hctx(struct request_queue *q, + exit_hctx: + if (set->ops->exit_hctx) + set->ops->exit_hctx(hctx, hctx_idx); +- unregister_cpu_notifier: +- blk_mq_remove_cpuhp(hctx); ++ fail: + return -1; + } + +@@ -3761,6 +3833,8 @@ blk_mq_alloc_hctx(struct request_queue *q, struct blk_mq_tag_set *set, + INIT_DELAYED_WORK(&hctx->run_work, blk_mq_run_work_fn); + spin_lock_init(&hctx->lock); + INIT_LIST_HEAD(&hctx->dispatch); ++ INIT_HLIST_NODE(&hctx->cpuhp_dead); ++ INIT_HLIST_NODE(&hctx->cpuhp_online); + hctx->queue = q; + hctx->flags = set->flags & ~BLK_MQ_F_TAG_QUEUE_SHARED; + +@@ -4204,6 +4278,15 @@ struct gendisk *blk_mq_alloc_disk_for_queue(struct request_queue *q, + } + EXPORT_SYMBOL(blk_mq_alloc_disk_for_queue); + ++/* ++ * Only hctx removed from cpuhp list can be reused ++ */ ++static bool blk_mq_hctx_is_reusable(struct blk_mq_hw_ctx *hctx) ++{ ++ return hlist_unhashed(&hctx->cpuhp_online) && ++ hlist_unhashed(&hctx->cpuhp_dead); ++} ++ + static struct blk_mq_hw_ctx *blk_mq_alloc_and_init_hctx( + struct blk_mq_tag_set *set, struct request_queue *q, + int hctx_idx, int node) +@@ -4213,7 +4296,7 @@ static struct blk_mq_hw_ctx *blk_mq_alloc_and_init_hctx( + /* reuse dead hctx first */ + spin_lock(&q->unused_hctx_lock); + list_for_each_entry(tmp, &q->unused_hctx_list, hctx_list) { +- if (tmp->numa_node == node) { ++ if (tmp->numa_node == node && blk_mq_hctx_is_reusable(tmp)) { + hctx = tmp; + break; + } +@@ -4279,6 +4362,12 @@ static void blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set, + xa_for_each_start(&q->hctx_table, j, hctx, j) + blk_mq_exit_hctx(q, set, hctx, j); + mutex_unlock(&q->sysfs_lock); ++ ++ /* unregister cpuhp callbacks for exited hctxs */ ++ blk_mq_remove_hw_queues_cpuhp(q); ++ ++ /* register cpuhp for new initialized hctxs */ ++ blk_mq_add_hw_queues_cpuhp(q); + } + + static void blk_mq_update_poll_flag(struct request_queue *q) +diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c +index 582564f8dde6f9..d9d339b8b57108 100644 +--- a/drivers/base/power/domain.c ++++ b/drivers/base/power/domain.c +@@ -2021,6 +2021,7 @@ static int genpd_alloc_data(struct generic_pm_domain *genpd) + + static void genpd_free_data(struct generic_pm_domain *genpd) + { ++ put_device(&genpd->dev); + if (genpd_is_cpu_domain(genpd)) + free_cpumask_var(genpd->cpus); + if (genpd->free_states) +diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c +index 1db04886def610..3011f7f9381b7f 100644 +--- a/drivers/base/regmap/regmap.c ++++ b/drivers/base/regmap/regmap.c +@@ -1062,13 +1062,13 @@ struct regmap *__regmap_init(struct device *dev, + + /* Sanity check */ + if (range_cfg->range_max < range_cfg->range_min) { +- dev_err(map->dev, "Invalid range %d: %d < %d\n", i, ++ dev_err(map->dev, "Invalid range %d: %u < %u\n", i, + range_cfg->range_max, range_cfg->range_min); + goto err_range; + } + + if (range_cfg->range_max > map->max_register) { +- dev_err(map->dev, "Invalid range %d: %d > %d\n", i, ++ dev_err(map->dev, "Invalid range %d: %u > %u\n", i, + range_cfg->range_max, map->max_register); + goto err_range; + } +diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c +index 997106fe73e49f..65a1f1576e55fb 100644 +--- a/drivers/block/virtio_blk.c ++++ b/drivers/block/virtio_blk.c +@@ -1624,9 +1624,12 @@ static void virtblk_remove(struct virtio_device *vdev) + static int virtblk_freeze(struct virtio_device *vdev) + { + struct virtio_blk *vblk = vdev->priv; ++ struct request_queue *q = vblk->disk->queue; + + /* Ensure no requests in virtqueues before deleting vqs. */ +- blk_mq_freeze_queue(vblk->disk->queue); ++ blk_mq_freeze_queue(q); ++ blk_mq_quiesce_queue_nowait(q); ++ blk_mq_unfreeze_queue(q); + + /* Ensure we don't receive any more interrupts */ + virtio_reset_device(vdev); +@@ -1650,8 +1653,8 @@ static int virtblk_restore(struct virtio_device *vdev) + return ret; + + virtio_device_ready(vdev); ++ blk_mq_unquiesce_queue(vblk->disk->queue); + +- blk_mq_unfreeze_queue(vblk->disk->queue); + return 0; + } + #endif +diff --git a/drivers/dma/apple-admac.c b/drivers/dma/apple-admac.c +index 356298e4dd22b3..5b1457f6e3bfc4 100644 +--- a/drivers/dma/apple-admac.c ++++ b/drivers/dma/apple-admac.c +@@ -153,6 +153,8 @@ static int admac_alloc_sram_carveout(struct admac_data *ad, + { + struct admac_sram *sram; + int i, ret = 0, nblocks; ++ ad->txcache.size = readl_relaxed(ad->base + REG_TX_SRAM_SIZE); ++ ad->rxcache.size = readl_relaxed(ad->base + REG_RX_SRAM_SIZE); + + if (dir == DMA_MEM_TO_DEV) + sram = &ad->txcache; +@@ -912,12 +914,7 @@ static int admac_probe(struct platform_device *pdev) + goto free_irq; + } + +- ad->txcache.size = readl_relaxed(ad->base + REG_TX_SRAM_SIZE); +- ad->rxcache.size = readl_relaxed(ad->base + REG_RX_SRAM_SIZE); +- + dev_info(&pdev->dev, "Audio DMA Controller\n"); +- dev_info(&pdev->dev, "imprint %x TX cache %u RX cache %u\n", +- readl_relaxed(ad->base + REG_IMPRINT), ad->txcache.size, ad->rxcache.size); + + return 0; + +diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c +index c3b37168b21f16..2d1ee284998ecd 100644 +--- a/drivers/dma/at_xdmac.c ++++ b/drivers/dma/at_xdmac.c +@@ -1363,6 +1363,8 @@ at_xdmac_prep_dma_memset(struct dma_chan *chan, dma_addr_t dest, int value, + return NULL; + + desc = at_xdmac_memset_create_desc(chan, atchan, dest, len, value); ++ if (!desc) ++ return NULL; + list_add_tail(&desc->desc_node, &desc->descs_list); + + desc->tx_dma_desc.cookie = -EBUSY; +diff --git a/drivers/dma/dw/acpi.c b/drivers/dma/dw/acpi.c +index c510c109d2c3ad..b6452fffa657ad 100644 +--- a/drivers/dma/dw/acpi.c ++++ b/drivers/dma/dw/acpi.c +@@ -8,13 +8,15 @@ + + static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param) + { ++ struct dw_dma *dw = to_dw_dma(chan->device); ++ struct dw_dma_chip_pdata *data = dev_get_drvdata(dw->dma.dev); + struct acpi_dma_spec *dma_spec = param; + struct dw_dma_slave slave = { + .dma_dev = dma_spec->dev, + .src_id = dma_spec->slave_id, + .dst_id = dma_spec->slave_id, +- .m_master = 0, +- .p_master = 1, ++ .m_master = data->m_master, ++ .p_master = data->p_master, + }; + + return dw_dma_filter(chan, &slave); +diff --git a/drivers/dma/dw/internal.h b/drivers/dma/dw/internal.h +index 563ce73488db32..f1bd06a20cd611 100644 +--- a/drivers/dma/dw/internal.h ++++ b/drivers/dma/dw/internal.h +@@ -51,11 +51,15 @@ struct dw_dma_chip_pdata { + int (*probe)(struct dw_dma_chip *chip); + int (*remove)(struct dw_dma_chip *chip); + struct dw_dma_chip *chip; ++ u8 m_master; ++ u8 p_master; + }; + + static __maybe_unused const struct dw_dma_chip_pdata dw_dma_chip_pdata = { + .probe = dw_dma_probe, + .remove = dw_dma_remove, ++ .m_master = 0, ++ .p_master = 1, + }; + + static const struct dw_dma_platform_data idma32_pdata = { +@@ -72,6 +76,8 @@ static __maybe_unused const struct dw_dma_chip_pdata idma32_chip_pdata = { + .pdata = &idma32_pdata, + .probe = idma32_dma_probe, + .remove = idma32_dma_remove, ++ .m_master = 0, ++ .p_master = 0, + }; + + static const struct dw_dma_platform_data xbar_pdata = { +@@ -88,6 +94,8 @@ static __maybe_unused const struct dw_dma_chip_pdata xbar_chip_pdata = { + .pdata = &xbar_pdata, + .probe = idma32_dma_probe, + .remove = idma32_dma_remove, ++ .m_master = 0, ++ .p_master = 0, + }; + + #endif /* _DMA_DW_INTERNAL_H */ +diff --git a/drivers/dma/dw/pci.c b/drivers/dma/dw/pci.c +index ad2d4d012cf729..e8a0eb81726a56 100644 +--- a/drivers/dma/dw/pci.c ++++ b/drivers/dma/dw/pci.c +@@ -56,10 +56,10 @@ static int dw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid) + if (ret) + return ret; + +- dw_dma_acpi_controller_register(chip->dw); +- + pci_set_drvdata(pdev, data); + ++ dw_dma_acpi_controller_register(chip->dw); ++ + return 0; + } + +diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h +index 6028389de408b0..8d4ef6eed3adbb 100644 +--- a/drivers/dma/fsl-edma-common.h ++++ b/drivers/dma/fsl-edma-common.h +@@ -151,6 +151,7 @@ struct fsl_edma_chan { + struct work_struct issue_worker; + struct platform_device *pdev; + struct device *pd_dev; ++ struct device_link *pd_dev_link; + u32 srcid; + struct clk *clk; + int priority; +diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c +index 8a0ae90548997c..cd394eae47d179 100644 +--- a/drivers/dma/fsl-edma-main.c ++++ b/drivers/dma/fsl-edma-main.c +@@ -384,10 +384,33 @@ static const struct of_device_id fsl_edma_dt_ids[] = { + }; + MODULE_DEVICE_TABLE(of, fsl_edma_dt_ids); + ++static void fsl_edma3_detach_pd(struct fsl_edma_engine *fsl_edma) ++{ ++ struct fsl_edma_chan *fsl_chan; ++ int i; ++ ++ for (i = 0; i < fsl_edma->n_chans; i++) { ++ if (fsl_edma->chan_masked & BIT(i)) ++ continue; ++ fsl_chan = &fsl_edma->chans[i]; ++ if (fsl_chan->pd_dev_link) ++ device_link_del(fsl_chan->pd_dev_link); ++ if (fsl_chan->pd_dev) { ++ dev_pm_domain_detach(fsl_chan->pd_dev, false); ++ pm_runtime_dont_use_autosuspend(fsl_chan->pd_dev); ++ pm_runtime_set_suspended(fsl_chan->pd_dev); ++ } ++ } ++} ++ ++static void devm_fsl_edma3_detach_pd(void *data) ++{ ++ fsl_edma3_detach_pd(data); ++} ++ + static int fsl_edma3_attach_pd(struct platform_device *pdev, struct fsl_edma_engine *fsl_edma) + { + struct fsl_edma_chan *fsl_chan; +- struct device_link *link; + struct device *pd_chan; + struct device *dev; + int i; +@@ -403,15 +426,16 @@ static int fsl_edma3_attach_pd(struct platform_device *pdev, struct fsl_edma_eng + pd_chan = dev_pm_domain_attach_by_id(dev, i); + if (IS_ERR_OR_NULL(pd_chan)) { + dev_err(dev, "Failed attach pd %d\n", i); +- return -EINVAL; ++ goto detach; + } + +- link = device_link_add(dev, pd_chan, DL_FLAG_STATELESS | ++ fsl_chan->pd_dev_link = device_link_add(dev, pd_chan, DL_FLAG_STATELESS | + DL_FLAG_PM_RUNTIME | + DL_FLAG_RPM_ACTIVE); +- if (!link) { ++ if (!fsl_chan->pd_dev_link) { + dev_err(dev, "Failed to add device_link to %d\n", i); +- return -EINVAL; ++ dev_pm_domain_detach(pd_chan, false); ++ goto detach; + } + + fsl_chan->pd_dev = pd_chan; +@@ -422,6 +446,10 @@ static int fsl_edma3_attach_pd(struct platform_device *pdev, struct fsl_edma_eng + } + + return 0; ++ ++detach: ++ fsl_edma3_detach_pd(fsl_edma); ++ return -EINVAL; + } + + static int fsl_edma_probe(struct platform_device *pdev) +@@ -522,6 +550,9 @@ static int fsl_edma_probe(struct platform_device *pdev) + ret = fsl_edma3_attach_pd(pdev, fsl_edma); + if (ret) + return ret; ++ ret = devm_add_action_or_reset(&pdev->dev, devm_fsl_edma3_detach_pd, fsl_edma); ++ if (ret) ++ return ret; + } + + INIT_LIST_HEAD(&fsl_edma->dma_dev.channels); +diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c +index 23b232b5751844..ea48661e87ea70 100644 +--- a/drivers/dma/mv_xor.c ++++ b/drivers/dma/mv_xor.c +@@ -1393,6 +1393,7 @@ static int mv_xor_probe(struct platform_device *pdev) + irq = irq_of_parse_and_map(np, 0); + if (!irq) { + ret = -ENODEV; ++ of_node_put(np); + goto err_channel_add; + } + +@@ -1401,6 +1402,7 @@ static int mv_xor_probe(struct platform_device *pdev) + if (IS_ERR(chan)) { + ret = PTR_ERR(chan); + irq_dispose_mapping(irq); ++ of_node_put(np); + goto err_channel_add; + } + +diff --git a/drivers/dma/tegra186-gpc-dma.c b/drivers/dma/tegra186-gpc-dma.c +index 674cf630528383..029f45f7e37f4e 100644 +--- a/drivers/dma/tegra186-gpc-dma.c ++++ b/drivers/dma/tegra186-gpc-dma.c +@@ -231,6 +231,7 @@ struct tegra_dma_channel { + bool config_init; + char name[30]; + enum dma_transfer_direction sid_dir; ++ enum dma_status status; + int id; + int irq; + int slave_id; +@@ -393,6 +394,8 @@ static int tegra_dma_pause(struct tegra_dma_channel *tdc) + tegra_dma_dump_chan_regs(tdc); + } + ++ tdc->status = DMA_PAUSED; ++ + return ret; + } + +@@ -419,6 +422,8 @@ static void tegra_dma_resume(struct tegra_dma_channel *tdc) + val = tdc_read(tdc, TEGRA_GPCDMA_CHAN_CSRE); + val &= ~TEGRA_GPCDMA_CHAN_CSRE_PAUSE; + tdc_write(tdc, TEGRA_GPCDMA_CHAN_CSRE, val); ++ ++ tdc->status = DMA_IN_PROGRESS; + } + + static int tegra_dma_device_resume(struct dma_chan *dc) +@@ -544,6 +549,7 @@ static void tegra_dma_xfer_complete(struct tegra_dma_channel *tdc) + + tegra_dma_sid_free(tdc); + tdc->dma_desc = NULL; ++ tdc->status = DMA_COMPLETE; + } + + static void tegra_dma_chan_decode_error(struct tegra_dma_channel *tdc, +@@ -716,6 +722,7 @@ static int tegra_dma_terminate_all(struct dma_chan *dc) + tdc->dma_desc = NULL; + } + ++ tdc->status = DMA_COMPLETE; + tegra_dma_sid_free(tdc); + vchan_get_all_descriptors(&tdc->vc, &head); + spin_unlock_irqrestore(&tdc->vc.lock, flags); +@@ -769,6 +776,9 @@ static enum dma_status tegra_dma_tx_status(struct dma_chan *dc, + if (ret == DMA_COMPLETE) + return ret; + ++ if (tdc->status == DMA_PAUSED) ++ ret = DMA_PAUSED; ++ + spin_lock_irqsave(&tdc->vc.lock, flags); + vd = vchan_find_desc(&tdc->vc, cookie); + if (vd) { +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +index af6c6d89e63afb..fbee10927bfb64 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +@@ -467,28 +467,6 @@ uint32_t amdgpu_amdkfd_get_max_engine_clock_in_mhz(struct amdgpu_device *adev) + return 100; + } + +-void amdgpu_amdkfd_get_cu_info(struct amdgpu_device *adev, struct kfd_cu_info *cu_info) +-{ +- struct amdgpu_cu_info acu_info = adev->gfx.cu_info; +- +- memset(cu_info, 0, sizeof(*cu_info)); +- if (sizeof(cu_info->cu_bitmap) != sizeof(acu_info.bitmap)) +- return; +- +- cu_info->cu_active_number = acu_info.number; +- cu_info->cu_ao_mask = acu_info.ao_cu_mask; +- memcpy(&cu_info->cu_bitmap[0], &acu_info.bitmap[0], +- sizeof(cu_info->cu_bitmap)); +- cu_info->num_shader_engines = adev->gfx.config.max_shader_engines; +- cu_info->num_shader_arrays_per_engine = adev->gfx.config.max_sh_per_se; +- cu_info->num_cu_per_sh = adev->gfx.config.max_cu_per_sh; +- cu_info->simd_per_cu = acu_info.simd_per_cu; +- cu_info->max_waves_per_simd = acu_info.max_waves_per_simd; +- cu_info->wave_front_size = acu_info.wave_front_size; +- cu_info->max_scratch_slots_per_cu = acu_info.max_scratch_slots_per_cu; +- cu_info->lds_size = acu_info.lds_size; +-} +- + int amdgpu_amdkfd_get_dmabuf_info(struct amdgpu_device *adev, int dma_buf_fd, + struct amdgpu_device **dmabuf_adev, + uint64_t *bo_size, void *metadata_buffer, +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h +index 3134e6ad81d1d4..ff2b8ace438b62 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h +@@ -235,8 +235,6 @@ void amdgpu_amdkfd_get_local_mem_info(struct amdgpu_device *adev, + uint64_t amdgpu_amdkfd_get_gpu_clock_counter(struct amdgpu_device *adev); + + uint32_t amdgpu_amdkfd_get_max_engine_clock_in_mhz(struct amdgpu_device *adev); +-void amdgpu_amdkfd_get_cu_info(struct amdgpu_device *adev, +- struct kfd_cu_info *cu_info); + int amdgpu_amdkfd_get_dmabuf_info(struct amdgpu_device *adev, int dma_buf_fd, + struct amdgpu_device **dmabuf_adev, + uint64_t *bo_size, void *metadata_buffer, +diff --git a/drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c b/drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c +index 71d1a2e3bac916..30210613dc5c47 100644 +--- a/drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c +@@ -40,10 +40,12 @@ + static void hdp_v4_0_flush_hdp(struct amdgpu_device *adev, + struct amdgpu_ring *ring) + { +- if (!ring || !ring->funcs->emit_wreg) +- WREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); +- else ++ if (!ring || !ring->funcs->emit_wreg) { ++ WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); ++ RREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2); ++ } else { + amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); ++ } + } + + static void hdp_v4_0_invalidate_hdp(struct amdgpu_device *adev, +@@ -53,11 +55,13 @@ static void hdp_v4_0_invalidate_hdp(struct amdgpu_device *adev, + adev->ip_versions[HDP_HWIP][0] == IP_VERSION(4, 4, 2)) + return; + +- if (!ring || !ring->funcs->emit_wreg) ++ if (!ring || !ring->funcs->emit_wreg) { + WREG32_SOC15_NO_KIQ(HDP, 0, mmHDP_READ_CACHE_INVALIDATE, 1); +- else ++ RREG32_SOC15_NO_KIQ(HDP, 0, mmHDP_READ_CACHE_INVALIDATE); ++ } else { + amdgpu_ring_emit_wreg(ring, SOC15_REG_OFFSET( + HDP, 0, mmHDP_READ_CACHE_INVALIDATE), 1); ++ } + } + + static void hdp_v4_0_query_ras_error_count(struct amdgpu_device *adev, +diff --git a/drivers/gpu/drm/amd/amdgpu/hdp_v5_0.c b/drivers/gpu/drm/amd/amdgpu/hdp_v5_0.c +index a9ea23fa0def7f..d3962d46908811 100644 +--- a/drivers/gpu/drm/amd/amdgpu/hdp_v5_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/hdp_v5_0.c +@@ -31,10 +31,12 @@ + static void hdp_v5_0_flush_hdp(struct amdgpu_device *adev, + struct amdgpu_ring *ring) + { +- if (!ring || !ring->funcs->emit_wreg) +- WREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); +- else ++ if (!ring || !ring->funcs->emit_wreg) { ++ WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); ++ RREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2); ++ } else { + amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); ++ } + } + + static void hdp_v5_0_invalidate_hdp(struct amdgpu_device *adev, +@@ -42,6 +44,7 @@ static void hdp_v5_0_invalidate_hdp(struct amdgpu_device *adev, + { + if (!ring || !ring->funcs->emit_wreg) { + WREG32_SOC15_NO_KIQ(HDP, 0, mmHDP_READ_CACHE_INVALIDATE, 1); ++ RREG32_SOC15_NO_KIQ(HDP, 0, mmHDP_READ_CACHE_INVALIDATE); + } else { + amdgpu_ring_emit_wreg(ring, SOC15_REG_OFFSET( + HDP, 0, mmHDP_READ_CACHE_INVALIDATE), 1); +diff --git a/drivers/gpu/drm/amd/amdgpu/hdp_v6_0.c b/drivers/gpu/drm/amd/amdgpu/hdp_v6_0.c +index 063eba619f2f6c..b6d71ec1debf9a 100644 +--- a/drivers/gpu/drm/amd/amdgpu/hdp_v6_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/hdp_v6_0.c +@@ -31,10 +31,12 @@ + static void hdp_v6_0_flush_hdp(struct amdgpu_device *adev, + struct amdgpu_ring *ring) + { +- if (!ring || !ring->funcs->emit_wreg) +- WREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); +- else ++ if (!ring || !ring->funcs->emit_wreg) { ++ WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); ++ RREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2); ++ } else { + amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); ++ } + } + + static void hdp_v6_0_update_clock_gating(struct amdgpu_device *adev, +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c +index f76b7aee5c0a12..29a02c1752289c 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c +@@ -2037,11 +2037,12 @@ static int kfd_create_vcrat_image_gpu(void *pcrat_image, + uint32_t proximity_domain) + { + struct crat_header *crat_table = (struct crat_header *)pcrat_image; ++ struct amdgpu_gfx_config *gfx_info = &kdev->adev->gfx.config; ++ struct amdgpu_cu_info *cu_info = &kdev->adev->gfx.cu_info; + struct crat_subtype_generic *sub_type_hdr; + struct kfd_local_mem_info local_mem_info; + struct kfd_topology_device *peer_dev; + struct crat_subtype_computeunit *cu; +- struct kfd_cu_info cu_info; + int avail_size = *size; + uint32_t total_num_of_cu; + uint32_t nid = 0; +@@ -2085,21 +2086,20 @@ static int kfd_create_vcrat_image_gpu(void *pcrat_image, + cu->flags |= CRAT_CU_FLAGS_GPU_PRESENT; + cu->proximity_domain = proximity_domain; + +- amdgpu_amdkfd_get_cu_info(kdev->adev, &cu_info); +- cu->num_simd_per_cu = cu_info.simd_per_cu; +- cu->num_simd_cores = cu_info.simd_per_cu * +- (cu_info.cu_active_number / kdev->kfd->num_nodes); +- cu->max_waves_simd = cu_info.max_waves_per_simd; ++ cu->num_simd_per_cu = cu_info->simd_per_cu; ++ cu->num_simd_cores = cu_info->simd_per_cu * ++ (cu_info->number / kdev->kfd->num_nodes); ++ cu->max_waves_simd = cu_info->max_waves_per_simd; + +- cu->wave_front_size = cu_info.wave_front_size; +- cu->array_count = cu_info.num_shader_arrays_per_engine * +- cu_info.num_shader_engines; +- total_num_of_cu = (cu->array_count * cu_info.num_cu_per_sh); ++ cu->wave_front_size = cu_info->wave_front_size; ++ cu->array_count = gfx_info->max_sh_per_se * ++ gfx_info->max_shader_engines; ++ total_num_of_cu = (cu->array_count * gfx_info->max_cu_per_sh); + cu->processor_id_low = get_and_inc_gpu_processor_id(total_num_of_cu); +- cu->num_cu_per_array = cu_info.num_cu_per_sh; +- cu->max_slots_scatch_cu = cu_info.max_scratch_slots_per_cu; +- cu->num_banks = cu_info.num_shader_engines; +- cu->lds_size_in_kb = cu_info.lds_size; ++ cu->num_cu_per_array = gfx_info->max_cu_per_sh; ++ cu->max_slots_scatch_cu = cu_info->max_scratch_slots_per_cu; ++ cu->num_banks = gfx_info->max_shader_engines; ++ cu->lds_size_in_kb = cu_info->lds_size; + + cu->hsa_capability = 0; + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +index 4d9a406925e189..43fa260ddbcea0 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +@@ -197,6 +197,21 @@ static int add_queue_mes(struct device_queue_manager *dqm, struct queue *q, + if (dqm->is_hws_hang) + return -EIO; + ++ if (!pdd->proc_ctx_cpu_ptr) { ++ r = amdgpu_amdkfd_alloc_gtt_mem(adev, ++ AMDGPU_MES_PROC_CTX_SIZE, ++ &pdd->proc_ctx_bo, ++ &pdd->proc_ctx_gpu_addr, ++ &pdd->proc_ctx_cpu_ptr, ++ false); ++ if (r) { ++ dev_err(adev->dev, ++ "failed to allocate process context bo\n"); ++ return r; ++ } ++ memset(pdd->proc_ctx_cpu_ptr, 0, AMDGPU_MES_PROC_CTX_SIZE); ++ } ++ + memset(&queue_input, 0x0, sizeof(struct mes_add_queue_input)); + queue_input.process_id = qpd->pqm->process->pasid; + queue_input.page_table_base_addr = qpd->page_table_base; +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c +index 6604a3f99c5ecf..b22a036523b7e4 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c +@@ -373,7 +373,8 @@ int kfd_init_apertures(struct kfd_process *process) + + pdd = kfd_create_process_device_data(dev, process); + if (!pdd) { +- pr_err("Failed to create process device data\n"); ++ dev_err(dev->adev->dev, ++ "Failed to create process device data\n"); + return -ENOMEM; + } + /* +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c +index 68d13c4fac8f4f..2c529339ff6572 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c +@@ -68,7 +68,7 @@ static bool kq_initialize(struct kernel_queue *kq, struct kfd_node *dev, + kq->mqd_mgr = dev->dqm->mqd_mgrs[KFD_MQD_TYPE_HIQ]; + break; + default: +- pr_err("Invalid queue type %d\n", type); ++ dev_err(dev->adev->dev, "Invalid queue type %d\n", type); + return false; + } + +@@ -78,13 +78,14 @@ static bool kq_initialize(struct kernel_queue *kq, struct kfd_node *dev, + prop.doorbell_ptr = kfd_get_kernel_doorbell(dev->kfd, &prop.doorbell_off); + + if (!prop.doorbell_ptr) { +- pr_err("Failed to initialize doorbell"); ++ dev_err(dev->adev->dev, "Failed to initialize doorbell"); + goto err_get_kernel_doorbell; + } + + retval = kfd_gtt_sa_allocate(dev, queue_size, &kq->pq); + if (retval != 0) { +- pr_err("Failed to init pq queues size %d\n", queue_size); ++ dev_err(dev->adev->dev, "Failed to init pq queues size %d\n", ++ queue_size); + goto err_pq_allocate_vidmem; + } + +@@ -332,7 +333,7 @@ struct kernel_queue *kernel_queue_init(struct kfd_node *dev, + if (kq_initialize(kq, dev, type, KFD_KERNEL_QUEUE_SIZE)) + return kq; + +- pr_err("Failed to init kernel queue\n"); ++ dev_err(dev->adev->dev, "Failed to init kernel queue\n"); + + kfree(kq); + return NULL; +@@ -351,26 +352,26 @@ static __attribute__((unused)) void test_kq(struct kfd_node *dev) + uint32_t *buffer, i; + int retval; + +- pr_err("Starting kernel queue test\n"); ++ dev_err(dev->adev->dev, "Starting kernel queue test\n"); + + kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_HIQ); + if (unlikely(!kq)) { +- pr_err(" Failed to initialize HIQ\n"); +- pr_err("Kernel queue test failed\n"); ++ dev_err(dev->adev->dev, " Failed to initialize HIQ\n"); ++ dev_err(dev->adev->dev, "Kernel queue test failed\n"); + return; + } + + retval = kq_acquire_packet_buffer(kq, 5, &buffer); + if (unlikely(retval != 0)) { +- pr_err(" Failed to acquire packet buffer\n"); +- pr_err("Kernel queue test failed\n"); ++ dev_err(dev->adev->dev, " Failed to acquire packet buffer\n"); ++ dev_err(dev->adev->dev, "Kernel queue test failed\n"); + return; + } + for (i = 0; i < 5; i++) + buffer[i] = kq->nop_packet; + kq_submit_packet(kq); + +- pr_err("Ending kernel queue test\n"); ++ dev_err(dev->adev->dev, "Ending kernel queue test\n"); + } + + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c +index 4c3f379803117e..0edae9ded68a99 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c +@@ -99,7 +99,8 @@ void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm, + const uint32_t *cu_mask, uint32_t cu_mask_count, + uint32_t *se_mask, uint32_t inst) + { +- struct kfd_cu_info cu_info; ++ struct amdgpu_cu_info *cu_info = &mm->dev->adev->gfx.cu_info; ++ struct amdgpu_gfx_config *gfx_info = &mm->dev->adev->gfx.config; + uint32_t cu_per_sh[KFD_MAX_NUM_SE][KFD_MAX_NUM_SH_PER_SE] = {0}; + bool wgp_mode_req = KFD_GC_VERSION(mm->dev) >= IP_VERSION(10, 0, 0); + uint32_t en_mask = wgp_mode_req ? 0x3 : 0x1; +@@ -108,9 +109,7 @@ void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm, + int inc = cu_inc * NUM_XCC(mm->dev->xcc_mask); + int xcc_inst = inst + ffs(mm->dev->xcc_mask) - 1; + +- amdgpu_amdkfd_get_cu_info(mm->dev->adev, &cu_info); +- +- cu_active_per_node = cu_info.cu_active_number / mm->dev->kfd->num_nodes; ++ cu_active_per_node = cu_info->number / mm->dev->kfd->num_nodes; + if (cu_mask_count > cu_active_per_node) + cu_mask_count = cu_active_per_node; + +@@ -118,13 +117,16 @@ void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm, + * Returning with no CU's enabled will hang the queue, which should be + * attention grabbing. + */ +- if (cu_info.num_shader_engines > KFD_MAX_NUM_SE) { +- pr_err("Exceeded KFD_MAX_NUM_SE, chip reports %d\n", cu_info.num_shader_engines); ++ if (gfx_info->max_shader_engines > KFD_MAX_NUM_SE) { ++ dev_err(mm->dev->adev->dev, ++ "Exceeded KFD_MAX_NUM_SE, chip reports %d\n", ++ gfx_info->max_shader_engines); + return; + } +- if (cu_info.num_shader_arrays_per_engine > KFD_MAX_NUM_SH_PER_SE) { +- pr_err("Exceeded KFD_MAX_NUM_SH, chip reports %d\n", +- cu_info.num_shader_arrays_per_engine * cu_info.num_shader_engines); ++ if (gfx_info->max_sh_per_se > KFD_MAX_NUM_SH_PER_SE) { ++ dev_err(mm->dev->adev->dev, ++ "Exceeded KFD_MAX_NUM_SH, chip reports %d\n", ++ gfx_info->max_sh_per_se * gfx_info->max_shader_engines); + return; + } + +@@ -142,10 +144,10 @@ void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm, + * See note on Arcturus cu_bitmap layout in gfx_v9_0_get_cu_info. + * See note on GFX11 cu_bitmap layout in gfx_v11_0_get_cu_info. + */ +- for (se = 0; se < cu_info.num_shader_engines; se++) +- for (sh = 0; sh < cu_info.num_shader_arrays_per_engine; sh++) ++ for (se = 0; se < gfx_info->max_shader_engines; se++) ++ for (sh = 0; sh < gfx_info->max_sh_per_se; sh++) + cu_per_sh[se][sh] = hweight32( +- cu_info.cu_bitmap[xcc_inst][se % 4][sh + (se / 4) * ++ cu_info->bitmap[xcc_inst][se % 4][sh + (se / 4) * + cu_bitmap_sh_mul]); + + /* Symmetrically map cu_mask to all SEs & SHs: +@@ -184,13 +186,13 @@ void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm, + * + * First ensure all CUs are disabled, then enable user specified CUs. + */ +- for (i = 0; i < cu_info.num_shader_engines; i++) ++ for (i = 0; i < gfx_info->max_shader_engines; i++) + se_mask[i] = 0; + + i = inst; + for (cu = 0; cu < 16; cu += cu_inc) { +- for (sh = 0; sh < cu_info.num_shader_arrays_per_engine; sh++) { +- for (se = 0; se < cu_info.num_shader_engines; se++) { ++ for (sh = 0; sh < gfx_info->max_sh_per_se; sh++) { ++ for (se = 0; se < gfx_info->max_shader_engines; se++) { + if (cu_per_sh[se][sh] > cu) { + if (cu_mask[i / 32] & (en_mask << (i % 32))) + se_mask[se] |= en_mask << (cu + sh * 16); +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c +index 401096c103b2f1..ecb38a6e8013cd 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c +@@ -45,7 +45,8 @@ static void pm_calc_rlib_size(struct packet_manager *pm, + unsigned int process_count, queue_count, compute_queue_count, gws_queue_count; + unsigned int map_queue_size; + unsigned int max_proc_per_quantum = 1; +- struct kfd_node *dev = pm->dqm->dev; ++ struct kfd_node *node = pm->dqm->dev; ++ struct device *dev = node->adev->dev; + + process_count = pm->dqm->processes_count; + queue_count = pm->dqm->active_queue_count; +@@ -59,14 +60,14 @@ static void pm_calc_rlib_size(struct packet_manager *pm, + */ + *over_subscription = false; + +- if (dev->max_proc_per_quantum > 1) +- max_proc_per_quantum = dev->max_proc_per_quantum; ++ if (node->max_proc_per_quantum > 1) ++ max_proc_per_quantum = node->max_proc_per_quantum; + + if ((process_count > max_proc_per_quantum) || + compute_queue_count > get_cp_queues_num(pm->dqm) || + gws_queue_count > 1) { + *over_subscription = true; +- pr_debug("Over subscribed runlist\n"); ++ dev_dbg(dev, "Over subscribed runlist\n"); + } + + map_queue_size = pm->pmf->map_queues_size; +@@ -81,7 +82,7 @@ static void pm_calc_rlib_size(struct packet_manager *pm, + if (*over_subscription) + *rlib_size += pm->pmf->runlist_size; + +- pr_debug("runlist ib size %d\n", *rlib_size); ++ dev_dbg(dev, "runlist ib size %d\n", *rlib_size); + } + + static int pm_allocate_runlist_ib(struct packet_manager *pm, +@@ -90,6 +91,8 @@ static int pm_allocate_runlist_ib(struct packet_manager *pm, + unsigned int *rl_buffer_size, + bool *is_over_subscription) + { ++ struct kfd_node *node = pm->dqm->dev; ++ struct device *dev = node->adev->dev; + int retval; + + if (WARN_ON(pm->allocated)) +@@ -99,11 +102,10 @@ static int pm_allocate_runlist_ib(struct packet_manager *pm, + + mutex_lock(&pm->lock); + +- retval = kfd_gtt_sa_allocate(pm->dqm->dev, *rl_buffer_size, +- &pm->ib_buffer_obj); ++ retval = kfd_gtt_sa_allocate(node, *rl_buffer_size, &pm->ib_buffer_obj); + + if (retval) { +- pr_err("Failed to allocate runlist IB\n"); ++ dev_err(dev, "Failed to allocate runlist IB\n"); + goto out; + } + +@@ -125,6 +127,8 @@ static int pm_create_runlist_ib(struct packet_manager *pm, + { + unsigned int alloc_size_bytes; + unsigned int *rl_buffer, rl_wptr, i; ++ struct kfd_node *node = pm->dqm->dev; ++ struct device *dev = node->adev->dev; + int retval, processes_mapped; + struct device_process_node *cur; + struct qcm_process_device *qpd; +@@ -142,7 +146,7 @@ static int pm_create_runlist_ib(struct packet_manager *pm, + *rl_size_bytes = alloc_size_bytes; + pm->ib_size_bytes = alloc_size_bytes; + +- pr_debug("Building runlist ib process count: %d queues count %d\n", ++ dev_dbg(dev, "Building runlist ib process count: %d queues count %d\n", + pm->dqm->processes_count, pm->dqm->active_queue_count); + + /* build the run list ib packet */ +@@ -150,7 +154,7 @@ static int pm_create_runlist_ib(struct packet_manager *pm, + qpd = cur->qpd; + /* build map process packet */ + if (processes_mapped >= pm->dqm->processes_count) { +- pr_debug("Not enough space left in runlist IB\n"); ++ dev_dbg(dev, "Not enough space left in runlist IB\n"); + pm_release_ib(pm); + return -ENOMEM; + } +@@ -167,7 +171,8 @@ static int pm_create_runlist_ib(struct packet_manager *pm, + if (!kq->queue->properties.is_active) + continue; + +- pr_debug("static_queue, mapping kernel q %d, is debug status %d\n", ++ dev_dbg(dev, ++ "static_queue, mapping kernel q %d, is debug status %d\n", + kq->queue->queue, qpd->is_debug); + + retval = pm->pmf->map_queues(pm, +@@ -186,7 +191,8 @@ static int pm_create_runlist_ib(struct packet_manager *pm, + if (!q->properties.is_active) + continue; + +- pr_debug("static_queue, mapping user queue %d, is debug status %d\n", ++ dev_dbg(dev, ++ "static_queue, mapping user queue %d, is debug status %d\n", + q->queue, qpd->is_debug); + + retval = pm->pmf->map_queues(pm, +@@ -203,11 +209,13 @@ static int pm_create_runlist_ib(struct packet_manager *pm, + } + } + +- pr_debug("Finished map process and queues to runlist\n"); ++ dev_dbg(dev, "Finished map process and queues to runlist\n"); + + if (is_over_subscription) { + if (!pm->is_over_subscription) +- pr_warn("Runlist is getting oversubscribed. Expect reduced ROCm performance.\n"); ++ dev_warn( ++ dev, ++ "Runlist is getting oversubscribed. Expect reduced ROCm performance.\n"); + retval = pm->pmf->runlist(pm, &rl_buffer[rl_wptr], + *rl_gpu_addr, + alloc_size_bytes / sizeof(uint32_t), +@@ -272,6 +280,8 @@ void pm_uninit(struct packet_manager *pm, bool hanging) + int pm_send_set_resources(struct packet_manager *pm, + struct scheduling_resources *res) + { ++ struct kfd_node *node = pm->dqm->dev; ++ struct device *dev = node->adev->dev; + uint32_t *buffer, size; + int retval = 0; + +@@ -281,7 +291,7 @@ int pm_send_set_resources(struct packet_manager *pm, + size / sizeof(uint32_t), + (unsigned int **)&buffer); + if (!buffer) { +- pr_err("Failed to allocate buffer on kernel queue\n"); ++ dev_err(dev, "Failed to allocate buffer on kernel queue\n"); + retval = -ENOMEM; + goto out; + } +@@ -343,6 +353,8 @@ int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues) + int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address, + uint64_t fence_value) + { ++ struct kfd_node *node = pm->dqm->dev; ++ struct device *dev = node->adev->dev; + uint32_t *buffer, size; + int retval = 0; + +@@ -354,7 +366,7 @@ int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address, + kq_acquire_packet_buffer(pm->priv_queue, + size / sizeof(uint32_t), (unsigned int **)&buffer); + if (!buffer) { +- pr_err("Failed to allocate buffer on kernel queue\n"); ++ dev_err(dev, "Failed to allocate buffer on kernel queue\n"); + retval = -ENOMEM; + goto out; + } +@@ -372,6 +384,8 @@ int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address, + + int pm_update_grace_period(struct packet_manager *pm, uint32_t grace_period) + { ++ struct kfd_node *node = pm->dqm->dev; ++ struct device *dev = node->adev->dev; + int retval = 0; + uint32_t *buffer, size; + +@@ -385,7 +399,8 @@ int pm_update_grace_period(struct packet_manager *pm, uint32_t grace_period) + (unsigned int **)&buffer); + + if (!buffer) { +- pr_err("Failed to allocate buffer on kernel queue\n"); ++ dev_err(dev, ++ "Failed to allocate buffer on kernel queue\n"); + retval = -ENOMEM; + goto out; + } +@@ -406,6 +421,8 @@ int pm_send_unmap_queue(struct packet_manager *pm, + enum kfd_unmap_queues_filter filter, + uint32_t filter_param, bool reset) + { ++ struct kfd_node *node = pm->dqm->dev; ++ struct device *dev = node->adev->dev; + uint32_t *buffer, size; + int retval = 0; + +@@ -414,7 +431,7 @@ int pm_send_unmap_queue(struct packet_manager *pm, + kq_acquire_packet_buffer(pm->priv_queue, + size / sizeof(uint32_t), (unsigned int **)&buffer); + if (!buffer) { +- pr_err("Failed to allocate buffer on kernel queue\n"); ++ dev_err(dev, "Failed to allocate buffer on kernel queue\n"); + retval = -ENOMEM; + goto out; + } +@@ -463,6 +480,8 @@ int pm_debugfs_runlist(struct seq_file *m, void *data) + + int pm_debugfs_hang_hws(struct packet_manager *pm) + { ++ struct kfd_node *node = pm->dqm->dev; ++ struct device *dev = node->adev->dev; + uint32_t *buffer, size; + int r = 0; + +@@ -474,16 +493,16 @@ int pm_debugfs_hang_hws(struct packet_manager *pm) + kq_acquire_packet_buffer(pm->priv_queue, + size / sizeof(uint32_t), (unsigned int **)&buffer); + if (!buffer) { +- pr_err("Failed to allocate buffer on kernel queue\n"); ++ dev_err(dev, "Failed to allocate buffer on kernel queue\n"); + r = -ENOMEM; + goto out; + } + memset(buffer, 0x55, size); + kq_submit_packet(pm->priv_queue); + +- pr_info("Submitting %x %x %x %x %x %x %x to HIQ to hang the HWS.", +- buffer[0], buffer[1], buffer[2], buffer[3], +- buffer[4], buffer[5], buffer[6]); ++ dev_info(dev, "Submitting %x %x %x %x %x %x %x to HIQ to hang the HWS.", ++ buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], ++ buffer[5], buffer[6]); + out: + mutex_unlock(&pm->lock); + return r; +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c +index fd640a061c96a8..64346c71c62a30 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c +@@ -1046,7 +1046,8 @@ static void kfd_process_destroy_pdds(struct kfd_process *p) + + kfd_free_process_doorbells(pdd->dev->kfd, pdd); + +- if (pdd->dev->kfd->shared_resources.enable_mes) ++ if (pdd->dev->kfd->shared_resources.enable_mes && ++ pdd->proc_ctx_cpu_ptr) + amdgpu_amdkfd_free_gtt_mem(pdd->dev->adev, + &pdd->proc_ctx_bo); + /* +@@ -1308,7 +1309,8 @@ int kfd_process_init_cwsr_apu(struct kfd_process *p, struct file *filep) + if (IS_ERR_VALUE(qpd->tba_addr)) { + int err = qpd->tba_addr; + +- pr_err("Failure to set tba address. error %d.\n", err); ++ dev_err(dev->adev->dev, ++ "Failure to set tba address. error %d.\n", err); + qpd->tba_addr = 0; + qpd->cwsr_kaddr = NULL; + return err; +@@ -1571,7 +1573,6 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_node *dev, + struct kfd_process *p) + { + struct kfd_process_device *pdd = NULL; +- int retval = 0; + + if (WARN_ON_ONCE(p->n_pdds >= MAX_GPU_INSTANCE)) + return NULL; +@@ -1595,20 +1596,6 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_node *dev, + pdd->user_gpu_id = dev->id; + atomic64_set(&pdd->evict_duration_counter, 0); + +- if (dev->kfd->shared_resources.enable_mes) { +- retval = amdgpu_amdkfd_alloc_gtt_mem(dev->adev, +- AMDGPU_MES_PROC_CTX_SIZE, +- &pdd->proc_ctx_bo, +- &pdd->proc_ctx_gpu_addr, +- &pdd->proc_ctx_cpu_ptr, +- false); +- if (retval) { +- pr_err("failed to allocate process context bo\n"); +- goto err_free_pdd; +- } +- memset(pdd->proc_ctx_cpu_ptr, 0, AMDGPU_MES_PROC_CTX_SIZE); +- } +- + p->pdds[p->n_pdds++] = pdd; + if (kfd_dbg_is_per_vmid_supported(pdd->dev)) + pdd->spi_dbg_override = pdd->dev->kfd2kgd->disable_debug_trap( +@@ -1620,10 +1607,6 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_node *dev, + idr_init(&pdd->alloc_idr); + + return pdd; +- +-err_free_pdd: +- kfree(pdd); +- return NULL; + } + + /** +@@ -1667,7 +1650,7 @@ int kfd_process_device_init_vm(struct kfd_process_device *pdd, + &p->kgd_process_info, + &p->ef); + if (ret) { +- pr_err("Failed to create process VM object\n"); ++ dev_err(dev->adev->dev, "Failed to create process VM object\n"); + return ret; + } + pdd->drm_priv = drm_file->private_data; +@@ -1714,7 +1697,7 @@ struct kfd_process_device *kfd_bind_process_to_device(struct kfd_node *dev, + + pdd = kfd_get_process_device_data(dev, p); + if (!pdd) { +- pr_err("Process device data doesn't exist\n"); ++ dev_err(dev->adev->dev, "Process device data doesn't exist\n"); + return ERR_PTR(-ENOMEM); + } + +@@ -1824,6 +1807,7 @@ int kfd_process_evict_queues(struct kfd_process *p, uint32_t trigger) + + for (i = 0; i < p->n_pdds; i++) { + struct kfd_process_device *pdd = p->pdds[i]; ++ struct device *dev = pdd->dev->adev->dev; + + kfd_smi_event_queue_eviction(pdd->dev, p->lead_thread->pid, + trigger); +@@ -1835,7 +1819,7 @@ int kfd_process_evict_queues(struct kfd_process *p, uint32_t trigger) + * them been add back since they actually not be saved right now. + */ + if (r && r != -EIO) { +- pr_err("Failed to evict process queues\n"); ++ dev_err(dev, "Failed to evict process queues\n"); + goto fail; + } + n_evicted++; +@@ -1857,7 +1841,8 @@ int kfd_process_evict_queues(struct kfd_process *p, uint32_t trigger) + + if (pdd->dev->dqm->ops.restore_process_queues(pdd->dev->dqm, + &pdd->qpd)) +- pr_err("Failed to restore queues\n"); ++ dev_err(pdd->dev->adev->dev, ++ "Failed to restore queues\n"); + + n_evicted--; + } +@@ -1873,13 +1858,14 @@ int kfd_process_restore_queues(struct kfd_process *p) + + for (i = 0; i < p->n_pdds; i++) { + struct kfd_process_device *pdd = p->pdds[i]; ++ struct device *dev = pdd->dev->adev->dev; + + kfd_smi_event_queue_restore(pdd->dev, p->lead_thread->pid); + + r = pdd->dev->dqm->ops.restore_process_queues(pdd->dev->dqm, + &pdd->qpd); + if (r) { +- pr_err("Failed to restore process queues\n"); ++ dev_err(dev, "Failed to restore process queues\n"); + if (!ret) + ret = r; + } +@@ -2039,7 +2025,7 @@ int kfd_reserved_mem_mmap(struct kfd_node *dev, struct kfd_process *process, + struct qcm_process_device *qpd; + + if ((vma->vm_end - vma->vm_start) != KFD_CWSR_TBA_TMA_SIZE) { +- pr_err("Incorrect CWSR mapping size.\n"); ++ dev_err(dev->adev->dev, "Incorrect CWSR mapping size.\n"); + return -EINVAL; + } + +@@ -2051,7 +2037,8 @@ int kfd_reserved_mem_mmap(struct kfd_node *dev, struct kfd_process *process, + qpd->cwsr_kaddr = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, + get_order(KFD_CWSR_TBA_TMA_SIZE)); + if (!qpd->cwsr_kaddr) { +- pr_err("Error allocating per process CWSR buffer.\n"); ++ dev_err(dev->adev->dev, ++ "Error allocating per process CWSR buffer.\n"); + return -ENOMEM; + } + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +index 8362a71ab70752..3885bb53f0191e 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +@@ -1537,7 +1537,6 @@ static int kfd_dev_create_p2p_links(void) + /* Helper function. See kfd_fill_gpu_cache_info for parameter description */ + static int fill_in_l1_pcache(struct kfd_cache_properties **props_ext, + struct kfd_gpu_cache_info *pcache_info, +- struct kfd_cu_info *cu_info, + int cu_bitmask, + int cache_type, unsigned int cu_processor_id, + int cu_block) +@@ -1599,7 +1598,8 @@ static int fill_in_l1_pcache(struct kfd_cache_properties **props_ext, + /* Helper function. See kfd_fill_gpu_cache_info for parameter description */ + static int fill_in_l2_l3_pcache(struct kfd_cache_properties **props_ext, + struct kfd_gpu_cache_info *pcache_info, +- struct kfd_cu_info *cu_info, ++ struct amdgpu_cu_info *cu_info, ++ struct amdgpu_gfx_config *gfx_info, + int cache_type, unsigned int cu_processor_id, + struct kfd_node *knode) + { +@@ -1610,7 +1610,7 @@ static int fill_in_l2_l3_pcache(struct kfd_cache_properties **props_ext, + + start = ffs(knode->xcc_mask) - 1; + end = start + NUM_XCC(knode->xcc_mask); +- cu_sibling_map_mask = cu_info->cu_bitmap[start][0][0]; ++ cu_sibling_map_mask = cu_info->bitmap[start][0][0]; + cu_sibling_map_mask &= + ((1 << pcache_info[cache_type].num_cu_shared) - 1); + first_active_cu = ffs(cu_sibling_map_mask); +@@ -1646,15 +1646,15 @@ static int fill_in_l2_l3_pcache(struct kfd_cache_properties **props_ext, + k = 0; + + for (xcc = start; xcc < end; xcc++) { +- for (i = 0; i < cu_info->num_shader_engines; i++) { +- for (j = 0; j < cu_info->num_shader_arrays_per_engine; j++) { ++ for (i = 0; i < gfx_info->max_shader_engines; i++) { ++ for (j = 0; j < gfx_info->max_sh_per_se; j++) { + pcache->sibling_map[k] = (uint8_t)(cu_sibling_map_mask & 0xFF); + pcache->sibling_map[k+1] = (uint8_t)((cu_sibling_map_mask >> 8) & 0xFF); + pcache->sibling_map[k+2] = (uint8_t)((cu_sibling_map_mask >> 16) & 0xFF); + pcache->sibling_map[k+3] = (uint8_t)((cu_sibling_map_mask >> 24) & 0xFF); + k += 4; + +- cu_sibling_map_mask = cu_info->cu_bitmap[xcc][i % 4][j + i / 4]; ++ cu_sibling_map_mask = cu_info->bitmap[xcc][i % 4][j + i / 4]; + cu_sibling_map_mask &= ((1 << pcache_info[cache_type].num_cu_shared) - 1); + } + } +@@ -1679,16 +1679,14 @@ static void kfd_fill_cache_non_crat_info(struct kfd_topology_device *dev, struct + unsigned int cu_processor_id; + int ret; + unsigned int num_cu_shared; +- struct kfd_cu_info cu_info; +- struct kfd_cu_info *pcu_info; ++ struct amdgpu_cu_info *cu_info = &kdev->adev->gfx.cu_info; ++ struct amdgpu_gfx_config *gfx_info = &kdev->adev->gfx.config; + int gpu_processor_id; + struct kfd_cache_properties *props_ext; + int num_of_entries = 0; + int num_of_cache_types = 0; + struct kfd_gpu_cache_info cache_info[KFD_MAX_CACHE_TYPES]; + +- amdgpu_amdkfd_get_cu_info(kdev->adev, &cu_info); +- pcu_info = &cu_info; + + gpu_processor_id = dev->node_props.simd_id_base; + +@@ -1715,12 +1713,12 @@ static void kfd_fill_cache_non_crat_info(struct kfd_topology_device *dev, struct + cu_processor_id = gpu_processor_id; + if (pcache_info[ct].cache_level == 1) { + for (xcc = start; xcc < end; xcc++) { +- for (i = 0; i < pcu_info->num_shader_engines; i++) { +- for (j = 0; j < pcu_info->num_shader_arrays_per_engine; j++) { +- for (k = 0; k < pcu_info->num_cu_per_sh; k += pcache_info[ct].num_cu_shared) { ++ for (i = 0; i < gfx_info->max_shader_engines; i++) { ++ for (j = 0; j < gfx_info->max_sh_per_se; j++) { ++ for (k = 0; k < gfx_info->max_cu_per_sh; k += pcache_info[ct].num_cu_shared) { + +- ret = fill_in_l1_pcache(&props_ext, pcache_info, pcu_info, +- pcu_info->cu_bitmap[xcc][i % 4][j + i / 4], ct, ++ ret = fill_in_l1_pcache(&props_ext, pcache_info, ++ cu_info->bitmap[xcc][i % 4][j + i / 4], ct, + cu_processor_id, k); + + if (ret < 0) +@@ -1733,9 +1731,9 @@ static void kfd_fill_cache_non_crat_info(struct kfd_topology_device *dev, struct + + /* Move to next CU block */ + num_cu_shared = ((k + pcache_info[ct].num_cu_shared) <= +- pcu_info->num_cu_per_sh) ? ++ gfx_info->max_cu_per_sh) ? + pcache_info[ct].num_cu_shared : +- (pcu_info->num_cu_per_sh - k); ++ (gfx_info->max_cu_per_sh - k); + cu_processor_id += num_cu_shared; + } + } +@@ -1743,7 +1741,7 @@ static void kfd_fill_cache_non_crat_info(struct kfd_topology_device *dev, struct + } + } else { + ret = fill_in_l2_l3_pcache(&props_ext, pcache_info, +- pcu_info, ct, cu_processor_id, kdev); ++ cu_info, gfx_info, ct, cu_processor_id, kdev); + + if (ret < 0) + break; +@@ -1922,10 +1920,11 @@ int kfd_topology_add_device(struct kfd_node *gpu) + { + uint32_t gpu_id; + struct kfd_topology_device *dev; +- struct kfd_cu_info cu_info; + int res = 0; + int i; + const char *asic_name = amdgpu_asic_name[gpu->adev->asic_type]; ++ struct amdgpu_gfx_config *gfx_info = &gpu->adev->gfx.config; ++ struct amdgpu_cu_info *cu_info = &gpu->adev->gfx.cu_info; + + gpu_id = kfd_generate_gpu_id(gpu); + if (gpu->xcp && !gpu->xcp->ddev) { +@@ -1963,9 +1962,6 @@ int kfd_topology_add_device(struct kfd_node *gpu) + /* Fill-in additional information that is not available in CRAT but + * needed for the topology + */ +- +- amdgpu_amdkfd_get_cu_info(dev->gpu->adev, &cu_info); +- + for (i = 0; i < KFD_TOPOLOGY_PUBLIC_NAME_SIZE-1; i++) { + dev->node_props.name[i] = __tolower(asic_name[i]); + if (asic_name[i] == '\0') +@@ -1974,7 +1970,7 @@ int kfd_topology_add_device(struct kfd_node *gpu) + dev->node_props.name[i] = '\0'; + + dev->node_props.simd_arrays_per_engine = +- cu_info.num_shader_arrays_per_engine; ++ gfx_info->max_sh_per_se; + + dev->node_props.gfx_target_version = + gpu->kfd->device_info.gfx_target_version; +@@ -2055,7 +2051,7 @@ int kfd_topology_add_device(struct kfd_node *gpu) + */ + if (dev->gpu->adev->asic_type == CHIP_CARRIZO) { + dev->node_props.simd_count = +- cu_info.simd_per_cu * cu_info.cu_active_number; ++ cu_info->simd_per_cu * cu_info->number; + dev->node_props.max_waves_per_simd = 10; + } + +diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h +index 3b5a56585c4b72..c653a7f4d5e55b 100644 +--- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h ++++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h +@@ -57,20 +57,6 @@ struct kfd_vm_fault_info { + bool prot_exec; + }; + +-struct kfd_cu_info { +- uint32_t num_shader_engines; +- uint32_t num_shader_arrays_per_engine; +- uint32_t num_cu_per_sh; +- uint32_t cu_active_number; +- uint32_t cu_ao_mask; +- uint32_t simd_per_cu; +- uint32_t max_waves_per_simd; +- uint32_t wave_front_size; +- uint32_t max_scratch_slots_per_cu; +- uint32_t lds_size; +- uint32_t cu_bitmap[AMDGPU_MAX_GC_INSTANCES][4][4]; +-}; +- + /* For getting GPU local memory information from KGD */ + struct kfd_local_mem_info { + uint64_t local_mem_size_private; +diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c +index 90bfb1e988fb31..d6c5de190c2742 100644 +--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c ++++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c +@@ -4033,9 +4033,10 @@ static void drm_dp_mst_up_req_work(struct work_struct *work) + static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr) + { + struct drm_dp_pending_up_req *up_req; ++ struct drm_dp_mst_branch *mst_primary; + + if (!drm_dp_get_one_sb_msg(mgr, true, NULL)) +- goto out; ++ goto out_clear_reply; + + if (!mgr->up_req_recv.have_eomt) + return 0; +@@ -4053,10 +4054,19 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr) + drm_dbg_kms(mgr->dev, "Received unknown up req type, ignoring: %x\n", + up_req->msg.req_type); + kfree(up_req); +- goto out; ++ goto out_clear_reply; ++ } ++ ++ mutex_lock(&mgr->lock); ++ mst_primary = mgr->mst_primary; ++ if (!mst_primary || !drm_dp_mst_topology_try_get_mstb(mst_primary)) { ++ mutex_unlock(&mgr->lock); ++ kfree(up_req); ++ goto out_clear_reply; + } ++ mutex_unlock(&mgr->lock); + +- drm_dp_send_up_ack_reply(mgr, mgr->mst_primary, up_req->msg.req_type, ++ drm_dp_send_up_ack_reply(mgr, mst_primary, up_req->msg.req_type, + false); + + if (up_req->msg.req_type == DP_CONNECTION_STATUS_NOTIFY) { +@@ -4073,13 +4083,13 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr) + conn_stat->peer_device_type); + + mutex_lock(&mgr->probe_lock); +- handle_csn = mgr->mst_primary->link_address_sent; ++ handle_csn = mst_primary->link_address_sent; + mutex_unlock(&mgr->probe_lock); + + if (!handle_csn) { + drm_dbg_kms(mgr->dev, "Got CSN before finish topology probing. Skip it."); + kfree(up_req); +- goto out; ++ goto out_put_primary; + } + } else if (up_req->msg.req_type == DP_RESOURCE_STATUS_NOTIFY) { + const struct drm_dp_resource_status_notify *res_stat = +@@ -4096,7 +4106,9 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr) + mutex_unlock(&mgr->up_req_lock); + queue_work(system_long_wq, &mgr->up_req_work); + +-out: ++out_put_primary: ++ drm_dp_mst_topology_put_mstb(mst_primary); ++out_clear_reply: + memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx)); + return 0; + } +diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c +index 0951bfdc89cfa5..913823a063c9ae 100644 +--- a/drivers/i2c/busses/i2c-imx.c ++++ b/drivers/i2c/busses/i2c-imx.c +@@ -286,6 +286,7 @@ static const struct of_device_id i2c_imx_dt_ids[] = { + { .compatible = "fsl,imx6sll-i2c", .data = &imx6_i2c_hwdata, }, + { .compatible = "fsl,imx6sx-i2c", .data = &imx6_i2c_hwdata, }, + { .compatible = "fsl,imx6ul-i2c", .data = &imx6_i2c_hwdata, }, ++ { .compatible = "fsl,imx7d-i2c", .data = &imx6_i2c_hwdata, }, + { .compatible = "fsl,imx7s-i2c", .data = &imx6_i2c_hwdata, }, + { .compatible = "fsl,imx8mm-i2c", .data = &imx6_i2c_hwdata, }, + { .compatible = "fsl,imx8mn-i2c", .data = &imx6_i2c_hwdata, }, +diff --git a/drivers/i2c/busses/i2c-microchip-corei2c.c b/drivers/i2c/busses/i2c-microchip-corei2c.c +index 0b0a1c4d17caef..b0a51695138ad0 100644 +--- a/drivers/i2c/busses/i2c-microchip-corei2c.c ++++ b/drivers/i2c/busses/i2c-microchip-corei2c.c +@@ -93,27 +93,35 @@ + * @base: pointer to register struct + * @dev: device reference + * @i2c_clk: clock reference for i2c input clock ++ * @msg_queue: pointer to the messages requiring sending + * @buf: pointer to msg buffer for easier use + * @msg_complete: xfer completion object + * @adapter: core i2c abstraction + * @msg_err: error code for completed message + * @bus_clk_rate: current i2c bus clock rate + * @isr_status: cached copy of local ISR status ++ * @total_num: total number of messages to be sent/received ++ * @current_num: index of the current message being sent/received + * @msg_len: number of bytes transferred in msg + * @addr: address of the current slave ++ * @restart_needed: whether or not a repeated start is required after current message + */ + struct mchp_corei2c_dev { + void __iomem *base; + struct device *dev; + struct clk *i2c_clk; ++ struct i2c_msg *msg_queue; + u8 *buf; + struct completion msg_complete; + struct i2c_adapter adapter; + int msg_err; ++ int total_num; ++ int current_num; + u32 bus_clk_rate; + u32 isr_status; + u16 msg_len; + u8 addr; ++ bool restart_needed; + }; + + static void mchp_corei2c_core_disable(struct mchp_corei2c_dev *idev) +@@ -222,6 +230,47 @@ static int mchp_corei2c_fill_tx(struct mchp_corei2c_dev *idev) + return 0; + } + ++static void mchp_corei2c_next_msg(struct mchp_corei2c_dev *idev) ++{ ++ struct i2c_msg *this_msg; ++ u8 ctrl; ++ ++ if (idev->current_num >= idev->total_num) { ++ complete(&idev->msg_complete); ++ return; ++ } ++ ++ /* ++ * If there's been an error, the isr needs to return control ++ * to the "main" part of the driver, so as not to keep sending ++ * messages once it completes and clears the SI bit. ++ */ ++ if (idev->msg_err) { ++ complete(&idev->msg_complete); ++ return; ++ } ++ ++ this_msg = idev->msg_queue++; ++ ++ if (idev->current_num < (idev->total_num - 1)) { ++ struct i2c_msg *next_msg = idev->msg_queue; ++ ++ idev->restart_needed = next_msg->flags & I2C_M_RD; ++ } else { ++ idev->restart_needed = false; ++ } ++ ++ idev->addr = i2c_8bit_addr_from_msg(this_msg); ++ idev->msg_len = this_msg->len; ++ idev->buf = this_msg->buf; ++ ++ ctrl = readb(idev->base + CORE_I2C_CTRL); ++ ctrl |= CTRL_STA; ++ writeb(ctrl, idev->base + CORE_I2C_CTRL); ++ ++ idev->current_num++; ++} ++ + static irqreturn_t mchp_corei2c_handle_isr(struct mchp_corei2c_dev *idev) + { + u32 status = idev->isr_status; +@@ -238,8 +287,6 @@ static irqreturn_t mchp_corei2c_handle_isr(struct mchp_corei2c_dev *idev) + ctrl &= ~CTRL_STA; + writeb(idev->addr, idev->base + CORE_I2C_DATA); + writeb(ctrl, idev->base + CORE_I2C_CTRL); +- if (idev->msg_len == 0) +- finished = true; + break; + case STATUS_M_ARB_LOST: + idev->msg_err = -EAGAIN; +@@ -247,10 +294,14 @@ static irqreturn_t mchp_corei2c_handle_isr(struct mchp_corei2c_dev *idev) + break; + case STATUS_M_SLAW_ACK: + case STATUS_M_TX_DATA_ACK: +- if (idev->msg_len > 0) ++ if (idev->msg_len > 0) { + mchp_corei2c_fill_tx(idev); +- else +- last_byte = true; ++ } else { ++ if (idev->restart_needed) ++ finished = true; ++ else ++ last_byte = true; ++ } + break; + case STATUS_M_TX_DATA_NACK: + case STATUS_M_SLAR_NACK: +@@ -287,7 +338,7 @@ static irqreturn_t mchp_corei2c_handle_isr(struct mchp_corei2c_dev *idev) + mchp_corei2c_stop(idev); + + if (last_byte || finished) +- complete(&idev->msg_complete); ++ mchp_corei2c_next_msg(idev); + + return IRQ_HANDLED; + } +@@ -311,21 +362,48 @@ static irqreturn_t mchp_corei2c_isr(int irq, void *_dev) + return ret; + } + +-static int mchp_corei2c_xfer_msg(struct mchp_corei2c_dev *idev, +- struct i2c_msg *msg) ++static int mchp_corei2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, ++ int num) + { +- u8 ctrl; ++ struct mchp_corei2c_dev *idev = i2c_get_adapdata(adap); ++ struct i2c_msg *this_msg = msgs; + unsigned long time_left; ++ u8 ctrl; ++ ++ mchp_corei2c_core_enable(idev); ++ ++ /* ++ * The isr controls the flow of a transfer, this info needs to be saved ++ * to a location that it can access the queue information from. ++ */ ++ idev->restart_needed = false; ++ idev->msg_queue = msgs; ++ idev->total_num = num; ++ idev->current_num = 0; + +- idev->addr = i2c_8bit_addr_from_msg(msg); +- idev->msg_len = msg->len; +- idev->buf = msg->buf; ++ /* ++ * But the first entry to the isr is triggered by the start in this ++ * function, so the first message needs to be "dequeued". ++ */ ++ idev->addr = i2c_8bit_addr_from_msg(this_msg); ++ idev->msg_len = this_msg->len; ++ idev->buf = this_msg->buf; + idev->msg_err = 0; + +- reinit_completion(&idev->msg_complete); ++ if (idev->total_num > 1) { ++ struct i2c_msg *next_msg = msgs + 1; + +- mchp_corei2c_core_enable(idev); ++ idev->restart_needed = next_msg->flags & I2C_M_RD; ++ } + ++ idev->current_num++; ++ idev->msg_queue++; ++ ++ reinit_completion(&idev->msg_complete); ++ ++ /* ++ * Send the first start to pass control to the isr ++ */ + ctrl = readb(idev->base + CORE_I2C_CTRL); + ctrl |= CTRL_STA; + writeb(ctrl, idev->base + CORE_I2C_CTRL); +@@ -335,20 +413,8 @@ static int mchp_corei2c_xfer_msg(struct mchp_corei2c_dev *idev, + if (!time_left) + return -ETIMEDOUT; + +- return idev->msg_err; +-} +- +-static int mchp_corei2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, +- int num) +-{ +- struct mchp_corei2c_dev *idev = i2c_get_adapdata(adap); +- int i, ret; +- +- for (i = 0; i < num; i++) { +- ret = mchp_corei2c_xfer_msg(idev, msgs++); +- if (ret) +- return ret; +- } ++ if (idev->msg_err) ++ return idev->msg_err; + + return num; + } +diff --git a/drivers/media/dvb-frontends/dib3000mb.c b/drivers/media/dvb-frontends/dib3000mb.c +index c598b2a6332565..7c452ddd9e40fa 100644 +--- a/drivers/media/dvb-frontends/dib3000mb.c ++++ b/drivers/media/dvb-frontends/dib3000mb.c +@@ -51,7 +51,7 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-a + static int dib3000_read_reg(struct dib3000_state *state, u16 reg) + { + u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff }; +- u8 rb[2]; ++ u8 rb[2] = {}; + struct i2c_msg msg[] = { + { .addr = state->config.demod_address, .flags = 0, .buf = wb, .len = 2 }, + { .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 }, +diff --git a/drivers/mtd/nand/raw/arasan-nand-controller.c b/drivers/mtd/nand/raw/arasan-nand-controller.c +index a492051c46f596..bde396b359c321 100644 +--- a/drivers/mtd/nand/raw/arasan-nand-controller.c ++++ b/drivers/mtd/nand/raw/arasan-nand-controller.c +@@ -1410,8 +1410,8 @@ static int anfc_parse_cs(struct arasan_nfc *nfc) + * case, the "not" chosen CS is assigned to nfc->spare_cs and selected + * whenever a GPIO CS must be asserted. + */ +- if (nfc->cs_array && nfc->ncs > 2) { +- if (!nfc->cs_array[0] && !nfc->cs_array[1]) { ++ if (nfc->cs_array) { ++ if (nfc->ncs > 2 && !nfc->cs_array[0] && !nfc->cs_array[1]) { + dev_err(nfc->dev, + "Assign a single native CS when using GPIOs\n"); + return -EINVAL; +@@ -1479,8 +1479,15 @@ static int anfc_probe(struct platform_device *pdev) + + static void anfc_remove(struct platform_device *pdev) + { ++ int i; + struct arasan_nfc *nfc = platform_get_drvdata(pdev); + ++ for (i = 0; i < nfc->ncs; i++) { ++ if (nfc->cs_array[i]) { ++ gpiod_put(nfc->cs_array[i]); ++ } ++ } ++ + anfc_chips_cleanup(nfc); + } + +diff --git a/drivers/mtd/nand/raw/atmel/pmecc.c b/drivers/mtd/nand/raw/atmel/pmecc.c +index a22aab4ed4e8ab..3c7dee1be21df1 100644 +--- a/drivers/mtd/nand/raw/atmel/pmecc.c ++++ b/drivers/mtd/nand/raw/atmel/pmecc.c +@@ -380,10 +380,8 @@ atmel_pmecc_create_user(struct atmel_pmecc *pmecc, + user->delta = user->dmu + req->ecc.strength + 1; + + gf_tables = atmel_pmecc_get_gf_tables(req); +- if (IS_ERR(gf_tables)) { +- kfree(user); ++ if (IS_ERR(gf_tables)) + return ERR_CAST(gf_tables); +- } + + user->gf_tables = gf_tables; + +diff --git a/drivers/mtd/nand/raw/diskonchip.c b/drivers/mtd/nand/raw/diskonchip.c +index 2068025d56396a..594e13a852c497 100644 +--- a/drivers/mtd/nand/raw/diskonchip.c ++++ b/drivers/mtd/nand/raw/diskonchip.c +@@ -1098,7 +1098,7 @@ static inline int __init inftl_partscan(struct mtd_info *mtd, struct mtd_partiti + (i == 0) && (ip->firstUnit > 0)) { + parts[0].name = " DiskOnChip IPL / Media Header partition"; + parts[0].offset = 0; +- parts[0].size = mtd->erasesize * ip->firstUnit; ++ parts[0].size = (uint64_t)mtd->erasesize * ip->firstUnit; + numparts = 1; + } + +diff --git a/drivers/pci/msi/irqdomain.c b/drivers/pci/msi/irqdomain.c +index cfd84a899c82d8..dfc15e7507f9b9 100644 +--- a/drivers/pci/msi/irqdomain.c ++++ b/drivers/pci/msi/irqdomain.c +@@ -330,8 +330,11 @@ bool pci_msi_domain_supports(struct pci_dev *pdev, unsigned int feature_mask, + + domain = dev_get_msi_domain(&pdev->dev); + +- if (!domain || !irq_domain_is_hierarchy(domain)) +- return mode == ALLOW_LEGACY; ++ if (!domain || !irq_domain_is_hierarchy(domain)) { ++ if (IS_ENABLED(CONFIG_PCI_MSI_ARCH_FALLBACKS)) ++ return mode == ALLOW_LEGACY; ++ return false; ++ } + + if (!irq_domain_is_msi_parent(domain)) { + /* +diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c +index 2d117cb74832be..053bb9fac6e3e1 100644 +--- a/drivers/pci/msi/msi.c ++++ b/drivers/pci/msi/msi.c +@@ -429,6 +429,10 @@ int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec, + if (WARN_ON_ONCE(dev->msi_enabled)) + return -EINVAL; + ++ /* Test for the availability of MSI support */ ++ if (!pci_msi_domain_supports(dev, 0, ALLOW_LEGACY)) ++ return -ENOTSUPP; ++ + nvec = pci_msi_vec_count(dev); + if (nvec < 0) + return nvec; +diff --git a/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c b/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c +index 4c10cafded4e93..530b571607c013 100644 +--- a/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c ++++ b/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c +@@ -323,6 +323,12 @@ static void usb_init_common_7216(struct brcm_usb_init_params *params) + void __iomem *ctrl = params->regs[BRCM_REGS_CTRL]; + + USB_CTRL_UNSET(ctrl, USB_PM, XHC_S2_CLK_SWITCH_EN); ++ ++ /* ++ * The PHY might be in a bad state if it is already powered ++ * up. Toggle the power just in case. ++ */ ++ USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN); + USB_CTRL_UNSET(ctrl, USB_PM, USB_PWRDN); + + /* 1 millisecond - for USB clocks to settle down */ +diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c +index 96a0b1e111f349..a892e1d7e2d024 100644 +--- a/drivers/phy/phy-core.c ++++ b/drivers/phy/phy-core.c +@@ -140,8 +140,10 @@ static struct phy_provider *of_phy_provider_lookup(struct device_node *node) + return phy_provider; + + for_each_child_of_node(phy_provider->children, child) +- if (child == node) ++ if (child == node) { ++ of_node_put(child); + return phy_provider; ++ } + } + + return ERR_PTR(-EPROBE_DEFER); +@@ -577,8 +579,10 @@ static struct phy *_of_phy_get(struct device_node *np, int index) + return ERR_PTR(-ENODEV); + + /* This phy type handled by the usb-phy subsystem for now */ +- if (of_device_is_compatible(args.np, "usb-nop-xceiv")) +- return ERR_PTR(-ENODEV); ++ if (of_device_is_compatible(args.np, "usb-nop-xceiv")) { ++ phy = ERR_PTR(-ENODEV); ++ goto out_put_node; ++ } + + mutex_lock(&phy_provider_mutex); + phy_provider = of_phy_provider_lookup(args.np); +@@ -600,6 +604,7 @@ static struct phy *_of_phy_get(struct device_node *np, int index) + + out_unlock: + mutex_unlock(&phy_provider_mutex); ++out_put_node: + of_node_put(args.np); + + return phy; +@@ -685,7 +690,7 @@ void devm_phy_put(struct device *dev, struct phy *phy) + if (!phy) + return; + +- r = devres_destroy(dev, devm_phy_release, devm_phy_match, phy); ++ r = devres_release(dev, devm_phy_release, devm_phy_match, phy); + dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n"); + } + EXPORT_SYMBOL_GPL(devm_phy_put); +@@ -1069,7 +1074,7 @@ void devm_phy_destroy(struct device *dev, struct phy *phy) + { + int r; + +- r = devres_destroy(dev, devm_phy_consume, devm_phy_match, phy); ++ r = devres_release(dev, devm_phy_consume, devm_phy_match, phy); + dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n"); + } + EXPORT_SYMBOL_GPL(devm_phy_destroy); +@@ -1207,12 +1212,12 @@ EXPORT_SYMBOL_GPL(of_phy_provider_unregister); + * of_phy_provider_unregister to unregister the phy provider. + */ + void devm_of_phy_provider_unregister(struct device *dev, +- struct phy_provider *phy_provider) ++ struct phy_provider *phy_provider) + { + int r; + +- r = devres_destroy(dev, devm_phy_provider_release, devm_phy_match, +- phy_provider); ++ r = devres_release(dev, devm_phy_provider_release, devm_phy_match, ++ phy_provider); + dev_WARN_ONCE(dev, r, "couldn't find PHY provider device resource\n"); + } + EXPORT_SYMBOL_GPL(devm_of_phy_provider_unregister); +diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c +index d5a726c13e39d1..c697d01b2a2a1e 100644 +--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c ++++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c +@@ -1088,7 +1088,7 @@ static const struct qmp_phy_init_tbl sc8280xp_usb3_uniphy_rx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f), + QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f), +- QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x0a), ++ QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL1, 0x54), + QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f), +diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +index 26b157f53f3da0..9c231094ba3594 100644 +--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c ++++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +@@ -309,7 +309,7 @@ static int rockchip_combphy_parse_dt(struct device *dev, struct rockchip_combphy + + priv->ext_refclk = device_property_present(dev, "rockchip,ext-refclk"); + +- priv->phy_rst = devm_reset_control_array_get_exclusive(dev); ++ priv->phy_rst = devm_reset_control_get(dev, "phy"); + if (IS_ERR(priv->phy_rst)) + return dev_err_probe(dev, PTR_ERR(priv->phy_rst), "failed to get phy reset\n"); + +diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c +index af3da303e2b15a..cba515ce3444df 100644 +--- a/drivers/platform/x86/asus-nb-wmi.c ++++ b/drivers/platform/x86/asus-nb-wmi.c +@@ -590,6 +590,7 @@ static const struct key_entry asus_nb_wmi_keymap[] = { + { KE_KEY, 0xC4, { KEY_KBDILLUMUP } }, + { KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } }, + { KE_IGNORE, 0xC6, }, /* Ambient Light Sensor notification */ ++ { KE_IGNORE, 0xCF, }, /* AC mode */ + { KE_KEY, 0xFA, { KEY_PROG2 } }, /* Lid flip action */ + { KE_KEY, 0xBD, { KEY_PROG2 } }, /* Lid flip action on ROG xflow laptops */ + { KE_END, 0}, +diff --git a/drivers/power/supply/gpio-charger.c b/drivers/power/supply/gpio-charger.c +index 68212b39785bea..6139f736ecbe4f 100644 +--- a/drivers/power/supply/gpio-charger.c ++++ b/drivers/power/supply/gpio-charger.c +@@ -67,6 +67,14 @@ static int set_charge_current_limit(struct gpio_charger *gpio_charger, int val) + if (gpio_charger->current_limit_map[i].limit_ua <= val) + break; + } ++ ++ /* ++ * If a valid charge current limit isn't found, default to smallest ++ * current limitation for safety reasons. ++ */ ++ if (i >= gpio_charger->current_limit_map_size) ++ i = gpio_charger->current_limit_map_size - 1; ++ + mapping = gpio_charger->current_limit_map[i]; + + for (i = 0; i < ndescs; i++) { +diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c +index 3d4f13da1ae873..4cc93cb79b8b0a 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_base.c ++++ b/drivers/scsi/megaraid/megaraid_sas_base.c +@@ -8904,8 +8904,11 @@ megasas_aen_polling(struct work_struct *work) + (ld_target_id / MEGASAS_MAX_DEV_PER_CHANNEL), + (ld_target_id % MEGASAS_MAX_DEV_PER_CHANNEL), + 0); +- if (sdev1) ++ if (sdev1) { ++ mutex_unlock(&instance->reset_mutex); + megasas_remove_scsi_device(sdev1); ++ mutex_lock(&instance->reset_mutex); ++ } + + event_type = SCAN_VD_CHANNEL; + break; +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c +index 8acf586dc8b2ed..a5d12b95fbd09f 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c +@@ -7050,11 +7050,12 @@ _base_handshake_req_reply_wait(struct MPT3SAS_ADAPTER *ioc, int request_bytes, + int i; + u8 failed; + __le32 *mfp; ++ int ret_val; + + /* make sure doorbell is not in use */ + if ((ioc->base_readl_ext_retry(&ioc->chip->Doorbell) & MPI2_DOORBELL_USED)) { + ioc_err(ioc, "doorbell is in use (line=%d)\n", __LINE__); +- return -EFAULT; ++ goto doorbell_diag_reset; + } + + /* clear pending doorbell interrupts from previous state changes */ +@@ -7144,6 +7145,10 @@ _base_handshake_req_reply_wait(struct MPT3SAS_ADAPTER *ioc, int request_bytes, + le32_to_cpu(mfp[i])); + } + return 0; ++ ++doorbell_diag_reset: ++ ret_val = _base_diag_reset(ioc); ++ return ret_val; + } + + /** +diff --git a/drivers/scsi/qla1280.h b/drivers/scsi/qla1280.h +index d309e2ca14deb3..dea2290b37d4d7 100644 +--- a/drivers/scsi/qla1280.h ++++ b/drivers/scsi/qla1280.h +@@ -116,12 +116,12 @@ struct device_reg { + uint16_t id_h; /* ID high */ + uint16_t cfg_0; /* Configuration 0 */ + #define ISP_CFG0_HWMSK 0x000f /* Hardware revision mask */ +-#define ISP_CFG0_1020 BIT_0 /* ISP1020 */ +-#define ISP_CFG0_1020A BIT_1 /* ISP1020A */ +-#define ISP_CFG0_1040 BIT_2 /* ISP1040 */ +-#define ISP_CFG0_1040A BIT_3 /* ISP1040A */ +-#define ISP_CFG0_1040B BIT_4 /* ISP1040B */ +-#define ISP_CFG0_1040C BIT_5 /* ISP1040C */ ++#define ISP_CFG0_1020 1 /* ISP1020 */ ++#define ISP_CFG0_1020A 2 /* ISP1020A */ ++#define ISP_CFG0_1040 3 /* ISP1040 */ ++#define ISP_CFG0_1040A 4 /* ISP1040A */ ++#define ISP_CFG0_1040B 5 /* ISP1040B */ ++#define ISP_CFG0_1040C 6 /* ISP1040C */ + uint16_t cfg_1; /* Configuration 1 */ + #define ISP_CFG1_F128 BIT_6 /* 128-byte FIFO threshold */ + #define ISP_CFG1_F64 BIT_4|BIT_5 /* 128-byte FIFO threshold */ +diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c +index 7ceb982040a5df..d0b55c1fa908a5 100644 +--- a/drivers/scsi/storvsc_drv.c ++++ b/drivers/scsi/storvsc_drv.c +@@ -149,6 +149,8 @@ struct hv_fc_wwn_packet { + */ + static int vmstor_proto_version; + ++static bool hv_dev_is_fc(struct hv_device *hv_dev); ++ + #define STORVSC_LOGGING_NONE 0 + #define STORVSC_LOGGING_ERROR 1 + #define STORVSC_LOGGING_WARN 2 +@@ -1138,6 +1140,7 @@ static void storvsc_on_io_completion(struct storvsc_device *stor_device, + * not correctly handle: + * INQUIRY command with page code parameter set to 0x80 + * MODE_SENSE command with cmd[2] == 0x1c ++ * MAINTENANCE_IN is not supported by HyperV FC passthrough + * + * Setup srb and scsi status so this won't be fatal. + * We do this so we can distinguish truly fatal failues +@@ -1145,7 +1148,9 @@ static void storvsc_on_io_completion(struct storvsc_device *stor_device, + */ + + if ((stor_pkt->vm_srb.cdb[0] == INQUIRY) || +- (stor_pkt->vm_srb.cdb[0] == MODE_SENSE)) { ++ (stor_pkt->vm_srb.cdb[0] == MODE_SENSE) || ++ (stor_pkt->vm_srb.cdb[0] == MAINTENANCE_IN && ++ hv_dev_is_fc(device))) { + vstor_packet->vm_srb.scsi_status = 0; + vstor_packet->vm_srb.srb_status = SRB_STATUS_SUCCESS; + } +diff --git a/drivers/spi/spi-intel-pci.c b/drivers/spi/spi-intel-pci.c +index 4337ca51d7aa21..5c0dec90eec1df 100644 +--- a/drivers/spi/spi-intel-pci.c ++++ b/drivers/spi/spi-intel-pci.c +@@ -86,6 +86,8 @@ static const struct pci_device_id intel_spi_pci_ids[] = { + { PCI_VDEVICE(INTEL, 0xa324), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0xa3a4), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0xa823), (unsigned long)&cnl_info }, ++ { PCI_VDEVICE(INTEL, 0xe323), (unsigned long)&cnl_info }, ++ { PCI_VDEVICE(INTEL, 0xe423), (unsigned long)&cnl_info }, + { }, + }; + MODULE_DEVICE_TABLE(pci, intel_spi_pci_ids); +diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c +index ddf1c684bcc7d8..3cfd262c1abc25 100644 +--- a/drivers/spi/spi-omap2-mcspi.c ++++ b/drivers/spi/spi-omap2-mcspi.c +@@ -1521,10 +1521,10 @@ static int omap2_mcspi_probe(struct platform_device *pdev) + } + + mcspi->ref_clk = devm_clk_get_optional_enabled(&pdev->dev, NULL); +- if (mcspi->ref_clk) +- mcspi->ref_clk_hz = clk_get_rate(mcspi->ref_clk); +- else ++ if (IS_ERR(mcspi->ref_clk)) + mcspi->ref_clk_hz = OMAP2_MCSPI_MAX_FREQ; ++ else ++ mcspi->ref_clk_hz = clk_get_rate(mcspi->ref_clk); + ctlr->max_speed_hz = mcspi->ref_clk_hz; + ctlr->min_speed_hz = mcspi->ref_clk_hz >> 15; + +diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c +index 843f9f8e391776..239947df613db1 100644 +--- a/drivers/watchdog/it87_wdt.c ++++ b/drivers/watchdog/it87_wdt.c +@@ -20,6 +20,8 @@ + + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + ++#include ++#include + #include + #include + #include +@@ -40,6 +42,7 @@ + #define VAL 0x2f + + /* Logical device Numbers LDN */ ++#define EC 0x04 + #define GPIO 0x07 + + /* Configuration Registers and Functions */ +@@ -71,6 +74,12 @@ + #define IT8784_ID 0x8784 + #define IT8786_ID 0x8786 + ++/* Environment Controller Configuration Registers LDN=0x04 */ ++#define SCR1 0xfa ++ ++/* Environment Controller Bits SCR1 */ ++#define WDT_PWRGD 0x20 ++ + /* GPIO Configuration Registers LDN=0x07 */ + #define WDTCTRL 0x71 + #define WDTCFG 0x72 +@@ -233,6 +242,21 @@ static int wdt_set_timeout(struct watchdog_device *wdd, unsigned int t) + return ret; + } + ++enum { ++ IT87_WDT_OUTPUT_THROUGH_PWRGD = BIT(0), ++}; ++ ++static const struct dmi_system_id it87_quirks[] = { ++ { ++ /* Qotom Q30900P (IT8786) */ ++ .matches = { ++ DMI_EXACT_MATCH(DMI_BOARD_NAME, "QCML04"), ++ }, ++ .driver_data = (void *)IT87_WDT_OUTPUT_THROUGH_PWRGD, ++ }, ++ {} ++}; ++ + static const struct watchdog_info ident = { + .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, + .firmware_version = 1, +@@ -254,8 +278,10 @@ static struct watchdog_device wdt_dev = { + + static int __init it87_wdt_init(void) + { ++ const struct dmi_system_id *dmi_id; + u8 chip_rev; + u8 ctrl; ++ int quirks = 0; + int rc; + + rc = superio_enter(); +@@ -266,6 +292,10 @@ static int __init it87_wdt_init(void) + chip_rev = superio_inb(CHIPREV) & 0x0f; + superio_exit(); + ++ dmi_id = dmi_first_match(it87_quirks); ++ if (dmi_id) ++ quirks = (long)dmi_id->driver_data; ++ + switch (chip_type) { + case IT8702_ID: + max_units = 255; +@@ -326,6 +356,15 @@ static int __init it87_wdt_init(void) + superio_outb(0x00, WDTCTRL); + } + ++ if (quirks & IT87_WDT_OUTPUT_THROUGH_PWRGD) { ++ superio_select(EC); ++ ctrl = superio_inb(SCR1); ++ if (!(ctrl & WDT_PWRGD)) { ++ ctrl |= WDT_PWRGD; ++ superio_outb(ctrl, SCR1); ++ } ++ } ++ + superio_exit(); + + if (timeout < 1 || timeout > max_units * 60) { +diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c +index 0559d9f2d97b36..66bb68ceb14cf6 100644 +--- a/drivers/watchdog/mtk_wdt.c ++++ b/drivers/watchdog/mtk_wdt.c +@@ -10,6 +10,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -81,6 +82,10 @@ static const struct mtk_wdt_data mt2712_data = { + .toprgu_sw_rst_num = MT2712_TOPRGU_SW_RST_NUM, + }; + ++static const struct mtk_wdt_data mt6735_data = { ++ .toprgu_sw_rst_num = MT6735_TOPRGU_RST_NUM, ++}; ++ + static const struct mtk_wdt_data mt6795_data = { + .toprgu_sw_rst_num = MT6795_TOPRGU_SW_RST_NUM, + }; +@@ -448,6 +453,7 @@ static int mtk_wdt_resume(struct device *dev) + static const struct of_device_id mtk_wdt_dt_ids[] = { + { .compatible = "mediatek,mt2712-wdt", .data = &mt2712_data }, + { .compatible = "mediatek,mt6589-wdt" }, ++ { .compatible = "mediatek,mt6735-wdt", .data = &mt6735_data }, + { .compatible = "mediatek,mt6795-wdt", .data = &mt6795_data }, + { .compatible = "mediatek,mt7986-wdt", .data = &mt7986_data }, + { .compatible = "mediatek,mt8183-wdt", .data = &mt8183_data }, +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index 035815c4394985..d6767f728c079d 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -7153,6 +7153,8 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len, + ret = -EAGAIN; + goto out; + } ++ ++ cond_resched(); + } + + if (orig_start) +diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c +index c9198723e4cb73..512d4cbac1ca0b 100644 +--- a/fs/btrfs/sysfs.c ++++ b/fs/btrfs/sysfs.c +@@ -1022,7 +1022,7 @@ static ssize_t btrfs_nodesize_show(struct kobject *kobj, + { + struct btrfs_fs_info *fs_info = to_fs_info(kobj); + +- return sysfs_emit(buf, "%u\n", fs_info->super_copy->nodesize); ++ return sysfs_emit(buf, "%u\n", fs_info->nodesize); + } + + BTRFS_ATTR(, nodesize, btrfs_nodesize_show); +@@ -1032,7 +1032,7 @@ static ssize_t btrfs_sectorsize_show(struct kobject *kobj, + { + struct btrfs_fs_info *fs_info = to_fs_info(kobj); + +- return sysfs_emit(buf, "%u\n", fs_info->super_copy->sectorsize); ++ return sysfs_emit(buf, "%u\n", fs_info->sectorsize); + } + + BTRFS_ATTR(, sectorsize, btrfs_sectorsize_show); +@@ -1084,7 +1084,7 @@ static ssize_t btrfs_clone_alignment_show(struct kobject *kobj, + { + struct btrfs_fs_info *fs_info = to_fs_info(kobj); + +- return sysfs_emit(buf, "%u\n", fs_info->super_copy->sectorsize); ++ return sysfs_emit(buf, "%u\n", fs_info->sectorsize); + } + + BTRFS_ATTR(, clone_alignment, btrfs_clone_alignment_show); +diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c +index 1a2776025e9861..2c92de964c5a2e 100644 +--- a/fs/ceph/addr.c ++++ b/fs/ceph/addr.c +@@ -355,6 +355,7 @@ static void ceph_netfs_issue_read(struct netfs_io_subrequest *subreq) + u64 len = subreq->len; + bool sparse = IS_ENCRYPTED(inode) || ceph_test_mount_opt(fsc, SPARSEREAD); + u64 off = subreq->start; ++ int extent_cnt; + + if (ceph_inode_is_shutdown(inode)) { + err = -EIO; +@@ -377,7 +378,8 @@ static void ceph_netfs_issue_read(struct netfs_io_subrequest *subreq) + } + + if (sparse) { +- err = ceph_alloc_sparse_ext_map(&req->r_ops[0]); ++ extent_cnt = __ceph_sparse_read_ext_count(inode, len); ++ err = ceph_alloc_sparse_ext_map(&req->r_ops[0], extent_cnt); + if (err) + goto out; + } +diff --git a/fs/ceph/file.c b/fs/ceph/file.c +index 813974244a9d37..a03b11cf788721 100644 +--- a/fs/ceph/file.c ++++ b/fs/ceph/file.c +@@ -1001,6 +1001,7 @@ ssize_t __ceph_sync_read(struct inode *inode, loff_t *ki_pos, + struct ceph_osd_req_op *op; + u64 read_off = off; + u64 read_len = len; ++ int extent_cnt; + + /* determine new offset/length if encrypted */ + ceph_fscrypt_adjust_off_and_len(inode, &read_off, &read_len); +@@ -1025,6 +1026,16 @@ ssize_t __ceph_sync_read(struct inode *inode, loff_t *ki_pos, + len = read_off + read_len - off; + more = len < iov_iter_count(to); + ++ op = &req->r_ops[0]; ++ if (sparse) { ++ extent_cnt = __ceph_sparse_read_ext_count(inode, read_len); ++ ret = ceph_alloc_sparse_ext_map(op, extent_cnt); ++ if (ret) { ++ ceph_osdc_put_request(req); ++ break; ++ } ++ } ++ + num_pages = calc_pages_for(read_off, read_len); + page_off = offset_in_page(off); + pages = ceph_alloc_page_vector(num_pages, GFP_KERNEL); +@@ -1038,15 +1049,6 @@ ssize_t __ceph_sync_read(struct inode *inode, loff_t *ki_pos, + offset_in_page(read_off), + false, true); + +- op = &req->r_ops[0]; +- if (sparse) { +- ret = ceph_alloc_sparse_ext_map(op); +- if (ret) { +- ceph_osdc_put_request(req); +- break; +- } +- } +- + ceph_osdc_start_request(osdc, req); + ret = ceph_osdc_wait_request(osdc, req); + +@@ -1431,6 +1433,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, + ssize_t len; + struct ceph_osd_req_op *op; + int readop = sparse ? CEPH_OSD_OP_SPARSE_READ : CEPH_OSD_OP_READ; ++ int extent_cnt; + + if (write) + size = min_t(u64, size, fsc->mount_options->wsize); +@@ -1451,6 +1454,16 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, + break; + } + ++ op = &req->r_ops[0]; ++ if (!write && sparse) { ++ extent_cnt = __ceph_sparse_read_ext_count(inode, size); ++ ret = ceph_alloc_sparse_ext_map(op, extent_cnt); ++ if (ret) { ++ ceph_osdc_put_request(req); ++ break; ++ } ++ } ++ + len = iter_get_bvecs_alloc(iter, size, &bvecs, &num_pages); + if (len < 0) { + ceph_osdc_put_request(req); +@@ -1460,6 +1473,8 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, + if (len != size) + osd_req_op_extent_update(req, 0, len); + ++ osd_req_op_extent_osd_data_bvecs(req, 0, bvecs, num_pages, len); ++ + /* + * To simplify error handling, allow AIO when IO within i_size + * or IO can be satisfied by single OSD request. +@@ -1491,16 +1506,6 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, + req->r_mtime = mtime; + } + +- osd_req_op_extent_osd_data_bvecs(req, 0, bvecs, num_pages, len); +- op = &req->r_ops[0]; +- if (sparse) { +- ret = ceph_alloc_sparse_ext_map(op); +- if (ret) { +- ceph_osdc_put_request(req); +- break; +- } +- } +- + if (aio_req) { + aio_req->total_len += len; + aio_req->num_reqs++; +diff --git a/fs/ceph/super.h b/fs/ceph/super.h +index 8efd4ba6077448..5903e3fb6d7506 100644 +--- a/fs/ceph/super.h ++++ b/fs/ceph/super.h +@@ -3,6 +3,7 @@ + #define _FS_CEPH_SUPER_H + + #include ++#include + + #include + #include +@@ -1401,6 +1402,19 @@ static inline void __ceph_update_quota(struct ceph_inode_info *ci, + ceph_adjust_quota_realms_count(&ci->netfs.inode, has_quota); + } + ++static inline int __ceph_sparse_read_ext_count(struct inode *inode, u64 len) ++{ ++ int cnt = 0; ++ ++ if (IS_ENCRYPTED(inode)) { ++ cnt = len >> CEPH_FSCRYPT_BLOCK_SHIFT; ++ if (cnt > CEPH_SPARSE_EXT_ARRAY_INITIAL) ++ cnt = 0; ++ } ++ ++ return cnt; ++} ++ + extern void ceph_handle_quota(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session, + struct ceph_msg *msg); +diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c +index d4d3ec58047e82..4b5d998cbc2f44 100644 +--- a/fs/nfsd/export.c ++++ b/fs/nfsd/export.c +@@ -40,24 +40,15 @@ + #define EXPKEY_HASHMAX (1 << EXPKEY_HASHBITS) + #define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1) + +-static void expkey_put_work(struct work_struct *work) ++static void expkey_put(struct kref *ref) + { +- struct svc_expkey *key = +- container_of(to_rcu_work(work), struct svc_expkey, ek_rcu_work); ++ struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref); + + if (test_bit(CACHE_VALID, &key->h.flags) && + !test_bit(CACHE_NEGATIVE, &key->h.flags)) + path_put(&key->ek_path); + auth_domain_put(key->ek_client); +- kfree(key); +-} +- +-static void expkey_put(struct kref *ref) +-{ +- struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref); +- +- INIT_RCU_WORK(&key->ek_rcu_work, expkey_put_work); +- queue_rcu_work(system_wq, &key->ek_rcu_work); ++ kfree_rcu(key, ek_rcu); + } + + static int expkey_upcall(struct cache_detail *cd, struct cache_head *h) +@@ -360,26 +351,16 @@ static void export_stats_destroy(struct export_stats *stats) + EXP_STATS_COUNTERS_NUM); + } + +-static void svc_export_put_work(struct work_struct *work) ++static void svc_export_put(struct kref *ref) + { +- struct svc_export *exp = +- container_of(to_rcu_work(work), struct svc_export, ex_rcu_work); +- ++ struct svc_export *exp = container_of(ref, struct svc_export, h.ref); + path_put(&exp->ex_path); + auth_domain_put(exp->ex_client); + nfsd4_fslocs_free(&exp->ex_fslocs); + export_stats_destroy(exp->ex_stats); + kfree(exp->ex_stats); + kfree(exp->ex_uuid); +- kfree(exp); +-} +- +-static void svc_export_put(struct kref *ref) +-{ +- struct svc_export *exp = container_of(ref, struct svc_export, h.ref); +- +- INIT_RCU_WORK(&exp->ex_rcu_work, svc_export_put_work); +- queue_rcu_work(system_wq, &exp->ex_rcu_work); ++ kfree_rcu(exp, ex_rcu); + } + + static int svc_export_upcall(struct cache_detail *cd, struct cache_head *h) +diff --git a/fs/nfsd/export.h b/fs/nfsd/export.h +index 9d895570ceba05..ca9dc230ae3d0b 100644 +--- a/fs/nfsd/export.h ++++ b/fs/nfsd/export.h +@@ -75,7 +75,7 @@ struct svc_export { + u32 ex_layout_types; + struct nfsd4_deviceid_map *ex_devid_map; + struct cache_detail *cd; +- struct rcu_work ex_rcu_work; ++ struct rcu_head ex_rcu; + unsigned long ex_xprtsec_modes; + struct export_stats *ex_stats; + }; +@@ -92,7 +92,7 @@ struct svc_expkey { + u32 ek_fsid[6]; + + struct path ek_path; +- struct rcu_work ek_rcu_work; ++ struct rcu_head ek_rcu; + }; + + #define EX_ISSYNC(exp) (!((exp)->ex_flags & NFSEXP_ASYNC)) +diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c +index 49a49529c6b8fb..54ffadf02e034f 100644 +--- a/fs/nfsd/nfs4callback.c ++++ b/fs/nfsd/nfs4callback.c +@@ -986,7 +986,7 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c + args.authflavor = clp->cl_cred.cr_flavor; + clp->cl_cb_ident = conn->cb_ident; + } else { +- if (!conn->cb_xprt) ++ if (!conn->cb_xprt || !ses) + return -EINVAL; + clp->cl_cb_session = ses; + args.bc_xprt = conn->cb_xprt; +@@ -1379,8 +1379,6 @@ static void nfsd4_process_cb_update(struct nfsd4_callback *cb) + ses = c->cn_session; + } + spin_unlock(&clp->cl_lock); +- if (!c) +- return; + + err = setup_callback_client(clp, &conn, ses); + if (err) { +diff --git a/fs/smb/server/smb_common.c b/fs/smb/server/smb_common.c +index 663b014b9d1886..23537e1b346858 100644 +--- a/fs/smb/server/smb_common.c ++++ b/fs/smb/server/smb_common.c +@@ -18,8 +18,8 @@ + #include "mgmt/share_config.h" + + /*for shortname implementation */ +-static const char basechars[43] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_-!@#$%"; +-#define MANGLE_BASE (sizeof(basechars) / sizeof(char) - 1) ++static const char *basechars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_-!@#$%"; ++#define MANGLE_BASE (strlen(basechars) - 1) + #define MAGIC_CHAR '~' + #define PERIOD '.' + #define mangle(V) ((char)(basechars[(V) % MANGLE_BASE])) +diff --git a/fs/udf/namei.c b/fs/udf/namei.c +index 605f182da42cbb..b3f57ad2b869ff 100644 +--- a/fs/udf/namei.c ++++ b/fs/udf/namei.c +@@ -521,7 +521,11 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry) + inode->i_nlink); + clear_nlink(inode); + inode->i_size = 0; +- inode_dec_link_count(dir); ++ if (dir->i_nlink >= 3) ++ inode_dec_link_count(dir); ++ else ++ udf_warn(inode->i_sb, "parent dir link count too low (%u)\n", ++ dir->i_nlink); + udf_add_fid_counter(dir->i_sb, true, -1); + dir->i_mtime = inode_set_ctime_to_ts(dir, + inode_set_ctime_current(inode)); +diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h +index f703fb8030de26..50e409e8446659 100644 +--- a/include/linux/ceph/osd_client.h ++++ b/include/linux/ceph/osd_client.h +@@ -573,9 +573,12 @@ int __ceph_alloc_sparse_ext_map(struct ceph_osd_req_op *op, int cnt); + */ + #define CEPH_SPARSE_EXT_ARRAY_INITIAL 16 + +-static inline int ceph_alloc_sparse_ext_map(struct ceph_osd_req_op *op) ++static inline int ceph_alloc_sparse_ext_map(struct ceph_osd_req_op *op, int cnt) + { +- return __ceph_alloc_sparse_ext_map(op, CEPH_SPARSE_EXT_ARRAY_INITIAL); ++ if (!cnt) ++ cnt = CEPH_SPARSE_EXT_ARRAY_INITIAL; ++ ++ return __ceph_alloc_sparse_ext_map(op, cnt); + } + + extern void ceph_osdc_get_request(struct ceph_osd_request *req); +diff --git a/include/linux/sched.h b/include/linux/sched.h +index 4809f27b520172..d4f9d82c69e0b0 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -1683,8 +1683,9 @@ static inline unsigned int __task_state_index(unsigned int tsk_state, + * We're lying here, but rather than expose a completely new task state + * to userspace, we can make this appear as if the task has gone through + * a regular rt_mutex_lock() call. ++ * Report frozen tasks as uninterruptible. + */ +- if (tsk_state & TASK_RTLOCK_WAIT) ++ if ((tsk_state & TASK_RTLOCK_WAIT) || (tsk_state & TASK_FROZEN)) + state = TASK_UNINTERRUPTIBLE; + + return fls(state); +diff --git a/include/linux/sched/task_stack.h b/include/linux/sched/task_stack.h +index f158b025c17509..d2117e1c8fa581 100644 +--- a/include/linux/sched/task_stack.h ++++ b/include/linux/sched/task_stack.h +@@ -8,6 +8,7 @@ + + #include + #include ++#include + + #ifdef CONFIG_THREAD_INFO_IN_TASK + +@@ -88,6 +89,7 @@ static inline int object_is_on_stack(const void *obj) + { + void *stack = task_stack_page(current); + ++ obj = kasan_reset_tag(obj); + return (obj >= stack) && (obj < (stack + THREAD_SIZE)); + } + +diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h +index 062fe440f5d095..6ccfd9236387c6 100644 +--- a/include/linux/skmsg.h ++++ b/include/linux/skmsg.h +@@ -308,17 +308,22 @@ static inline void sock_drop(struct sock *sk, struct sk_buff *skb) + kfree_skb(skb); + } + +-static inline void sk_psock_queue_msg(struct sk_psock *psock, ++static inline bool sk_psock_queue_msg(struct sk_psock *psock, + struct sk_msg *msg) + { ++ bool ret; ++ + spin_lock_bh(&psock->ingress_lock); +- if (sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED)) ++ if (sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED)) { + list_add_tail(&msg->list, &psock->ingress_msg); +- else { ++ ret = true; ++ } else { + sk_msg_free(psock->sk, msg); + kfree(msg); ++ ret = false; + } + spin_unlock_bh(&psock->ingress_lock); ++ return ret; + } + + static inline struct sk_msg *sk_psock_dequeue_msg(struct sk_psock *psock) +diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h +index 9d799777c333c0..9df2524fff33ae 100644 +--- a/include/linux/trace_events.h ++++ b/include/linux/trace_events.h +@@ -369,7 +369,7 @@ struct trace_event_call { + struct list_head list; + struct trace_event_class *class; + union { +- char *name; ++ const char *name; + /* Set TRACE_EVENT_FL_TRACEPOINT flag when using "tp" */ + struct tracepoint *tp; + }; +diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h +index fed855bae6d8e8..3219b368db79cc 100644 +--- a/include/linux/vmstat.h ++++ b/include/linux/vmstat.h +@@ -519,7 +519,7 @@ static inline const char *node_stat_name(enum node_stat_item item) + + static inline const char *lru_list_name(enum lru_list lru) + { +- return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_" ++ return node_stat_name(NR_LRU_BASE + (enum node_stat_item)lru) + 3; // skip "nr_" + } + + static inline const char *writeback_stat_name(enum writeback_stat_item item) +diff --git a/include/net/sock.h b/include/net/sock.h +index a6b795ec7c9cb6..dc625f94ee37b7 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -1635,7 +1635,7 @@ static inline bool sk_wmem_schedule(struct sock *sk, int size) + } + + static inline bool +-sk_rmem_schedule(struct sock *sk, struct sk_buff *skb, int size) ++__sk_rmem_schedule(struct sock *sk, int size, bool pfmemalloc) + { + int delta; + +@@ -1643,7 +1643,13 @@ sk_rmem_schedule(struct sock *sk, struct sk_buff *skb, int size) + return true; + delta = size - sk->sk_forward_alloc; + return delta <= 0 || __sk_mem_schedule(sk, delta, SK_MEM_RECV) || +- skb_pfmemalloc(skb); ++ pfmemalloc; ++} ++ ++static inline bool ++sk_rmem_schedule(struct sock *sk, struct sk_buff *skb, int size) ++{ ++ return __sk_rmem_schedule(sk, size, skb_pfmemalloc(skb)); + } + + static inline int sk_unused_reserved_mem(const struct sock *sk) +diff --git a/include/uapi/linux/stddef.h b/include/uapi/linux/stddef.h +index 2ec6f35cda32e9..473ad86706d837 100644 +--- a/include/uapi/linux/stddef.h ++++ b/include/uapi/linux/stddef.h +@@ -8,6 +8,13 @@ + #define __always_inline inline + #endif + ++/* Not all C++ standards support type declarations inside an anonymous union */ ++#ifndef __cplusplus ++#define __struct_group_tag(TAG) TAG ++#else ++#define __struct_group_tag(TAG) ++#endif ++ + /** + * __struct_group() - Create a mirrored named and anonyomous struct + * +@@ -20,13 +27,13 @@ + * and size: one anonymous and one named. The former's members can be used + * normally without sub-struct naming, and the latter can be used to + * reason about the start, end, and size of the group of struct members. +- * The named struct can also be explicitly tagged for layer reuse, as well +- * as both having struct attributes appended. ++ * The named struct can also be explicitly tagged for layer reuse (C only), ++ * as well as both having struct attributes appended. + */ + #define __struct_group(TAG, NAME, ATTRS, MEMBERS...) \ + union { \ + struct { MEMBERS } ATTRS; \ +- struct TAG { MEMBERS } ATTRS NAME; \ ++ struct __struct_group_tag(TAG) { MEMBERS } ATTRS NAME; \ + } ATTRS + + #ifdef __cplusplus +diff --git a/io_uring/sqpoll.c b/io_uring/sqpoll.c +index cdf8b567cb9443..489e66647e0795 100644 +--- a/io_uring/sqpoll.c ++++ b/io_uring/sqpoll.c +@@ -352,6 +352,7 @@ void io_sqpoll_wait_sq(struct io_ring_ctx *ctx) + __cold int io_sq_offload_create(struct io_ring_ctx *ctx, + struct io_uring_params *p) + { ++ struct task_struct *task_to_put = NULL; + int ret; + + /* Retain compatibility with failing for an invalid attach attempt */ +@@ -432,6 +433,7 @@ __cold int io_sq_offload_create(struct io_ring_ctx *ctx, + } + + sqd->thread = tsk; ++ task_to_put = get_task_struct(tsk); + ret = io_uring_alloc_task_context(tsk, ctx); + wake_up_new_task(tsk); + if (ret) +@@ -442,11 +444,15 @@ __cold int io_sq_offload_create(struct io_ring_ctx *ctx, + goto err; + } + ++ if (task_to_put) ++ put_task_struct(task_to_put); + return 0; + err_sqpoll: + complete(&ctx->sq_data->exited); + err: + io_sq_thread_finish(ctx); ++ if (task_to_put) ++ put_task_struct(task_to_put); + return ret; + } + +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index ecd869ed27670c..220903117c5139 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -5331,6 +5331,9 @@ tracing_cpumask_write(struct file *filp, const char __user *ubuf, + cpumask_var_t tracing_cpumask_new; + int err; + ++ if (count == 0 || count > KMALLOC_MAX_SIZE) ++ return -EINVAL; ++ + if (!zalloc_cpumask_var(&tracing_cpumask_new, GFP_KERNEL)) + return -ENOMEM; + +diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c +index 94cb09d44115ae..508c10414a9343 100644 +--- a/kernel/trace/trace_kprobe.c ++++ b/kernel/trace/trace_kprobe.c +@@ -702,7 +702,7 @@ static int trace_kprobe_module_callback(struct notifier_block *nb, + + static struct notifier_block trace_kprobe_module_nb = { + .notifier_call = trace_kprobe_module_callback, +- .priority = 1 /* Invoked after kprobe module callback */ ++ .priority = 2 /* Invoked after kprobe and jump_label module callback */ + }; + + static int count_symbols(void *data, unsigned long unused) +diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c +index 3babcd5e65e16d..0b6a8bb0642f25 100644 +--- a/net/ceph/osd_client.c ++++ b/net/ceph/osd_client.c +@@ -1173,6 +1173,8 @@ EXPORT_SYMBOL(ceph_osdc_new_request); + + int __ceph_alloc_sparse_ext_map(struct ceph_osd_req_op *op, int cnt) + { ++ WARN_ON(op->op != CEPH_OSD_OP_SPARSE_READ); ++ + op->extent.sparse_ext_cnt = cnt; + op->extent.sparse_ext = kmalloc_array(cnt, + sizeof(*op->extent.sparse_ext), +diff --git a/net/core/filter.c b/net/core/filter.c +index bc52ab3374f3ac..34320ce70096ac 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -3731,13 +3731,22 @@ static const struct bpf_func_proto bpf_skb_adjust_room_proto = { + + static u32 __bpf_skb_min_len(const struct sk_buff *skb) + { +- u32 min_len = skb_network_offset(skb); ++ int offset = skb_network_offset(skb); ++ u32 min_len = 0; + +- if (skb_transport_header_was_set(skb)) +- min_len = skb_transport_offset(skb); +- if (skb->ip_summed == CHECKSUM_PARTIAL) +- min_len = skb_checksum_start_offset(skb) + +- skb->csum_offset + sizeof(__sum16); ++ if (offset > 0) ++ min_len = offset; ++ if (skb_transport_header_was_set(skb)) { ++ offset = skb_transport_offset(skb); ++ if (offset > 0) ++ min_len = offset; ++ } ++ if (skb->ip_summed == CHECKSUM_PARTIAL) { ++ offset = skb_checksum_start_offset(skb) + ++ skb->csum_offset + sizeof(__sum16); ++ if (offset > 0) ++ min_len = offset; ++ } + return min_len; + } + +diff --git a/net/core/skmsg.c b/net/core/skmsg.c +index 846fd672f0e529..902098e221b396 100644 +--- a/net/core/skmsg.c ++++ b/net/core/skmsg.c +@@ -445,8 +445,10 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg, + if (likely(!peek)) { + sge->offset += copy; + sge->length -= copy; +- if (!msg_rx->skb) ++ if (!msg_rx->skb) { + sk_mem_uncharge(sk, copy); ++ atomic_sub(copy, &sk->sk_rmem_alloc); ++ } + msg_rx->sg.size -= copy; + + if (!sge->length) { +@@ -772,6 +774,8 @@ static void __sk_psock_purge_ingress_msg(struct sk_psock *psock) + + list_for_each_entry_safe(msg, tmp, &psock->ingress_msg, list) { + list_del(&msg->list); ++ if (!msg->skb) ++ atomic_sub(msg->sg.size, &psock->sk->sk_rmem_alloc); + sk_msg_free(psock->sk, msg); + kfree(msg); + } +diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c +index 0a42d73c0850e0..f882054fae5ee1 100644 +--- a/net/ipv4/tcp_bpf.c ++++ b/net/ipv4/tcp_bpf.c +@@ -49,13 +49,14 @@ static int bpf_tcp_ingress(struct sock *sk, struct sk_psock *psock, + sge = sk_msg_elem(msg, i); + size = (apply && apply_bytes < sge->length) ? + apply_bytes : sge->length; +- if (!sk_wmem_schedule(sk, size)) { ++ if (!__sk_rmem_schedule(sk, size, false)) { + if (!copied) + ret = -ENOMEM; + break; + } + + sk_mem_charge(sk, size); ++ atomic_add(size, &sk->sk_rmem_alloc); + sk_msg_xfer(tmp, msg, i, size); + copied += size; + if (sge->length) +@@ -74,7 +75,8 @@ static int bpf_tcp_ingress(struct sock *sk, struct sk_psock *psock, + + if (!ret) { + msg->sg.start = i; +- sk_psock_queue_msg(psock, tmp); ++ if (!sk_psock_queue_msg(psock, tmp)) ++ atomic_sub(copied, &sk->sk_rmem_alloc); + sk_psock_data_ready(sk, psock); + } else { + sk_msg_free(sk, tmp); +diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c +index b3208b068dd809..989ce0fb62919f 100644 +--- a/sound/pci/hda/patch_conexant.c ++++ b/sound/pci/hda/patch_conexant.c +@@ -311,6 +311,7 @@ enum { + CXT_FIXUP_HP_MIC_NO_PRESENCE, + CXT_PINCFG_SWS_JS201D, + CXT_PINCFG_TOP_SPEAKER, ++ CXT_FIXUP_HP_A_U, + }; + + /* for hda_fixup_thinkpad_acpi() */ +@@ -778,6 +779,18 @@ static void cxt_setup_mute_led(struct hda_codec *codec, + } + } + ++static void cxt_setup_gpio_unmute(struct hda_codec *codec, ++ unsigned int gpio_mute_mask) ++{ ++ if (gpio_mute_mask) { ++ // set gpio data to 0. ++ snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); ++ snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, gpio_mute_mask); ++ snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION, gpio_mute_mask); ++ snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_STICKY_MASK, 0); ++ } ++} ++ + static void cxt_fixup_mute_led_gpio(struct hda_codec *codec, + const struct hda_fixup *fix, int action) + { +@@ -792,6 +805,15 @@ static void cxt_fixup_hp_zbook_mute_led(struct hda_codec *codec, + cxt_setup_mute_led(codec, 0x10, 0x20); + } + ++static void cxt_fixup_hp_a_u(struct hda_codec *codec, ++ const struct hda_fixup *fix, int action) ++{ ++ // Init vers in BIOS mute the spk/hp by set gpio high to avoid pop noise, ++ // so need to unmute once by clearing the gpio data when runs into the system. ++ if (action == HDA_FIXUP_ACT_INIT) ++ cxt_setup_gpio_unmute(codec, 0x2); ++} ++ + /* ThinkPad X200 & co with cxt5051 */ + static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = { + { 0x16, 0x042140ff }, /* HP (seq# overridden) */ +@@ -1002,6 +1024,10 @@ static const struct hda_fixup cxt_fixups[] = { + { } + }, + }, ++ [CXT_FIXUP_HP_A_U] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = cxt_fixup_hp_a_u, ++ }, + }; + + static const struct hda_quirk cxt5045_fixups[] = { +@@ -1076,6 +1102,7 @@ static const struct hda_quirk cxt5066_fixups[] = { + SND_PCI_QUIRK(0x103c, 0x8457, "HP Z2 G4 mini", CXT_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x8458, "HP Z2 G4 mini premium", CXT_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), ++ SND_PCI_QUIRK(0x14f1, 0x0252, "MBX-Z60MR100", CXT_FIXUP_HP_A_U), + SND_PCI_QUIRK(0x14f1, 0x0265, "SWS JS201D", CXT_PINCFG_SWS_JS201D), + SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), + SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), +@@ -1121,6 +1148,7 @@ static const struct hda_model_fixup cxt5066_fixup_models[] = { + { .id = CXT_PINCFG_LENOVO_NOTEBOOK, .name = "lenovo-20149" }, + { .id = CXT_PINCFG_SWS_JS201D, .name = "sws-js201d" }, + { .id = CXT_PINCFG_TOP_SPEAKER, .name = "sirius-top-speaker" }, ++ { .id = CXT_FIXUP_HP_A_U, .name = "HP-U-support" }, + {} + }; + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index d61c317b49ead1..29d7eb8c6bec3e 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -10054,6 +10054,13 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x8ca4, "HP ZBook Fury", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8ca7, "HP ZBook Fury", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8cf5, "HP ZBook Studio 16", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8d01, "HP ZBook Power 14 G12", ALC285_FIXUP_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8d84, "HP EliteBook X G1i", ALC285_FIXUP_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8d91, "HP ZBook Firefly 14 G12", ALC285_FIXUP_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8d92, "HP ZBook Firefly 16 G12", ALC285_FIXUP_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8e18, "HP ZBook Firefly 14 G12A", ALC285_FIXUP_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8e19, "HP ZBook Firefly 14 G12A", ALC285_FIXUP_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8e1a, "HP ZBook Firefly 14 G12A", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), + SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), + SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), +diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c +index 95ba3abd4e47eb..13fe6a76005ec4 100644 +--- a/sound/sh/sh_dac_audio.c ++++ b/sound/sh/sh_dac_audio.c +@@ -163,7 +163,7 @@ static int snd_sh_dac_pcm_copy(struct snd_pcm_substream *substream, + /* channel is not used (interleaved data) */ + struct snd_sh_dac *chip = snd_pcm_substream_chip(substream); + +- if (copy_from_iter_toio(chip->data_buffer + pos, src, count)) ++ if (copy_from_iter(chip->data_buffer + pos, count, src) != count) + return -EFAULT; + chip->buffer_end = chip->data_buffer + pos + count; + +@@ -182,7 +182,7 @@ static int snd_sh_dac_pcm_silence(struct snd_pcm_substream *substream, + /* channel is not used (interleaved data) */ + struct snd_sh_dac *chip = snd_pcm_substream_chip(substream); + +- memset_io(chip->data_buffer + pos, 0, count); ++ memset(chip->data_buffer + pos, 0, count); + chip->buffer_end = chip->data_buffer + pos + count; + + if (chip->empty) { +@@ -211,7 +211,6 @@ static const struct snd_pcm_ops snd_sh_dac_pcm_ops = { + .pointer = snd_sh_dac_pcm_pointer, + .copy = snd_sh_dac_pcm_copy, + .fill_silence = snd_sh_dac_pcm_silence, +- .mmap = snd_pcm_lib_mmap_iomem, + }; + + static int snd_sh_dac_pcm(struct snd_sh_dac *chip, int device) +diff --git a/tools/include/uapi/linux/stddef.h b/tools/include/uapi/linux/stddef.h +index bb6ea517efb511..c53cde425406b7 100644 +--- a/tools/include/uapi/linux/stddef.h ++++ b/tools/include/uapi/linux/stddef.h +@@ -8,6 +8,13 @@ + #define __always_inline __inline__ + #endif + ++/* Not all C++ standards support type declarations inside an anonymous union */ ++#ifndef __cplusplus ++#define __struct_group_tag(TAG) TAG ++#else ++#define __struct_group_tag(TAG) ++#endif ++ + /** + * __struct_group() - Create a mirrored named and anonyomous struct + * +@@ -20,14 +27,14 @@ + * and size: one anonymous and one named. The former's members can be used + * normally without sub-struct naming, and the latter can be used to + * reason about the start, end, and size of the group of struct members. +- * The named struct can also be explicitly tagged for layer reuse, as well +- * as both having struct attributes appended. ++ * The named struct can also be explicitly tagged for layer reuse (C only), ++ * as well as both having struct attributes appended. + */ + #define __struct_group(TAG, NAME, ATTRS, MEMBERS...) \ + union { \ + struct { MEMBERS } ATTRS; \ +- struct TAG { MEMBERS } ATTRS NAME; \ +- } ++ struct __struct_group_tag(TAG) { MEMBERS } ATTRS NAME; \ ++ } ATTRS + + /** + * __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union diff --git a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.69-70.patch b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.69-70.patch new file mode 100644 index 000000000000..0ccd04cd7a67 --- /dev/null +++ b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.69-70.patch @@ -0,0 +1,12214 @@ +diff --git a/Documentation/admin-guide/media/building.rst b/Documentation/admin-guide/media/building.rst +index a0647342991637..7a413ba07f93bb 100644 +--- a/Documentation/admin-guide/media/building.rst ++++ b/Documentation/admin-guide/media/building.rst +@@ -15,7 +15,7 @@ Please notice, however, that, if: + + you should use the main media development tree ``master`` branch: + +- https://git.linuxtv.org/media_tree.git/ ++ https://git.linuxtv.org/media.git/ + + In this case, you may find some useful information at the + `LinuxTv wiki pages `_: +diff --git a/Documentation/admin-guide/media/saa7134.rst b/Documentation/admin-guide/media/saa7134.rst +index 51eae7eb5ab7f4..18d7cbc897db4b 100644 +--- a/Documentation/admin-guide/media/saa7134.rst ++++ b/Documentation/admin-guide/media/saa7134.rst +@@ -67,7 +67,7 @@ Changes / Fixes + Please mail to linux-media AT vger.kernel.org unified diffs against + the linux media git tree: + +- https://git.linuxtv.org/media_tree.git/ ++ https://git.linuxtv.org/media.git/ + + This is done by committing a patch at a clone of the git tree and + submitting the patch using ``git send-email``. Don't forget to +diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst +index 3cf806733083c7..8209c7a7c3970e 100644 +--- a/Documentation/arch/arm64/silicon-errata.rst ++++ b/Documentation/arch/arm64/silicon-errata.rst +@@ -244,8 +244,9 @@ stable kernels. + +----------------+-----------------+-----------------+-----------------------------+ + | Hisilicon | Hip08 SMMU PMCG | #162001800 | N/A | + +----------------+-----------------+-----------------+-----------------------------+ +-| Hisilicon | Hip08 SMMU PMCG | #162001900 | N/A | +-| | Hip09 SMMU PMCG | | | ++| Hisilicon | Hip{08,09,09A,10| #162001900 | N/A | ++| | ,10C,11} | | | ++| | SMMU PMCG | | | + +----------------+-----------------+-----------------+-----------------------------+ + +----------------+-----------------+-----------------+-----------------------------+ + | Qualcomm Tech. | Kryo/Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 | +diff --git a/Documentation/devicetree/bindings/display/bridge/adi,adv7533.yaml b/Documentation/devicetree/bindings/display/bridge/adi,adv7533.yaml +index 987aa83c264943..e956f524e379dc 100644 +--- a/Documentation/devicetree/bindings/display/bridge/adi,adv7533.yaml ++++ b/Documentation/devicetree/bindings/display/bridge/adi,adv7533.yaml +@@ -87,7 +87,7 @@ properties: + adi,dsi-lanes: + description: Number of DSI data lanes connected to the DSI host. + $ref: /schemas/types.yaml#/definitions/uint32 +- enum: [ 1, 2, 3, 4 ] ++ enum: [ 2, 3, 4 ] + + ports: + description: +diff --git a/Documentation/i2c/busses/i2c-i801.rst b/Documentation/i2c/busses/i2c-i801.rst +index 10eced6c2e4625..47e8ac5b7099f7 100644 +--- a/Documentation/i2c/busses/i2c-i801.rst ++++ b/Documentation/i2c/busses/i2c-i801.rst +@@ -48,6 +48,8 @@ Supported adapters: + * Intel Raptor Lake (PCH) + * Intel Meteor Lake (SOC and PCH) + * Intel Birch Stream (SOC) ++ * Intel Arrow Lake (SOC) ++ * Intel Panther Lake (SOC) + + Datasheets: Publicly available at the Intel website + +diff --git a/Makefile b/Makefile +index ec4d9d1d9b7ae7..4c0dd62e02e465 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 69 ++SUBLEVEL = 70 + EXTRAVERSION = + NAME = Pinguïn Aangedreven + +diff --git a/arch/arc/Makefile b/arch/arc/Makefile +index 2390dd042e3636..fb98478ed1ab09 100644 +--- a/arch/arc/Makefile ++++ b/arch/arc/Makefile +@@ -6,7 +6,7 @@ + KBUILD_DEFCONFIG := haps_hs_smp_defconfig + + ifeq ($(CROSS_COMPILE),) +-CROSS_COMPILE := $(call cc-cross-prefix, arc-linux- arceb-linux-) ++CROSS_COMPILE := $(call cc-cross-prefix, arc-linux- arceb-linux- arc-linux-gnu-) + endif + + cflags-y += -fno-common -pipe -fno-builtin -mmedium-calls -D__linux__ +diff --git a/arch/loongarch/kernel/numa.c b/arch/loongarch/kernel/numa.c +index 6e65ff12d5c7dc..8fe21f868f72d4 100644 +--- a/arch/loongarch/kernel/numa.c ++++ b/arch/loongarch/kernel/numa.c +@@ -226,32 +226,6 @@ static void __init node_mem_init(unsigned int node) + + #ifdef CONFIG_ACPI_NUMA + +-/* +- * Sanity check to catch more bad NUMA configurations (they are amazingly +- * common). Make sure the nodes cover all memory. +- */ +-static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi) +-{ +- int i; +- u64 numaram, biosram; +- +- numaram = 0; +- for (i = 0; i < mi->nr_blks; i++) { +- u64 s = mi->blk[i].start >> PAGE_SHIFT; +- u64 e = mi->blk[i].end >> PAGE_SHIFT; +- +- numaram += e - s; +- numaram -= __absent_pages_in_range(mi->blk[i].nid, s, e); +- if ((s64)numaram < 0) +- numaram = 0; +- } +- max_pfn = max_low_pfn; +- biosram = max_pfn - absent_pages_in_range(0, max_pfn); +- +- BUG_ON((s64)(biosram - numaram) >= (1 << (20 - PAGE_SHIFT))); +- return true; +-} +- + static void __init add_node_intersection(u32 node, u64 start, u64 size, u32 type) + { + static unsigned long num_physpages; +@@ -396,7 +370,7 @@ int __init init_numa_memory(void) + return -EINVAL; + + init_node_memblock(); +- if (numa_meminfo_cover_memory(&numa_meminfo) == false) ++ if (!memblock_validate_numa_coverage(SZ_1M)) + return -EINVAL; + + for_each_node_mask(node, node_possible_map) { +diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c +index d43db8150767be..dddf4f31c219ac 100644 +--- a/arch/powerpc/kernel/setup-common.c ++++ b/arch/powerpc/kernel/setup-common.c +@@ -601,7 +601,6 @@ struct seq_buf ppc_hw_desc __initdata = { + .buffer = ppc_hw_desc_buf, + .size = sizeof(ppc_hw_desc_buf), + .len = 0, +- .readpos = 0, + }; + + static __init void probe_machine(void) +diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c +index 1245000a8792fd..2fb7d53cf3338d 100644 +--- a/arch/x86/entry/vsyscall/vsyscall_64.c ++++ b/arch/x86/entry/vsyscall/vsyscall_64.c +@@ -76,7 +76,7 @@ static void warn_bad_vsyscall(const char *level, struct pt_regs *regs, + if (!show_unhandled_signals) + return; + +- printk_ratelimited("%s%s[%d] %s ip:%lx cs:%lx sp:%lx ax:%lx si:%lx di:%lx\n", ++ printk_ratelimited("%s%s[%d] %s ip:%lx cs:%x sp:%lx ax:%lx si:%lx di:%lx\n", + level, current->comm, task_pid_nr(current), + message, regs->ip, regs->cs, + regs->sp, regs->ax, regs->si, regs->di); +diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h +index f4db78b09c8f0b..5a83fbd9bc0b44 100644 +--- a/arch/x86/include/asm/ptrace.h ++++ b/arch/x86/include/asm/ptrace.h +@@ -56,18 +56,64 @@ struct pt_regs { + + #else /* __i386__ */ + ++struct fred_cs { ++ /* CS selector */ ++ u64 cs : 16, ++ /* Stack level at event time */ ++ sl : 2, ++ /* IBT in WAIT_FOR_ENDBRANCH state */ ++ wfe : 1, ++ : 45; ++}; ++ ++struct fred_ss { ++ /* SS selector */ ++ u64 ss : 16, ++ /* STI state */ ++ sti : 1, ++ /* Set if syscall, sysenter or INT n */ ++ swevent : 1, ++ /* Event is NMI type */ ++ nmi : 1, ++ : 13, ++ /* Event vector */ ++ vector : 8, ++ : 8, ++ /* Event type */ ++ type : 4, ++ : 4, ++ /* Event was incident to enclave execution */ ++ enclave : 1, ++ /* CPU was in long mode */ ++ lm : 1, ++ /* ++ * Nested exception during FRED delivery, not set ++ * for #DF. ++ */ ++ nested : 1, ++ : 1, ++ /* ++ * The length of the instruction causing the event. ++ * Only set for INTO, INT1, INT3, INT n, SYSCALL ++ * and SYSENTER. 0 otherwise. ++ */ ++ insnlen : 4; ++}; ++ + struct pt_regs { +-/* +- * C ABI says these regs are callee-preserved. They aren't saved on kernel entry +- * unless syscall needs a complete, fully filled "struct pt_regs". +- */ ++ /* ++ * C ABI says these regs are callee-preserved. They aren't saved on ++ * kernel entry unless syscall needs a complete, fully filled ++ * "struct pt_regs". ++ */ + unsigned long r15; + unsigned long r14; + unsigned long r13; + unsigned long r12; + unsigned long bp; + unsigned long bx; +-/* These regs are callee-clobbered. Always saved on kernel entry. */ ++ ++ /* These regs are callee-clobbered. Always saved on kernel entry. */ + unsigned long r11; + unsigned long r10; + unsigned long r9; +@@ -77,18 +123,50 @@ struct pt_regs { + unsigned long dx; + unsigned long si; + unsigned long di; +-/* +- * On syscall entry, this is syscall#. On CPU exception, this is error code. +- * On hw interrupt, it's IRQ number: +- */ ++ ++ /* ++ * orig_ax is used on entry for: ++ * - the syscall number (syscall, sysenter, int80) ++ * - error_code stored by the CPU on traps and exceptions ++ * - the interrupt number for device interrupts ++ * ++ * A FRED stack frame starts here: ++ * 1) It _always_ includes an error code; ++ * ++ * 2) The return frame for ERET[US] starts here, but ++ * the content of orig_ax is ignored. ++ */ + unsigned long orig_ax; +-/* Return frame for iretq */ ++ ++ /* The IRETQ return frame starts here */ + unsigned long ip; +- unsigned long cs; ++ ++ union { ++ /* CS selector */ ++ u16 cs; ++ /* The extended 64-bit data slot containing CS */ ++ u64 csx; ++ /* The FRED CS extension */ ++ struct fred_cs fred_cs; ++ }; ++ + unsigned long flags; + unsigned long sp; +- unsigned long ss; +-/* top of stack page */ ++ ++ union { ++ /* SS selector */ ++ u16 ss; ++ /* The extended 64-bit data slot containing SS */ ++ u64 ssx; ++ /* The FRED SS extension */ ++ struct fred_ss fred_ss; ++ }; ++ ++ /* ++ * Top of stack on IDT systems, while FRED systems have extra fields ++ * defined above for storing exception related information, e.g. CR2 or ++ * DR6. ++ */ + }; + + #endif /* !__i386__ */ +diff --git a/arch/x86/include/asm/tlb.h b/arch/x86/include/asm/tlb.h +index 580636cdc257b7..4d3c9d00d6b6b2 100644 +--- a/arch/x86/include/asm/tlb.h ++++ b/arch/x86/include/asm/tlb.h +@@ -34,4 +34,8 @@ static inline void __tlb_remove_table(void *table) + free_page_and_swap_cache(table); + } + ++static inline void invlpg(unsigned long addr) ++{ ++ asm volatile("invlpg (%0)" ::"r" (addr) : "memory"); ++} + #endif /* _ASM_X86_TLB_H */ +diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile +index 3269a0e23d3ab8..15fc9fc3dcf052 100644 +--- a/arch/x86/kernel/Makefile ++++ b/arch/x86/kernel/Makefile +@@ -99,9 +99,9 @@ obj-$(CONFIG_TRACING) += trace.o + obj-$(CONFIG_RETHOOK) += rethook.o + obj-$(CONFIG_CRASH_CORE) += crash_core_$(BITS).o + obj-$(CONFIG_KEXEC_CORE) += machine_kexec_$(BITS).o +-obj-$(CONFIG_KEXEC_CORE) += relocate_kernel_$(BITS).o crash.o ++obj-$(CONFIG_KEXEC_CORE) += relocate_kernel_$(BITS).o + obj-$(CONFIG_KEXEC_FILE) += kexec-bzimage64.o +-obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o ++obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o crash.o + obj-y += kprobes/ + obj-$(CONFIG_MODULES) += module.o + obj-$(CONFIG_X86_32) += doublefault_32.o +diff --git a/arch/x86/kernel/cet.c b/arch/x86/kernel/cet.c +index d2c732a34e5d90..303bf74d175b30 100644 +--- a/arch/x86/kernel/cet.c ++++ b/arch/x86/kernel/cet.c +@@ -81,6 +81,34 @@ static void do_user_cp_fault(struct pt_regs *regs, unsigned long error_code) + + static __ro_after_init bool ibt_fatal = true; + ++/* ++ * By definition, all missing-ENDBRANCH #CPs are a result of WFE && !ENDBR. ++ * ++ * For the kernel IBT no ENDBR selftest where #CPs are deliberately triggered, ++ * the WFE state of the interrupted context needs to be cleared to let execution ++ * continue. Otherwise when the CPU resumes from the instruction that just ++ * caused the previous #CP, another missing-ENDBRANCH #CP is raised and the CPU ++ * enters a dead loop. ++ * ++ * This is not a problem with IDT because it doesn't preserve WFE and IRET doesn't ++ * set WFE. But FRED provides space on the entry stack (in an expanded CS area) ++ * to save and restore the WFE state, thus the WFE state is no longer clobbered, ++ * so software must clear it. ++ */ ++static void ibt_clear_fred_wfe(struct pt_regs *regs) ++{ ++ /* ++ * No need to do any FRED checks. ++ * ++ * For IDT event delivery, the high-order 48 bits of CS are pushed ++ * as 0s into the stack, and later IRET ignores these bits. ++ * ++ * For FRED, a test to check if fred_cs.wfe is set would be dropped ++ * by compilers. ++ */ ++ regs->fred_cs.wfe = 0; ++} ++ + static void do_kernel_cp_fault(struct pt_regs *regs, unsigned long error_code) + { + if ((error_code & CP_EC) != CP_ENDBR) { +@@ -90,6 +118,7 @@ static void do_kernel_cp_fault(struct pt_regs *regs, unsigned long error_code) + + if (unlikely(regs->ip == (unsigned long)&ibt_selftest_noendbr)) { + regs->ax = 0; ++ ibt_clear_fred_wfe(regs); + return; + } + +@@ -97,6 +126,7 @@ static void do_kernel_cp_fault(struct pt_regs *regs, unsigned long error_code) + if (!ibt_fatal) { + printk(KERN_DEFAULT CUT_HERE); + __warn(__FILE__, __LINE__, (void *)regs->ip, TAINT_WARN, regs, NULL); ++ ibt_clear_fred_wfe(regs); + return; + } + BUG(); +diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c +index bcb2d640a0cd85..6328cf56e59be2 100644 +--- a/arch/x86/kernel/cpu/mshyperv.c ++++ b/arch/x86/kernel/cpu/mshyperv.c +@@ -209,7 +209,9 @@ static void hv_machine_shutdown(void) + if (kexec_in_progress) + hyperv_cleanup(); + } ++#endif /* CONFIG_KEXEC_CORE */ + ++#ifdef CONFIG_CRASH_DUMP + static void hv_machine_crash_shutdown(struct pt_regs *regs) + { + if (hv_crash_handler) +@@ -221,7 +223,64 @@ static void hv_machine_crash_shutdown(struct pt_regs *regs) + /* Disable the hypercall page when there is only 1 active CPU. */ + hyperv_cleanup(); + } +-#endif /* CONFIG_KEXEC_CORE */ ++#endif /* CONFIG_CRASH_DUMP */ ++ ++static u64 hv_ref_counter_at_suspend; ++static void (*old_save_sched_clock_state)(void); ++static void (*old_restore_sched_clock_state)(void); ++ ++/* ++ * Hyper-V clock counter resets during hibernation. Save and restore clock ++ * offset during suspend/resume, while also considering the time passed ++ * before suspend. This is to make sure that sched_clock using hv tsc page ++ * based clocksource, proceeds from where it left off during suspend and ++ * it shows correct time for the timestamps of kernel messages after resume. ++ */ ++static void save_hv_clock_tsc_state(void) ++{ ++ hv_ref_counter_at_suspend = hv_read_reference_counter(); ++} ++ ++static void restore_hv_clock_tsc_state(void) ++{ ++ /* ++ * Adjust the offsets used by hv tsc clocksource to ++ * account for the time spent before hibernation. ++ * adjusted value = reference counter (time) at suspend ++ * - reference counter (time) now. ++ */ ++ hv_adj_sched_clock_offset(hv_ref_counter_at_suspend - hv_read_reference_counter()); ++} ++ ++/* ++ * Functions to override save_sched_clock_state and restore_sched_clock_state ++ * functions of x86_platform. The Hyper-V clock counter is reset during ++ * suspend-resume and the offset used to measure time needs to be ++ * corrected, post resume. ++ */ ++static void hv_save_sched_clock_state(void) ++{ ++ old_save_sched_clock_state(); ++ save_hv_clock_tsc_state(); ++} ++ ++static void hv_restore_sched_clock_state(void) ++{ ++ restore_hv_clock_tsc_state(); ++ old_restore_sched_clock_state(); ++} ++ ++static void __init x86_setup_ops_for_tsc_pg_clock(void) ++{ ++ if (!(ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE)) ++ return; ++ ++ old_save_sched_clock_state = x86_platform.save_sched_clock_state; ++ x86_platform.save_sched_clock_state = hv_save_sched_clock_state; ++ ++ old_restore_sched_clock_state = x86_platform.restore_sched_clock_state; ++ x86_platform.restore_sched_clock_state = hv_restore_sched_clock_state; ++} + #endif /* CONFIG_HYPERV */ + + static uint32_t __init ms_hyperv_platform(void) +@@ -493,9 +552,13 @@ static void __init ms_hyperv_init_platform(void) + no_timer_check = 1; + #endif + +-#if IS_ENABLED(CONFIG_HYPERV) && defined(CONFIG_KEXEC_CORE) ++#if IS_ENABLED(CONFIG_HYPERV) ++#if defined(CONFIG_KEXEC_CORE) + machine_ops.shutdown = hv_machine_shutdown; ++#endif ++#if defined(CONFIG_CRASH_DUMP) + machine_ops.crash_shutdown = hv_machine_crash_shutdown; ++#endif + #endif + if (ms_hyperv.features & HV_ACCESS_TSC_INVARIANT) { + /* +@@ -572,6 +635,7 @@ static void __init ms_hyperv_init_platform(void) + + /* Register Hyper-V specific clocksource */ + hv_init_clocksource(); ++ x86_setup_ops_for_tsc_pg_clock(); + hv_vtl_init_platform(); + #endif + /* +diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c +index a61c12c0127097..0de509c02d18b9 100644 +--- a/arch/x86/kernel/kexec-bzimage64.c ++++ b/arch/x86/kernel/kexec-bzimage64.c +@@ -263,11 +263,13 @@ setup_boot_parameters(struct kimage *image, struct boot_params *params, + memset(¶ms->hd0_info, 0, sizeof(params->hd0_info)); + memset(¶ms->hd1_info, 0, sizeof(params->hd1_info)); + ++#ifdef CONFIG_CRASH_DUMP + if (image->type == KEXEC_TYPE_CRASH) { + ret = crash_setup_memmap_entries(image, params); + if (ret) + return ret; + } else ++#endif + setup_e820_entries(params); + + nr_e820_entries = params->e820_entries; +@@ -428,12 +430,14 @@ static void *bzImage64_load(struct kimage *image, char *kernel, + return ERR_PTR(-EINVAL); + } + ++#ifdef CONFIG_CRASH_DUMP + /* Allocate and load backup region */ + if (image->type == KEXEC_TYPE_CRASH) { + ret = crash_load_segments(image); + if (ret) + return ERR_PTR(ret); + } ++#endif + + /* + * Load purgatory. For 64bit entry point, purgatory code can be +diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c +index b8ab9ee5896c19..38d88c8b56ec07 100644 +--- a/arch/x86/kernel/kvm.c ++++ b/arch/x86/kernel/kvm.c +@@ -769,7 +769,7 @@ static struct notifier_block kvm_pv_reboot_nb = { + * won't be valid. In cases like kexec, in which you install a new kernel, this + * means a random memory location will be kept being written. + */ +-#ifdef CONFIG_KEXEC_CORE ++#ifdef CONFIG_CRASH_DUMP + static void kvm_crash_shutdown(struct pt_regs *regs) + { + kvm_guest_cpu_offline(true); +@@ -852,7 +852,7 @@ static void __init kvm_guest_init(void) + kvm_guest_cpu_init(); + #endif + +-#ifdef CONFIG_KEXEC_CORE ++#ifdef CONFIG_CRASH_DUMP + machine_ops.crash_shutdown = kvm_crash_shutdown; + #endif + +diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c +index 2fa12d1dc67602..aaeac2deb85dc6 100644 +--- a/arch/x86/kernel/machine_kexec_64.c ++++ b/arch/x86/kernel/machine_kexec_64.c +@@ -545,6 +545,8 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image) + } + #endif /* CONFIG_KEXEC_FILE */ + ++#ifdef CONFIG_CRASH_DUMP ++ + static int + kexec_mark_range(unsigned long start, unsigned long end, bool protect) + { +@@ -589,6 +591,7 @@ void arch_kexec_unprotect_crashkres(void) + { + kexec_mark_crashkres(false); + } ++#endif + + /* + * During a traditional boot under SME, SME will encrypt the kernel, +diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c +index d595ef7c1de05e..dd19a4db741afd 100644 +--- a/arch/x86/kernel/process_64.c ++++ b/arch/x86/kernel/process_64.c +@@ -117,7 +117,7 @@ void __show_regs(struct pt_regs *regs, enum show_regs_mode mode, + + printk("%sFS: %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n", + log_lvl, fs, fsindex, gs, gsindex, shadowgs); +- printk("%sCS: %04lx DS: %04x ES: %04x CR0: %016lx\n", ++ printk("%sCS: %04x DS: %04x ES: %04x CR0: %016lx\n", + log_lvl, regs->cs, ds, es, cr0); + printk("%sCR2: %016lx CR3: %016lx CR4: %016lx\n", + log_lvl, cr2, cr3, cr4); +diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c +index 830425e6d38e2f..f3130f762784a1 100644 +--- a/arch/x86/kernel/reboot.c ++++ b/arch/x86/kernel/reboot.c +@@ -796,7 +796,7 @@ struct machine_ops machine_ops __ro_after_init = { + .emergency_restart = native_machine_emergency_restart, + .restart = native_machine_restart, + .halt = native_machine_halt, +-#ifdef CONFIG_KEXEC_CORE ++#ifdef CONFIG_CRASH_DUMP + .crash_shutdown = native_machine_crash_shutdown, + #endif + }; +@@ -826,7 +826,7 @@ void machine_halt(void) + machine_ops.halt(); + } + +-#ifdef CONFIG_KEXEC_CORE ++#ifdef CONFIG_CRASH_DUMP + void machine_crash_shutdown(struct pt_regs *regs) + { + machine_ops.crash_shutdown(regs); +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index eb129277dcdd64..8bcecabd475bdf 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -547,7 +547,7 @@ static void __init reserve_crashkernel(void) + bool high = false; + int ret; + +- if (!IS_ENABLED(CONFIG_KEXEC_CORE)) ++ if (!IS_ENABLED(CONFIG_CRASH_RESERVE)) + return; + + total_mem = memblock_phys_mem_size(); +diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c +index 96a771f9f930a6..52c3823b721191 100644 +--- a/arch/x86/kernel/smp.c ++++ b/arch/x86/kernel/smp.c +@@ -282,7 +282,7 @@ struct smp_ops smp_ops = { + .smp_cpus_done = native_smp_cpus_done, + + .stop_other_cpus = native_stop_other_cpus, +-#if defined(CONFIG_KEXEC_CORE) ++#if defined(CONFIG_CRASH_DUMP) + .crash_stop_other_cpus = kdump_nmi_shootdown_cpus, + #endif + .smp_send_reschedule = native_smp_send_reschedule, +diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c +index c7fa5396c0f05c..2c67bfc3cf3204 100644 +--- a/arch/x86/mm/numa.c ++++ b/arch/x86/mm/numa.c +@@ -448,37 +448,6 @@ int __node_distance(int from, int to) + } + EXPORT_SYMBOL(__node_distance); + +-/* +- * Sanity check to catch more bad NUMA configurations (they are amazingly +- * common). Make sure the nodes cover all memory. +- */ +-static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi) +-{ +- u64 numaram, e820ram; +- int i; +- +- numaram = 0; +- for (i = 0; i < mi->nr_blks; i++) { +- u64 s = mi->blk[i].start >> PAGE_SHIFT; +- u64 e = mi->blk[i].end >> PAGE_SHIFT; +- numaram += e - s; +- numaram -= __absent_pages_in_range(mi->blk[i].nid, s, e); +- if ((s64)numaram < 0) +- numaram = 0; +- } +- +- e820ram = max_pfn - absent_pages_in_range(0, max_pfn); +- +- /* We seem to lose 3 pages somewhere. Allow 1M of slack. */ +- if ((s64)(e820ram - numaram) >= (1 << (20 - PAGE_SHIFT))) { +- printk(KERN_ERR "NUMA: nodes only cover %LuMB of your %LuMB e820 RAM. Not used.\n", +- (numaram << PAGE_SHIFT) >> 20, +- (e820ram << PAGE_SHIFT) >> 20); +- return false; +- } +- return true; +-} +- + /* + * Mark all currently memblock-reserved physical memory (which covers the + * kernel's own memory ranges) as hot-unswappable. +@@ -584,7 +553,8 @@ static int __init numa_register_memblks(struct numa_meminfo *mi) + return -EINVAL; + } + } +- if (!numa_meminfo_cover_memory(mi)) ++ ++ if (!memblock_validate_numa_coverage(SZ_1M)) + return -EINVAL; + + /* Finally register nodes. */ +diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c +index 2fbae48f0b470a..64f594826a2822 100644 +--- a/arch/x86/mm/tlb.c ++++ b/arch/x86/mm/tlb.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + #include "mm_internal.h" + +@@ -1145,7 +1146,7 @@ STATIC_NOPV void native_flush_tlb_one_user(unsigned long addr) + bool cpu_pcide; + + /* Flush 'addr' from the kernel PCID: */ +- asm volatile("invlpg (%0)" ::"r" (addr) : "memory"); ++ invlpg(addr); + + /* If PTI is off there is no user PCID and nothing to flush. */ + if (!static_cpu_has(X86_FEATURE_PTI)) +diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c +index 70be57e8f51caa..ade22feee7aeb1 100644 +--- a/arch/x86/xen/enlighten_hvm.c ++++ b/arch/x86/xen/enlighten_hvm.c +@@ -141,7 +141,9 @@ static void xen_hvm_shutdown(void) + if (kexec_in_progress) + xen_reboot(SHUTDOWN_soft_reset); + } ++#endif + ++#ifdef CONFIG_CRASH_DUMP + static void xen_hvm_crash_shutdown(struct pt_regs *regs) + { + native_machine_crash_shutdown(regs); +@@ -229,6 +231,8 @@ static void __init xen_hvm_guest_init(void) + + #ifdef CONFIG_KEXEC_CORE + machine_ops.shutdown = xen_hvm_shutdown; ++#endif ++#ifdef CONFIG_CRASH_DUMP + machine_ops.crash_shutdown = xen_hvm_crash_shutdown; + #endif + } +diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c +index 6b201e64d8abc8..bfd57d07f4b5ee 100644 +--- a/arch/x86/xen/mmu_pv.c ++++ b/arch/x86/xen/mmu_pv.c +@@ -2517,7 +2517,7 @@ int xen_remap_pfn(struct vm_area_struct *vma, unsigned long addr, + } + EXPORT_SYMBOL_GPL(xen_remap_pfn); + +-#ifdef CONFIG_KEXEC_CORE ++#ifdef CONFIG_VMCORE_INFO + phys_addr_t paddr_vmcoreinfo_note(void) + { + if (xen_pv_domain()) +diff --git a/crypto/ecc.c b/crypto/ecc.c +index f53fb4d6af992b..21504280aca2e5 100644 +--- a/crypto/ecc.c ++++ b/crypto/ecc.c +@@ -66,6 +66,28 @@ const struct ecc_curve *ecc_get_curve(unsigned int curve_id) + } + EXPORT_SYMBOL(ecc_get_curve); + ++void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes, ++ u64 *out, unsigned int ndigits) ++{ ++ int diff = ndigits - DIV_ROUND_UP(nbytes, sizeof(u64)); ++ unsigned int o = nbytes & 7; ++ __be64 msd = 0; ++ ++ /* diff > 0: not enough input bytes: set most significant digits to 0 */ ++ if (diff > 0) { ++ ndigits -= diff; ++ memset(&out[ndigits - 1], 0, diff * sizeof(u64)); ++ } ++ ++ if (o) { ++ memcpy((u8 *)&msd + sizeof(msd) - o, in, o); ++ out[--ndigits] = be64_to_cpu(msd); ++ in += o; ++ } ++ ecc_swap_digits(in, out, ndigits); ++} ++EXPORT_SYMBOL(ecc_digits_from_bytes); ++ + static u64 *ecc_alloc_digits_space(unsigned int ndigits) + { + size_t len = ndigits * sizeof(u64); +diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c +index 3f9ec273a121fd..da04df3c8ecf4d 100644 +--- a/crypto/ecdsa.c ++++ b/crypto/ecdsa.c +@@ -35,40 +35,27 @@ struct ecdsa_signature_ctx { + static int ecdsa_get_signature_rs(u64 *dest, size_t hdrlen, unsigned char tag, + const void *value, size_t vlen, unsigned int ndigits) + { +- size_t keylen = ndigits * sizeof(u64); +- ssize_t diff = vlen - keylen; ++ size_t bufsize = ndigits * sizeof(u64); + const char *d = value; +- u8 rs[ECC_MAX_BYTES]; + +- if (!value || !vlen) ++ if (!value || !vlen || vlen > bufsize + 1) + return -EINVAL; + +- /* diff = 0: 'value' has exacly the right size +- * diff > 0: 'value' has too many bytes; one leading zero is allowed that +- * makes the value a positive integer; error on more +- * diff < 0: 'value' is missing leading zeros, which we add ++ /* ++ * vlen may be 1 byte larger than bufsize due to a leading zero byte ++ * (necessary if the most significant bit of the integer is set). + */ +- if (diff > 0) { ++ if (vlen > bufsize) { + /* skip over leading zeros that make 'value' a positive int */ + if (*d == 0) { + vlen -= 1; +- diff--; + d++; +- } +- if (diff) ++ } else { + return -EINVAL; ++ } + } +- if (-diff >= keylen) +- return -EINVAL; +- +- if (diff) { +- /* leading zeros not given in 'value' */ +- memset(rs, 0, -diff); +- } +- +- memcpy(&rs[-diff], d, vlen); + +- ecc_swap_digits((u64 *)rs, dest, ndigits); ++ ecc_digits_from_bytes(d, vlen, dest, ndigits); + + return 0; + } +@@ -138,7 +125,7 @@ static int ecdsa_verify(struct akcipher_request *req) + { + struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); + struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm); +- size_t keylen = ctx->curve->g.ndigits * sizeof(u64); ++ size_t bufsize = ctx->curve->g.ndigits * sizeof(u64); + struct ecdsa_signature_ctx sig_ctx = { + .curve = ctx->curve, + }; +@@ -165,14 +152,14 @@ static int ecdsa_verify(struct akcipher_request *req) + goto error; + + /* if the hash is shorter then we will add leading zeros to fit to ndigits */ +- diff = keylen - req->dst_len; ++ diff = bufsize - req->dst_len; + if (diff >= 0) { + if (diff) + memset(rawhash, 0, diff); + memcpy(&rawhash[diff], buffer + req->src_len, req->dst_len); + } else if (diff < 0) { + /* given hash is longer, we take the left-most bytes */ +- memcpy(&rawhash, buffer + req->src_len, keylen); ++ memcpy(&rawhash, buffer + req->src_len, bufsize); + } + + ecc_swap_digits((u64 *)rawhash, hash, ctx->curve->g.ndigits); +@@ -222,9 +209,8 @@ static int ecdsa_ecc_ctx_reset(struct ecc_ctx *ctx) + static int ecdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsigned int keylen) + { + struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm); ++ unsigned int digitlen, ndigits; + const unsigned char *d = key; +- const u64 *digits = (const u64 *)&d[1]; +- unsigned int ndigits; + int ret; + + ret = ecdsa_ecc_ctx_reset(ctx); +@@ -238,12 +224,17 @@ static int ecdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsig + return -EINVAL; + + keylen--; +- ndigits = (keylen >> 1) / sizeof(u64); ++ digitlen = keylen >> 1; ++ ++ ndigits = DIV_ROUND_UP(digitlen, sizeof(u64)); + if (ndigits != ctx->curve->g.ndigits) + return -EINVAL; + +- ecc_swap_digits(digits, ctx->pub_key.x, ndigits); +- ecc_swap_digits(&digits[ndigits], ctx->pub_key.y, ndigits); ++ d++; ++ ++ ecc_digits_from_bytes(d, digitlen, ctx->pub_key.x, ndigits); ++ ecc_digits_from_bytes(&d[digitlen], digitlen, ctx->pub_key.y, ndigits); ++ + ret = ecc_is_pubkey_valid_full(ctx->curve, &ctx->pub_key); + + ctx->pub_key_set = ret == 0; +diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c +index 6496ff5a6ba20d..1a31106a14e446 100644 +--- a/drivers/acpi/arm64/iort.c ++++ b/drivers/acpi/arm64/iort.c +@@ -1712,6 +1712,15 @@ static struct acpi_platform_list pmcg_plat_info[] __initdata = { + /* HiSilicon Hip09 Platform */ + {"HISI ", "HIP09 ", 0, ACPI_SIG_IORT, greater_than_or_equal, + "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09}, ++ {"HISI ", "HIP09A ", 0, ACPI_SIG_IORT, greater_than_or_equal, ++ "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09}, ++ /* HiSilicon Hip10/11 Platform uses the same SMMU IP with Hip09 */ ++ {"HISI ", "HIP10 ", 0, ACPI_SIG_IORT, greater_than_or_equal, ++ "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09}, ++ {"HISI ", "HIP10C ", 0, ACPI_SIG_IORT, greater_than_or_equal, ++ "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09}, ++ {"HISI ", "HIP11 ", 0, ACPI_SIG_IORT, greater_than_or_equal, ++ "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09}, + { } + }; + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index fe5e30662017de..c80b5aa7628ae9 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -620,6 +620,9 @@ static const struct usb_device_id quirks_table[] = { + { USB_DEVICE(0x0e8d, 0x0608), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH | + BTUSB_VALID_LE_STATES }, ++ { USB_DEVICE(0x13d3, 0x3606), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH | ++ BTUSB_VALID_LE_STATES }, + + /* MediaTek MT7922A Bluetooth devices */ + { USB_DEVICE(0x0489, 0xe0d8), .driver_info = BTUSB_MEDIATEK | +@@ -658,6 +661,37 @@ static const struct usb_device_id quirks_table[] = { + { USB_DEVICE(0x04ca, 0x3804), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH | + BTUSB_VALID_LE_STATES }, ++ { USB_DEVICE(0x35f5, 0x7922), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH | ++ BTUSB_VALID_LE_STATES }, ++ { USB_DEVICE(0x13d3, 0x3614), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH | ++ BTUSB_VALID_LE_STATES }, ++ { USB_DEVICE(0x13d3, 0x3615), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH | ++ BTUSB_VALID_LE_STATES }, ++ { USB_DEVICE(0x04ca, 0x38e4), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH | ++ BTUSB_VALID_LE_STATES }, ++ { USB_DEVICE(0x13d3, 0x3605), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH | ++ BTUSB_VALID_LE_STATES }, ++ { USB_DEVICE(0x13d3, 0x3607), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH | ++ BTUSB_VALID_LE_STATES }, ++ ++ /* Additional MediaTek MT7925 Bluetooth devices */ ++ { USB_DEVICE(0x0489, 0xe111), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0489, 0xe113), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH | ++ BTUSB_VALID_LE_STATES }, ++ { USB_DEVICE(0x13d3, 0x3602), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH | ++ BTUSB_VALID_LE_STATES }, ++ { USB_DEVICE(0x13d3, 0x3603), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH | ++ BTUSB_VALID_LE_STATES }, + + /* Additional Realtek 8723AE Bluetooth devices */ + { USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK }, +@@ -858,6 +892,10 @@ struct btusb_data { + + int (*setup_on_usb)(struct hci_dev *hdev); + ++ int (*suspend)(struct hci_dev *hdev); ++ int (*resume)(struct hci_dev *hdev); ++ int (*disconnect)(struct hci_dev *hdev); ++ + int oob_wake_irq; /* irq for out-of-band wake-on-bt */ + unsigned cmd_timeout_cnt; + +@@ -4609,6 +4647,9 @@ static void btusb_disconnect(struct usb_interface *intf) + if (data->diag) + usb_set_intfdata(data->diag, NULL); + ++ if (data->disconnect) ++ data->disconnect(hdev); ++ + hci_unregister_dev(hdev); + + if (intf == data->intf) { +@@ -4657,6 +4698,9 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message) + + cancel_work_sync(&data->work); + ++ if (data->suspend) ++ data->suspend(data->hdev); ++ + btusb_stop_traffic(data); + usb_kill_anchored_urbs(&data->tx_anchor); + +@@ -4760,6 +4804,9 @@ static int btusb_resume(struct usb_interface *intf) + btusb_submit_isoc_urb(hdev, GFP_NOIO); + } + ++ if (data->resume) ++ data->resume(hdev); ++ + spin_lock_irq(&data->txlock); + play_deferred(data); + clear_bit(BTUSB_SUSPENDING, &data->flags); +diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c +index 8b3e5f84e89a77..ce44dbfd47e275 100644 +--- a/drivers/clk/qcom/clk-alpha-pll.c ++++ b/drivers/clk/qcom/clk-alpha-pll.c +@@ -52,6 +52,7 @@ + #define PLL_CONFIG_CTL(p) ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL]) + #define PLL_CONFIG_CTL_U(p) ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U]) + #define PLL_CONFIG_CTL_U1(p) ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U1]) ++#define PLL_CONFIG_CTL_U2(p) ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U2]) + #define PLL_TEST_CTL(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL]) + #define PLL_TEST_CTL_U(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U]) + #define PLL_TEST_CTL_U1(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U1]) +@@ -227,6 +228,32 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { + [PLL_OFF_ALPHA_VAL] = 0x24, + [PLL_OFF_ALPHA_VAL_U] = 0x28, + }, ++ [CLK_ALPHA_PLL_TYPE_ZONDA_OLE] = { ++ [PLL_OFF_L_VAL] = 0x04, ++ [PLL_OFF_ALPHA_VAL] = 0x08, ++ [PLL_OFF_USER_CTL] = 0x0c, ++ [PLL_OFF_USER_CTL_U] = 0x10, ++ [PLL_OFF_CONFIG_CTL] = 0x14, ++ [PLL_OFF_CONFIG_CTL_U] = 0x18, ++ [PLL_OFF_CONFIG_CTL_U1] = 0x1c, ++ [PLL_OFF_CONFIG_CTL_U2] = 0x20, ++ [PLL_OFF_TEST_CTL] = 0x24, ++ [PLL_OFF_TEST_CTL_U] = 0x28, ++ [PLL_OFF_TEST_CTL_U1] = 0x2c, ++ [PLL_OFF_OPMODE] = 0x30, ++ [PLL_OFF_STATUS] = 0x3c, ++ }, ++ [CLK_ALPHA_PLL_TYPE_NSS_HUAYRA] = { ++ [PLL_OFF_L_VAL] = 0x04, ++ [PLL_OFF_ALPHA_VAL] = 0x08, ++ [PLL_OFF_TEST_CTL] = 0x0c, ++ [PLL_OFF_TEST_CTL_U] = 0x10, ++ [PLL_OFF_USER_CTL] = 0x14, ++ [PLL_OFF_CONFIG_CTL] = 0x18, ++ [PLL_OFF_CONFIG_CTL_U] = 0x1c, ++ [PLL_OFF_STATUS] = 0x20, ++ }, ++ + }; + EXPORT_SYMBOL_GPL(clk_alpha_pll_regs); + +diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h +index 3fd0ef41c72c89..52dc5b9b546a15 100644 +--- a/drivers/clk/qcom/clk-alpha-pll.h ++++ b/drivers/clk/qcom/clk-alpha-pll.h +@@ -21,6 +21,7 @@ enum { + CLK_ALPHA_PLL_TYPE_LUCID = CLK_ALPHA_PLL_TYPE_TRION, + CLK_ALPHA_PLL_TYPE_AGERA, + CLK_ALPHA_PLL_TYPE_ZONDA, ++ CLK_ALPHA_PLL_TYPE_ZONDA_OLE, + CLK_ALPHA_PLL_TYPE_LUCID_EVO, + CLK_ALPHA_PLL_TYPE_LUCID_OLE, + CLK_ALPHA_PLL_TYPE_RIVIAN_EVO, +@@ -28,6 +29,7 @@ enum { + CLK_ALPHA_PLL_TYPE_BRAMMO_EVO, + CLK_ALPHA_PLL_TYPE_STROMER, + CLK_ALPHA_PLL_TYPE_STROMER_PLUS, ++ CLK_ALPHA_PLL_TYPE_NSS_HUAYRA, + CLK_ALPHA_PLL_TYPE_MAX, + }; + +@@ -42,6 +44,7 @@ enum { + PLL_OFF_CONFIG_CTL, + PLL_OFF_CONFIG_CTL_U, + PLL_OFF_CONFIG_CTL_U1, ++ PLL_OFF_CONFIG_CTL_U2, + PLL_OFF_TEST_CTL, + PLL_OFF_TEST_CTL_U, + PLL_OFF_TEST_CTL_U1, +@@ -119,6 +122,7 @@ struct alpha_pll_config { + u32 config_ctl_val; + u32 config_ctl_hi_val; + u32 config_ctl_hi1_val; ++ u32 config_ctl_hi2_val; + u32 user_ctl_val; + u32 user_ctl_hi_val; + u32 user_ctl_hi1_val; +@@ -173,6 +177,7 @@ extern const struct clk_ops clk_alpha_pll_postdiv_lucid_5lpe_ops; + + extern const struct clk_ops clk_alpha_pll_zonda_ops; + #define clk_alpha_pll_postdiv_zonda_ops clk_alpha_pll_postdiv_fabia_ops ++#define clk_alpha_pll_zonda_ole_ops clk_alpha_pll_zonda_ops + + extern const struct clk_ops clk_alpha_pll_lucid_evo_ops; + extern const struct clk_ops clk_alpha_pll_reset_lucid_evo_ops; +diff --git a/drivers/clocksource/hyperv_timer.c b/drivers/clocksource/hyperv_timer.c +index 8ff7cd4e20bb11..5eec1457e13967 100644 +--- a/drivers/clocksource/hyperv_timer.c ++++ b/drivers/clocksource/hyperv_timer.c +@@ -27,7 +27,8 @@ + #include + + static struct clock_event_device __percpu *hv_clock_event; +-static u64 hv_sched_clock_offset __ro_after_init; ++/* Note: offset can hold negative values after hibernation. */ ++static u64 hv_sched_clock_offset __read_mostly; + + /* + * If false, we're using the old mechanism for stimer0 interrupts +@@ -456,6 +457,17 @@ static void resume_hv_clock_tsc(struct clocksource *arg) + hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64); + } + ++/* ++ * Called during resume from hibernation, from overridden ++ * x86_platform.restore_sched_clock_state routine. This is to adjust offsets ++ * used to calculate time for hv tsc page based sched_clock, to account for ++ * time spent before hibernation. ++ */ ++void hv_adj_sched_clock_offset(u64 offset) ++{ ++ hv_sched_clock_offset -= offset; ++} ++ + #ifdef HAVE_VDSO_CLOCKMODE_HVCLOCK + static int hv_cs_enable(struct clocksource *cs) + { +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c +index 3263b5fa182d20..f99e3b812ee44b 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c +@@ -319,7 +319,7 @@ svm_migrate_copy_to_vram(struct kfd_node *node, struct svm_range *prange, + spage = migrate_pfn_to_page(migrate->src[i]); + if (spage && !is_zone_device_page(spage)) { + src[i] = dma_map_page(dev, spage, 0, PAGE_SIZE, +- DMA_TO_DEVICE); ++ DMA_BIDIRECTIONAL); + r = dma_mapping_error(dev, src[i]); + if (r) { + dev_err(dev, "%s: fail %d dma_map_page\n", +@@ -634,7 +634,7 @@ svm_migrate_copy_to_ram(struct amdgpu_device *adev, struct svm_range *prange, + goto out_oom; + } + +- dst[i] = dma_map_page(dev, dpage, 0, PAGE_SIZE, DMA_FROM_DEVICE); ++ dst[i] = dma_map_page(dev, dpage, 0, PAGE_SIZE, DMA_BIDIRECTIONAL); + r = dma_mapping_error(dev, dst[i]); + if (r) { + dev_err(adev->dev, "%s: fail %d dma_map_page\n", __func__, r); +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +index 9ec9792f115a8a..385a5a75fdf873 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +@@ -1219,10 +1219,6 @@ static bool is_dsc_need_re_compute( + if (dc_link->type != dc_connection_mst_branch) + return false; + +- if (!(dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT || +- dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT)) +- return false; +- + for (i = 0; i < MAX_PIPES; i++) + stream_on_link[i] = NULL; + +@@ -1243,6 +1239,18 @@ static bool is_dsc_need_re_compute( + if (!aconnector) + continue; + ++ /* ++ * Check if cached virtual MST DSC caps are available and DSC is supported ++ * this change takes care of newer MST DSC capable devices that report their ++ * DPCD caps as per specifications in their Virtual DPCD registers. ++ ++ * TODO: implement the check for older MST DSC devices that do not conform to ++ * specifications. ++ */ ++ if (!(aconnector->dc_sink->dsc_caps.dsc_dec_caps.is_dsc_supported || ++ aconnector->dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT)) ++ continue; ++ + stream_on_link[new_stream_on_link_num] = aconnector; + new_stream_on_link_num++; + +diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c +index 61f4a38e7d2bf6..8f786592143b6c 100644 +--- a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c ++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c +@@ -153,7 +153,16 @@ static int adv7511_hdmi_hw_params(struct device *dev, void *data, + ADV7511_AUDIO_CFG3_LEN_MASK, len); + regmap_update_bits(adv7511->regmap, ADV7511_REG_I2C_FREQ_ID_CFG, + ADV7511_I2C_FREQ_ID_CFG_RATE_MASK, rate << 4); +- regmap_write(adv7511->regmap, 0x73, 0x1); ++ ++ /* send current Audio infoframe values while updating */ ++ regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, ++ BIT(5), BIT(5)); ++ ++ regmap_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME(0), 0x1); ++ ++ /* use Audio infoframe updated info */ ++ regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, ++ BIT(5), 0); + + return 0; + } +@@ -184,8 +193,9 @@ static int audio_startup(struct device *dev, void *data) + regmap_update_bits(adv7511->regmap, ADV7511_REG_GC(0), + BIT(7) | BIT(6), BIT(7)); + /* use Audio infoframe updated info */ +- regmap_update_bits(adv7511->regmap, ADV7511_REG_GC(1), ++ regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, + BIT(5), 0); ++ + /* enable SPDIF receiver */ + if (adv7511->audio_source == ADV7511_AUDIO_SOURCE_SPDIF) + regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CONFIG, +diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +index ef2b6ce544d0a8..1aa4153b40e0c1 100644 +--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c ++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +@@ -1225,8 +1225,10 @@ static int adv7511_probe(struct i2c_client *i2c) + return ret; + + ret = adv7511_init_regulators(adv7511); +- if (ret) +- return dev_err_probe(dev, ret, "failed to init regulators\n"); ++ if (ret) { ++ dev_err_probe(dev, ret, "failed to init regulators\n"); ++ goto err_of_node_put; ++ } + + /* + * The power down GPIO is optional. If present, toggle it from active to +@@ -1346,6 +1348,8 @@ static int adv7511_probe(struct i2c_client *i2c) + i2c_unregister_device(adv7511->i2c_edid); + uninit_regulators: + adv7511_uninit_regulators(adv7511); ++err_of_node_put: ++ of_node_put(adv7511->host_node); + + return ret; + } +@@ -1354,6 +1358,8 @@ static void adv7511_remove(struct i2c_client *i2c) + { + struct adv7511 *adv7511 = i2c_get_clientdata(i2c); + ++ of_node_put(adv7511->host_node); ++ + adv7511_uninit_regulators(adv7511); + + drm_bridge_remove(&adv7511->bridge); +diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c +index 7e3e56441aedc5..6a4733c7082700 100644 +--- a/drivers/gpu/drm/bridge/adv7511/adv7533.c ++++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c +@@ -175,7 +175,7 @@ int adv7533_parse_dt(struct device_node *np, struct adv7511 *adv) + + of_property_read_u32(np, "adi,dsi-lanes", &num_lanes); + +- if (num_lanes < 1 || num_lanes > 4) ++ if (num_lanes < 2 || num_lanes > 4) + return -EINVAL; + + adv->num_dsi_lanes = num_lanes; +@@ -184,8 +184,6 @@ int adv7533_parse_dt(struct device_node *np, struct adv7511 *adv) + if (!adv->host_node) + return -ENODEV; + +- of_node_put(adv->host_node); +- + adv->use_timing_gen = !of_property_read_bool(np, + "adi,disable-timing-generator"); + +diff --git a/drivers/gpu/drm/i915/gt/intel_rc6.c b/drivers/gpu/drm/i915/gt/intel_rc6.c +index 9e113e9473260a..6e8c182b2559e7 100644 +--- a/drivers/gpu/drm/i915/gt/intel_rc6.c ++++ b/drivers/gpu/drm/i915/gt/intel_rc6.c +@@ -133,7 +133,7 @@ static void gen11_rc6_enable(struct intel_rc6 *rc6) + GEN9_MEDIA_PG_ENABLE | + GEN11_MEDIA_SAMPLER_PG_ENABLE; + +- if (GRAPHICS_VER(gt->i915) >= 12) { ++ if (GRAPHICS_VER(gt->i915) >= 12 && !IS_DG1(gt->i915)) { + for (i = 0; i < I915_MAX_VCS; i++) + if (HAS_ENGINE(gt, _VCS(i))) + pg_enable |= (VDN_HCP_POWERGATE_ENABLE(i) | +diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig +index 97d27e01a6ee27..982007a112c2a0 100644 +--- a/drivers/i2c/busses/Kconfig ++++ b/drivers/i2c/busses/Kconfig +@@ -159,6 +159,8 @@ config I2C_I801 + Raptor Lake (PCH) + Meteor Lake (SOC and PCH) + Birch Stream (SOC) ++ Arrow Lake (SOC) ++ Panther Lake (SOC) + + This driver can also be built as a module. If so, the module + will be called i2c-i801. +diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c +index 2b8bcd121ffa5d..18c04f5e41d9c5 100644 +--- a/drivers/i2c/busses/i2c-i801.c ++++ b/drivers/i2c/busses/i2c-i801.c +@@ -80,6 +80,9 @@ + * Meteor Lake SoC-S (SOC) 0xae22 32 hard yes yes yes + * Meteor Lake PCH-S (PCH) 0x7f23 32 hard yes yes yes + * Birch Stream (SOC) 0x5796 32 hard yes yes yes ++ * Arrow Lake-H (SOC) 0x7722 32 hard yes yes yes ++ * Panther Lake-H (SOC) 0xe322 32 hard yes yes yes ++ * Panther Lake-P (SOC) 0xe422 32 hard yes yes yes + * + * Features supported by this driver: + * Software PEC no +@@ -234,6 +237,7 @@ + #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_M_SMBUS 0x54a3 + #define PCI_DEVICE_ID_INTEL_BIRCH_STREAM_SMBUS 0x5796 + #define PCI_DEVICE_ID_INTEL_BROXTON_SMBUS 0x5ad4 ++#define PCI_DEVICE_ID_INTEL_ARROW_LAKE_H_SMBUS 0x7722 + #define PCI_DEVICE_ID_INTEL_RAPTOR_LAKE_S_SMBUS 0x7a23 + #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_S_SMBUS 0x7aa3 + #define PCI_DEVICE_ID_INTEL_METEOR_LAKE_P_SMBUS 0x7e22 +@@ -256,6 +260,8 @@ + #define PCI_DEVICE_ID_INTEL_CANNONLAKE_H_SMBUS 0xa323 + #define PCI_DEVICE_ID_INTEL_COMETLAKE_V_SMBUS 0xa3a3 + #define PCI_DEVICE_ID_INTEL_METEOR_LAKE_SOC_S_SMBUS 0xae22 ++#define PCI_DEVICE_ID_INTEL_PANTHER_LAKE_H_SMBUS 0xe322 ++#define PCI_DEVICE_ID_INTEL_PANTHER_LAKE_P_SMBUS 0xe422 + + struct i801_mux_config { + char *gpio_chip; +@@ -1046,6 +1052,9 @@ static const struct pci_device_id i801_ids[] = { + { PCI_DEVICE_DATA(INTEL, METEOR_LAKE_SOC_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, METEOR_LAKE_PCH_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, BIRCH_STREAM_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, ARROW_LAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, PANTHER_LAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, PANTHER_LAKE_P_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { 0, } + }; + +diff --git a/drivers/i2c/busses/i2c-xgene-slimpro.c b/drivers/i2c/busses/i2c-xgene-slimpro.c +index fbc1ffbd2fa7d6..658396c9eeabf9 100644 +--- a/drivers/i2c/busses/i2c-xgene-slimpro.c ++++ b/drivers/i2c/busses/i2c-xgene-slimpro.c +@@ -91,14 +91,6 @@ + + #define SLIMPRO_IIC_MSG_DWORD_COUNT 3 + +-/* PCC related defines */ +-#define PCC_SIGNATURE 0x50424300 +-#define PCC_STS_CMD_COMPLETE BIT(0) +-#define PCC_STS_SCI_DOORBELL BIT(1) +-#define PCC_STS_ERR BIT(2) +-#define PCC_STS_PLAT_NOTIFY BIT(3) +-#define PCC_CMD_GENERATE_DB_INT BIT(15) +- + struct slimpro_i2c_dev { + struct i2c_adapter adapter; + struct device *dev; +@@ -160,11 +152,11 @@ static void slimpro_i2c_pcc_rx_cb(struct mbox_client *cl, void *msg) + + /* Check if platform sends interrupt */ + if (!xgene_word_tst_and_clr(&generic_comm_base->status, +- PCC_STS_SCI_DOORBELL)) ++ PCC_STATUS_SCI_DOORBELL)) + return; + + if (xgene_word_tst_and_clr(&generic_comm_base->status, +- PCC_STS_CMD_COMPLETE)) { ++ PCC_STATUS_CMD_COMPLETE)) { + msg = generic_comm_base + 1; + + /* Response message msg[1] contains the return value. */ +@@ -186,10 +178,10 @@ static void slimpro_i2c_pcc_tx_prepare(struct slimpro_i2c_dev *ctx, u32 *msg) + cpu_to_le32(PCC_SIGNATURE | ctx->mbox_idx)); + + WRITE_ONCE(generic_comm_base->command, +- cpu_to_le16(SLIMPRO_MSG_TYPE(msg[0]) | PCC_CMD_GENERATE_DB_INT)); ++ cpu_to_le16(SLIMPRO_MSG_TYPE(msg[0]) | PCC_CMD_GENERATE_DB_INTR)); + + status = le16_to_cpu(READ_ONCE(generic_comm_base->status)); +- status &= ~PCC_STS_CMD_COMPLETE; ++ status &= ~PCC_STATUS_CMD_COMPLETE; + WRITE_ONCE(generic_comm_base->status, cpu_to_le16(status)); + + /* Copy the message to the PCC comm space */ +diff --git a/drivers/iio/adc/ad7192.c b/drivers/iio/adc/ad7192.c +index b64fd365f83fb8..fa6810aa6a4a7a 100644 +--- a/drivers/iio/adc/ad7192.c ++++ b/drivers/iio/adc/ad7192.c +@@ -16,7 +16,9 @@ + #include + #include + #include +-#include ++#include ++#include ++#include + + #include + #include +@@ -360,19 +362,19 @@ static inline bool ad7192_valid_external_frequency(u32 freq) + freq <= AD7192_EXT_FREQ_MHZ_MAX); + } + +-static int ad7192_of_clock_select(struct ad7192_state *st) ++static int ad7192_clock_select(struct ad7192_state *st) + { +- struct device_node *np = st->sd.spi->dev.of_node; ++ struct device *dev = &st->sd.spi->dev; + unsigned int clock_sel; + + clock_sel = AD7192_CLK_INT; + + /* use internal clock */ + if (!st->mclk) { +- if (of_property_read_bool(np, "adi,int-clock-output-enable")) ++ if (device_property_read_bool(dev, "adi,int-clock-output-enable")) + clock_sel = AD7192_CLK_INT_CO; + } else { +- if (of_property_read_bool(np, "adi,clock-xtal")) ++ if (device_property_read_bool(dev, "adi,clock-xtal")) + clock_sel = AD7192_CLK_EXT_MCLK1_2; + else + clock_sel = AD7192_CLK_EXT_MCLK2; +@@ -381,7 +383,7 @@ static int ad7192_of_clock_select(struct ad7192_state *st) + return clock_sel; + } + +-static int ad7192_setup(struct iio_dev *indio_dev, struct device_node *np) ++static int ad7192_setup(struct iio_dev *indio_dev, struct device *dev) + { + struct ad7192_state *st = iio_priv(indio_dev); + bool rej60_en, refin2_en; +@@ -403,7 +405,7 @@ static int ad7192_setup(struct iio_dev *indio_dev, struct device_node *np) + id &= AD7192_ID_MASK; + + if (id != st->chip_info->chip_id) +- dev_warn(&st->sd.spi->dev, "device ID query failed (0x%X != 0x%X)\n", ++ dev_warn(dev, "device ID query failed (0x%X != 0x%X)\n", + id, st->chip_info->chip_id); + + st->mode = AD7192_MODE_SEL(AD7192_MODE_IDLE) | +@@ -412,31 +414,31 @@ static int ad7192_setup(struct iio_dev *indio_dev, struct device_node *np) + + st->conf = AD7192_CONF_GAIN(0); + +- rej60_en = of_property_read_bool(np, "adi,rejection-60-Hz-enable"); ++ rej60_en = device_property_read_bool(dev, "adi,rejection-60-Hz-enable"); + if (rej60_en) + st->mode |= AD7192_MODE_REJ60; + +- refin2_en = of_property_read_bool(np, "adi,refin2-pins-enable"); ++ refin2_en = device_property_read_bool(dev, "adi,refin2-pins-enable"); + if (refin2_en && st->chip_info->chip_id != CHIPID_AD7195) + st->conf |= AD7192_CONF_REFSEL; + + st->conf &= ~AD7192_CONF_CHOP; + st->f_order = AD7192_NO_SYNC_FILTER; + +- buf_en = of_property_read_bool(np, "adi,buffer-enable"); ++ buf_en = device_property_read_bool(dev, "adi,buffer-enable"); + if (buf_en) + st->conf |= AD7192_CONF_BUF; + +- bipolar = of_property_read_bool(np, "bipolar"); ++ bipolar = device_property_read_bool(dev, "bipolar"); + if (!bipolar) + st->conf |= AD7192_CONF_UNIPOLAR; + +- burnout_curr_en = of_property_read_bool(np, +- "adi,burnout-currents-enable"); ++ burnout_curr_en = device_property_read_bool(dev, ++ "adi,burnout-currents-enable"); + if (burnout_curr_en && buf_en) { + st->conf |= AD7192_CONF_BURN; + } else if (burnout_curr_en) { +- dev_warn(&st->sd.spi->dev, ++ dev_warn(dev, + "Can't enable burnout currents: see CHOP or buffer\n"); + } + +@@ -1036,9 +1038,10 @@ static int ad7192_probe(struct spi_device *spi) + } + st->int_vref_mv = ret / 1000; + +- st->chip_info = of_device_get_match_data(&spi->dev); ++ st->chip_info = spi_get_device_match_data(spi); + if (!st->chip_info) +- st->chip_info = (void *)spi_get_device_id(spi)->driver_data; ++ return -ENODEV; ++ + indio_dev->name = st->chip_info->name; + indio_dev->modes = INDIO_DIRECT_MODE; + +@@ -1065,7 +1068,7 @@ static int ad7192_probe(struct spi_device *spi) + if (IS_ERR(st->mclk)) + return PTR_ERR(st->mclk); + +- st->clock_sel = ad7192_of_clock_select(st); ++ st->clock_sel = ad7192_clock_select(st); + + if (st->clock_sel == AD7192_CLK_EXT_MCLK1_2 || + st->clock_sel == AD7192_CLK_EXT_MCLK2) { +@@ -1077,7 +1080,7 @@ static int ad7192_probe(struct spi_device *spi) + } + } + +- ret = ad7192_setup(indio_dev, spi->dev.of_node); ++ ret = ad7192_setup(indio_dev, &spi->dev); + if (ret) + return ret; + +diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c +index e836c9c477f675..c6053e82ecf6f3 100644 +--- a/drivers/infiniband/core/uverbs_cmd.c ++++ b/drivers/infiniband/core/uverbs_cmd.c +@@ -161,7 +161,7 @@ static const void __user *uverbs_request_next_ptr(struct uverbs_req_iter *iter, + { + const void __user *res = iter->cur; + +- if (iter->cur + len > iter->end) ++ if (len > iter->end - iter->cur) + return (void __force __user *)ERR_PTR(-ENOSPC); + iter->cur += len; + return res; +@@ -2009,11 +2009,13 @@ static int ib_uverbs_post_send(struct uverbs_attr_bundle *attrs) + ret = uverbs_request_start(attrs, &iter, &cmd, sizeof(cmd)); + if (ret) + return ret; +- wqes = uverbs_request_next_ptr(&iter, cmd.wqe_size * cmd.wr_count); ++ wqes = uverbs_request_next_ptr(&iter, size_mul(cmd.wqe_size, ++ cmd.wr_count)); + if (IS_ERR(wqes)) + return PTR_ERR(wqes); +- sgls = uverbs_request_next_ptr( +- &iter, cmd.sge_count * sizeof(struct ib_uverbs_sge)); ++ sgls = uverbs_request_next_ptr(&iter, ++ size_mul(cmd.sge_count, ++ sizeof(struct ib_uverbs_sge))); + if (IS_ERR(sgls)) + return PTR_ERR(sgls); + ret = uverbs_request_finish(&iter); +@@ -2199,11 +2201,11 @@ ib_uverbs_unmarshall_recv(struct uverbs_req_iter *iter, u32 wr_count, + if (wqe_size < sizeof(struct ib_uverbs_recv_wr)) + return ERR_PTR(-EINVAL); + +- wqes = uverbs_request_next_ptr(iter, wqe_size * wr_count); ++ wqes = uverbs_request_next_ptr(iter, size_mul(wqe_size, wr_count)); + if (IS_ERR(wqes)) + return ERR_CAST(wqes); +- sgls = uverbs_request_next_ptr( +- iter, sge_count * sizeof(struct ib_uverbs_sge)); ++ sgls = uverbs_request_next_ptr(iter, size_mul(sge_count, ++ sizeof(struct ib_uverbs_sge))); + if (IS_ERR(sgls)) + return ERR_CAST(sgls); + ret = uverbs_request_finish(iter); +diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +index df589726060144..13c65ec5825687 100644 +--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c ++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +@@ -147,7 +147,7 @@ int bnxt_re_query_device(struct ib_device *ibdev, + + ib_attr->vendor_id = rdev->en_dev->pdev->vendor; + ib_attr->vendor_part_id = rdev->en_dev->pdev->device; +- ib_attr->hw_ver = rdev->en_dev->pdev->subsystem_device; ++ ib_attr->hw_ver = rdev->en_dev->pdev->revision; + ib_attr->max_qp = dev_attr->max_qp; + ib_attr->max_qp_wr = dev_attr->max_qp_wqes; + ib_attr->device_cap_flags = +@@ -992,23 +992,22 @@ static int bnxt_re_setup_swqe_size(struct bnxt_re_qp *qp, + align = sizeof(struct sq_send_hdr); + ilsize = ALIGN(init_attr->cap.max_inline_data, align); + +- sq->wqe_size = bnxt_re_get_wqe_size(ilsize, sq->max_sge); +- if (sq->wqe_size > bnxt_re_get_swqe_size(dev_attr->max_qp_sges)) +- return -EINVAL; +- /* For gen p4 and gen p5 backward compatibility mode +- * wqe size is fixed to 128 bytes ++ /* For gen p4 and gen p5 fixed wqe compatibility mode ++ * wqe size is fixed to 128 bytes - ie 6 SGEs + */ +- if (sq->wqe_size < bnxt_re_get_swqe_size(dev_attr->max_qp_sges) && +- qplqp->wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC) +- sq->wqe_size = bnxt_re_get_swqe_size(dev_attr->max_qp_sges); ++ if (qplqp->wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC) { ++ sq->wqe_size = bnxt_re_get_swqe_size(BNXT_STATIC_MAX_SGE); ++ sq->max_sge = BNXT_STATIC_MAX_SGE; ++ } else { ++ sq->wqe_size = bnxt_re_get_wqe_size(ilsize, sq->max_sge); ++ if (sq->wqe_size > bnxt_re_get_swqe_size(dev_attr->max_qp_sges)) ++ return -EINVAL; ++ } + + if (init_attr->cap.max_inline_data) { + qplqp->max_inline_data = sq->wqe_size - + sizeof(struct sq_send_hdr); + init_attr->cap.max_inline_data = qplqp->max_inline_data; +- if (qplqp->wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC) +- sq->max_sge = qplqp->max_inline_data / +- sizeof(struct sq_sge); + } + + return 0; +@@ -1154,6 +1153,7 @@ static struct bnxt_re_qp *bnxt_re_create_shadow_qp + /* Shadow QP SQ depth should be same as QP1 RQ depth */ + qp->qplib_qp.sq.wqe_size = bnxt_re_get_wqe_size(0, 6); + qp->qplib_qp.sq.max_wqe = qp1_qp->rq.max_wqe; ++ qp->qplib_qp.sq.max_sw_wqe = qp1_qp->rq.max_wqe; + qp->qplib_qp.sq.max_sge = 2; + /* Q full delta can be 1 since it is internal QP */ + qp->qplib_qp.sq.q_full_delta = 1; +@@ -1165,6 +1165,7 @@ static struct bnxt_re_qp *bnxt_re_create_shadow_qp + + qp->qplib_qp.rq.wqe_size = bnxt_re_get_rwqe_size(6); + qp->qplib_qp.rq.max_wqe = qp1_qp->rq.max_wqe; ++ qp->qplib_qp.rq.max_sw_wqe = qp1_qp->rq.max_wqe; + qp->qplib_qp.rq.max_sge = qp1_qp->rq.max_sge; + /* Q full delta can be 1 since it is internal QP */ + qp->qplib_qp.rq.q_full_delta = 1; +@@ -1226,6 +1227,7 @@ static int bnxt_re_init_rq_attr(struct bnxt_re_qp *qp, + */ + entries = bnxt_re_init_depth(init_attr->cap.max_recv_wr + 1, uctx); + rq->max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + 1); ++ rq->max_sw_wqe = rq->max_wqe; + rq->q_full_delta = 0; + rq->sg_info.pgsize = PAGE_SIZE; + rq->sg_info.pgshft = PAGE_SHIFT; +@@ -1285,6 +1287,7 @@ static int bnxt_re_init_sq_attr(struct bnxt_re_qp *qp, + 0 : BNXT_QPLIB_RESERVED_QP_WRS; + entries = bnxt_re_init_depth(entries + diff + 1, uctx); + sq->max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + diff + 1); ++ sq->max_sw_wqe = bnxt_qplib_get_depth(sq, qplqp->wqe_mode, true); + sq->q_full_delta = diff + 1; + /* + * Reserving one slot for Phantom WQE. Application can +@@ -2055,18 +2058,20 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr, + } + } + +- if (qp_attr_mask & IB_QP_PATH_MTU) { +- qp->qplib_qp.modify_flags |= +- CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU; +- qp->qplib_qp.path_mtu = __from_ib_mtu(qp_attr->path_mtu); +- qp->qplib_qp.mtu = ib_mtu_enum_to_int(qp_attr->path_mtu); +- } else if (qp_attr->qp_state == IB_QPS_RTR) { +- qp->qplib_qp.modify_flags |= +- CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU; +- qp->qplib_qp.path_mtu = +- __from_ib_mtu(iboe_get_mtu(rdev->netdev->mtu)); +- qp->qplib_qp.mtu = +- ib_mtu_enum_to_int(iboe_get_mtu(rdev->netdev->mtu)); ++ if (qp_attr->qp_state == IB_QPS_RTR) { ++ enum ib_mtu qpmtu; ++ ++ qpmtu = iboe_get_mtu(rdev->netdev->mtu); ++ if (qp_attr_mask & IB_QP_PATH_MTU) { ++ if (ib_mtu_enum_to_int(qp_attr->path_mtu) > ++ ib_mtu_enum_to_int(qpmtu)) ++ return -EINVAL; ++ qpmtu = qp_attr->path_mtu; ++ } ++ ++ qp->qplib_qp.modify_flags |= CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU; ++ qp->qplib_qp.path_mtu = __from_ib_mtu(qpmtu); ++ qp->qplib_qp.mtu = ib_mtu_enum_to_int(qpmtu); + } + + if (qp_attr_mask & IB_QP_TIMEOUT) { +@@ -2153,6 +2158,7 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr, + entries = bnxt_re_init_depth(qp_attr->cap.max_recv_wr, uctx); + qp->qplib_qp.rq.max_wqe = + min_t(u32, entries, dev_attr->max_qp_wqes + 1); ++ qp->qplib_qp.rq.max_sw_wqe = qp->qplib_qp.rq.max_wqe; + qp->qplib_qp.rq.q_full_delta = qp->qplib_qp.rq.max_wqe - + qp_attr->cap.max_recv_wr; + qp->qplib_qp.rq.max_sge = qp_attr->cap.max_recv_sge; +@@ -2710,7 +2716,8 @@ static int bnxt_re_post_send_shadow_qp(struct bnxt_re_dev *rdev, + wr = wr->next; + } + bnxt_qplib_post_send_db(&qp->qplib_qp); +- bnxt_ud_qp_hw_stall_workaround(qp); ++ if (!bnxt_qplib_is_chip_gen_p5_p7(qp->rdev->chip_ctx)) ++ bnxt_ud_qp_hw_stall_workaround(qp); + spin_unlock_irqrestore(&qp->sq_lock, flags); + return rc; + } +@@ -2822,7 +2829,8 @@ int bnxt_re_post_send(struct ib_qp *ib_qp, const struct ib_send_wr *wr, + wr = wr->next; + } + bnxt_qplib_post_send_db(&qp->qplib_qp); +- bnxt_ud_qp_hw_stall_workaround(qp); ++ if (!bnxt_qplib_is_chip_gen_p5_p7(qp->rdev->chip_ctx)) ++ bnxt_ud_qp_hw_stall_workaround(qp); + spin_unlock_irqrestore(&qp->sq_lock, flags); + + return rc; +@@ -4167,9 +4175,6 @@ int bnxt_re_alloc_ucontext(struct ib_ucontext *ctx, struct ib_udata *udata) + resp.cqe_sz = sizeof(struct cq_base); + resp.max_cqd = dev_attr->max_cq_wqes; + +- resp.comp_mask |= BNXT_RE_UCNTX_CMASK_HAVE_MODE; +- resp.mode = rdev->chip_ctx->modes.wqe_mode; +- + if (rdev->chip_ctx->modes.db_push) + resp.comp_mask |= BNXT_RE_UCNTX_CMASK_WC_DPI_ENABLED; + +diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c +index 0373d0e9db6329..c7e51cc2ea2687 100644 +--- a/drivers/infiniband/hw/bnxt_re/main.c ++++ b/drivers/infiniband/hw/bnxt_re/main.c +@@ -128,13 +128,13 @@ static void bnxt_re_set_db_offset(struct bnxt_re_dev *rdev) + } + } + +-static void bnxt_re_set_drv_mode(struct bnxt_re_dev *rdev, u8 mode) ++static void bnxt_re_set_drv_mode(struct bnxt_re_dev *rdev) + { + struct bnxt_qplib_chip_ctx *cctx; + + cctx = rdev->chip_ctx; +- cctx->modes.wqe_mode = bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx) ? +- mode : BNXT_QPLIB_WQE_MODE_STATIC; ++ cctx->modes.wqe_mode = bnxt_qplib_is_chip_gen_p7(rdev->chip_ctx) ? ++ BNXT_QPLIB_WQE_MODE_VARIABLE : BNXT_QPLIB_WQE_MODE_STATIC; + if (bnxt_re_hwrm_qcaps(rdev)) + dev_err(rdev_to_dev(rdev), + "Failed to query hwrm qcaps\n"); +@@ -155,7 +155,7 @@ static void bnxt_re_destroy_chip_ctx(struct bnxt_re_dev *rdev) + kfree(chip_ctx); + } + +-static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev, u8 wqe_mode) ++static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev) + { + struct bnxt_qplib_chip_ctx *chip_ctx; + struct bnxt_en_dev *en_dev; +@@ -177,7 +177,7 @@ static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev, u8 wqe_mode) + rdev->qplib_res.dattr = &rdev->dev_attr; + rdev->qplib_res.is_vf = BNXT_EN_VF(en_dev); + +- bnxt_re_set_drv_mode(rdev, wqe_mode); ++ bnxt_re_set_drv_mode(rdev); + + bnxt_re_set_db_offset(rdev); + rc = bnxt_qplib_map_db_bar(&rdev->qplib_res); +@@ -1440,7 +1440,7 @@ static void bnxt_re_worker(struct work_struct *work) + schedule_delayed_work(&rdev->worker, msecs_to_jiffies(30000)); + } + +-static int bnxt_re_dev_init(struct bnxt_re_dev *rdev, u8 wqe_mode) ++static int bnxt_re_dev_init(struct bnxt_re_dev *rdev) + { + struct bnxt_re_ring_attr rattr = {}; + struct bnxt_qplib_creq_ctx *creq; +@@ -1458,7 +1458,7 @@ static int bnxt_re_dev_init(struct bnxt_re_dev *rdev, u8 wqe_mode) + } + set_bit(BNXT_RE_FLAG_NETDEV_REGISTERED, &rdev->flags); + +- rc = bnxt_re_setup_chip_ctx(rdev, wqe_mode); ++ rc = bnxt_re_setup_chip_ctx(rdev); + if (rc) { + bnxt_unregister_dev(rdev->en_dev); + clear_bit(BNXT_RE_FLAG_NETDEV_REGISTERED, &rdev->flags); +@@ -1609,7 +1609,7 @@ static int bnxt_re_dev_init(struct bnxt_re_dev *rdev, u8 wqe_mode) + return rc; + } + +-static int bnxt_re_add_device(struct auxiliary_device *adev, u8 wqe_mode) ++static int bnxt_re_add_device(struct auxiliary_device *adev) + { + struct bnxt_aux_priv *aux_priv = + container_of(adev, struct bnxt_aux_priv, aux_dev); +@@ -1626,7 +1626,7 @@ static int bnxt_re_add_device(struct auxiliary_device *adev, u8 wqe_mode) + goto exit; + } + +- rc = bnxt_re_dev_init(rdev, wqe_mode); ++ rc = bnxt_re_dev_init(rdev); + if (rc) + goto re_dev_dealloc; + +@@ -1756,7 +1756,8 @@ static int bnxt_re_probe(struct auxiliary_device *adev, + int rc; + + mutex_lock(&bnxt_re_mutex); +- rc = bnxt_re_add_device(adev, BNXT_QPLIB_WQE_MODE_STATIC); ++ ++ rc = bnxt_re_add_device(adev); + if (rc) { + mutex_unlock(&bnxt_re_mutex); + return rc; +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c +index b624c255eee6fa..871a49315c880f 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c +@@ -639,13 +639,6 @@ int bnxt_qplib_create_srq(struct bnxt_qplib_res *res, + rc = bnxt_qplib_alloc_init_hwq(&srq->hwq, &hwq_attr); + if (rc) + return rc; +- +- srq->swq = kcalloc(srq->hwq.max_elements, sizeof(*srq->swq), +- GFP_KERNEL); +- if (!srq->swq) { +- rc = -ENOMEM; +- goto fail; +- } + srq->dbinfo.flags = 0; + bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req, + CMDQ_BASE_OPCODE_CREATE_SRQ, +@@ -674,9 +667,17 @@ int bnxt_qplib_create_srq(struct bnxt_qplib_res *res, + spin_lock_init(&srq->lock); + srq->start_idx = 0; + srq->last_idx = srq->hwq.max_elements - 1; +- for (idx = 0; idx < srq->hwq.max_elements; idx++) +- srq->swq[idx].next_idx = idx + 1; +- srq->swq[srq->last_idx].next_idx = -1; ++ if (!srq->hwq.is_user) { ++ srq->swq = kcalloc(srq->hwq.max_elements, sizeof(*srq->swq), ++ GFP_KERNEL); ++ if (!srq->swq) { ++ rc = -ENOMEM; ++ goto fail; ++ } ++ for (idx = 0; idx < srq->hwq.max_elements; idx++) ++ srq->swq[idx].next_idx = idx + 1; ++ srq->swq[srq->last_idx].next_idx = -1; ++ } + + srq->id = le32_to_cpu(resp.xid); + srq->dbinfo.hwq = &srq->hwq; +@@ -806,13 +807,13 @@ static int bnxt_qplib_alloc_init_swq(struct bnxt_qplib_q *que) + { + int indx; + +- que->swq = kcalloc(que->max_wqe, sizeof(*que->swq), GFP_KERNEL); ++ que->swq = kcalloc(que->max_sw_wqe, sizeof(*que->swq), GFP_KERNEL); + if (!que->swq) + return -ENOMEM; + + que->swq_start = 0; +- que->swq_last = que->max_wqe - 1; +- for (indx = 0; indx < que->max_wqe; indx++) ++ que->swq_last = que->max_sw_wqe - 1; ++ for (indx = 0; indx < que->max_sw_wqe; indx++) + que->swq[indx].next_idx = indx + 1; + que->swq[que->swq_last].next_idx = 0; /* Make it circular */ + que->swq_last = 0; +@@ -848,7 +849,7 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) + hwq_attr.res = res; + hwq_attr.sginfo = &sq->sg_info; + hwq_attr.stride = sizeof(struct sq_sge); +- hwq_attr.depth = bnxt_qplib_get_depth(sq); ++ hwq_attr.depth = bnxt_qplib_get_depth(sq, qp->wqe_mode, false); + hwq_attr.type = HWQ_TYPE_QUEUE; + rc = bnxt_qplib_alloc_init_hwq(&sq->hwq, &hwq_attr); + if (rc) +@@ -876,7 +877,7 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) + hwq_attr.res = res; + hwq_attr.sginfo = &rq->sg_info; + hwq_attr.stride = sizeof(struct sq_sge); +- hwq_attr.depth = bnxt_qplib_get_depth(rq); ++ hwq_attr.depth = bnxt_qplib_get_depth(rq, qp->wqe_mode, false); + hwq_attr.type = HWQ_TYPE_QUEUE; + rc = bnxt_qplib_alloc_init_hwq(&rq->hwq, &hwq_attr); + if (rc) +@@ -980,9 +981,7 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) + u32 tbl_indx; + u16 nsge; + +- if (res->dattr) +- qp->dev_cap_flags = res->dattr->dev_cap_flags; +- ++ qp->is_host_msn_tbl = _is_host_msn_table(res->dattr->dev_cap_flags2); + sq->dbinfo.flags = 0; + bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req, + CMDQ_BASE_OPCODE_CREATE_QP, +@@ -999,7 +998,7 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) + sizeof(struct sq_psn_search_ext) : + sizeof(struct sq_psn_search); + +- if (BNXT_RE_HW_RETX(qp->dev_cap_flags)) { ++ if (qp->is_host_msn_tbl) { + psn_sz = sizeof(struct sq_msn_search); + qp->msn = 0; + } +@@ -1008,13 +1007,18 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) + hwq_attr.res = res; + hwq_attr.sginfo = &sq->sg_info; + hwq_attr.stride = sizeof(struct sq_sge); +- hwq_attr.depth = bnxt_qplib_get_depth(sq); ++ hwq_attr.depth = bnxt_qplib_get_depth(sq, qp->wqe_mode, true); + hwq_attr.aux_stride = psn_sz; + hwq_attr.aux_depth = psn_sz ? bnxt_qplib_set_sq_size(sq, qp->wqe_mode) + : 0; + /* Update msn tbl size */ +- if (BNXT_RE_HW_RETX(qp->dev_cap_flags) && psn_sz) { +- hwq_attr.aux_depth = roundup_pow_of_two(bnxt_qplib_set_sq_size(sq, qp->wqe_mode)); ++ if (qp->is_host_msn_tbl && psn_sz) { ++ if (qp->wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC) ++ hwq_attr.aux_depth = ++ roundup_pow_of_two(bnxt_qplib_set_sq_size(sq, qp->wqe_mode)); ++ else ++ hwq_attr.aux_depth = ++ roundup_pow_of_two(bnxt_qplib_set_sq_size(sq, qp->wqe_mode)) / 2; + qp->msn_tbl_sz = hwq_attr.aux_depth; + qp->msn = 0; + } +@@ -1024,13 +1028,14 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) + if (rc) + return rc; + +- rc = bnxt_qplib_alloc_init_swq(sq); +- if (rc) +- goto fail_sq; +- +- if (psn_sz) +- bnxt_qplib_init_psn_ptr(qp, psn_sz); ++ if (!sq->hwq.is_user) { ++ rc = bnxt_qplib_alloc_init_swq(sq); ++ if (rc) ++ goto fail_sq; + ++ if (psn_sz) ++ bnxt_qplib_init_psn_ptr(qp, psn_sz); ++ } + req.sq_size = cpu_to_le32(bnxt_qplib_set_sq_size(sq, qp->wqe_mode)); + pbl = &sq->hwq.pbl[PBL_LVL_0]; + req.sq_pbl = cpu_to_le64(pbl->pg_map_arr[0]); +@@ -1049,16 +1054,18 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) + hwq_attr.res = res; + hwq_attr.sginfo = &rq->sg_info; + hwq_attr.stride = sizeof(struct sq_sge); +- hwq_attr.depth = bnxt_qplib_get_depth(rq); ++ hwq_attr.depth = bnxt_qplib_get_depth(rq, qp->wqe_mode, false); + hwq_attr.aux_stride = 0; + hwq_attr.aux_depth = 0; + hwq_attr.type = HWQ_TYPE_QUEUE; + rc = bnxt_qplib_alloc_init_hwq(&rq->hwq, &hwq_attr); + if (rc) + goto sq_swq; +- rc = bnxt_qplib_alloc_init_swq(rq); +- if (rc) +- goto fail_rq; ++ if (!rq->hwq.is_user) { ++ rc = bnxt_qplib_alloc_init_swq(rq); ++ if (rc) ++ goto fail_rq; ++ } + + req.rq_size = cpu_to_le32(rq->max_wqe); + pbl = &rq->hwq.pbl[PBL_LVL_0]; +@@ -1154,9 +1161,11 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) + rq->dbinfo.db = qp->dpi->dbr; + rq->dbinfo.max_slot = bnxt_qplib_set_rq_max_slot(rq->wqe_size); + } ++ spin_lock_bh(&rcfw->tbl_lock); + tbl_indx = map_qp_id_to_tbl_indx(qp->id, rcfw); + rcfw->qp_tbl[tbl_indx].qp_id = qp->id; + rcfw->qp_tbl[tbl_indx].qp_handle = (void *)qp; ++ spin_unlock_bh(&rcfw->tbl_lock); + + return 0; + fail: +@@ -1638,7 +1647,7 @@ static void bnxt_qplib_fill_psn_search(struct bnxt_qplib_qp *qp, + if (!swq->psn_search) + return; + /* Handle MSN differently on cap flags */ +- if (BNXT_RE_HW_RETX(qp->dev_cap_flags)) { ++ if (qp->is_host_msn_tbl) { + bnxt_qplib_fill_msn_search(qp, wqe, swq); + return; + } +@@ -1820,7 +1829,7 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp, + } + + swq = bnxt_qplib_get_swqe(sq, &wqe_idx); +- bnxt_qplib_pull_psn_buff(qp, sq, swq, BNXT_RE_HW_RETX(qp->dev_cap_flags)); ++ bnxt_qplib_pull_psn_buff(qp, sq, swq, qp->is_host_msn_tbl); + + idx = 0; + swq->slot_idx = hwq->prod; +@@ -2010,7 +2019,7 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp, + rc = -EINVAL; + goto done; + } +- if (!BNXT_RE_HW_RETX(qp->dev_cap_flags) || msn_update) { ++ if (!qp->is_host_msn_tbl || msn_update) { + swq->next_psn = sq->psn & BTH_PSN_MASK; + bnxt_qplib_fill_psn_search(qp, wqe, swq); + } +@@ -2491,7 +2500,7 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq, + } + sq = &qp->sq; + +- cqe_sq_cons = le16_to_cpu(hwcqe->sq_cons_idx) % sq->max_wqe; ++ cqe_sq_cons = le16_to_cpu(hwcqe->sq_cons_idx) % sq->max_sw_wqe; + if (qp->sq.flushed) { + dev_dbg(&cq->hwq.pdev->dev, + "%s: QP in Flush QP = %p\n", __func__, qp); +@@ -2534,10 +2543,12 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq, + bnxt_qplib_add_flush_qp(qp); + } else { + /* Before we complete, do WA 9060 */ +- if (do_wa9060(qp, cq, cq_cons, sq->swq_last, +- cqe_sq_cons)) { +- *lib_qp = qp; +- goto out; ++ if (!bnxt_qplib_is_chip_gen_p5_p7(qp->cctx)) { ++ if (do_wa9060(qp, cq, cq_cons, sq->swq_last, ++ cqe_sq_cons)) { ++ *lib_qp = qp; ++ goto out; ++ } + } + if (swq->flags & SQ_SEND_FLAGS_SIGNAL_COMP) { + cqe->status = CQ_REQ_STATUS_OK; +@@ -2881,7 +2892,7 @@ static int bnxt_qplib_cq_process_terminal(struct bnxt_qplib_cq *cq, + cqe_cons = le16_to_cpu(hwcqe->sq_cons_idx); + if (cqe_cons == 0xFFFF) + goto do_rq; +- cqe_cons %= sq->max_wqe; ++ cqe_cons %= sq->max_sw_wqe; + + if (qp->sq.flushed) { + dev_dbg(&cq->hwq.pdev->dev, +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h +index 5d4c49089a20f4..b5c53e864fbb39 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h ++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h +@@ -113,7 +113,6 @@ struct bnxt_qplib_sge { + u32 size; + }; + +-#define BNXT_QPLIB_QP_MAX_SGL 6 + struct bnxt_qplib_swq { + u64 wr_id; + int next_idx; +@@ -153,7 +152,7 @@ struct bnxt_qplib_swqe { + #define BNXT_QPLIB_SWQE_FLAGS_UC_FENCE BIT(2) + #define BNXT_QPLIB_SWQE_FLAGS_SOLICIT_EVENT BIT(3) + #define BNXT_QPLIB_SWQE_FLAGS_INLINE BIT(4) +- struct bnxt_qplib_sge sg_list[BNXT_QPLIB_QP_MAX_SGL]; ++ struct bnxt_qplib_sge sg_list[BNXT_VAR_MAX_SGE]; + int num_sge; + /* Max inline data is 96 bytes */ + u32 inline_len; +@@ -251,6 +250,7 @@ struct bnxt_qplib_q { + struct bnxt_qplib_db_info dbinfo; + struct bnxt_qplib_sg_info sg_info; + u32 max_wqe; ++ u32 max_sw_wqe; + u16 wqe_size; + u16 q_full_delta; + u16 max_sge; +@@ -340,7 +340,7 @@ struct bnxt_qplib_qp { + struct list_head rq_flush; + u32 msn; + u32 msn_tbl_sz; +- u16 dev_cap_flags; ++ bool is_host_msn_tbl; + }; + + #define BNXT_QPLIB_MAX_CQE_ENTRY_SIZE sizeof(struct cq_base) +@@ -585,15 +585,22 @@ static inline void bnxt_qplib_swq_mod_start(struct bnxt_qplib_q *que, u32 idx) + que->swq_start = que->swq[idx].next_idx; + } + +-static inline u32 bnxt_qplib_get_depth(struct bnxt_qplib_q *que) ++static inline u32 bnxt_qplib_get_depth(struct bnxt_qplib_q *que, u8 wqe_mode, bool is_sq) + { +- return (que->wqe_size * que->max_wqe) / sizeof(struct sq_sge); ++ u32 slots; ++ ++ /* Queue depth is the number of slots. */ ++ slots = (que->wqe_size * que->max_wqe) / sizeof(struct sq_sge); ++ /* For variable WQE mode, need to align the slots to 256 */ ++ if (wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE && is_sq) ++ slots = ALIGN(slots, BNXT_VAR_MAX_SLOT_ALIGN); ++ return slots; + } + + static inline u32 bnxt_qplib_set_sq_size(struct bnxt_qplib_q *que, u8 wqe_mode) + { + return (wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC) ? +- que->max_wqe : bnxt_qplib_get_depth(que); ++ que->max_wqe : bnxt_qplib_get_depth(que, wqe_mode, true); + } + + static inline u32 bnxt_qplib_set_sq_max_slot(u8 wqe_mode) +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_res.h b/drivers/infiniband/hw/bnxt_re/qplib_res.h +index f9e7aa3757cfb2..c2152122a4329d 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_res.h ++++ b/drivers/infiniband/hw/bnxt_re/qplib_res.h +@@ -523,6 +523,12 @@ static inline bool _is_hw_retx_supported(u16 dev_cap_flags) + + #define BNXT_RE_HW_RETX(a) _is_hw_retx_supported((a)) + ++static inline bool _is_host_msn_table(u16 dev_cap_ext_flags2) ++{ ++ return (dev_cap_ext_flags2 & CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_MASK) == ++ CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_HOST_MSN_TABLE; ++} ++ + static inline u8 bnxt_qplib_dbr_pacing_en(struct bnxt_qplib_chip_ctx *cctx) + { + return cctx->modes.dbr_pacing; +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +index 0b98577cd7082e..74c3f6b26c4d3a 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +@@ -95,11 +95,13 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw, + struct bnxt_qplib_cmdqmsg msg = {}; + struct creq_query_func_resp_sb *sb; + struct bnxt_qplib_rcfw_sbuf sbuf; ++ struct bnxt_qplib_chip_ctx *cctx; + struct cmdq_query_func req = {}; + u8 *tqm_alloc; + int i, rc; + u32 temp; + ++ cctx = rcfw->res->cctx; + bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req, + CMDQ_BASE_OPCODE_QUERY_FUNC, + sizeof(req)); +@@ -127,14 +129,21 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw, + attr->max_qp_init_rd_atom = + sb->max_qp_init_rd_atom > BNXT_QPLIB_MAX_OUT_RD_ATOM ? + BNXT_QPLIB_MAX_OUT_RD_ATOM : sb->max_qp_init_rd_atom; +- attr->max_qp_wqes = le16_to_cpu(sb->max_qp_wr); +- /* +- * 128 WQEs needs to be reserved for the HW (8916). Prevent +- * reporting the max number +- */ +- attr->max_qp_wqes -= BNXT_QPLIB_RESERVED_QP_WRS + 1; +- attr->max_qp_sges = bnxt_qplib_is_chip_gen_p5_p7(rcfw->res->cctx) ? +- 6 : sb->max_sge; ++ attr->max_qp_wqes = le16_to_cpu(sb->max_qp_wr) - 1; ++ if (!bnxt_qplib_is_chip_gen_p5_p7(rcfw->res->cctx)) { ++ /* ++ * 128 WQEs needs to be reserved for the HW (8916). Prevent ++ * reporting the max number on legacy devices ++ */ ++ attr->max_qp_wqes -= BNXT_QPLIB_RESERVED_QP_WRS + 1; ++ } ++ ++ /* Adjust for max_qp_wqes for variable wqe */ ++ if (cctx->modes.wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE) ++ attr->max_qp_wqes = BNXT_VAR_MAX_WQE - 1; ++ ++ attr->max_qp_sges = cctx->modes.wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE ? ++ min_t(u32, sb->max_sge_var_wqe, BNXT_VAR_MAX_SGE) : 6; + attr->max_cq = le32_to_cpu(sb->max_cq); + attr->max_cq_wqes = le32_to_cpu(sb->max_cqe); + if (!bnxt_qplib_is_chip_gen_p7(rcfw->res->cctx)) +@@ -165,6 +174,7 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw, + attr->max_sgid = le32_to_cpu(sb->max_gid); + attr->max_sgid = min_t(u32, BNXT_QPLIB_NUM_GIDS_SUPPORTED, 2 * attr->max_sgid); + attr->dev_cap_flags = le16_to_cpu(sb->dev_cap_flags); ++ attr->dev_cap_flags2 = le16_to_cpu(sb->dev_cap_ext_flags_2); + + bnxt_qplib_query_version(rcfw, attr->fw_ver); + +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.h b/drivers/infiniband/hw/bnxt_re/qplib_sp.h +index 755765e68eaab2..aeacd0a9a92cc4 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.h ++++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.h +@@ -40,6 +40,7 @@ + #ifndef __BNXT_QPLIB_SP_H__ + #define __BNXT_QPLIB_SP_H__ + ++#include + #define BNXT_QPLIB_RESERVED_QP_WRS 128 + + struct bnxt_qplib_dev_attr { +@@ -73,6 +74,7 @@ struct bnxt_qplib_dev_attr { + u8 tqm_alloc_reqs[MAX_TQM_ALLOC_REQ]; + bool is_atomic; + u16 dev_cap_flags; ++ u16 dev_cap_flags2; + u32 max_dpi; + }; + +@@ -351,4 +353,11 @@ int bnxt_qplib_qext_stat(struct bnxt_qplib_rcfw *rcfw, u32 fid, + int bnxt_qplib_modify_cc(struct bnxt_qplib_res *res, + struct bnxt_qplib_cc_param *cc_param); + ++#define BNXT_VAR_MAX_WQE 4352 ++#define BNXT_VAR_MAX_SLOT_ALIGN 256 ++#define BNXT_VAR_MAX_SGE 13 ++#define BNXT_RE_MAX_RQ_WQES 65536 ++ ++#define BNXT_STATIC_MAX_SGE 6 ++ + #endif /* __BNXT_QPLIB_SP_H__*/ +diff --git a/drivers/infiniband/hw/bnxt_re/roce_hsi.h b/drivers/infiniband/hw/bnxt_re/roce_hsi.h +index 2909608f4b5de4..cb4e7e19fbaf08 100644 +--- a/drivers/infiniband/hw/bnxt_re/roce_hsi.h ++++ b/drivers/infiniband/hw/bnxt_re/roce_hsi.h +@@ -2157,8 +2157,36 @@ struct creq_query_func_resp_sb { + __le32 tqm_alloc_reqs[12]; + __le32 max_dpi; + u8 max_sge_var_wqe; +- u8 reserved_8; ++ u8 dev_cap_ext_flags; ++ #define CREQ_QUERY_FUNC_RESP_SB_ATOMIC_OPS_NOT_SUPPORTED 0x1UL ++ #define CREQ_QUERY_FUNC_RESP_SB_DRV_VERSION_RGTR_SUPPORTED 0x2UL ++ #define CREQ_QUERY_FUNC_RESP_SB_CREATE_QP_BATCH_SUPPORTED 0x4UL ++ #define CREQ_QUERY_FUNC_RESP_SB_DESTROY_QP_BATCH_SUPPORTED 0x8UL ++ #define CREQ_QUERY_FUNC_RESP_SB_ROCE_STATS_EXT_CTX_SUPPORTED 0x10UL ++ #define CREQ_QUERY_FUNC_RESP_SB_CREATE_SRQ_SGE_SUPPORTED 0x20UL ++ #define CREQ_QUERY_FUNC_RESP_SB_FIXED_SIZE_WQE_DISABLED 0x40UL ++ #define CREQ_QUERY_FUNC_RESP_SB_DCN_SUPPORTED 0x80UL + __le16 max_inline_data_var_wqe; ++ __le32 start_qid; ++ u8 max_msn_table_size; ++ u8 reserved8_1; ++ __le16 dev_cap_ext_flags_2; ++ #define CREQ_QUERY_FUNC_RESP_SB_OPTIMIZE_MODIFY_QP_SUPPORTED 0x1UL ++ #define CREQ_QUERY_FUNC_RESP_SB_CHANGE_UDP_SRC_PORT_WQE_SUPPORTED 0x2UL ++ #define CREQ_QUERY_FUNC_RESP_SB_CQ_COALESCING_SUPPORTED 0x4UL ++ #define CREQ_QUERY_FUNC_RESP_SB_MEMORY_REGION_RO_SUPPORTED 0x8UL ++ #define CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_MASK 0x30UL ++ #define CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_SFT 4 ++ #define CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_HOST_PSN_TABLE (0x0UL << 4) ++ #define CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_HOST_MSN_TABLE (0x1UL << 4) ++ #define CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_IQM_MSN_TABLE (0x2UL << 4) ++ #define CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_LAST \ ++ CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_IQM_MSN_TABLE ++ __le16 max_xp_qp_size; ++ __le16 create_qp_batch_size; ++ __le16 destroy_qp_batch_size; ++ __le16 reserved16; ++ __le64 reserved64; + }; + + /* cmdq_set_func_resources (size:448b/56B) */ +diff --git a/drivers/infiniband/hw/hns/hns_roce_alloc.c b/drivers/infiniband/hw/hns/hns_roce_alloc.c +index 11a78ceae56891..950c133d4220e7 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_alloc.c ++++ b/drivers/infiniband/hw/hns/hns_roce_alloc.c +@@ -153,8 +153,7 @@ int hns_roce_get_kmem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs, + return total; + } + +-int hns_roce_get_umem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs, +- int buf_cnt, struct ib_umem *umem, ++int hns_roce_get_umem_bufs(dma_addr_t *bufs, int buf_cnt, struct ib_umem *umem, + unsigned int page_shift) + { + struct ib_block_iter biter; +diff --git a/drivers/infiniband/hw/hns/hns_roce_cq.c b/drivers/infiniband/hw/hns/hns_roce_cq.c +index 9b91731a620795..5e0d78f4e54548 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_cq.c ++++ b/drivers/infiniband/hw/hns/hns_roce_cq.c +@@ -133,14 +133,12 @@ static int alloc_cqc(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq) + struct hns_roce_cq_table *cq_table = &hr_dev->cq_table; + struct ib_device *ibdev = &hr_dev->ib_dev; + u64 mtts[MTT_MIN_COUNT] = {}; +- dma_addr_t dma_handle; + int ret; + +- ret = hns_roce_mtr_find(hr_dev, &hr_cq->mtr, 0, mtts, ARRAY_SIZE(mtts), +- &dma_handle); +- if (!ret) { ++ ret = hns_roce_mtr_find(hr_dev, &hr_cq->mtr, 0, mtts, ARRAY_SIZE(mtts)); ++ if (ret) { + ibdev_err(ibdev, "failed to find CQ mtr, ret = %d.\n", ret); +- return -EINVAL; ++ return ret; + } + + /* Get CQC memory HEM(Hardware Entry Memory) table */ +@@ -157,7 +155,8 @@ static int alloc_cqc(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq) + goto err_put; + } + +- ret = hns_roce_create_cqc(hr_dev, hr_cq, mtts, dma_handle); ++ ret = hns_roce_create_cqc(hr_dev, hr_cq, mtts, ++ hns_roce_get_mtr_ba(&hr_cq->mtr)); + if (ret) + goto err_xa; + +diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h +index 21ef00fdb65631..03b6546f63cdc6 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_device.h ++++ b/drivers/infiniband/hw/hns/hns_roce_device.h +@@ -892,8 +892,7 @@ struct hns_roce_hw { + int (*rereg_write_mtpt)(struct hns_roce_dev *hr_dev, + struct hns_roce_mr *mr, int flags, + void *mb_buf); +- int (*frmr_write_mtpt)(struct hns_roce_dev *hr_dev, void *mb_buf, +- struct hns_roce_mr *mr); ++ int (*frmr_write_mtpt)(void *mb_buf, struct hns_roce_mr *mr); + int (*mw_write_mtpt)(void *mb_buf, struct hns_roce_mw *mw); + void (*write_cqc)(struct hns_roce_dev *hr_dev, + struct hns_roce_cq *hr_cq, void *mb_buf, u64 *mtts, +@@ -1129,8 +1128,13 @@ void hns_roce_cmd_use_polling(struct hns_roce_dev *hr_dev); + + /* hns roce hw need current block and next block addr from mtt */ + #define MTT_MIN_COUNT 2 ++static inline dma_addr_t hns_roce_get_mtr_ba(struct hns_roce_mtr *mtr) ++{ ++ return mtr->hem_cfg.root_ba; ++} ++ + int hns_roce_mtr_find(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr, +- u32 offset, u64 *mtt_buf, int mtt_max, u64 *base_addr); ++ u32 offset, u64 *mtt_buf, int mtt_max); + int hns_roce_mtr_create(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr, + struct hns_roce_buf_attr *buf_attr, + unsigned int page_shift, struct ib_udata *udata, +@@ -1188,7 +1192,7 @@ struct hns_roce_buf *hns_roce_buf_alloc(struct hns_roce_dev *hr_dev, u32 size, + int hns_roce_get_kmem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs, + int buf_cnt, struct hns_roce_buf *buf, + unsigned int page_shift); +-int hns_roce_get_umem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs, ++int hns_roce_get_umem_bufs(dma_addr_t *bufs, + int buf_cnt, struct ib_umem *umem, + unsigned int page_shift); + +diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c +index 0ab514c49d5e6e..51ab6041ca91bc 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hem.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hem.c +@@ -986,6 +986,7 @@ struct hns_roce_hem_item { + size_t count; /* max ba numbers */ + int start; /* start buf offset in this hem */ + int end; /* end buf offset in this hem */ ++ bool exist_bt; + }; + + /* All HEM items are linked in a tree structure */ +@@ -1014,6 +1015,7 @@ hem_list_alloc_item(struct hns_roce_dev *hr_dev, int start, int end, int count, + } + } + ++ hem->exist_bt = exist_bt; + hem->count = count; + hem->start = start; + hem->end = end; +@@ -1024,34 +1026,32 @@ hem_list_alloc_item(struct hns_roce_dev *hr_dev, int start, int end, int count, + } + + static void hem_list_free_item(struct hns_roce_dev *hr_dev, +- struct hns_roce_hem_item *hem, bool exist_bt) ++ struct hns_roce_hem_item *hem) + { +- if (exist_bt) ++ if (hem->exist_bt) + dma_free_coherent(hr_dev->dev, hem->count * BA_BYTE_LEN, + hem->addr, hem->dma_addr); + kfree(hem); + } + + static void hem_list_free_all(struct hns_roce_dev *hr_dev, +- struct list_head *head, bool exist_bt) ++ struct list_head *head) + { + struct hns_roce_hem_item *hem, *temp_hem; + + list_for_each_entry_safe(hem, temp_hem, head, list) { + list_del(&hem->list); +- hem_list_free_item(hr_dev, hem, exist_bt); ++ hem_list_free_item(hr_dev, hem); + } + } + +-static void hem_list_link_bt(struct hns_roce_dev *hr_dev, void *base_addr, +- u64 table_addr) ++static void hem_list_link_bt(void *base_addr, u64 table_addr) + { + *(u64 *)(base_addr) = table_addr; + } + + /* assign L0 table address to hem from root bt */ +-static void hem_list_assign_bt(struct hns_roce_dev *hr_dev, +- struct hns_roce_hem_item *hem, void *cpu_addr, ++static void hem_list_assign_bt(struct hns_roce_hem_item *hem, void *cpu_addr, + u64 phy_addr) + { + hem->addr = cpu_addr; +@@ -1141,6 +1141,10 @@ int hns_roce_hem_list_calc_root_ba(const struct hns_roce_buf_region *regions, + + for (i = 0; i < region_cnt; i++) { + r = (struct hns_roce_buf_region *)®ions[i]; ++ /* when r->hopnum = 0, the region should not occupy root_ba. */ ++ if (!r->hopnum) ++ continue; ++ + if (r->hopnum > 1) { + step = hem_list_calc_ba_range(r->hopnum, 1, unit); + if (step > 0) +@@ -1222,8 +1226,7 @@ static int hem_list_alloc_mid_bt(struct hns_roce_dev *hr_dev, + if (level > 1) { + pre = hem_ptrs[level - 1]; + step = (cur->start - pre->start) / step * BA_BYTE_LEN; +- hem_list_link_bt(hr_dev, pre->addr + step, +- cur->dma_addr); ++ hem_list_link_bt(pre->addr + step, cur->dma_addr); + } + } + +@@ -1235,7 +1238,7 @@ static int hem_list_alloc_mid_bt(struct hns_roce_dev *hr_dev, + + err_exit: + for (level = 1; level < hopnum; level++) +- hem_list_free_all(hr_dev, &temp_list[level], true); ++ hem_list_free_all(hr_dev, &temp_list[level]); + + return ret; + } +@@ -1276,16 +1279,26 @@ static int alloc_fake_root_bt(struct hns_roce_dev *hr_dev, void *cpu_base, + { + struct hns_roce_hem_item *hem; + ++ /* This is on the has_mtt branch, if r->hopnum ++ * is 0, there is no root_ba to reuse for the ++ * region's fake hem, so a dma_alloc request is ++ * necessary here. ++ */ + hem = hem_list_alloc_item(hr_dev, r->offset, r->offset + r->count - 1, +- r->count, false); ++ r->count, !r->hopnum); + if (!hem) + return -ENOMEM; + +- hem_list_assign_bt(hr_dev, hem, cpu_base, phy_base); ++ /* The root_ba can be reused only when r->hopnum > 0. */ ++ if (r->hopnum) ++ hem_list_assign_bt(hem, cpu_base, phy_base); + list_add(&hem->list, branch_head); + list_add(&hem->sibling, leaf_head); + +- return r->count; ++ /* If r->hopnum == 0, 0 is returned, ++ * so that the root_bt entry is not occupied. ++ */ ++ return r->hopnum ? r->count : 0; + } + + static int setup_middle_bt(struct hns_roce_dev *hr_dev, void *cpu_base, +@@ -1304,7 +1317,7 @@ static int setup_middle_bt(struct hns_roce_dev *hr_dev, void *cpu_base, + /* if exist mid bt, link L1 to L0 */ + list_for_each_entry_safe(hem, temp_hem, branch_head, list) { + offset = (hem->start - r->offset) / step * BA_BYTE_LEN; +- hem_list_link_bt(hr_dev, cpu_base + offset, hem->dma_addr); ++ hem_list_link_bt(cpu_base + offset, hem->dma_addr); + total++; + } + +@@ -1329,7 +1342,7 @@ setup_root_hem(struct hns_roce_dev *hr_dev, struct hns_roce_hem_list *hem_list, + return -ENOMEM; + + total = 0; +- for (i = 0; i < region_cnt && total < max_ba_num; i++) { ++ for (i = 0; i < region_cnt && total <= max_ba_num; i++) { + r = ®ions[i]; + if (!r->count) + continue; +@@ -1395,9 +1408,9 @@ static int hem_list_alloc_root_bt(struct hns_roce_dev *hr_dev, + region_cnt); + if (ret) { + for (i = 0; i < region_cnt; i++) +- hem_list_free_all(hr_dev, &head.branch[i], false); ++ hem_list_free_all(hr_dev, &head.branch[i]); + +- hem_list_free_all(hr_dev, &head.root, true); ++ hem_list_free_all(hr_dev, &head.root); + } + + return ret; +@@ -1460,10 +1473,9 @@ void hns_roce_hem_list_release(struct hns_roce_dev *hr_dev, + + for (i = 0; i < HNS_ROCE_MAX_BT_REGION; i++) + for (j = 0; j < HNS_ROCE_MAX_BT_LEVEL; j++) +- hem_list_free_all(hr_dev, &hem_list->mid_bt[i][j], +- j != 0); ++ hem_list_free_all(hr_dev, &hem_list->mid_bt[i][j]); + +- hem_list_free_all(hr_dev, &hem_list->root_bt, true); ++ hem_list_free_all(hr_dev, &hem_list->root_bt); + INIT_LIST_HEAD(&hem_list->btm_bt); + hem_list->root_ba = 0; + } +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +index 2824d390ec3161..aded0a7f42838d 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +@@ -471,7 +471,7 @@ static inline int set_ud_wqe(struct hns_roce_qp *qp, + valid_num_sge = calc_wr_sge_num(wr, &msg_len); + + ret = set_ud_opcode(ud_sq_wqe, wr); +- if (WARN_ON(ret)) ++ if (WARN_ON_ONCE(ret)) + return ret; + + ud_sq_wqe->msg_len = cpu_to_le32(msg_len); +@@ -575,7 +575,7 @@ static inline int set_rc_wqe(struct hns_roce_qp *qp, + rc_sq_wqe->msg_len = cpu_to_le32(msg_len); + + ret = set_rc_opcode(hr_dev, rc_sq_wqe, wr); +- if (WARN_ON(ret)) ++ if (WARN_ON_ONCE(ret)) + return ret; + + hr_reg_write(rc_sq_wqe, RC_SEND_WQE_SO, +@@ -673,6 +673,10 @@ static void write_dwqe(struct hns_roce_dev *hr_dev, struct hns_roce_qp *qp, + #define HNS_ROCE_SL_SHIFT 2 + struct hns_roce_v2_rc_send_wqe *rc_sq_wqe = wqe; + ++ if (unlikely(qp->state == IB_QPS_ERR)) { ++ flush_cqe(hr_dev, qp); ++ return; ++ } + /* All kinds of DirectWQE have the same header field layout */ + hr_reg_enable(rc_sq_wqe, RC_SEND_WQE_FLAG); + hr_reg_write(rc_sq_wqe, RC_SEND_WQE_DB_SL_L, qp->sl); +@@ -3181,21 +3185,22 @@ static int set_mtpt_pbl(struct hns_roce_dev *hr_dev, + u64 pages[HNS_ROCE_V2_MAX_INNER_MTPT_NUM] = { 0 }; + struct ib_device *ibdev = &hr_dev->ib_dev; + dma_addr_t pbl_ba; +- int i, count; ++ int ret; ++ int i; + +- count = hns_roce_mtr_find(hr_dev, &mr->pbl_mtr, 0, pages, +- min_t(int, ARRAY_SIZE(pages), mr->npages), +- &pbl_ba); +- if (count < 1) { +- ibdev_err(ibdev, "failed to find PBL mtr, count = %d.\n", +- count); +- return -ENOBUFS; ++ ret = hns_roce_mtr_find(hr_dev, &mr->pbl_mtr, 0, pages, ++ min_t(int, ARRAY_SIZE(pages), mr->npages)); ++ if (ret) { ++ ibdev_err(ibdev, "failed to find PBL mtr, ret = %d.\n", ret); ++ return ret; + } + + /* Aligned to the hardware address access unit */ +- for (i = 0; i < count; i++) ++ for (i = 0; i < ARRAY_SIZE(pages); i++) + pages[i] >>= 6; + ++ pbl_ba = hns_roce_get_mtr_ba(&mr->pbl_mtr); ++ + mpt_entry->pbl_size = cpu_to_le32(mr->npages); + mpt_entry->pbl_ba_l = cpu_to_le32(pbl_ba >> 3); + hr_reg_write(mpt_entry, MPT_PBL_BA_H, upper_32_bits(pbl_ba >> 3)); +@@ -3291,21 +3296,14 @@ static int hns_roce_v2_rereg_write_mtpt(struct hns_roce_dev *hr_dev, + return ret; + } + +-static int hns_roce_v2_frmr_write_mtpt(struct hns_roce_dev *hr_dev, +- void *mb_buf, struct hns_roce_mr *mr) ++static int hns_roce_v2_frmr_write_mtpt(void *mb_buf, struct hns_roce_mr *mr) + { +- struct ib_device *ibdev = &hr_dev->ib_dev; ++ dma_addr_t pbl_ba = hns_roce_get_mtr_ba(&mr->pbl_mtr); + struct hns_roce_v2_mpt_entry *mpt_entry; +- dma_addr_t pbl_ba = 0; + + mpt_entry = mb_buf; + memset(mpt_entry, 0, sizeof(*mpt_entry)); + +- if (hns_roce_mtr_find(hr_dev, &mr->pbl_mtr, 0, NULL, 0, &pbl_ba) < 0) { +- ibdev_err(ibdev, "failed to find frmr mtr.\n"); +- return -ENOBUFS; +- } +- + hr_reg_write(mpt_entry, MPT_ST, V2_MPT_ST_FREE); + hr_reg_write(mpt_entry, MPT_PD, mr->pd); + +@@ -4213,8 +4211,7 @@ static void set_access_flags(struct hns_roce_qp *hr_qp, + } + + static void set_qpc_wqe_cnt(struct hns_roce_qp *hr_qp, +- struct hns_roce_v2_qp_context *context, +- struct hns_roce_v2_qp_context *qpc_mask) ++ struct hns_roce_v2_qp_context *context) + { + hr_reg_write(context, QPC_SGE_SHIFT, + to_hr_hem_entries_shift(hr_qp->sge.sge_cnt, +@@ -4236,7 +4233,6 @@ static inline int get_pdn(struct ib_pd *ib_pd) + } + + static void modify_qp_reset_to_init(struct ib_qp *ibqp, +- const struct ib_qp_attr *attr, + struct hns_roce_v2_qp_context *context, + struct hns_roce_v2_qp_context *qpc_mask) + { +@@ -4255,7 +4251,7 @@ static void modify_qp_reset_to_init(struct ib_qp *ibqp, + + hr_reg_write(context, QPC_RQWS, ilog2(hr_qp->rq.max_gs)); + +- set_qpc_wqe_cnt(hr_qp, context, qpc_mask); ++ set_qpc_wqe_cnt(hr_qp, context); + + /* No VLAN need to set 0xFFF */ + hr_reg_write(context, QPC_VLAN_ID, 0xfff); +@@ -4296,7 +4292,6 @@ static void modify_qp_reset_to_init(struct ib_qp *ibqp, + } + + static void modify_qp_init_to_init(struct ib_qp *ibqp, +- const struct ib_qp_attr *attr, + struct hns_roce_v2_qp_context *context, + struct hns_roce_v2_qp_context *qpc_mask) + { +@@ -4333,17 +4328,20 @@ static int config_qp_rq_buf(struct hns_roce_dev *hr_dev, + { + u64 mtts[MTT_MIN_COUNT] = { 0 }; + u64 wqe_sge_ba; +- int count; ++ int ret; + + /* Search qp buf's mtts */ +- count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr, hr_qp->rq.offset, mtts, +- MTT_MIN_COUNT, &wqe_sge_ba); +- if (hr_qp->rq.wqe_cnt && count < 1) { ++ ret = hns_roce_mtr_find(hr_dev, &hr_qp->mtr, hr_qp->rq.offset, mtts, ++ MTT_MIN_COUNT); ++ if (hr_qp->rq.wqe_cnt && ret) { + ibdev_err(&hr_dev->ib_dev, +- "failed to find RQ WQE, QPN = 0x%lx.\n", hr_qp->qpn); +- return -EINVAL; ++ "failed to find QP(0x%lx) RQ WQE buf, ret = %d.\n", ++ hr_qp->qpn, ret); ++ return ret; + } + ++ wqe_sge_ba = hns_roce_get_mtr_ba(&hr_qp->mtr); ++ + context->wqe_sge_ba = cpu_to_le32(wqe_sge_ba >> 3); + qpc_mask->wqe_sge_ba = 0; + +@@ -4407,23 +4405,23 @@ static int config_qp_sq_buf(struct hns_roce_dev *hr_dev, + struct ib_device *ibdev = &hr_dev->ib_dev; + u64 sge_cur_blk = 0; + u64 sq_cur_blk = 0; +- int count; ++ int ret; + + /* search qp buf's mtts */ +- count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr, 0, &sq_cur_blk, 1, NULL); +- if (count < 1) { +- ibdev_err(ibdev, "failed to find QP(0x%lx) SQ buf.\n", +- hr_qp->qpn); +- return -EINVAL; ++ ret = hns_roce_mtr_find(hr_dev, &hr_qp->mtr, hr_qp->sq.offset, ++ &sq_cur_blk, 1); ++ if (ret) { ++ ibdev_err(ibdev, "failed to find QP(0x%lx) SQ WQE buf, ret = %d.\n", ++ hr_qp->qpn, ret); ++ return ret; + } + if (hr_qp->sge.sge_cnt > 0) { +- count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr, +- hr_qp->sge.offset, +- &sge_cur_blk, 1, NULL); +- if (count < 1) { +- ibdev_err(ibdev, "failed to find QP(0x%lx) SGE buf.\n", +- hr_qp->qpn); +- return -EINVAL; ++ ret = hns_roce_mtr_find(hr_dev, &hr_qp->mtr, ++ hr_qp->sge.offset, &sge_cur_blk, 1); ++ if (ret) { ++ ibdev_err(ibdev, "failed to find QP(0x%lx) SGE buf, ret = %d.\n", ++ hr_qp->qpn, ret); ++ return ret; + } + } + +@@ -4614,8 +4612,7 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp, + return 0; + } + +-static int modify_qp_rtr_to_rts(struct ib_qp *ibqp, +- const struct ib_qp_attr *attr, int attr_mask, ++static int modify_qp_rtr_to_rts(struct ib_qp *ibqp, int attr_mask, + struct hns_roce_v2_qp_context *context, + struct hns_roce_v2_qp_context *qpc_mask) + { +@@ -4984,15 +4981,14 @@ static int hns_roce_v2_set_abs_fields(struct ib_qp *ibqp, + + if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) { + memset(qpc_mask, 0, hr_dev->caps.qpc_sz); +- modify_qp_reset_to_init(ibqp, attr, context, qpc_mask); ++ modify_qp_reset_to_init(ibqp, context, qpc_mask); + } else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_INIT) { +- modify_qp_init_to_init(ibqp, attr, context, qpc_mask); ++ modify_qp_init_to_init(ibqp, context, qpc_mask); + } else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR) { + ret = modify_qp_init_to_rtr(ibqp, attr, attr_mask, context, + qpc_mask, udata); + } else if (cur_state == IB_QPS_RTR && new_state == IB_QPS_RTS) { +- ret = modify_qp_rtr_to_rts(ibqp, attr, attr_mask, context, +- qpc_mask); ++ ret = modify_qp_rtr_to_rts(ibqp, attr_mask, context, qpc_mask); + } + + return ret; +@@ -5550,18 +5546,20 @@ static int hns_roce_v2_write_srqc_index_queue(struct hns_roce_srq *srq, + struct ib_device *ibdev = srq->ibsrq.device; + struct hns_roce_dev *hr_dev = to_hr_dev(ibdev); + u64 mtts_idx[MTT_MIN_COUNT] = {}; +- dma_addr_t dma_handle_idx = 0; ++ dma_addr_t dma_handle_idx; + int ret; + + /* Get physical address of idx que buf */ + ret = hns_roce_mtr_find(hr_dev, &idx_que->mtr, 0, mtts_idx, +- ARRAY_SIZE(mtts_idx), &dma_handle_idx); +- if (ret < 1) { ++ ARRAY_SIZE(mtts_idx)); ++ if (ret) { + ibdev_err(ibdev, "failed to find mtr for SRQ idx, ret = %d.\n", + ret); +- return -ENOBUFS; ++ return ret; + } + ++ dma_handle_idx = hns_roce_get_mtr_ba(&idx_que->mtr); ++ + hr_reg_write(ctx, SRQC_IDX_HOP_NUM, + to_hr_hem_hopnum(hr_dev->caps.idx_hop_num, srq->wqe_cnt)); + +@@ -5593,20 +5591,22 @@ static int hns_roce_v2_write_srqc(struct hns_roce_srq *srq, void *mb_buf) + struct hns_roce_dev *hr_dev = to_hr_dev(ibdev); + struct hns_roce_srq_context *ctx = mb_buf; + u64 mtts_wqe[MTT_MIN_COUNT] = {}; +- dma_addr_t dma_handle_wqe = 0; ++ dma_addr_t dma_handle_wqe; + int ret; + + memset(ctx, 0, sizeof(*ctx)); + + /* Get the physical address of srq buf */ + ret = hns_roce_mtr_find(hr_dev, &srq->buf_mtr, 0, mtts_wqe, +- ARRAY_SIZE(mtts_wqe), &dma_handle_wqe); +- if (ret < 1) { ++ ARRAY_SIZE(mtts_wqe)); ++ if (ret) { + ibdev_err(ibdev, "failed to find mtr for SRQ WQE, ret = %d.\n", + ret); +- return -ENOBUFS; ++ return ret; + } + ++ dma_handle_wqe = hns_roce_get_mtr_ba(&srq->buf_mtr); ++ + hr_reg_write(ctx, SRQC_SRQ_ST, 1); + hr_reg_write_bool(ctx, SRQC_SRQ_TYPE, + srq->ibsrq.srq_type == IB_SRQT_XRC); +@@ -6327,7 +6327,7 @@ static int config_eqc(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq, + u64 eqe_ba[MTT_MIN_COUNT] = { 0 }; + struct hns_roce_eq_context *eqc; + u64 bt_ba = 0; +- int count; ++ int ret; + + eqc = mb_buf; + memset(eqc, 0, sizeof(struct hns_roce_eq_context)); +@@ -6335,13 +6335,15 @@ static int config_eqc(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq, + init_eq_config(hr_dev, eq); + + /* if not multi-hop, eqe buffer only use one trunk */ +- count = hns_roce_mtr_find(hr_dev, &eq->mtr, 0, eqe_ba, MTT_MIN_COUNT, +- &bt_ba); +- if (count < 1) { +- dev_err(hr_dev->dev, "failed to find EQE mtr\n"); +- return -ENOBUFS; ++ ret = hns_roce_mtr_find(hr_dev, &eq->mtr, 0, eqe_ba, ++ ARRAY_SIZE(eqe_ba)); ++ if (ret) { ++ dev_err(hr_dev->dev, "failed to find EQE mtr, ret = %d\n", ret); ++ return ret; + } + ++ bt_ba = hns_roce_get_mtr_ba(&eq->mtr); ++ + hr_reg_write(eqc, EQC_EQ_ST, HNS_ROCE_V2_EQ_STATE_VALID); + hr_reg_write(eqc, EQC_EQE_HOP_NUM, eq->hop_num); + hr_reg_write(eqc, EQC_OVER_IGNORE, eq->over_ignore); +diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c +index 7f29a55d378f02..408ef2a9614927 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_mr.c ++++ b/drivers/infiniband/hw/hns/hns_roce_mr.c +@@ -154,7 +154,7 @@ static int hns_roce_mr_enable(struct hns_roce_dev *hr_dev, + if (mr->type != MR_TYPE_FRMR) + ret = hr_dev->hw->write_mtpt(hr_dev, mailbox->buf, mr); + else +- ret = hr_dev->hw->frmr_write_mtpt(hr_dev, mailbox->buf, mr); ++ ret = hr_dev->hw->frmr_write_mtpt(mailbox->buf, mr); + if (ret) { + dev_err(dev, "failed to write mtpt, ret = %d.\n", ret); + goto err_page; +@@ -714,7 +714,7 @@ static int mtr_map_bufs(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr, + return -ENOMEM; + + if (mtr->umem) +- npage = hns_roce_get_umem_bufs(hr_dev, pages, page_count, ++ npage = hns_roce_get_umem_bufs(pages, page_count, + mtr->umem, page_shift); + else + npage = hns_roce_get_kmem_bufs(hr_dev, pages, page_count, +@@ -767,11 +767,6 @@ int hns_roce_mtr_map(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr, + for (i = 0, mapped_cnt = 0; i < mtr->hem_cfg.region_count && + mapped_cnt < page_cnt; i++) { + r = &mtr->hem_cfg.region[i]; +- /* if hopnum is 0, no need to map pages in this region */ +- if (!r->hopnum) { +- mapped_cnt += r->count; +- continue; +- } + + if (r->offset + r->count > page_cnt) { + ret = -EINVAL; +@@ -802,47 +797,53 @@ int hns_roce_mtr_map(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr, + return ret; + } + +-int hns_roce_mtr_find(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr, +- u32 offset, u64 *mtt_buf, int mtt_max, u64 *base_addr) ++static int hns_roce_get_direct_addr_mtt(struct hns_roce_hem_cfg *cfg, ++ u32 start_index, u64 *mtt_buf, ++ int mtt_cnt) + { +- struct hns_roce_hem_cfg *cfg = &mtr->hem_cfg; +- int mtt_count, left; +- u32 start_index; ++ int mtt_count; + int total = 0; +- __le64 *mtts; + u32 npage; + u64 addr; + +- if (!mtt_buf || mtt_max < 1) +- goto done; +- +- /* no mtt memory in direct mode, so just return the buffer address */ +- if (cfg->is_direct) { +- start_index = offset >> HNS_HW_PAGE_SHIFT; +- for (mtt_count = 0; mtt_count < cfg->region_count && +- total < mtt_max; mtt_count++) { +- npage = cfg->region[mtt_count].offset; +- if (npage < start_index) +- continue; ++ if (mtt_cnt > cfg->region_count) ++ return -EINVAL; + +- addr = cfg->root_ba + (npage << HNS_HW_PAGE_SHIFT); +- mtt_buf[total] = addr; ++ for (mtt_count = 0; mtt_count < cfg->region_count && total < mtt_cnt; ++ mtt_count++) { ++ npage = cfg->region[mtt_count].offset; ++ if (npage < start_index) ++ continue; + +- total++; +- } ++ addr = cfg->root_ba + (npage << HNS_HW_PAGE_SHIFT); ++ mtt_buf[total] = addr; + +- goto done; ++ total++; + } + +- start_index = offset >> cfg->buf_pg_shift; +- left = mtt_max; ++ if (!total) ++ return -ENOENT; ++ ++ return 0; ++} ++ ++static int hns_roce_get_mhop_mtt(struct hns_roce_dev *hr_dev, ++ struct hns_roce_mtr *mtr, u32 start_index, ++ u64 *mtt_buf, int mtt_cnt) ++{ ++ int left = mtt_cnt; ++ int total = 0; ++ int mtt_count; ++ __le64 *mtts; ++ u32 npage; ++ + while (left > 0) { + mtt_count = 0; + mtts = hns_roce_hem_list_find_mtt(hr_dev, &mtr->hem_list, + start_index + total, + &mtt_count); + if (!mtts || !mtt_count) +- goto done; ++ break; + + npage = min(mtt_count, left); + left -= npage; +@@ -850,11 +851,33 @@ int hns_roce_mtr_find(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr, + mtt_buf[total++] = le64_to_cpu(mtts[mtt_count]); + } + +-done: +- if (base_addr) +- *base_addr = cfg->root_ba; ++ if (!total) ++ return -ENOENT; ++ ++ return 0; ++} + +- return total; ++int hns_roce_mtr_find(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr, ++ u32 offset, u64 *mtt_buf, int mtt_max) ++{ ++ struct hns_roce_hem_cfg *cfg = &mtr->hem_cfg; ++ u32 start_index; ++ int ret; ++ ++ if (!mtt_buf || mtt_max < 1) ++ return -EINVAL; ++ ++ /* no mtt memory in direct mode, so just return the buffer address */ ++ if (cfg->is_direct) { ++ start_index = offset >> HNS_HW_PAGE_SHIFT; ++ ret = hns_roce_get_direct_addr_mtt(cfg, start_index, ++ mtt_buf, mtt_max); ++ } else { ++ start_index = offset >> cfg->buf_pg_shift; ++ ret = hns_roce_get_mhop_mtt(hr_dev, mtr, start_index, ++ mtt_buf, mtt_max); ++ } ++ return ret; + } + + static int mtr_init_buf_cfg(struct hns_roce_dev *hr_dev, +diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c +index 88a4777d29f8b8..97d79c8d5cd069 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_qp.c ++++ b/drivers/infiniband/hw/hns/hns_roce_qp.c +@@ -1075,7 +1075,6 @@ static int set_qp_param(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp, + } + + static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev, +- struct ib_pd *ib_pd, + struct ib_qp_init_attr *init_attr, + struct ib_udata *udata, + struct hns_roce_qp *hr_qp) +@@ -1229,7 +1228,6 @@ int hns_roce_create_qp(struct ib_qp *qp, struct ib_qp_init_attr *init_attr, + struct ib_device *ibdev = qp->device; + struct hns_roce_dev *hr_dev = to_hr_dev(ibdev); + struct hns_roce_qp *hr_qp = to_hr_qp(qp); +- struct ib_pd *pd = qp->pd; + int ret; + + ret = check_qp_type(hr_dev, init_attr->qp_type, !!udata); +@@ -1244,7 +1242,7 @@ int hns_roce_create_qp(struct ib_qp *qp, struct ib_qp_init_attr *init_attr, + hr_qp->phy_port = hr_dev->iboe.phy_port[hr_qp->port]; + } + +- ret = hns_roce_create_qp_common(hr_dev, pd, init_attr, udata, hr_qp); ++ ret = hns_roce_create_qp_common(hr_dev, init_attr, udata, hr_qp); + if (ret) + ibdev_err(ibdev, "create QP type 0x%x failed(%d)\n", + init_attr->qp_type, ret); +diff --git a/drivers/infiniband/hw/hns/hns_roce_srq.c b/drivers/infiniband/hw/hns/hns_roce_srq.c +index 652508b660a060..80fcb1b0e8fdcf 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_srq.c ++++ b/drivers/infiniband/hw/hns/hns_roce_srq.c +@@ -249,7 +249,7 @@ static void free_srq_wqe_buf(struct hns_roce_dev *hr_dev, + hns_roce_mtr_destroy(hr_dev, &srq->buf_mtr); + } + +-static int alloc_srq_wrid(struct hns_roce_dev *hr_dev, struct hns_roce_srq *srq) ++static int alloc_srq_wrid(struct hns_roce_srq *srq) + { + srq->wrid = kvmalloc_array(srq->wqe_cnt, sizeof(u64), GFP_KERNEL); + if (!srq->wrid) +@@ -365,7 +365,7 @@ static int alloc_srq_buf(struct hns_roce_dev *hr_dev, struct hns_roce_srq *srq, + goto err_idx; + + if (!udata) { +- ret = alloc_srq_wrid(hr_dev, srq); ++ ret = alloc_srq_wrid(srq); + if (ret) + goto err_wqe_buf; + } +diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c +index c510484e024b1a..ada7dbf8eb1cf5 100644 +--- a/drivers/infiniband/hw/mlx5/main.c ++++ b/drivers/infiniband/hw/mlx5/main.c +@@ -3372,7 +3372,8 @@ static int mlx5_ib_init_multiport_master(struct mlx5_ib_dev *dev) + list_for_each_entry(mpi, &mlx5_ib_unaffiliated_port_list, + list) { + if (dev->sys_image_guid == mpi->sys_image_guid && +- (mlx5_core_native_port_num(mpi->mdev) - 1) == i) { ++ (mlx5_core_native_port_num(mpi->mdev) - 1) == i && ++ mlx5_core_same_coredev_type(dev->mdev, mpi->mdev)) { + bound = mlx5_ib_bind_slave_port(dev, mpi); + } + +@@ -4406,7 +4407,8 @@ static int mlx5r_mp_probe(struct auxiliary_device *adev, + + mutex_lock(&mlx5_ib_multiport_mutex); + list_for_each_entry(dev, &mlx5_ib_dev_list, ib_dev_list) { +- if (dev->sys_image_guid == mpi->sys_image_guid) ++ if (dev->sys_image_guid == mpi->sys_image_guid && ++ mlx5_core_same_coredev_type(dev->mdev, mpi->mdev)) + bound = mlx5_ib_bind_slave_port(dev, mpi); + + if (bound) { +diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +index 758a3d9c2844d1..84d1654148d764 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +@@ -346,6 +346,7 @@ static int send_io_resp_imm(struct rtrs_srv_con *con, struct rtrs_srv_op *id, + struct rtrs_srv_mr *srv_mr; + bool need_inval = false; + enum ib_send_flags flags; ++ struct ib_sge list; + u32 imm; + int err; + +@@ -398,7 +399,6 @@ static int send_io_resp_imm(struct rtrs_srv_con *con, struct rtrs_srv_op *id, + imm = rtrs_to_io_rsp_imm(id->msg_id, errno, need_inval); + imm_wr.wr.next = NULL; + if (always_invalidate) { +- struct ib_sge list; + struct rtrs_msg_rkey_rsp *msg; + + srv_mr = &srv_path->mrs[id->msg_id]; +diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c +index 412196a7dad587..2c6c50348afd19 100644 +--- a/drivers/irqchip/irq-gic.c ++++ b/drivers/irqchip/irq-gic.c +@@ -64,7 +64,7 @@ static void gic_check_cpu_features(void) + + union gic_base { + void __iomem *common_base; +- void __percpu * __iomem *percpu_base; ++ void __iomem * __percpu *percpu_base; + }; + + struct gic_chip_data { +diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c +index a44d4b3e5beb22..82102a4c5d6883 100644 +--- a/drivers/mailbox/pcc.c ++++ b/drivers/mailbox/pcc.c +@@ -91,6 +91,14 @@ struct pcc_chan_reg { + * @cmd_update: PCC register bundle for the command complete update register + * @error: PCC register bundle for the error status register + * @plat_irq: platform interrupt ++ * @type: PCC subspace type ++ * @plat_irq_flags: platform interrupt flags ++ * @chan_in_use: this flag is used just to check if the interrupt needs ++ * handling when it is shared. Since only one transfer can occur ++ * at a time and mailbox takes care of locking, this flag can be ++ * accessed without a lock. Note: the type only support the ++ * communication from OSPM to Platform, like type3, use it, and ++ * other types completely ignore it. + */ + struct pcc_chan_info { + struct pcc_mbox_chan chan; +@@ -100,12 +108,17 @@ struct pcc_chan_info { + struct pcc_chan_reg cmd_update; + struct pcc_chan_reg error; + int plat_irq; ++ u8 type; ++ unsigned int plat_irq_flags; ++ bool chan_in_use; + }; + + #define to_pcc_chan_info(c) container_of(c, struct pcc_chan_info, chan) + static struct pcc_chan_info *chan_info; + static int pcc_chan_count; + ++static int pcc_send_data(struct mbox_chan *chan, void *data); ++ + /* + * PCC can be used with perf critical drivers such as CPPC + * So it makes sense to locally cache the virtual address and +@@ -221,6 +234,70 @@ static int pcc_map_interrupt(u32 interrupt, u32 flags) + return acpi_register_gsi(NULL, interrupt, trigger, polarity); + } + ++static bool pcc_chan_plat_irq_can_be_shared(struct pcc_chan_info *pchan) ++{ ++ return (pchan->plat_irq_flags & ACPI_PCCT_INTERRUPT_MODE) == ++ ACPI_LEVEL_SENSITIVE; ++} ++ ++static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan) ++{ ++ u64 val; ++ int ret; ++ ++ ret = pcc_chan_reg_read(&pchan->cmd_complete, &val); ++ if (ret) ++ return false; ++ ++ if (!pchan->cmd_complete.gas) ++ return true; ++ ++ /* ++ * Judge if the channel respond the interrupt based on the value of ++ * command complete. ++ */ ++ val &= pchan->cmd_complete.status_mask; ++ ++ /* ++ * If this is PCC slave subspace channel, and the command complete ++ * bit 0 indicates that Platform is sending a notification and OSPM ++ * needs to respond this interrupt to process this command. ++ */ ++ if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE) ++ return !val; ++ ++ return !!val; ++} ++ ++static void check_and_ack(struct pcc_chan_info *pchan, struct mbox_chan *chan) ++{ ++ struct acpi_pcct_ext_pcc_shared_memory pcc_hdr; ++ ++ if (pchan->type != ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE) ++ return; ++ /* If the memory region has not been mapped, we cannot ++ * determine if we need to send the message, but we still ++ * need to set the cmd_update flag before returning. ++ */ ++ if (pchan->chan.shmem == NULL) { ++ pcc_chan_reg_read_modify_write(&pchan->cmd_update); ++ return; ++ } ++ memcpy_fromio(&pcc_hdr, pchan->chan.shmem, ++ sizeof(struct acpi_pcct_ext_pcc_shared_memory)); ++ /* ++ * The PCC slave subspace channel needs to set the command complete bit ++ * after processing message. If the PCC_ACK_FLAG is set, it should also ++ * ring the doorbell. ++ * ++ * The PCC master subspace channel clears chan_in_use to free channel. ++ */ ++ if (le32_to_cpup(&pcc_hdr.flags) & PCC_ACK_FLAG_MASK) ++ pcc_send_data(chan, NULL); ++ else ++ pcc_chan_reg_read_modify_write(&pchan->cmd_update); ++} ++ + /** + * pcc_mbox_irq - PCC mailbox interrupt handler + * @irq: interrupt number +@@ -236,16 +313,12 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p) + int ret; + + pchan = chan->con_priv; +- +- ret = pcc_chan_reg_read(&pchan->cmd_complete, &val); +- if (ret) ++ if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE && ++ !pchan->chan_in_use) + return IRQ_NONE; + +- if (val) { /* Ensure GAS exists and value is non-zero */ +- val &= pchan->cmd_complete.status_mask; +- if (!val) +- return IRQ_NONE; +- } ++ if (!pcc_mbox_cmd_complete_check(pchan)) ++ return IRQ_NONE; + + ret = pcc_chan_reg_read(&pchan->error, &val); + if (ret) +@@ -262,6 +335,9 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p) + + mbox_chan_received_data(chan, NULL); + ++ check_and_ack(pchan, chan); ++ pchan->chan_in_use = false; ++ + return IRQ_HANDLED; + } + +@@ -311,14 +387,37 @@ EXPORT_SYMBOL_GPL(pcc_mbox_request_channel); + void pcc_mbox_free_channel(struct pcc_mbox_chan *pchan) + { + struct mbox_chan *chan = pchan->mchan; ++ struct pcc_chan_info *pchan_info; ++ struct pcc_mbox_chan *pcc_mbox_chan; + + if (!chan || !chan->cl) + return; ++ pchan_info = chan->con_priv; ++ pcc_mbox_chan = &pchan_info->chan; ++ if (pcc_mbox_chan->shmem) { ++ iounmap(pcc_mbox_chan->shmem); ++ pcc_mbox_chan->shmem = NULL; ++ } + + mbox_free_channel(chan); + } + EXPORT_SYMBOL_GPL(pcc_mbox_free_channel); + ++int pcc_mbox_ioremap(struct mbox_chan *chan) ++{ ++ struct pcc_chan_info *pchan_info; ++ struct pcc_mbox_chan *pcc_mbox_chan; ++ ++ if (!chan || !chan->cl) ++ return -1; ++ pchan_info = chan->con_priv; ++ pcc_mbox_chan = &pchan_info->chan; ++ pcc_mbox_chan->shmem = ioremap(pcc_mbox_chan->shmem_base_addr, ++ pcc_mbox_chan->shmem_size); ++ return 0; ++} ++EXPORT_SYMBOL_GPL(pcc_mbox_ioremap); ++ + /** + * pcc_send_data - Called from Mailbox Controller code. Used + * here only to ring the channel doorbell. The PCC client +@@ -340,7 +439,11 @@ static int pcc_send_data(struct mbox_chan *chan, void *data) + if (ret) + return ret; + +- return pcc_chan_reg_read_modify_write(&pchan->db); ++ ret = pcc_chan_reg_read_modify_write(&pchan->db); ++ if (!ret && pchan->plat_irq > 0) ++ pchan->chan_in_use = true; ++ ++ return ret; + } + + /** +@@ -353,11 +456,14 @@ static int pcc_send_data(struct mbox_chan *chan, void *data) + static int pcc_startup(struct mbox_chan *chan) + { + struct pcc_chan_info *pchan = chan->con_priv; ++ unsigned long irqflags; + int rc; + + if (pchan->plat_irq > 0) { +- rc = devm_request_irq(chan->mbox->dev, pchan->plat_irq, pcc_mbox_irq, 0, +- MBOX_IRQ_NAME, chan); ++ irqflags = pcc_chan_plat_irq_can_be_shared(pchan) ? ++ IRQF_SHARED | IRQF_ONESHOT : 0; ++ rc = devm_request_irq(chan->mbox->dev, pchan->plat_irq, pcc_mbox_irq, ++ irqflags, MBOX_IRQ_NAME, chan); + if (unlikely(rc)) { + dev_err(chan->mbox->dev, "failed to register PCC interrupt %d\n", + pchan->plat_irq); +@@ -463,6 +569,7 @@ static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan, + pcct_ss->platform_interrupt); + return -EINVAL; + } ++ pchan->plat_irq_flags = pcct_ss->flags; + + if (pcct_ss->header.type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2) { + struct acpi_pcct_hw_reduced_type2 *pcct2_ss = (void *)pcct_ss; +@@ -484,6 +591,12 @@ static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan, + "PLAT IRQ ACK"); + } + ++ if (pcc_chan_plat_irq_can_be_shared(pchan) && ++ !pchan->plat_irq_ack.gas) { ++ pr_err("PCC subspace has level IRQ with no ACK register\n"); ++ return -EINVAL; ++ } ++ + return ret; + } + +@@ -698,6 +811,7 @@ static int pcc_mbox_probe(struct platform_device *pdev) + + pcc_parse_subspace_shmem(pchan, pcct_entry); + ++ pchan->type = pcct_entry->type; + pcct_entry = (struct acpi_subtable_header *) + ((unsigned long) pcct_entry + pcct_entry->length); + } +diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c +index 5a3e933df63352..1b05890f99f4f4 100644 +--- a/drivers/media/usb/uvc/uvc_driver.c ++++ b/drivers/media/usb/uvc/uvc_driver.c +@@ -2519,6 +2519,28 @@ static const struct usb_device_id uvc_ids[] = { + .bInterfaceSubClass = 1, + .bInterfaceProtocol = UVC_PC_PROTOCOL_15, + .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_limited }, ++ /* Quanta ACER HD User Facing */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x0408, ++ .idProduct = 0x4033, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = UVC_PC_PROTOCOL_15, ++ .driver_info = (kernel_ulong_t)&(const struct uvc_device_info){ ++ .uvc_version = 0x010a, ++ } }, ++ /* Quanta ACER HD User Facing */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x0408, ++ .idProduct = 0x4035, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = UVC_PC_PROTOCOL_15, ++ .driver_info = (kernel_ulong_t)&(const struct uvc_device_info){ ++ .uvc_version = 0x010a, ++ } }, + /* LogiLink Wireless Webcam */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, +diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c +index e113b99a3eab59..8716004fcf6c90 100644 +--- a/drivers/mmc/host/sdhci-msm.c ++++ b/drivers/mmc/host/sdhci-msm.c +@@ -1867,20 +1867,20 @@ static int sdhci_msm_program_key(struct cqhci_host *cq_host, + struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); + union cqhci_crypto_cap_entry cap; + ++ if (!(cfg->config_enable & CQHCI_CRYPTO_CONFIGURATION_ENABLE)) ++ return qcom_ice_evict_key(msm_host->ice, slot); ++ + /* Only AES-256-XTS has been tested so far. */ + cap = cq_host->crypto_cap_array[cfg->crypto_cap_idx]; + if (cap.algorithm_id != CQHCI_CRYPTO_ALG_AES_XTS || + cap.key_size != CQHCI_CRYPTO_KEY_SIZE_256) + return -EINVAL; + +- if (cfg->config_enable & CQHCI_CRYPTO_CONFIGURATION_ENABLE) +- return qcom_ice_program_key(msm_host->ice, +- QCOM_ICE_CRYPTO_ALG_AES_XTS, +- QCOM_ICE_CRYPTO_KEY_SIZE_256, +- cfg->crypto_key, +- cfg->data_unit_size, slot); +- else +- return qcom_ice_evict_key(msm_host->ice, slot); ++ return qcom_ice_program_key(msm_host->ice, ++ QCOM_ICE_CRYPTO_ALG_AES_XTS, ++ QCOM_ICE_CRYPTO_KEY_SIZE_256, ++ cfg->crypto_key, ++ cfg->data_unit_size, slot); + } + + #else /* CONFIG_MMC_CRYPTO */ +diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c +index a7e8fcdf25768b..59134d117846d1 100644 +--- a/drivers/net/dsa/microchip/ksz9477.c ++++ b/drivers/net/dsa/microchip/ksz9477.c +@@ -2,7 +2,7 @@ + /* + * Microchip KSZ9477 switch driver main logic + * +- * Copyright (C) 2017-2019 Microchip Technology Inc. ++ * Copyright (C) 2017-2024 Microchip Technology Inc. + */ + + #include +@@ -916,26 +916,51 @@ void ksz9477_get_caps(struct ksz_device *dev, int port, + int ksz9477_set_ageing_time(struct ksz_device *dev, unsigned int msecs) + { + u32 secs = msecs / 1000; +- u8 value; +- u8 data; ++ u8 data, mult, value; ++ u32 max_val; + int ret; + +- value = FIELD_GET(SW_AGE_PERIOD_7_0_M, secs); ++#define MAX_TIMER_VAL ((1 << 8) - 1) + +- ret = ksz_write8(dev, REG_SW_LUE_CTRL_3, value); +- if (ret < 0) +- return ret; ++ /* The aging timer comprises a 3-bit multiplier and an 8-bit second ++ * value. Either of them cannot be zero. The maximum timer is then ++ * 7 * 255 = 1785 seconds. ++ */ ++ if (!secs) ++ secs = 1; + +- data = FIELD_GET(SW_AGE_PERIOD_10_8_M, secs); ++ /* Return error if too large. */ ++ else if (secs > 7 * MAX_TIMER_VAL) ++ return -EINVAL; + + ret = ksz_read8(dev, REG_SW_LUE_CTRL_0, &value); + if (ret < 0) + return ret; + +- value &= ~SW_AGE_CNT_M; +- value |= FIELD_PREP(SW_AGE_CNT_M, data); ++ /* Check whether there is need to update the multiplier. */ ++ mult = FIELD_GET(SW_AGE_CNT_M, value); ++ max_val = MAX_TIMER_VAL; ++ if (mult > 0) { ++ /* Try to use the same multiplier already in the register as ++ * the hardware default uses multiplier 4 and 75 seconds for ++ * 300 seconds. ++ */ ++ max_val = DIV_ROUND_UP(secs, mult); ++ if (max_val > MAX_TIMER_VAL || max_val * mult != secs) ++ max_val = MAX_TIMER_VAL; ++ } ++ ++ data = DIV_ROUND_UP(secs, max_val); ++ if (mult != data) { ++ value &= ~SW_AGE_CNT_M; ++ value |= FIELD_PREP(SW_AGE_CNT_M, data); ++ ret = ksz_write8(dev, REG_SW_LUE_CTRL_0, value); ++ if (ret < 0) ++ return ret; ++ } + +- return ksz_write8(dev, REG_SW_LUE_CTRL_0, value); ++ value = DIV_ROUND_UP(secs, data); ++ return ksz_write8(dev, REG_SW_LUE_CTRL_3, value); + } + + void ksz9477_port_queue_split(struct ksz_device *dev, int port) +diff --git a/drivers/net/dsa/microchip/ksz9477_reg.h b/drivers/net/dsa/microchip/ksz9477_reg.h +index a2ef4b18349c41..d0886ed984c578 100644 +--- a/drivers/net/dsa/microchip/ksz9477_reg.h ++++ b/drivers/net/dsa/microchip/ksz9477_reg.h +@@ -2,7 +2,7 @@ + /* + * Microchip KSZ9477 register definitions + * +- * Copyright (C) 2017-2018 Microchip Technology Inc. ++ * Copyright (C) 2017-2024 Microchip Technology Inc. + */ + + #ifndef __KSZ9477_REGS_H +@@ -190,8 +190,6 @@ + #define SW_VLAN_ENABLE BIT(7) + #define SW_DROP_INVALID_VID BIT(6) + #define SW_AGE_CNT_M GENMASK(5, 3) +-#define SW_AGE_CNT_S 3 +-#define SW_AGE_PERIOD_10_8_M GENMASK(10, 8) + #define SW_RESV_MCAST_ENABLE BIT(2) + #define SW_HASH_OPTION_M 0x03 + #define SW_HASH_OPTION_CRC 1 +diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c +index b479a628b1ae56..dde37e61faa359 100644 +--- a/drivers/net/dsa/microchip/lan937x_main.c ++++ b/drivers/net/dsa/microchip/lan937x_main.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0 + /* Microchip LAN937X switch driver main logic +- * Copyright (C) 2019-2022 Microchip Technology Inc. ++ * Copyright (C) 2019-2024 Microchip Technology Inc. + */ + #include + #include +@@ -257,10 +257,66 @@ int lan937x_change_mtu(struct ksz_device *dev, int port, int new_mtu) + + int lan937x_set_ageing_time(struct ksz_device *dev, unsigned int msecs) + { +- u32 secs = msecs / 1000; +- u32 value; ++ u8 data, mult, value8; ++ bool in_msec = false; ++ u32 max_val, value; ++ u32 secs = msecs; + int ret; + ++#define MAX_TIMER_VAL ((1 << 20) - 1) ++ ++ /* The aging timer comprises a 3-bit multiplier and a 20-bit second ++ * value. Either of them cannot be zero. The maximum timer is then ++ * 7 * 1048575 = 7340025 seconds. As this value is too large for ++ * practical use it can be interpreted as microseconds, making the ++ * maximum timer 7340 seconds with finer control. This allows for ++ * maximum 122 minutes compared to 29 minutes in KSZ9477 switch. ++ */ ++ if (msecs % 1000) ++ in_msec = true; ++ else ++ secs /= 1000; ++ if (!secs) ++ secs = 1; ++ ++ /* Return error if too large. */ ++ else if (secs > 7 * MAX_TIMER_VAL) ++ return -EINVAL; ++ ++ /* Configure how to interpret the number value. */ ++ ret = ksz_rmw8(dev, REG_SW_LUE_CTRL_2, SW_AGE_CNT_IN_MICROSEC, ++ in_msec ? SW_AGE_CNT_IN_MICROSEC : 0); ++ if (ret < 0) ++ return ret; ++ ++ ret = ksz_read8(dev, REG_SW_LUE_CTRL_0, &value8); ++ if (ret < 0) ++ return ret; ++ ++ /* Check whether there is need to update the multiplier. */ ++ mult = FIELD_GET(SW_AGE_CNT_M, value8); ++ max_val = MAX_TIMER_VAL; ++ if (mult > 0) { ++ /* Try to use the same multiplier already in the register as ++ * the hardware default uses multiplier 4 and 75 seconds for ++ * 300 seconds. ++ */ ++ max_val = DIV_ROUND_UP(secs, mult); ++ if (max_val > MAX_TIMER_VAL || max_val * mult != secs) ++ max_val = MAX_TIMER_VAL; ++ } ++ ++ data = DIV_ROUND_UP(secs, max_val); ++ if (mult != data) { ++ value8 &= ~SW_AGE_CNT_M; ++ value8 |= FIELD_PREP(SW_AGE_CNT_M, data); ++ ret = ksz_write8(dev, REG_SW_LUE_CTRL_0, value8); ++ if (ret < 0) ++ return ret; ++ } ++ ++ secs = DIV_ROUND_UP(secs, data); ++ + value = FIELD_GET(SW_AGE_PERIOD_7_0_M, secs); + + ret = ksz_write8(dev, REG_SW_AGE_PERIOD__1, value); +diff --git a/drivers/net/dsa/microchip/lan937x_reg.h b/drivers/net/dsa/microchip/lan937x_reg.h +index 45b606b6429f65..b3e536e7c68694 100644 +--- a/drivers/net/dsa/microchip/lan937x_reg.h ++++ b/drivers/net/dsa/microchip/lan937x_reg.h +@@ -1,6 +1,6 @@ + /* SPDX-License-Identifier: GPL-2.0 */ + /* Microchip LAN937X switch register definitions +- * Copyright (C) 2019-2021 Microchip Technology Inc. ++ * Copyright (C) 2019-2024 Microchip Technology Inc. + */ + #ifndef __LAN937X_REG_H + #define __LAN937X_REG_H +@@ -48,8 +48,7 @@ + + #define SW_VLAN_ENABLE BIT(7) + #define SW_DROP_INVALID_VID BIT(6) +-#define SW_AGE_CNT_M 0x7 +-#define SW_AGE_CNT_S 3 ++#define SW_AGE_CNT_M GENMASK(5, 3) + #define SW_RESV_MCAST_ENABLE BIT(2) + + #define REG_SW_LUE_CTRL_1 0x0311 +@@ -62,6 +61,10 @@ + #define SW_FAST_AGING BIT(1) + #define SW_LINK_AUTO_AGING BIT(0) + ++#define REG_SW_LUE_CTRL_2 0x0312 ++ ++#define SW_AGE_CNT_IN_MICROSEC BIT(7) ++ + #define REG_SW_AGE_PERIOD__1 0x0313 + #define SW_AGE_PERIOD_7_0_M GENMASK(7, 0) + +diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c +index 49e890a7e04a37..23cc2d85994e42 100644 +--- a/drivers/net/ethernet/broadcom/bcmsysport.c ++++ b/drivers/net/ethernet/broadcom/bcmsysport.c +@@ -1967,7 +1967,11 @@ static int bcm_sysport_open(struct net_device *dev) + unsigned int i; + int ret; + +- clk_prepare_enable(priv->clk); ++ ret = clk_prepare_enable(priv->clk); ++ if (ret) { ++ netdev_err(dev, "could not enable priv clock\n"); ++ return ret; ++ } + + /* Reset UniMAC */ + umac_reset(priv); +@@ -2625,7 +2629,11 @@ static int bcm_sysport_probe(struct platform_device *pdev) + goto err_deregister_notifier; + } + +- clk_prepare_enable(priv->clk); ++ ret = clk_prepare_enable(priv->clk); ++ if (ret) { ++ dev_err(&pdev->dev, "could not enable priv clock\n"); ++ goto err_deregister_netdev; ++ } + + priv->rev = topctrl_readl(priv, REV_CNTL) & REV_MASK; + dev_info(&pdev->dev, +@@ -2639,6 +2647,8 @@ static int bcm_sysport_probe(struct platform_device *pdev) + + return 0; + ++err_deregister_netdev: ++ unregister_netdev(dev); + err_deregister_notifier: + unregister_netdevice_notifier(&priv->netdev_notifier); + err_deregister_fixed_link: +@@ -2810,7 +2820,12 @@ static int __maybe_unused bcm_sysport_resume(struct device *d) + if (!netif_running(dev)) + return 0; + +- clk_prepare_enable(priv->clk); ++ ret = clk_prepare_enable(priv->clk); ++ if (ret) { ++ netdev_err(dev, "could not enable priv clock\n"); ++ return ret; ++ } ++ + if (priv->wolopts) + clk_disable_unprepare(priv->wol_clk); + +diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c +index 5703240474e5b2..d70305654e7d07 100644 +--- a/drivers/net/ethernet/google/gve/gve_main.c ++++ b/drivers/net/ethernet/google/gve/gve_main.c +@@ -1528,8 +1528,8 @@ static int gve_xsk_pool_enable(struct net_device *dev, + if (err) + return err; + +- /* If XDP prog is not installed, return */ +- if (!priv->xdp_prog) ++ /* If XDP prog is not installed or interface is down, return. */ ++ if (!priv->xdp_prog || !netif_running(dev)) + return 0; + + rx = &priv->rx[qid]; +@@ -1574,21 +1574,16 @@ static int gve_xsk_pool_disable(struct net_device *dev, + if (qid >= priv->rx_cfg.num_queues) + return -EINVAL; + +- /* If XDP prog is not installed, unmap DMA and return */ +- if (!priv->xdp_prog) +- goto done; +- +- tx_qid = gve_xdp_tx_queue_id(priv, qid); +- if (!netif_running(dev)) { +- priv->rx[qid].xsk_pool = NULL; +- xdp_rxq_info_unreg(&priv->rx[qid].xsk_rxq); +- priv->tx[tx_qid].xsk_pool = NULL; ++ /* If XDP prog is not installed or interface is down, unmap DMA and ++ * return. ++ */ ++ if (!priv->xdp_prog || !netif_running(dev)) + goto done; +- } + + napi_rx = &priv->ntfy_blocks[priv->rx[qid].ntfy_id].napi; + napi_disable(napi_rx); /* make sure current rx poll is done */ + ++ tx_qid = gve_xdp_tx_queue_id(priv, qid); + napi_tx = &priv->ntfy_blocks[priv->tx[tx_qid].ntfy_id].napi; + napi_disable(napi_tx); /* make sure current tx poll is done */ + +@@ -1616,6 +1611,9 @@ static int gve_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags) + struct gve_priv *priv = netdev_priv(dev); + int tx_queue_id = gve_xdp_tx_queue_id(priv, queue_id); + ++ if (!gve_get_napi_enabled(priv)) ++ return -ENETDOWN; ++ + if (queue_id >= priv->rx_cfg.num_queues || !priv->xdp_prog) + return -EINVAL; + +@@ -1757,6 +1755,9 @@ static void gve_turndown(struct gve_priv *priv) + + gve_clear_napi_enabled(priv); + gve_clear_report_stats(priv); ++ ++ /* Make sure that all traffic is finished processing. */ ++ synchronize_net(); + } + + static void gve_turnup(struct gve_priv *priv) +diff --git a/drivers/net/ethernet/google/gve/gve_tx.c b/drivers/net/ethernet/google/gve/gve_tx.c +index 2ae891a62875c7..29987624791a68 100644 +--- a/drivers/net/ethernet/google/gve/gve_tx.c ++++ b/drivers/net/ethernet/google/gve/gve_tx.c +@@ -777,9 +777,12 @@ int gve_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames, + struct gve_tx_ring *tx; + int i, err = 0, qid; + +- if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK)) ++ if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK) || !priv->xdp_prog) + return -EINVAL; + ++ if (!gve_get_napi_enabled(priv)) ++ return -ENETDOWN; ++ + qid = gve_xdp_tx_queue_id(priv, + smp_processor_id() % priv->num_xdp_queues); + +diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c +index 3b129a1c338152..07e5051171a48a 100644 +--- a/drivers/net/ethernet/marvell/mv643xx_eth.c ++++ b/drivers/net/ethernet/marvell/mv643xx_eth.c +@@ -2708,9 +2708,15 @@ static struct platform_device *port_platdev[3]; + + static void mv643xx_eth_shared_of_remove(void) + { ++ struct mv643xx_eth_platform_data *pd; + int n; + + for (n = 0; n < 3; n++) { ++ if (!port_platdev[n]) ++ continue; ++ pd = dev_get_platdata(&port_platdev[n]->dev); ++ if (pd) ++ of_node_put(pd->phy_node); + platform_device_del(port_platdev[n]); + port_platdev[n] = NULL; + } +@@ -2773,8 +2779,10 @@ static int mv643xx_eth_shared_of_add_port(struct platform_device *pdev, + } + + ppdev = platform_device_alloc(MV643XX_ETH_NAME, dev_num); +- if (!ppdev) +- return -ENOMEM; ++ if (!ppdev) { ++ ret = -ENOMEM; ++ goto put_err; ++ } + ppdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); + ppdev->dev.of_node = pnp; + +@@ -2796,6 +2804,8 @@ static int mv643xx_eth_shared_of_add_port(struct platform_device *pdev, + + port_err: + platform_device_put(ppdev); ++put_err: ++ of_node_put(ppd.phy_node); + return ret; + } + +diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c +index 07720841a8d700..dd3d93720358bd 100644 +--- a/drivers/net/ethernet/marvell/sky2.c ++++ b/drivers/net/ethernet/marvell/sky2.c +@@ -129,6 +129,7 @@ static const struct pci_device_id sky2_id_table[] = { + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436C) }, /* 88E8072 */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436D) }, /* 88E8055 */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4370) }, /* 88E8075 */ ++ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4373) }, /* 88E8075 */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4380) }, /* 88E8057 */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4381) }, /* 88E8059 */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4382) }, /* 88E8079 */ +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c +index cc9bcc42003242..6ab02f3fc29123 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c +@@ -339,9 +339,13 @@ static int mlx5e_macsec_init_sa_fs(struct macsec_context *ctx, + { + struct mlx5e_priv *priv = macsec_netdev_priv(ctx->netdev); + struct mlx5_macsec_fs *macsec_fs = priv->mdev->macsec_fs; ++ const struct macsec_tx_sc *tx_sc = &ctx->secy->tx_sc; + struct mlx5_macsec_rule_attrs rule_attrs; + union mlx5_macsec_rule *macsec_rule; + ++ if (is_tx && tx_sc->encoding_sa != sa->assoc_num) ++ return 0; ++ + rule_attrs.macsec_obj_id = sa->macsec_obj_id; + rule_attrs.sci = sa->sci; + rule_attrs.assoc_num = sa->assoc_num; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.c +index 13b5916b64e224..eed8fcde261384 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.c +@@ -150,11 +150,11 @@ void mlx5_esw_ipsec_restore_dest_uplink(struct mlx5_core_dev *mdev) + unsigned long i; + int err; + +- xa_for_each(&esw->offloads.vport_reps, i, rep) { +- rpriv = rep->rep_data[REP_ETH].priv; +- if (!rpriv || !rpriv->netdev) ++ mlx5_esw_for_each_rep(esw, i, rep) { ++ if (atomic_read(&rep->rep_data[REP_ETH].state) != REP_LOADED) + continue; + ++ rpriv = rep->rep_data[REP_ETH].priv; + rhashtable_walk_enter(&rpriv->tc_ht, &iter); + rhashtable_walk_start(&iter); + while ((flow = rhashtable_walk_next(&iter)) != NULL) { +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +index 9b771b572593b5..3e58e731b5697c 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +@@ -713,6 +713,9 @@ void mlx5e_tc_clean_fdb_peer_flows(struct mlx5_eswitch *esw); + MLX5_CAP_GEN_2((esw->dev), ec_vf_vport_base) +\ + (last) - 1) + ++#define mlx5_esw_for_each_rep(esw, i, rep) \ ++ xa_for_each(&((esw)->offloads.vport_reps), i, rep) ++ + struct mlx5_eswitch *__must_check + mlx5_devlink_eswitch_get(struct devlink *devlink); + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +index 58529d1a98b37b..7eba3a5bb97cae 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +@@ -52,9 +52,6 @@ + #include "lag/lag.h" + #include "en/tc/post_meter.h" + +-#define mlx5_esw_for_each_rep(esw, i, rep) \ +- xa_for_each(&((esw)->offloads.vport_reps), i, rep) +- + /* There are two match-all miss flows, one for unicast dst mac and + * one for multicast. + */ +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +index 991250f44c2ed1..474e63d02ba492 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +@@ -3478,6 +3478,7 @@ void mlx5_fs_core_free(struct mlx5_core_dev *dev) + int mlx5_fs_core_alloc(struct mlx5_core_dev *dev) + { + struct mlx5_flow_steering *steering; ++ char name[80]; + int err = 0; + + err = mlx5_init_fc_stats(dev); +@@ -3502,10 +3503,12 @@ int mlx5_fs_core_alloc(struct mlx5_core_dev *dev) + else + steering->mode = MLX5_FLOW_STEERING_MODE_DMFS; + +- steering->fgs_cache = kmem_cache_create("mlx5_fs_fgs", ++ snprintf(name, sizeof(name), "%s-mlx5_fs_fgs", dev_name(dev->device)); ++ steering->fgs_cache = kmem_cache_create(name, + sizeof(struct mlx5_flow_group), 0, + 0, NULL); +- steering->ftes_cache = kmem_cache_create("mlx5_fs_ftes", sizeof(struct fs_fte), 0, ++ snprintf(name, sizeof(name), "%s-mlx5_fs_ftes", dev_name(dev->device)); ++ steering->ftes_cache = kmem_cache_create(name, sizeof(struct fs_fte), 0, + 0, NULL); + if (!steering->ftes_cache || !steering->fgs_cache) { + err = -ENOMEM; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c +index 6fa06ba2d34653..f57c84e5128bc7 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c +@@ -1067,7 +1067,6 @@ static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev, + int inlen, err, eqn; + void *cqc, *in; + __be64 *pas; +- int vector; + u32 i; + + cq = kzalloc(sizeof(*cq), GFP_KERNEL); +@@ -1096,8 +1095,7 @@ static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev, + if (!in) + goto err_cqwq; + +- vector = raw_smp_processor_id() % mlx5_comp_vectors_max(mdev); +- err = mlx5_comp_eqn_get(mdev, vector, &eqn); ++ err = mlx5_comp_eqn_get(mdev, 0, &eqn); + if (err) { + kvfree(in); + goto err_cqwq; +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c +index dcd198104141f1..fa3fef2b74db0d 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c +@@ -423,8 +423,7 @@ mlxsw_sp_span_gretap4_route(const struct net_device *to_dev, + + parms = mlxsw_sp_ipip_netdev_parms4(to_dev); + ip_tunnel_init_flow(&fl4, parms.iph.protocol, *daddrp, *saddrp, +- 0, 0, dev_net(to_dev), parms.link, tun->fwmark, 0, +- 0); ++ 0, 0, tun->net, parms.link, tun->fwmark, 0, 0); + + rt = ip_route_output_key(tun->net, &fl4); + if (IS_ERR(rt)) +diff --git a/drivers/net/ethernet/renesas/rswitch.c b/drivers/net/ethernet/renesas/rswitch.c +index 54aa56c841334c..2f483531d95cb7 100644 +--- a/drivers/net/ethernet/renesas/rswitch.c ++++ b/drivers/net/ethernet/renesas/rswitch.c +@@ -1632,8 +1632,9 @@ static netdev_tx_t rswitch_start_xmit(struct sk_buff *skb, struct net_device *nd + if (dma_mapping_error(ndev->dev.parent, dma_addr_orig)) + goto err_kfree; + +- gq->skbs[gq->cur] = skb; +- gq->unmap_addrs[gq->cur] = dma_addr_orig; ++ /* Stored the skb at the last descriptor to avoid skb free before hardware completes send */ ++ gq->skbs[(gq->cur + nr_desc - 1) % gq->ring_size] = skb; ++ gq->unmap_addrs[(gq->cur + nr_desc - 1) % gq->ring_size] = dma_addr_orig; + + dma_wmb(); + +diff --git a/drivers/net/ethernet/sfc/tc_conntrack.c b/drivers/net/ethernet/sfc/tc_conntrack.c +index 44bb57670340da..109d2aa34ae332 100644 +--- a/drivers/net/ethernet/sfc/tc_conntrack.c ++++ b/drivers/net/ethernet/sfc/tc_conntrack.c +@@ -16,7 +16,7 @@ static int efx_tc_flow_block(enum tc_setup_type type, void *type_data, + void *cb_priv); + + static const struct rhashtable_params efx_tc_ct_zone_ht_params = { +- .key_len = offsetof(struct efx_tc_ct_zone, linkage), ++ .key_len = sizeof_field(struct efx_tc_ct_zone, zone), + .key_offset = 0, + .head_offset = offsetof(struct efx_tc_ct_zone, linkage), + }; +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +index b4fdd40be63cb4..4d570efd9d4bbe 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +@@ -296,62 +296,80 @@ static int stmmac_mtl_setup(struct platform_device *pdev, + } + + /** +- * stmmac_dt_phy - parse device-tree driver parameters to allocate PHY resources +- * @plat: driver data platform structure +- * @np: device tree node +- * @dev: device pointer +- * Description: +- * The mdio bus will be allocated in case of a phy transceiver is on board; +- * it will be NULL if the fixed-link is configured. +- * If there is the "snps,dwmac-mdio" sub-node the mdio will be allocated +- * in any case (for DSA, mdio must be registered even if fixed-link). +- * The table below sums the supported configurations: +- * ------------------------------- +- * snps,phy-addr | Y +- * ------------------------------- +- * phy-handle | Y +- * ------------------------------- +- * fixed-link | N +- * ------------------------------- +- * snps,dwmac-mdio | +- * even if | Y +- * fixed-link | +- * ------------------------------- ++ * stmmac_of_get_mdio() - Gets the MDIO bus from the devicetree. ++ * @np: devicetree node ++ * ++ * The MDIO bus will be searched for in the following ways: ++ * 1. The compatible is "snps,dwc-qos-ethernet-4.10" && a "mdio" named ++ * child node exists ++ * 2. A child node with the "snps,dwmac-mdio" compatible is present + * +- * It returns 0 in case of success otherwise -ENODEV. ++ * Return: The MDIO node if present otherwise NULL + */ +-static int stmmac_dt_phy(struct plat_stmmacenet_data *plat, +- struct device_node *np, struct device *dev) ++static struct device_node *stmmac_of_get_mdio(struct device_node *np) + { +- bool mdio = !of_phy_is_fixed_link(np); + static const struct of_device_id need_mdio_ids[] = { + { .compatible = "snps,dwc-qos-ethernet-4.10" }, + {}, + }; ++ struct device_node *mdio_node = NULL; + + if (of_match_node(need_mdio_ids, np)) { +- plat->mdio_node = of_get_child_by_name(np, "mdio"); ++ mdio_node = of_get_child_by_name(np, "mdio"); + } else { + /** + * If snps,dwmac-mdio is passed from DT, always register + * the MDIO + */ +- for_each_child_of_node(np, plat->mdio_node) { +- if (of_device_is_compatible(plat->mdio_node, ++ for_each_child_of_node(np, mdio_node) { ++ if (of_device_is_compatible(mdio_node, + "snps,dwmac-mdio")) + break; + } + } + +- if (plat->mdio_node) { ++ return mdio_node; ++} ++ ++/** ++ * stmmac_mdio_setup() - Populate platform related MDIO structures. ++ * @plat: driver data platform structure ++ * @np: devicetree node ++ * @dev: device pointer ++ * ++ * This searches for MDIO information from the devicetree. ++ * If an MDIO node is found, it's assigned to plat->mdio_node and ++ * plat->mdio_bus_data is allocated. ++ * If no connection can be determined, just plat->mdio_bus_data is allocated ++ * to indicate a bus should be created and scanned for a phy. ++ * If it's determined there's no MDIO bus needed, both are left NULL. ++ * ++ * This expects that plat->phy_node has already been searched for. ++ * ++ * Return: 0 on success, errno otherwise. ++ */ ++static int stmmac_mdio_setup(struct plat_stmmacenet_data *plat, ++ struct device_node *np, struct device *dev) ++{ ++ bool legacy_mdio; ++ ++ plat->mdio_node = stmmac_of_get_mdio(np); ++ if (plat->mdio_node) + dev_dbg(dev, "Found MDIO subnode\n"); +- mdio = true; +- } + +- if (mdio) { +- plat->mdio_bus_data = +- devm_kzalloc(dev, sizeof(struct stmmac_mdio_bus_data), +- GFP_KERNEL); ++ /* Legacy devicetrees allowed for no MDIO bus description and expect ++ * the bus to be scanned for devices. If there's no phy or fixed-link ++ * described assume this is the case since there must be something ++ * connected to the MAC. ++ */ ++ legacy_mdio = !of_phy_is_fixed_link(np) && !plat->phy_node; ++ if (legacy_mdio) ++ dev_info(dev, "Deprecated MDIO bus assumption used\n"); ++ ++ if (plat->mdio_node || legacy_mdio) { ++ plat->mdio_bus_data = devm_kzalloc(dev, ++ sizeof(*plat->mdio_bus_data), ++ GFP_KERNEL); + if (!plat->mdio_bus_data) + return -ENOMEM; + +@@ -455,10 +473,11 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) + if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0) + dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n"); + +- /* To Configure PHY by using all device-tree supported properties */ +- rc = stmmac_dt_phy(plat, np, &pdev->dev); +- if (rc) +- return ERR_PTR(rc); ++ rc = stmmac_mdio_setup(plat, np, &pdev->dev); ++ if (rc) { ++ ret = ERR_PTR(rc); ++ goto error_put_phy; ++ } + + of_property_read_u32(np, "tx-fifo-depth", &plat->tx_fifo_size); + +@@ -547,8 +566,8 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) + dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg), + GFP_KERNEL); + if (!dma_cfg) { +- stmmac_remove_config_dt(pdev, plat); +- return ERR_PTR(-ENOMEM); ++ ret = ERR_PTR(-ENOMEM); ++ goto error_put_mdio; + } + plat->dma_cfg = dma_cfg; + +@@ -576,8 +595,8 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) + + rc = stmmac_mtl_setup(pdev, plat); + if (rc) { +- stmmac_remove_config_dt(pdev, plat); +- return ERR_PTR(rc); ++ ret = ERR_PTR(rc); ++ goto error_put_mdio; + } + + /* clock setup */ +@@ -629,6 +648,10 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) + clk_disable_unprepare(plat->pclk); + error_pclk_get: + clk_disable_unprepare(plat->stmmac_clk); ++error_put_mdio: ++ of_node_put(plat->mdio_node); ++error_put_phy: ++ of_node_put(plat->phy_node); + + return ret; + } +@@ -637,16 +660,17 @@ static void devm_stmmac_remove_config_dt(void *data) + { + struct plat_stmmacenet_data *plat = data; + +- /* Platform data argument is unused */ +- stmmac_remove_config_dt(NULL, plat); ++ clk_disable_unprepare(plat->stmmac_clk); ++ clk_disable_unprepare(plat->pclk); ++ of_node_put(plat->mdio_node); ++ of_node_put(plat->phy_node); + } + + /** + * devm_stmmac_probe_config_dt + * @pdev: platform_device structure + * @mac: MAC address to use +- * Description: Devres variant of stmmac_probe_config_dt(). Does not require +- * the user to call stmmac_remove_config_dt() at driver detach. ++ * Description: Devres variant of stmmac_probe_config_dt(). + */ + struct plat_stmmacenet_data * + devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) +diff --git a/drivers/net/ethernet/ti/icssg/icss_iep.c b/drivers/net/ethernet/ti/icssg/icss_iep.c +index 3025e9c189702b..f06cdec14ed7a1 100644 +--- a/drivers/net/ethernet/ti/icssg/icss_iep.c ++++ b/drivers/net/ethernet/ti/icssg/icss_iep.c +@@ -290,6 +290,9 @@ static void icss_iep_enable_shadow_mode(struct icss_iep *iep) + for (cmp = IEP_MIN_CMP; cmp < IEP_MAX_CMP; cmp++) { + regmap_update_bits(iep->map, ICSS_IEP_CMP_STAT_REG, + IEP_CMP_STATUS(cmp), IEP_CMP_STATUS(cmp)); ++ ++ regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG, ++ IEP_CMP_CFG_CMP_EN(cmp), 0); + } + + /* enable reset counter on CMP0 event */ +@@ -808,6 +811,11 @@ int icss_iep_exit(struct icss_iep *iep) + } + icss_iep_disable(iep); + ++ if (iep->pps_enabled) ++ icss_iep_pps_enable(iep, false); ++ else if (iep->perout_enabled) ++ icss_iep_perout_enable(iep, NULL, false); ++ + return 0; + } + EXPORT_SYMBOL_GPL(icss_iep_exit); +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index 89775b6d0699a0..8e30df676ededb 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -1373,6 +1373,9 @@ static const struct usb_device_id products[] = { + {QMI_QUIRK_SET_DTR(0x1bc7, 0x10a0, 0)}, /* Telit FN920C04 */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x10a4, 0)}, /* Telit FN920C04 */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x10a9, 0)}, /* Telit FN920C04 */ ++ {QMI_QUIRK_SET_DTR(0x1bc7, 0x10c0, 0)}, /* Telit FE910C04 */ ++ {QMI_QUIRK_SET_DTR(0x1bc7, 0x10c4, 0)}, /* Telit FE910C04 */ ++ {QMI_QUIRK_SET_DTR(0x1bc7, 0x10c8, 0)}, /* Telit FE910C04 */ + {QMI_FIXED_INTF(0x1bc7, 0x1100, 3)}, /* Telit ME910 */ + {QMI_FIXED_INTF(0x1bc7, 0x1101, 3)}, /* Telit ME910 dual modem */ + {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ +diff --git a/drivers/net/wireless/ath/ath10k/bmi.c b/drivers/net/wireless/ath/ath10k/bmi.c +index af6546572df26b..9a4f8e815412cb 100644 +--- a/drivers/net/wireless/ath/ath10k/bmi.c ++++ b/drivers/net/wireless/ath/ath10k/bmi.c +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2014,2016-2017 Qualcomm Atheros, Inc. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include "bmi.h" +diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c +index c27b8204718a6d..afae4a8027f833 100644 +--- a/drivers/net/wireless/ath/ath10k/ce.c ++++ b/drivers/net/wireless/ath/ath10k/ce.c +@@ -3,6 +3,7 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include "hif.h" +diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c +index 81058be3598f15..c3a8b3496be2a5 100644 +--- a/drivers/net/wireless/ath/ath10k/core.c ++++ b/drivers/net/wireless/ath/ath10k/core.c +@@ -3,6 +3,7 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include +diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h +index 4b5239de401840..cb2359d2ee0b04 100644 +--- a/drivers/net/wireless/ath/ath10k/core.h ++++ b/drivers/net/wireless/ath/ath10k/core.h +@@ -3,6 +3,7 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef _CORE_H_ +diff --git a/drivers/net/wireless/ath/ath10k/coredump.c b/drivers/net/wireless/ath/ath10k/coredump.c +index 2d1634a890dde3..bb3a276b7ed584 100644 +--- a/drivers/net/wireless/ath/ath10k/coredump.c ++++ b/drivers/net/wireless/ath/ath10k/coredump.c +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include "coredump.h" +diff --git a/drivers/net/wireless/ath/ath10k/coredump.h b/drivers/net/wireless/ath/ath10k/coredump.h +index 437b9759f05d3d..e5ef0352e319c7 100644 +--- a/drivers/net/wireless/ath/ath10k/coredump.h ++++ b/drivers/net/wireless/ath/ath10k/coredump.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: ISC */ + /* + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef _COREDUMP_H_ +diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c +index fe89bc61e5317d..92ad0a04bcc738 100644 +--- a/drivers/net/wireless/ath/ath10k/debug.c ++++ b/drivers/net/wireless/ath/ath10k/debug.c +@@ -3,6 +3,7 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include +diff --git a/drivers/net/wireless/ath/ath10k/debugfs_sta.c b/drivers/net/wireless/ath/ath10k/debugfs_sta.c +index 5598cf706daabc..0f6de862c3a9ba 100644 +--- a/drivers/net/wireless/ath/ath10k/debugfs_sta.c ++++ b/drivers/net/wireless/ath/ath10k/debugfs_sta.c +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2014-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include "core.h" +diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c +index 5bfeecb95fca23..a6e21ce90bad64 100644 +--- a/drivers/net/wireless/ath/ath10k/htc.c ++++ b/drivers/net/wireless/ath/ath10k/htc.c +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include "core.h" +diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h +index 7b24297146e72a..52f6dc6b81c5ee 100644 +--- a/drivers/net/wireless/ath/ath10k/htt.h ++++ b/drivers/net/wireless/ath/ath10k/htt.h +@@ -3,6 +3,7 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021, 2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef _HTT_H_ +diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c +index 438b0caaceb79e..51855f23ea2664 100644 +--- a/drivers/net/wireless/ath/ath10k/htt_rx.c ++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c +@@ -3,6 +3,7 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include "core.h" +diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c +index bd603feb795314..60425d22d70790 100644 +--- a/drivers/net/wireless/ath/ath10k/htt_tx.c ++++ b/drivers/net/wireless/ath/ath10k/htt_tx.c +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include +diff --git a/drivers/net/wireless/ath/ath10k/hw.c b/drivers/net/wireless/ath/ath10k/hw.c +index 6d32b43a4da65e..8fafe096adff53 100644 +--- a/drivers/net/wireless/ath/ath10k/hw.c ++++ b/drivers/net/wireless/ath/ath10k/hw.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: ISC + /* + * Copyright (c) 2014-2017 Qualcomm Atheros, Inc. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include +diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h +index 7ecdd0011cfa48..afd336282615c6 100644 +--- a/drivers/net/wireless/ath/ath10k/hw.h ++++ b/drivers/net/wireless/ath/ath10k/hw.h +@@ -3,6 +3,7 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef _HW_H_ +diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c +index d5e6e11f630b95..655fb5cdf01f86 100644 +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -3,6 +3,7 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include "mac.h" +diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c +index 23f36622193908..aaa240f3c08a9f 100644 +--- a/drivers/net/wireless/ath/ath10k/pci.c ++++ b/drivers/net/wireless/ath/ath10k/pci.c +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include +diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h +index 480cd97ab739de..27bb4cf2dfea93 100644 +--- a/drivers/net/wireless/ath/ath10k/pci.h ++++ b/drivers/net/wireless/ath/ath10k/pci.h +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef _PCI_H_ +diff --git a/drivers/net/wireless/ath/ath10k/qmi.c b/drivers/net/wireless/ath/ath10k/qmi.c +index 52c1a3de8da60a..38e939f572a9ed 100644 +--- a/drivers/net/wireless/ath/ath10k/qmi.c ++++ b/drivers/net/wireless/ath/ath10k/qmi.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: ISC + /* + * Copyright (c) 2018 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include +diff --git a/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c b/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c +index 1c81e454f943fd..0e85c75d227836 100644 +--- a/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c ++++ b/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: ISC + /* + * Copyright (c) 2018 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include +diff --git a/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h b/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h +index f0db991408dc26..9f311f3bc9e7f9 100644 +--- a/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h ++++ b/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: ISC */ + /* + * Copyright (c) 2018 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef WCN3990_QMI_SVC_V01_H +diff --git a/drivers/net/wireless/ath/ath10k/rx_desc.h b/drivers/net/wireless/ath/ath10k/rx_desc.h +index 777e53aa69dc86..564293df1e9acf 100644 +--- a/drivers/net/wireless/ath/ath10k/rx_desc.h ++++ b/drivers/net/wireless/ath/ath10k/rx_desc.h +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef _RX_DESC_H_ +diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c +index 56fbcfb80bf886..850d999615a2c3 100644 +--- a/drivers/net/wireless/ath/ath10k/sdio.c ++++ b/drivers/net/wireless/ath/ath10k/sdio.c +@@ -3,6 +3,7 @@ + * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012,2017 Qualcomm Atheros, Inc. + * Copyright (c) 2016-2017 Erik Stromdahl ++ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include +@@ -2647,9 +2648,9 @@ static void ath10k_sdio_remove(struct sdio_func *func) + + netif_napi_del(&ar->napi); + +- ath10k_core_destroy(ar); +- + destroy_workqueue(ar_sdio->workqueue); ++ ++ ath10k_core_destroy(ar); + } + + static const struct sdio_device_id ath10k_sdio_devices[] = { +diff --git a/drivers/net/wireless/ath/ath10k/thermal.c b/drivers/net/wireless/ath/ath10k/thermal.c +index cefd97323dfe50..31c8d7fbb0955b 100644 +--- a/drivers/net/wireless/ath/ath10k/thermal.c ++++ b/drivers/net/wireless/ath/ath10k/thermal.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: ISC + /* + * Copyright (c) 2014-2015 Qualcomm Atheros, Inc. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include +diff --git a/drivers/net/wireless/ath/ath10k/usb.h b/drivers/net/wireless/ath/ath10k/usb.h +index 48e066ba816249..7e4cfbb673c9a8 100644 +--- a/drivers/net/wireless/ath/ath10k/usb.h ++++ b/drivers/net/wireless/ath/ath10k/usb.h +@@ -3,6 +3,7 @@ + * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. + * Copyright (c) 2016-2017 Erik Stromdahl ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef _USB_H_ +diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h +index dbb48d70f2e93e..83a8f07a687f73 100644 +--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h ++++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h +@@ -3,6 +3,7 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + #ifndef _WMI_TLV_H + #define _WMI_TLV_H +diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c +index 1c21dbde77b84e..818aea99f85eb3 100644 +--- a/drivers/net/wireless/ath/ath10k/wmi.c ++++ b/drivers/net/wireless/ath/ath10k/wmi.c +@@ -3,6 +3,7 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include +diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h +index b112e88260931c..9146df98fceeee 100644 +--- a/drivers/net/wireless/ath/ath10k/wmi.h ++++ b/drivers/net/wireless/ath/ath10k/wmi.h +@@ -3,6 +3,7 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef _WMI_H_ +diff --git a/drivers/net/wireless/ath/ath10k/wow.c b/drivers/net/wireless/ath/ath10k/wow.c +index 20b9aa8ddf7d52..aa7b2e703f3d4b 100644 +--- a/drivers/net/wireless/ath/ath10k/wow.c ++++ b/drivers/net/wireless/ath/ath10k/wow.c +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2015-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include "mac.h" +diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c +index f90191a290c26a..713899735ccc5e 100644 +--- a/drivers/net/wireless/ath/ath12k/mac.c ++++ b/drivers/net/wireless/ath/ath12k/mac.c +@@ -4945,7 +4945,7 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw, + if (ret) { + ath12k_warn(ar->ab, "failed to queue management frame %d\n", + ret); +- ieee80211_free_txskb(ar->hw, skb); ++ ieee80211_free_txskb(hw, skb); + } + return; + } +@@ -4953,7 +4953,7 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw, + ret = ath12k_dp_tx(ar, arvif, skb); + if (ret) { + ath12k_warn(ar->ab, "failed to transmit frame %d\n", ret); +- ieee80211_free_txskb(ar->hw, skb); ++ ieee80211_free_txskb(hw, skb); + } + } + +@@ -5496,7 +5496,7 @@ static int ath12k_mac_op_add_interface(struct ieee80211_hw *hw, + goto err_peer_del; + + param_id = WMI_VDEV_PARAM_RTS_THRESHOLD; +- param_value = ar->hw->wiphy->rts_threshold; ++ param_value = hw->wiphy->rts_threshold; + ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, + param_id, param_value); + if (ret) { +@@ -6676,9 +6676,9 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, + arvif->vdev_id, ret); + return ret; + } +- ieee80211_iterate_stations_atomic(ar->hw, +- ath12k_mac_disable_peer_fixed_rate, +- arvif); ++ ieee80211_iterate_stations_mtx(hw, ++ ath12k_mac_disable_peer_fixed_rate, ++ arvif); + } else if (ath12k_mac_bitrate_mask_get_single_nss(ar, band, mask, + &single_nss)) { + rate = WMI_FIXED_RATE_NONE; +@@ -6722,16 +6722,16 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, + return -EINVAL; + } + +- ieee80211_iterate_stations_atomic(ar->hw, +- ath12k_mac_disable_peer_fixed_rate, +- arvif); ++ ieee80211_iterate_stations_mtx(hw, ++ ath12k_mac_disable_peer_fixed_rate, ++ arvif); + + mutex_lock(&ar->conf_mutex); + + arvif->bitrate_mask = *mask; +- ieee80211_iterate_stations_atomic(ar->hw, +- ath12k_mac_set_bitrate_mask_iter, +- arvif); ++ ieee80211_iterate_stations_mtx(hw, ++ ath12k_mac_set_bitrate_mask_iter, ++ arvif); + + mutex_unlock(&ar->conf_mutex); + } +@@ -6767,7 +6767,7 @@ ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw, + ath12k_warn(ar->ab, "pdev %d successfully recovered\n", + ar->pdev->pdev_id); + ar->state = ATH12K_STATE_ON; +- ieee80211_wake_queues(ar->hw); ++ ieee80211_wake_queues(hw); + + if (ab->is_reset) { + recovery_count = atomic_inc_return(&ab->recovery_count); +diff --git a/drivers/net/wireless/ath/ath12k/reg.c b/drivers/net/wireless/ath/ath12k/reg.c +index 32bdefeccc2453..837a3e1ec3a49c 100644 +--- a/drivers/net/wireless/ath/ath12k/reg.c ++++ b/drivers/net/wireless/ath/ath12k/reg.c +@@ -28,11 +28,11 @@ static const struct ieee80211_regdomain ath12k_world_regd = { + } + }; + +-static bool ath12k_regdom_changes(struct ath12k *ar, char *alpha2) ++static bool ath12k_regdom_changes(struct ieee80211_hw *hw, char *alpha2) + { + const struct ieee80211_regdomain *regd; + +- regd = rcu_dereference_rtnl(ar->hw->wiphy->regd); ++ regd = rcu_dereference_rtnl(hw->wiphy->regd); + /* This can happen during wiphy registration where the previous + * user request is received before we update the regd received + * from firmware. +@@ -71,7 +71,7 @@ ath12k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) + return; + } + +- if (!ath12k_regdom_changes(ar, request->alpha2)) { ++ if (!ath12k_regdom_changes(hw, request->alpha2)) { + ath12k_dbg(ar->ab, ATH12K_DBG_REG, "Country is already set\n"); + return; + } +diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c +index 0cae5746f540fa..5bd1ee81210d1d 100644 +--- a/drivers/net/wireless/realtek/rtw88/sdio.c ++++ b/drivers/net/wireless/realtek/rtw88/sdio.c +@@ -1295,12 +1295,12 @@ static void rtw_sdio_deinit_tx(struct rtw_dev *rtwdev) + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + int i; + +- for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++) +- skb_queue_purge(&rtwsdio->tx_queue[i]); +- + flush_workqueue(rtwsdio->txwq); + destroy_workqueue(rtwsdio->txwq); + kfree(rtwsdio->tx_handler_data); ++ ++ for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++) ++ ieee80211_purge_tx_queue(rtwdev->hw, &rtwsdio->tx_queue[i]); + } + + int rtw_sdio_probe(struct sdio_func *sdio_func, +diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c +index 04a64afcbf8a2d..8f1d653282b7ec 100644 +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -416,10 +416,11 @@ static void rtw_usb_tx_handler(struct work_struct *work) + + static void rtw_usb_tx_queue_purge(struct rtw_usb *rtwusb) + { ++ struct rtw_dev *rtwdev = rtwusb->rtwdev; + int i; + + for (i = 0; i < ARRAY_SIZE(rtwusb->tx_queue); i++) +- skb_queue_purge(&rtwusb->tx_queue[i]); ++ ieee80211_purge_tx_queue(rtwdev->hw, &rtwusb->tx_queue[i]); + } + + static void rtw_usb_write_port_complete(struct urb *urb) +@@ -801,9 +802,9 @@ static void rtw_usb_deinit_tx(struct rtw_dev *rtwdev) + { + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + +- rtw_usb_tx_queue_purge(rtwusb); + flush_workqueue(rtwusb->txwq); + destroy_workqueue(rtwusb->txwq); ++ rtw_usb_tx_queue_purge(rtwusb); + } + + static int rtw_usb_intf_init(struct rtw_dev *rtwdev, +diff --git a/drivers/net/wwan/iosm/iosm_ipc_mmio.c b/drivers/net/wwan/iosm/iosm_ipc_mmio.c +index 63eb08c43c0517..6764c13530b9bd 100644 +--- a/drivers/net/wwan/iosm/iosm_ipc_mmio.c ++++ b/drivers/net/wwan/iosm/iosm_ipc_mmio.c +@@ -104,7 +104,7 @@ struct iosm_mmio *ipc_mmio_init(void __iomem *mmio, struct device *dev) + break; + + msleep(20); +- } while (retries-- > 0); ++ } while (--retries > 0); + + if (!retries) { + dev_err(ipc_mmio->dev, "invalid exec stage %X", stage); +diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c b/drivers/net/wwan/t7xx/t7xx_state_monitor.c +index 80edb8e75a6ad7..64868df3640d13 100644 +--- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c ++++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c +@@ -97,14 +97,21 @@ void t7xx_fsm_broadcast_state(struct t7xx_fsm_ctl *ctl, enum md_state state) + fsm_state_notify(ctl->md, state); + } + ++static void fsm_release_command(struct kref *ref) ++{ ++ struct t7xx_fsm_command *cmd = container_of(ref, typeof(*cmd), refcnt); ++ ++ kfree(cmd); ++} ++ + static void fsm_finish_command(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command *cmd, int result) + { + if (cmd->flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) { +- *cmd->ret = result; +- complete_all(cmd->done); ++ cmd->result = result; ++ complete_all(&cmd->done); + } + +- kfree(cmd); ++ kref_put(&cmd->refcnt, fsm_release_command); + } + + static void fsm_del_kf_event(struct t7xx_fsm_event *event) +@@ -396,7 +403,6 @@ static int fsm_main_thread(void *data) + + int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id, unsigned int flag) + { +- DECLARE_COMPLETION_ONSTACK(done); + struct t7xx_fsm_command *cmd; + unsigned long flags; + int ret; +@@ -408,11 +414,13 @@ int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id + INIT_LIST_HEAD(&cmd->entry); + cmd->cmd_id = cmd_id; + cmd->flag = flag; ++ kref_init(&cmd->refcnt); + if (flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) { +- cmd->done = &done; +- cmd->ret = &ret; ++ init_completion(&cmd->done); ++ kref_get(&cmd->refcnt); + } + ++ kref_get(&cmd->refcnt); + spin_lock_irqsave(&ctl->command_lock, flags); + list_add_tail(&cmd->entry, &ctl->command_queue); + spin_unlock_irqrestore(&ctl->command_lock, flags); +@@ -422,11 +430,11 @@ int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id + if (flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) { + unsigned long wait_ret; + +- wait_ret = wait_for_completion_timeout(&done, ++ wait_ret = wait_for_completion_timeout(&cmd->done, + msecs_to_jiffies(FSM_CMD_TIMEOUT_MS)); +- if (!wait_ret) +- return -ETIMEDOUT; + ++ ret = wait_ret ? cmd->result : -ETIMEDOUT; ++ kref_put(&cmd->refcnt, fsm_release_command); + return ret; + } + +diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.h b/drivers/net/wwan/t7xx/t7xx_state_monitor.h +index b6e76f3903c892..74f96fd2605e8e 100644 +--- a/drivers/net/wwan/t7xx/t7xx_state_monitor.h ++++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.h +@@ -109,8 +109,9 @@ struct t7xx_fsm_command { + struct list_head entry; + enum t7xx_fsm_cmd_state cmd_id; + unsigned int flag; +- struct completion *done; +- int *ret; ++ struct completion done; ++ int result; ++ struct kref refcnt; + }; + + struct t7xx_fsm_notifier { +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 5b6a6bd4e6e800..4aad16390d4790 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -1178,13 +1178,13 @@ static void nvme_queue_keep_alive_work(struct nvme_ctrl *ctrl) + nvme_keep_alive_work_period(ctrl)); + } + +-static void nvme_keep_alive_finish(struct request *rq, +- blk_status_t status, struct nvme_ctrl *ctrl) ++static enum rq_end_io_ret nvme_keep_alive_end_io(struct request *rq, ++ blk_status_t status) + { +- unsigned long flags; +- bool startka = false; ++ struct nvme_ctrl *ctrl = rq->end_io_data; + unsigned long rtt = jiffies - (rq->deadline - rq->timeout); + unsigned long delay = nvme_keep_alive_work_period(ctrl); ++ enum nvme_ctrl_state state = nvme_ctrl_state(ctrl); + + /* + * Subtract off the keepalive RTT so nvme_keep_alive_work runs +@@ -1198,22 +1198,20 @@ static void nvme_keep_alive_finish(struct request *rq, + delay = 0; + } + ++ blk_mq_free_request(rq); ++ + if (status) { + dev_err(ctrl->device, + "failed nvme_keep_alive_end_io error=%d\n", + status); +- return; ++ return RQ_END_IO_NONE; + } + + ctrl->ka_last_check_time = jiffies; + ctrl->comp_seen = false; +- spin_lock_irqsave(&ctrl->lock, flags); +- if (ctrl->state == NVME_CTRL_LIVE || +- ctrl->state == NVME_CTRL_CONNECTING) +- startka = true; +- spin_unlock_irqrestore(&ctrl->lock, flags); +- if (startka) ++ if (state == NVME_CTRL_LIVE || state == NVME_CTRL_CONNECTING) + queue_delayed_work(nvme_wq, &ctrl->ka_work, delay); ++ return RQ_END_IO_NONE; + } + + static void nvme_keep_alive_work(struct work_struct *work) +@@ -1222,7 +1220,6 @@ static void nvme_keep_alive_work(struct work_struct *work) + struct nvme_ctrl, ka_work); + bool comp_seen = ctrl->comp_seen; + struct request *rq; +- blk_status_t status; + + ctrl->ka_last_check_time = jiffies; + +@@ -1245,9 +1242,9 @@ static void nvme_keep_alive_work(struct work_struct *work) + nvme_init_request(rq, &ctrl->ka_cmd); + + rq->timeout = ctrl->kato * HZ; +- status = blk_execute_rq(rq, false); +- nvme_keep_alive_finish(rq, status, ctrl); +- blk_mq_free_request(rq); ++ rq->end_io = nvme_keep_alive_end_io; ++ rq->end_io_data = ctrl; ++ blk_execute_rq_nowait(rq, false); + } + + static void nvme_start_keep_alive(struct nvme_ctrl *ctrl) +diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h +index bddc068d58c7ea..e867ac859a878e 100644 +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -172,6 +172,11 @@ enum nvme_quirks { + * MSI (but not MSI-X) interrupts are broken and never fire. + */ + NVME_QUIRK_BROKEN_MSI = (1 << 21), ++ ++ /* ++ * Align dma pool segment size to 512 bytes ++ */ ++ NVME_QUIRK_DMAPOOL_ALIGN_512 = (1 << 22), + }; + + /* +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index d525fa1229d791..52c8fd3d5c4796 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -2653,15 +2653,20 @@ static int nvme_disable_prepare_reset(struct nvme_dev *dev, bool shutdown) + + static int nvme_setup_prp_pools(struct nvme_dev *dev) + { ++ size_t small_align = 256; ++ + dev->prp_page_pool = dma_pool_create("prp list page", dev->dev, + NVME_CTRL_PAGE_SIZE, + NVME_CTRL_PAGE_SIZE, 0); + if (!dev->prp_page_pool) + return -ENOMEM; + ++ if (dev->ctrl.quirks & NVME_QUIRK_DMAPOOL_ALIGN_512) ++ small_align = 512; ++ + /* Optimisation for I/Os between 4k and 128k */ + dev->prp_small_pool = dma_pool_create("prp list 256", dev->dev, +- 256, 256, 0); ++ 256, small_align, 0); + if (!dev->prp_small_pool) { + dma_pool_destroy(dev->prp_page_pool); + return -ENOMEM; +@@ -3403,7 +3408,7 @@ static const struct pci_device_id nvme_id_table[] = { + { PCI_VDEVICE(REDHAT, 0x0010), /* Qemu emulated controller */ + .driver_data = NVME_QUIRK_BOGUS_NID, }, + { PCI_DEVICE(0x1217, 0x8760), /* O2 Micro 64GB Steam Deck */ +- .driver_data = NVME_QUIRK_QDEPTH_ONE }, ++ .driver_data = NVME_QUIRK_DMAPOOL_ALIGN_512, }, + { PCI_DEVICE(0x126f, 0x2262), /* Silicon Motion generic */ + .driver_data = NVME_QUIRK_NO_DEEPEST_PS | + NVME_QUIRK_BOGUS_NID, }, +diff --git a/drivers/of/address.c b/drivers/of/address.c +index dfd05cb2b2fcfa..34d880a1be0a5e 100644 +--- a/drivers/of/address.c ++++ b/drivers/of/address.c +@@ -46,7 +46,7 @@ struct of_bus { + u64 (*map)(__be32 *addr, const __be32 *range, + int na, int ns, int pna); + int (*translate)(__be32 *addr, u64 offset, int na); +- bool has_flags; ++ int flag_cells; + unsigned int (*get_flags)(const __be32 *addr); + }; + +@@ -217,10 +217,6 @@ static u64 of_bus_pci_map(__be32 *addr, const __be32 *range, int na, int ns, + return da - cp; + } + +-static int of_bus_pci_translate(__be32 *addr, u64 offset, int na) +-{ +- return of_bus_default_translate(addr + 1, offset, na - 1); +-} + #endif /* CONFIG_PCI */ + + /* +@@ -344,11 +340,6 @@ static u64 of_bus_isa_map(__be32 *addr, const __be32 *range, int na, int ns, + return da - cp; + } + +-static int of_bus_isa_translate(__be32 *addr, u64 offset, int na) +-{ +- return of_bus_default_translate(addr + 1, offset, na - 1); +-} +- + static unsigned int of_bus_isa_get_flags(const __be32 *addr) + { + unsigned int flags = 0; +@@ -379,8 +370,8 @@ static struct of_bus of_busses[] = { + .match = of_bus_pci_match, + .count_cells = of_bus_pci_count_cells, + .map = of_bus_pci_map, +- .translate = of_bus_pci_translate, +- .has_flags = true, ++ .translate = of_bus_default_flags_translate, ++ .flag_cells = 1, + .get_flags = of_bus_pci_get_flags, + }, + #endif /* CONFIG_PCI */ +@@ -391,8 +382,8 @@ static struct of_bus of_busses[] = { + .match = of_bus_isa_match, + .count_cells = of_bus_isa_count_cells, + .map = of_bus_isa_map, +- .translate = of_bus_isa_translate, +- .has_flags = true, ++ .translate = of_bus_default_flags_translate, ++ .flag_cells = 1, + .get_flags = of_bus_isa_get_flags, + }, + /* Default with flags cell */ +@@ -403,7 +394,7 @@ static struct of_bus of_busses[] = { + .count_cells = of_bus_default_count_cells, + .map = of_bus_default_flags_map, + .translate = of_bus_default_flags_translate, +- .has_flags = true, ++ .flag_cells = 1, + .get_flags = of_bus_default_flags_get_flags, + }, + /* Default */ +@@ -485,7 +476,8 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, + } + if (ranges == NULL || rlen == 0) { + offset = of_read_number(addr, na); +- memset(addr, 0, pna * 4); ++ /* set address to zero, pass flags through */ ++ memset(addr + pbus->flag_cells, 0, (pna - pbus->flag_cells) * 4); + pr_debug("empty ranges; 1:1 translation\n"); + goto finish; + } +@@ -836,7 +828,7 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser, + int na = parser->na; + int ns = parser->ns; + int np = parser->pna + na + ns; +- int busflag_na = 0; ++ int busflag_na = parser->bus->flag_cells; + + if (!range) + return NULL; +@@ -846,10 +838,6 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser, + + range->flags = parser->bus->get_flags(parser->range); + +- /* A extra cell for resource flags */ +- if (parser->bus->has_flags) +- busflag_na = 1; +- + range->bus_addr = of_read_number(parser->range + busflag_na, na - busflag_na); + + if (parser->dma) +diff --git a/drivers/pinctrl/pinctrl-mcp23s08.c b/drivers/pinctrl/pinctrl-mcp23s08.c +index 4551575e4e7d7d..fd97b6ee2a8d11 100644 +--- a/drivers/pinctrl/pinctrl-mcp23s08.c ++++ b/drivers/pinctrl/pinctrl-mcp23s08.c +@@ -86,6 +86,7 @@ const struct regmap_config mcp23x08_regmap = { + .num_reg_defaults = ARRAY_SIZE(mcp23x08_defaults), + .cache_type = REGCACHE_FLAT, + .max_register = MCP_OLAT, ++ .disable_locking = true, /* mcp->lock protects the regmap */ + }; + EXPORT_SYMBOL_GPL(mcp23x08_regmap); + +@@ -132,6 +133,7 @@ const struct regmap_config mcp23x17_regmap = { + .num_reg_defaults = ARRAY_SIZE(mcp23x17_defaults), + .cache_type = REGCACHE_FLAT, + .val_format_endian = REGMAP_ENDIAN_LITTLE, ++ .disable_locking = true, /* mcp->lock protects the regmap */ + }; + EXPORT_SYMBOL_GPL(mcp23x17_regmap); + +@@ -228,7 +230,9 @@ static int mcp_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, + + switch (param) { + case PIN_CONFIG_BIAS_PULL_UP: ++ mutex_lock(&mcp->lock); + ret = mcp_read(mcp, MCP_GPPU, &data); ++ mutex_unlock(&mcp->lock); + if (ret < 0) + return ret; + status = (data & BIT(pin)) ? 1 : 0; +@@ -257,7 +261,9 @@ static int mcp_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, + + switch (param) { + case PIN_CONFIG_BIAS_PULL_UP: ++ mutex_lock(&mcp->lock); + ret = mcp_set_bit(mcp, MCP_GPPU, pin, arg); ++ mutex_unlock(&mcp->lock); + break; + default: + dev_dbg(mcp->dev, "Invalid config param %04x\n", param); +diff --git a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c +index a2ffe4157df10c..b8d77adc9ea145 100644 +--- a/drivers/platform/x86/mlx-platform.c ++++ b/drivers/platform/x86/mlx-platform.c +@@ -6237,6 +6237,7 @@ mlxplat_pci_fpga_device_init(unsigned int device, const char *res_name, struct p + fail_pci_request_regions: + pci_disable_device(pci_dev); + fail_pci_enable_device: ++ pci_dev_put(pci_dev); + return err; + } + +@@ -6247,6 +6248,7 @@ mlxplat_pci_fpga_device_exit(struct pci_dev *pci_bridge, + iounmap(pci_bridge_addr); + pci_release_regions(pci_bridge); + pci_disable_device(pci_bridge); ++ pci_dev_put(pci_bridge); + } + + static int +diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c +index 6235721f2c1aec..fd6bf9e77afcb8 100644 +--- a/drivers/remoteproc/qcom_q6v5_pas.c ++++ b/drivers/remoteproc/qcom_q6v5_pas.c +@@ -786,6 +786,23 @@ static const struct adsp_data adsp_resource_init = { + .ssctl_id = 0x14, + }; + ++static const struct adsp_data sa8775p_adsp_resource = { ++ .crash_reason_smem = 423, ++ .firmware_name = "adsp.mbn", ++ .pas_id = 1, ++ .minidump_id = 5, ++ .auto_boot = true, ++ .proxy_pd_names = (char*[]){ ++ "lcx", ++ "lmx", ++ NULL ++ }, ++ .load_state = "adsp", ++ .ssr_name = "lpass", ++ .sysmon_name = "adsp", ++ .ssctl_id = 0x14, ++}; ++ + static const struct adsp_data sdm845_adsp_resource_init = { + .crash_reason_smem = 423, + .firmware_name = "adsp.mdt", +@@ -885,6 +902,42 @@ static const struct adsp_data cdsp_resource_init = { + .ssctl_id = 0x17, + }; + ++static const struct adsp_data sa8775p_cdsp0_resource = { ++ .crash_reason_smem = 601, ++ .firmware_name = "cdsp0.mbn", ++ .pas_id = 18, ++ .minidump_id = 7, ++ .auto_boot = true, ++ .proxy_pd_names = (char*[]){ ++ "cx", ++ "mxc", ++ "nsp", ++ NULL ++ }, ++ .load_state = "cdsp", ++ .ssr_name = "cdsp", ++ .sysmon_name = "cdsp", ++ .ssctl_id = 0x17, ++}; ++ ++static const struct adsp_data sa8775p_cdsp1_resource = { ++ .crash_reason_smem = 633, ++ .firmware_name = "cdsp1.mbn", ++ .pas_id = 30, ++ .minidump_id = 20, ++ .auto_boot = true, ++ .proxy_pd_names = (char*[]){ ++ "cx", ++ "mxc", ++ "nsp", ++ NULL ++ }, ++ .load_state = "nsp", ++ .ssr_name = "cdsp1", ++ .sysmon_name = "cdsp1", ++ .ssctl_id = 0x20, ++}; ++ + static const struct adsp_data sdm845_cdsp_resource_init = { + .crash_reason_smem = 601, + .firmware_name = "cdsp.mdt", +@@ -987,6 +1040,40 @@ static const struct adsp_data sm8350_cdsp_resource = { + .ssctl_id = 0x17, + }; + ++static const struct adsp_data sa8775p_gpdsp0_resource = { ++ .crash_reason_smem = 640, ++ .firmware_name = "gpdsp0.mbn", ++ .pas_id = 39, ++ .minidump_id = 21, ++ .auto_boot = true, ++ .proxy_pd_names = (char*[]){ ++ "cx", ++ "mxc", ++ NULL ++ }, ++ .load_state = "gpdsp0", ++ .ssr_name = "gpdsp0", ++ .sysmon_name = "gpdsp0", ++ .ssctl_id = 0x21, ++}; ++ ++static const struct adsp_data sa8775p_gpdsp1_resource = { ++ .crash_reason_smem = 641, ++ .firmware_name = "gpdsp1.mbn", ++ .pas_id = 40, ++ .minidump_id = 22, ++ .auto_boot = true, ++ .proxy_pd_names = (char*[]){ ++ "cx", ++ "mxc", ++ NULL ++ }, ++ .load_state = "gpdsp1", ++ .ssr_name = "gpdsp1", ++ .sysmon_name = "gpdsp1", ++ .ssctl_id = 0x22, ++}; ++ + static const struct adsp_data mpss_resource_init = { + .crash_reason_smem = 421, + .firmware_name = "modem.mdt", +@@ -1163,6 +1250,13 @@ static const struct of_device_id adsp_of_match[] = { + { .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init }, + { .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init }, + { .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init }, ++ { .compatible = "qcom,sa8775p-adsp-pas", .data = &sa8775p_adsp_resource}, ++ { .compatible = "qcom,sa8775p-cdsp0-pas", .data = &sa8775p_cdsp0_resource}, ++ { .compatible = "qcom,sa8775p-cdsp1-pas", .data = &sa8775p_cdsp1_resource}, ++ { .compatible = "qcom,sa8775p-gpdsp0-pas", .data = &sa8775p_gpdsp0_resource}, ++ { .compatible = "qcom,sa8775p-gpdsp1-pas", .data = &sa8775p_gpdsp1_resource}, ++ { .compatible = "qcom,sar2130p-adsp-pas", .data = &sm8350_adsp_resource}, ++ { .compatible = "qcom,sc7180-adsp-pas", .data = &sm8250_adsp_resource}, + { .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init}, + { .compatible = "qcom,sc7280-mpss-pas", .data = &mpss_resource_init}, + { .compatible = "qcom,sc8180x-adsp-pas", .data = &sm8150_adsp_resource}, +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 9e73e9cbbcfc6c..1e4550156b735d 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -343,7 +343,7 @@ struct hisi_sas_hw { + u8 reg_index, u8 reg_count, u8 *write_data); + void (*wait_cmds_complete_timeout)(struct hisi_hba *hisi_hba, + int delay_ms, int timeout_ms); +- void (*debugfs_snapshot_regs)(struct hisi_hba *hisi_hba); ++ int (*debugfs_snapshot_regs)(struct hisi_hba *hisi_hba); + int complete_hdr_size; + const struct scsi_host_template *sht; + }; +@@ -451,7 +451,6 @@ struct hisi_hba { + const struct hisi_sas_hw *hw; /* Low level hw interface */ + unsigned long sata_dev_bitmap[BITS_TO_LONGS(HISI_SAS_MAX_DEVICES)]; + struct work_struct rst_work; +- struct work_struct debugfs_work; + u32 phy_state; + u32 intr_coal_ticks; /* Time of interrupt coalesce in us */ + u32 intr_coal_count; /* Interrupt count to coalesce */ +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index db9ae206974c21..f78c5f8a49ffac 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1579,7 +1579,7 @@ static int hisi_sas_controller_prereset(struct hisi_hba *hisi_hba) + return -EPERM; + } + +- if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct) ++ if (hisi_sas_debugfs_enable) + hisi_hba->hw->debugfs_snapshot_regs(hisi_hba); + + return 0; +@@ -1967,8 +1967,19 @@ static bool hisi_sas_internal_abort_timeout(struct sas_task *task, + struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); + struct hisi_sas_internal_abort_data *timeout = data; + +- if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct) +- queue_work(hisi_hba->wq, &hisi_hba->debugfs_work); ++ if (hisi_sas_debugfs_enable) { ++ /* ++ * If timeout occurs in device gone scenario, to avoid ++ * circular dependency like: ++ * hisi_sas_dev_gone() -> down() -> ... -> ++ * hisi_sas_internal_abort_timeout() -> down(). ++ */ ++ if (!timeout->rst_ha_timeout) ++ down(&hisi_hba->sem); ++ hisi_hba->hw->debugfs_snapshot_regs(hisi_hba); ++ if (!timeout->rst_ha_timeout) ++ up(&hisi_hba->sem); ++ } + + if (task->task_state_flags & SAS_TASK_STATE_DONE) { + pr_err("Internal abort: timeout %016llx\n", +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 4054659d48f74c..ff5f86867dbf06 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -558,8 +558,7 @@ static int experimental_iopoll_q_cnt; + module_param(experimental_iopoll_q_cnt, int, 0444); + MODULE_PARM_DESC(experimental_iopoll_q_cnt, "number of queues to be used as poll mode, def=0"); + +-static void debugfs_work_handler_v3_hw(struct work_struct *work); +-static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba); ++static int debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba); + + static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off) + { +@@ -3397,7 +3396,6 @@ hisi_sas_shost_alloc_pci(struct pci_dev *pdev) + hisi_hba = shost_priv(shost); + + INIT_WORK(&hisi_hba->rst_work, hisi_sas_rst_work_handler); +- INIT_WORK(&hisi_hba->debugfs_work, debugfs_work_handler_v3_hw); + hisi_hba->hw = &hisi_sas_v3_hw; + hisi_hba->pci_dev = pdev; + hisi_hba->dev = dev; +@@ -3562,6 +3560,11 @@ debugfs_to_reg_name_v3_hw(int off, int base_off, + return NULL; + } + ++static bool debugfs_dump_is_generated_v3_hw(void *p) ++{ ++ return p ? true : false; ++} ++ + static void debugfs_print_reg_v3_hw(u32 *regs_val, struct seq_file *s, + const struct hisi_sas_debugfs_reg *reg) + { +@@ -3587,6 +3590,9 @@ static int debugfs_global_v3_hw_show(struct seq_file *s, void *p) + { + struct hisi_sas_debugfs_regs *global = s->private; + ++ if (!debugfs_dump_is_generated_v3_hw(global->data)) ++ return -EPERM; ++ + debugfs_print_reg_v3_hw(global->data, s, + &debugfs_global_reg); + +@@ -3598,6 +3604,9 @@ static int debugfs_axi_v3_hw_show(struct seq_file *s, void *p) + { + struct hisi_sas_debugfs_regs *axi = s->private; + ++ if (!debugfs_dump_is_generated_v3_hw(axi->data)) ++ return -EPERM; ++ + debugfs_print_reg_v3_hw(axi->data, s, + &debugfs_axi_reg); + +@@ -3609,6 +3618,9 @@ static int debugfs_ras_v3_hw_show(struct seq_file *s, void *p) + { + struct hisi_sas_debugfs_regs *ras = s->private; + ++ if (!debugfs_dump_is_generated_v3_hw(ras->data)) ++ return -EPERM; ++ + debugfs_print_reg_v3_hw(ras->data, s, + &debugfs_ras_reg); + +@@ -3621,6 +3633,9 @@ static int debugfs_port_v3_hw_show(struct seq_file *s, void *p) + struct hisi_sas_debugfs_port *port = s->private; + const struct hisi_sas_debugfs_reg *reg_port = &debugfs_port_reg; + ++ if (!debugfs_dump_is_generated_v3_hw(port->data)) ++ return -EPERM; ++ + debugfs_print_reg_v3_hw(port->data, s, reg_port); + + return 0; +@@ -3676,6 +3691,9 @@ static int debugfs_cq_v3_hw_show(struct seq_file *s, void *p) + struct hisi_sas_debugfs_cq *debugfs_cq = s->private; + int slot; + ++ if (!debugfs_dump_is_generated_v3_hw(debugfs_cq->complete_hdr)) ++ return -EPERM; ++ + for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++) + debugfs_cq_show_slot_v3_hw(s, slot, debugfs_cq); + +@@ -3697,8 +3715,12 @@ static void debugfs_dq_show_slot_v3_hw(struct seq_file *s, int slot, + + static int debugfs_dq_v3_hw_show(struct seq_file *s, void *p) + { ++ struct hisi_sas_debugfs_dq *debugfs_dq = s->private; + int slot; + ++ if (!debugfs_dump_is_generated_v3_hw(debugfs_dq->hdr)) ++ return -EPERM; ++ + for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++) + debugfs_dq_show_slot_v3_hw(s, slot, s->private); + +@@ -3712,6 +3734,9 @@ static int debugfs_iost_v3_hw_show(struct seq_file *s, void *p) + struct hisi_sas_iost *iost = debugfs_iost->iost; + int i, max_command_entries = HISI_SAS_MAX_COMMANDS; + ++ if (!debugfs_dump_is_generated_v3_hw(iost)) ++ return -EPERM; ++ + for (i = 0; i < max_command_entries; i++, iost++) { + __le64 *data = &iost->qw0; + +@@ -3731,6 +3756,9 @@ static int debugfs_iost_cache_v3_hw_show(struct seq_file *s, void *p) + int i, tab_idx; + __le64 *iost; + ++ if (!debugfs_dump_is_generated_v3_hw(iost_cache)) ++ return -EPERM; ++ + for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_NUM; i++, iost_cache++) { + /* + * Data struct of IOST cache: +@@ -3754,6 +3782,9 @@ static int debugfs_itct_v3_hw_show(struct seq_file *s, void *p) + struct hisi_sas_debugfs_itct *debugfs_itct = s->private; + struct hisi_sas_itct *itct = debugfs_itct->itct; + ++ if (!debugfs_dump_is_generated_v3_hw(itct)) ++ return -EPERM; ++ + for (i = 0; i < HISI_SAS_MAX_ITCT_ENTRIES; i++, itct++) { + __le64 *data = &itct->qw0; + +@@ -3773,6 +3804,9 @@ static int debugfs_itct_cache_v3_hw_show(struct seq_file *s, void *p) + int i, tab_idx; + __le64 *itct; + ++ if (!debugfs_dump_is_generated_v3_hw(itct_cache)) ++ return -EPERM; ++ + for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_NUM; i++, itct_cache++) { + /* + * Data struct of ITCT cache: +@@ -3790,10 +3824,9 @@ static int debugfs_itct_cache_v3_hw_show(struct seq_file *s, void *p) + } + DEFINE_SHOW_ATTRIBUTE(debugfs_itct_cache_v3_hw); + +-static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba) ++static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba, int index) + { + u64 *debugfs_timestamp; +- int dump_index = hisi_hba->debugfs_dump_index; + struct dentry *dump_dentry; + struct dentry *dentry; + char name[256]; +@@ -3801,17 +3834,17 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba) + int c; + int d; + +- snprintf(name, 256, "%d", dump_index); ++ snprintf(name, 256, "%d", index); + + dump_dentry = debugfs_create_dir(name, hisi_hba->debugfs_dump_dentry); + +- debugfs_timestamp = &hisi_hba->debugfs_timestamp[dump_index]; ++ debugfs_timestamp = &hisi_hba->debugfs_timestamp[index]; + + debugfs_create_u64("timestamp", 0400, dump_dentry, + debugfs_timestamp); + + debugfs_create_file("global", 0400, dump_dentry, +- &hisi_hba->debugfs_regs[dump_index][DEBUGFS_GLOBAL], ++ &hisi_hba->debugfs_regs[index][DEBUGFS_GLOBAL], + &debugfs_global_v3_hw_fops); + + /* Create port dir and files */ +@@ -3820,7 +3853,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba) + snprintf(name, 256, "%d", p); + + debugfs_create_file(name, 0400, dentry, +- &hisi_hba->debugfs_port_reg[dump_index][p], ++ &hisi_hba->debugfs_port_reg[index][p], + &debugfs_port_v3_hw_fops); + } + +@@ -3830,7 +3863,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba) + snprintf(name, 256, "%d", c); + + debugfs_create_file(name, 0400, dentry, +- &hisi_hba->debugfs_cq[dump_index][c], ++ &hisi_hba->debugfs_cq[index][c], + &debugfs_cq_v3_hw_fops); + } + +@@ -3840,66 +3873,35 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba) + snprintf(name, 256, "%d", d); + + debugfs_create_file(name, 0400, dentry, +- &hisi_hba->debugfs_dq[dump_index][d], ++ &hisi_hba->debugfs_dq[index][d], + &debugfs_dq_v3_hw_fops); + } + + debugfs_create_file("iost", 0400, dump_dentry, +- &hisi_hba->debugfs_iost[dump_index], ++ &hisi_hba->debugfs_iost[index], + &debugfs_iost_v3_hw_fops); + + debugfs_create_file("iost_cache", 0400, dump_dentry, +- &hisi_hba->debugfs_iost_cache[dump_index], ++ &hisi_hba->debugfs_iost_cache[index], + &debugfs_iost_cache_v3_hw_fops); + + debugfs_create_file("itct", 0400, dump_dentry, +- &hisi_hba->debugfs_itct[dump_index], ++ &hisi_hba->debugfs_itct[index], + &debugfs_itct_v3_hw_fops); + + debugfs_create_file("itct_cache", 0400, dump_dentry, +- &hisi_hba->debugfs_itct_cache[dump_index], ++ &hisi_hba->debugfs_itct_cache[index], + &debugfs_itct_cache_v3_hw_fops); + + debugfs_create_file("axi", 0400, dump_dentry, +- &hisi_hba->debugfs_regs[dump_index][DEBUGFS_AXI], ++ &hisi_hba->debugfs_regs[index][DEBUGFS_AXI], + &debugfs_axi_v3_hw_fops); + + debugfs_create_file("ras", 0400, dump_dentry, +- &hisi_hba->debugfs_regs[dump_index][DEBUGFS_RAS], ++ &hisi_hba->debugfs_regs[index][DEBUGFS_RAS], + &debugfs_ras_v3_hw_fops); + } + +-static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba) +-{ +- int debugfs_dump_index = hisi_hba->debugfs_dump_index; +- struct device *dev = hisi_hba->dev; +- u64 timestamp = local_clock(); +- +- if (debugfs_dump_index >= hisi_sas_debugfs_dump_count) { +- dev_warn(dev, "dump count exceeded!\n"); +- return; +- } +- +- do_div(timestamp, NSEC_PER_MSEC); +- hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp; +- +- debugfs_snapshot_prepare_v3_hw(hisi_hba); +- +- debugfs_snapshot_global_reg_v3_hw(hisi_hba); +- debugfs_snapshot_port_reg_v3_hw(hisi_hba); +- debugfs_snapshot_axi_reg_v3_hw(hisi_hba); +- debugfs_snapshot_ras_reg_v3_hw(hisi_hba); +- debugfs_snapshot_cq_reg_v3_hw(hisi_hba); +- debugfs_snapshot_dq_reg_v3_hw(hisi_hba); +- debugfs_snapshot_itct_reg_v3_hw(hisi_hba); +- debugfs_snapshot_iost_reg_v3_hw(hisi_hba); +- +- debugfs_create_files_v3_hw(hisi_hba); +- +- debugfs_snapshot_restore_v3_hw(hisi_hba); +- hisi_hba->debugfs_dump_index++; +-} +- + static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +@@ -3907,9 +3909,6 @@ static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file, + struct hisi_hba *hisi_hba = file->f_inode->i_private; + char buf[8]; + +- if (hisi_hba->debugfs_dump_index >= hisi_sas_debugfs_dump_count) +- return -EFAULT; +- + if (count > 8) + return -EFAULT; + +@@ -3919,7 +3918,12 @@ static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file, + if (buf[0] != '1') + return -EFAULT; + +- queue_work(hisi_hba->wq, &hisi_hba->debugfs_work); ++ down(&hisi_hba->sem); ++ if (debugfs_snapshot_regs_v3_hw(hisi_hba)) { ++ up(&hisi_hba->sem); ++ return -EFAULT; ++ } ++ up(&hisi_hba->sem); + + return count; + } +@@ -4670,36 +4674,40 @@ static void debugfs_fifo_init_v3_hw(struct hisi_hba *hisi_hba) + } + } + +-static void debugfs_work_handler_v3_hw(struct work_struct *work) +-{ +- struct hisi_hba *hisi_hba = +- container_of(work, struct hisi_hba, debugfs_work); +- +- debugfs_snapshot_regs_v3_hw(hisi_hba); +-} +- + static void debugfs_release_v3_hw(struct hisi_hba *hisi_hba, int dump_index) + { + struct device *dev = hisi_hba->dev; + int i; + + devm_kfree(dev, hisi_hba->debugfs_iost_cache[dump_index].cache); ++ hisi_hba->debugfs_iost_cache[dump_index].cache = NULL; + devm_kfree(dev, hisi_hba->debugfs_itct_cache[dump_index].cache); ++ hisi_hba->debugfs_itct_cache[dump_index].cache = NULL; + devm_kfree(dev, hisi_hba->debugfs_iost[dump_index].iost); ++ hisi_hba->debugfs_iost[dump_index].iost = NULL; + devm_kfree(dev, hisi_hba->debugfs_itct[dump_index].itct); ++ hisi_hba->debugfs_itct[dump_index].itct = NULL; + +- for (i = 0; i < hisi_hba->queue_count; i++) ++ for (i = 0; i < hisi_hba->queue_count; i++) { + devm_kfree(dev, hisi_hba->debugfs_dq[dump_index][i].hdr); ++ hisi_hba->debugfs_dq[dump_index][i].hdr = NULL; ++ } + +- for (i = 0; i < hisi_hba->queue_count; i++) ++ for (i = 0; i < hisi_hba->queue_count; i++) { + devm_kfree(dev, + hisi_hba->debugfs_cq[dump_index][i].complete_hdr); ++ hisi_hba->debugfs_cq[dump_index][i].complete_hdr = NULL; ++ } + +- for (i = 0; i < DEBUGFS_REGS_NUM; i++) ++ for (i = 0; i < DEBUGFS_REGS_NUM; i++) { + devm_kfree(dev, hisi_hba->debugfs_regs[dump_index][i].data); ++ hisi_hba->debugfs_regs[dump_index][i].data = NULL; ++ } + +- for (i = 0; i < hisi_hba->n_phy; i++) ++ for (i = 0; i < hisi_hba->n_phy; i++) { + devm_kfree(dev, hisi_hba->debugfs_port_reg[dump_index][i].data); ++ hisi_hba->debugfs_port_reg[dump_index][i].data = NULL; ++ } + } + + static const struct hisi_sas_debugfs_reg *debugfs_reg_array_v3_hw[DEBUGFS_REGS_NUM] = { +@@ -4712,7 +4720,7 @@ static int debugfs_alloc_v3_hw(struct hisi_hba *hisi_hba, int dump_index) + { + const struct hisi_sas_hw *hw = hisi_hba->hw; + struct device *dev = hisi_hba->dev; +- int p, c, d, r, i; ++ int p, c, d, r; + size_t sz; + + for (r = 0; r < DEBUGFS_REGS_NUM; r++) { +@@ -4792,11 +4800,46 @@ static int debugfs_alloc_v3_hw(struct hisi_hba *hisi_hba, int dump_index) + + return 0; + fail: +- for (i = 0; i < hisi_sas_debugfs_dump_count; i++) +- debugfs_release_v3_hw(hisi_hba, i); ++ debugfs_release_v3_hw(hisi_hba, dump_index); + return -ENOMEM; + } + ++static int debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ int debugfs_dump_index = hisi_hba->debugfs_dump_index; ++ struct device *dev = hisi_hba->dev; ++ u64 timestamp = local_clock(); ++ ++ if (debugfs_dump_index >= hisi_sas_debugfs_dump_count) { ++ dev_warn(dev, "dump count exceeded!\n"); ++ return -EINVAL; ++ } ++ ++ if (debugfs_alloc_v3_hw(hisi_hba, debugfs_dump_index)) { ++ dev_warn(dev, "failed to alloc memory\n"); ++ return -ENOMEM; ++ } ++ ++ do_div(timestamp, NSEC_PER_MSEC); ++ hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp; ++ ++ debugfs_snapshot_prepare_v3_hw(hisi_hba); ++ ++ debugfs_snapshot_global_reg_v3_hw(hisi_hba); ++ debugfs_snapshot_port_reg_v3_hw(hisi_hba); ++ debugfs_snapshot_axi_reg_v3_hw(hisi_hba); ++ debugfs_snapshot_ras_reg_v3_hw(hisi_hba); ++ debugfs_snapshot_cq_reg_v3_hw(hisi_hba); ++ debugfs_snapshot_dq_reg_v3_hw(hisi_hba); ++ debugfs_snapshot_itct_reg_v3_hw(hisi_hba); ++ debugfs_snapshot_iost_reg_v3_hw(hisi_hba); ++ ++ debugfs_snapshot_restore_v3_hw(hisi_hba); ++ hisi_hba->debugfs_dump_index++; ++ ++ return 0; ++} ++ + static void debugfs_phy_down_cnt_init_v3_hw(struct hisi_hba *hisi_hba) + { + struct dentry *dir = debugfs_create_dir("phy_down_cnt", +@@ -4874,6 +4917,17 @@ static void debugfs_bist_init_v3_hw(struct hisi_hba *hisi_hba) + hisi_hba->debugfs_bist_linkrate = SAS_LINK_RATE_1_5_GBPS; + } + ++static void debugfs_dump_init_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ int i; ++ ++ hisi_hba->debugfs_dump_dentry = ++ debugfs_create_dir("dump", hisi_hba->debugfs_dir); ++ ++ for (i = 0; i < hisi_sas_debugfs_dump_count; i++) ++ debugfs_create_files_v3_hw(hisi_hba, i); ++} ++ + static void debugfs_exit_v3_hw(struct hisi_hba *hisi_hba) + { + debugfs_remove_recursive(hisi_hba->debugfs_dir); +@@ -4883,7 +4937,6 @@ static void debugfs_exit_v3_hw(struct hisi_hba *hisi_hba) + static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba) + { + struct device *dev = hisi_hba->dev; +- int i; + + hisi_hba->debugfs_dir = debugfs_create_dir(dev_name(dev), + hisi_sas_debugfs_dir); +@@ -4895,19 +4948,10 @@ static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba) + /* create bist structures */ + debugfs_bist_init_v3_hw(hisi_hba); + +- hisi_hba->debugfs_dump_dentry = +- debugfs_create_dir("dump", hisi_hba->debugfs_dir); ++ debugfs_dump_init_v3_hw(hisi_hba); + + debugfs_phy_down_cnt_init_v3_hw(hisi_hba); + debugfs_fifo_init_v3_hw(hisi_hba); +- +- for (i = 0; i < hisi_sas_debugfs_dump_count; i++) { +- if (debugfs_alloc_v3_hw(hisi_hba, i)) { +- debugfs_exit_v3_hw(hisi_hba); +- dev_dbg(dev, "failed to init debugfs!\n"); +- break; +- } +- } + } + + static int +diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c +index 7f32619234696f..7880675a68dba6 100644 +--- a/drivers/scsi/mpi3mr/mpi3mr_os.c ++++ b/drivers/scsi/mpi3mr/mpi3mr_os.c +@@ -8,11 +8,12 @@ + */ + + #include "mpi3mr.h" ++#include + + /* global driver scop variables */ + LIST_HEAD(mrioc_list); + DEFINE_SPINLOCK(mrioc_list_lock); +-static int mrioc_ids; ++static DEFINE_IDA(mrioc_ida); + static int warn_non_secure_ctlr; + atomic64_t event_counter; + +@@ -5065,7 +5066,10 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id) + } + + mrioc = shost_priv(shost); +- mrioc->id = mrioc_ids++; ++ retval = ida_alloc_range(&mrioc_ida, 0, U8_MAX, GFP_KERNEL); ++ if (retval < 0) ++ goto id_alloc_failed; ++ mrioc->id = (u8)retval; + sprintf(mrioc->driver_name, "%s", MPI3MR_DRIVER_NAME); + sprintf(mrioc->name, "%s%d", mrioc->driver_name, mrioc->id); + INIT_LIST_HEAD(&mrioc->list); +@@ -5215,9 +5219,11 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id) + resource_alloc_failed: + destroy_workqueue(mrioc->fwevt_worker_thread); + fwevtthread_failed: ++ ida_free(&mrioc_ida, mrioc->id); + spin_lock(&mrioc_list_lock); + list_del(&mrioc->list); + spin_unlock(&mrioc_list_lock); ++id_alloc_failed: + scsi_host_put(shost); + shost_failed: + return retval; +@@ -5303,6 +5309,7 @@ static void mpi3mr_remove(struct pci_dev *pdev) + mrioc->sas_hba.num_phys = 0; + } + ++ ida_free(&mrioc_ida, mrioc->id); + spin_lock(&mrioc_list_lock); + list_del(&mrioc->list); + spin_unlock(&mrioc_list_lock); +@@ -5518,6 +5525,7 @@ static void __exit mpi3mr_exit(void) + &driver_attr_event_counter); + pci_unregister_driver(&mpi3mr_pci_driver); + sas_release_transport(mpi3mr_transport_template); ++ ida_destroy(&mrioc_ida); + } + + module_init(mpi3mr_init); +diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c +index 1ec6f9c82aef06..79f2bf5df19a6c 100644 +--- a/drivers/thunderbolt/nhi.c ++++ b/drivers/thunderbolt/nhi.c +@@ -1524,6 +1524,18 @@ static struct pci_device_id nhi_ids[] = { + .driver_data = (kernel_ulong_t)&icl_nhi_ops }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MTL_P_NHI1), + .driver_data = (kernel_ulong_t)&icl_nhi_ops }, ++ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_LNL_NHI0), ++ .driver_data = (kernel_ulong_t)&icl_nhi_ops }, ++ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_LNL_NHI1), ++ .driver_data = (kernel_ulong_t)&icl_nhi_ops }, ++ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_PTL_M_NHI0), ++ .driver_data = (kernel_ulong_t)&icl_nhi_ops }, ++ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_PTL_M_NHI1), ++ .driver_data = (kernel_ulong_t)&icl_nhi_ops }, ++ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_PTL_P_NHI0), ++ .driver_data = (kernel_ulong_t)&icl_nhi_ops }, ++ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_PTL_P_NHI1), ++ .driver_data = (kernel_ulong_t)&icl_nhi_ops }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_80G_NHI) }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_40G_NHI) }, + +diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h +index 0f029ce758825e..16744f25a9a069 100644 +--- a/drivers/thunderbolt/nhi.h ++++ b/drivers/thunderbolt/nhi.h +@@ -90,6 +90,12 @@ extern const struct tb_nhi_ops icl_nhi_ops; + #define PCI_DEVICE_ID_INTEL_TGL_H_NHI1 0x9a21 + #define PCI_DEVICE_ID_INTEL_RPL_NHI0 0xa73e + #define PCI_DEVICE_ID_INTEL_RPL_NHI1 0xa76d ++#define PCI_DEVICE_ID_INTEL_LNL_NHI0 0xa833 ++#define PCI_DEVICE_ID_INTEL_LNL_NHI1 0xa834 ++#define PCI_DEVICE_ID_INTEL_PTL_M_NHI0 0xe333 ++#define PCI_DEVICE_ID_INTEL_PTL_M_NHI1 0xe334 ++#define PCI_DEVICE_ID_INTEL_PTL_P_NHI0 0xe433 ++#define PCI_DEVICE_ID_INTEL_PTL_P_NHI1 0xe434 + + #define PCI_CLASS_SERIAL_USB_USB4 0x0c0340 + +diff --git a/drivers/thunderbolt/retimer.c b/drivers/thunderbolt/retimer.c +index 47becb363adacb..2ee8c5ebca7c3c 100644 +--- a/drivers/thunderbolt/retimer.c ++++ b/drivers/thunderbolt/retimer.c +@@ -98,6 +98,7 @@ static int tb_retimer_nvm_add(struct tb_retimer *rt) + + err_nvm: + dev_dbg(&rt->dev, "NVM upgrade disabled\n"); ++ rt->no_nvm_upgrade = true; + if (!IS_ERR(nvm)) + tb_nvm_free(nvm); + +@@ -177,8 +178,6 @@ static ssize_t nvm_authenticate_show(struct device *dev, + + if (!rt->nvm) + ret = -EAGAIN; +- else if (rt->no_nvm_upgrade) +- ret = -EOPNOTSUPP; + else + ret = sysfs_emit(buf, "%#x\n", rt->auth_status); + +@@ -331,6 +330,19 @@ static ssize_t vendor_show(struct device *dev, struct device_attribute *attr, + } + static DEVICE_ATTR_RO(vendor); + ++static umode_t retimer_is_visible(struct kobject *kobj, struct attribute *attr, ++ int n) ++{ ++ struct device *dev = kobj_to_dev(kobj); ++ struct tb_retimer *rt = tb_to_retimer(dev); ++ ++ if (attr == &dev_attr_nvm_authenticate.attr || ++ attr == &dev_attr_nvm_version.attr) ++ return rt->no_nvm_upgrade ? 0 : attr->mode; ++ ++ return attr->mode; ++} ++ + static struct attribute *retimer_attrs[] = { + &dev_attr_device.attr, + &dev_attr_nvm_authenticate.attr, +@@ -340,6 +352,7 @@ static struct attribute *retimer_attrs[] = { + }; + + static const struct attribute_group retimer_group = { ++ .is_visible = retimer_is_visible, + .attrs = retimer_attrs, + }; + +diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h +index 2a38e1eb65466c..97437de52ef681 100644 +--- a/drivers/usb/chipidea/ci.h ++++ b/drivers/usb/chipidea/ci.h +@@ -25,6 +25,7 @@ + #define TD_PAGE_COUNT 5 + #define CI_HDRC_PAGE_SIZE 4096ul /* page size for TD's */ + #define ENDPT_MAX 32 ++#define CI_MAX_REQ_SIZE (4 * CI_HDRC_PAGE_SIZE) + #define CI_MAX_BUF_SIZE (TD_PAGE_COUNT * CI_HDRC_PAGE_SIZE) + + /****************************************************************************** +@@ -260,6 +261,7 @@ struct ci_hdrc { + bool b_sess_valid_event; + bool imx28_write_fix; + bool has_portsc_pec_bug; ++ bool has_short_pkt_limit; + bool supports_runtime_pm; + bool in_lpm; + bool wakeup_int; +diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c +index e28bb2f2612dc6..477af457c1a1f0 100644 +--- a/drivers/usb/chipidea/ci_hdrc_imx.c ++++ b/drivers/usb/chipidea/ci_hdrc_imx.c +@@ -334,6 +334,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) + struct ci_hdrc_platform_data pdata = { + .name = dev_name(&pdev->dev), + .capoffset = DEF_CAPOFFSET, ++ .flags = CI_HDRC_HAS_SHORT_PKT_LIMIT, + .notify_event = ci_hdrc_imx_notify_event, + }; + int ret; +diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c +index ca71df4f32e4cc..c161a4ee529064 100644 +--- a/drivers/usb/chipidea/core.c ++++ b/drivers/usb/chipidea/core.c +@@ -1076,6 +1076,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) + CI_HDRC_SUPPORTS_RUNTIME_PM); + ci->has_portsc_pec_bug = !!(ci->platdata->flags & + CI_HDRC_HAS_PORTSC_PEC_MISSED); ++ ci->has_short_pkt_limit = !!(ci->platdata->flags & ++ CI_HDRC_HAS_SHORT_PKT_LIMIT); + platform_set_drvdata(pdev, ci); + + ret = hw_device_init(ci, base); +diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c +index f5490f2a5b6bca..647e98f4e35110 100644 +--- a/drivers/usb/chipidea/otg.c ++++ b/drivers/usb/chipidea/otg.c +@@ -130,8 +130,11 @@ enum ci_role ci_otg_role(struct ci_hdrc *ci) + + void ci_handle_vbus_change(struct ci_hdrc *ci) + { +- if (!ci->is_otg) ++ if (!ci->is_otg) { ++ if (ci->platdata->flags & CI_HDRC_FORCE_VBUS_ACTIVE_ALWAYS) ++ usb_gadget_vbus_connect(&ci->gadget); + return; ++ } + + if (hw_read_otgsc(ci, OTGSC_BSV) && !ci->vbus_active) + usb_gadget_vbus_connect(&ci->gadget); +diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c +index 9f7d003e467b54..f2ae5f4c58283a 100644 +--- a/drivers/usb/chipidea/udc.c ++++ b/drivers/usb/chipidea/udc.c +@@ -959,6 +959,12 @@ static int _ep_queue(struct usb_ep *ep, struct usb_request *req, + return -EMSGSIZE; + } + ++ if (ci->has_short_pkt_limit && ++ hwreq->req.length > CI_MAX_REQ_SIZE) { ++ dev_err(hwep->ci->dev, "request length too big (max 16KB)\n"); ++ return -EMSGSIZE; ++ } ++ + /* first nuke then test link, e.g. previous status has not sent */ + if (!list_empty(&hwreq->queue)) { + dev_err(hwep->ci->dev, "request already in queue\n"); +diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h +index b118f4aab18984..d00bf714a7ccfb 100644 +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -899,6 +899,7 @@ struct dwc3_hwparams { + #define DWC3_MODE(n) ((n) & 0x7) + + /* HWPARAMS1 */ ++#define DWC3_SPRAM_TYPE(n) (((n) >> 23) & 1) + #define DWC3_NUM_INT(n) (((n) & (0x3f << 15)) >> 15) + + /* HWPARAMS3 */ +@@ -909,6 +910,9 @@ struct dwc3_hwparams { + #define DWC3_NUM_IN_EPS(p) (((p)->hwparams3 & \ + (DWC3_NUM_IN_EPS_MASK)) >> 18) + ++/* HWPARAMS6 */ ++#define DWC3_RAM0_DEPTH(n) (((n) & (0xffff0000)) >> 16) ++ + /* HWPARAMS7 */ + #define DWC3_RAM1_DEPTH(n) ((n) & 0xffff) + +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index b560996bd4218a..656460c0c1dd7e 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -687,6 +687,44 @@ static int dwc3_gadget_calc_tx_fifo_size(struct dwc3 *dwc, int mult) + return fifo_size; + } + ++/** ++ * dwc3_gadget_calc_ram_depth - calculates the ram depth for txfifo ++ * @dwc: pointer to the DWC3 context ++ */ ++static int dwc3_gadget_calc_ram_depth(struct dwc3 *dwc) ++{ ++ int ram_depth; ++ int fifo_0_start; ++ bool is_single_port_ram; ++ ++ /* Check supporting RAM type by HW */ ++ is_single_port_ram = DWC3_SPRAM_TYPE(dwc->hwparams.hwparams1); ++ ++ /* ++ * If a single port RAM is utilized, then allocate TxFIFOs from ++ * RAM0. otherwise, allocate them from RAM1. ++ */ ++ ram_depth = is_single_port_ram ? DWC3_RAM0_DEPTH(dwc->hwparams.hwparams6) : ++ DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7); ++ ++ /* ++ * In a single port RAM configuration, the available RAM is shared ++ * between the RX and TX FIFOs. This means that the txfifo can begin ++ * at a non-zero address. ++ */ ++ if (is_single_port_ram) { ++ u32 reg; ++ ++ /* Check if TXFIFOs start at non-zero addr */ ++ reg = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(0)); ++ fifo_0_start = DWC3_GTXFIFOSIZ_TXFSTADDR(reg); ++ ++ ram_depth -= (fifo_0_start >> 16); ++ } ++ ++ return ram_depth; ++} ++ + /** + * dwc3_gadget_clear_tx_fifos - Clears txfifo allocation + * @dwc: pointer to the DWC3 context +@@ -753,7 +791,7 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep) + { + struct dwc3 *dwc = dep->dwc; + int fifo_0_start; +- int ram1_depth; ++ int ram_depth; + int fifo_size; + int min_depth; + int num_in_ep; +@@ -773,7 +811,7 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep) + if (dep->flags & DWC3_EP_TXFIFO_RESIZED) + return 0; + +- ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7); ++ ram_depth = dwc3_gadget_calc_ram_depth(dwc); + + if ((dep->endpoint.maxburst > 1 && + usb_endpoint_xfer_bulk(dep->endpoint.desc)) || +@@ -794,7 +832,7 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep) + + /* Reserve at least one FIFO for the number of IN EPs */ + min_depth = num_in_ep * (fifo + 1); +- remaining = ram1_depth - min_depth - dwc->last_fifo_depth; ++ remaining = ram_depth - min_depth - dwc->last_fifo_depth; + remaining = max_t(int, 0, remaining); + /* + * We've already reserved 1 FIFO per EP, so check what we can fit in +@@ -820,9 +858,9 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep) + dwc->last_fifo_depth += DWC31_GTXFIFOSIZ_TXFDEP(fifo_size); + + /* Check fifo size allocation doesn't exceed available RAM size. */ +- if (dwc->last_fifo_depth >= ram1_depth) { ++ if (dwc->last_fifo_depth >= ram_depth) { + dev_err(dwc->dev, "Fifosize(%d) > RAM size(%d) %s depth:%d\n", +- dwc->last_fifo_depth, ram1_depth, ++ dwc->last_fifo_depth, ram_depth, + dep->endpoint.name, fifo_size); + if (DWC3_IP_IS(DWC3)) + fifo_size = DWC3_GTXFIFOSIZ_TXFDEP(fifo_size); +@@ -3078,7 +3116,7 @@ static int dwc3_gadget_check_config(struct usb_gadget *g) + struct dwc3 *dwc = gadget_to_dwc(g); + struct usb_ep *ep; + int fifo_size = 0; +- int ram1_depth; ++ int ram_depth; + int ep_num = 0; + + if (!dwc->do_fifo_resize) +@@ -3101,8 +3139,8 @@ static int dwc3_gadget_check_config(struct usb_gadget *g) + fifo_size += dwc->max_cfg_eps; + + /* Check if we can fit a single fifo per endpoint */ +- ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7); +- if (fifo_size > ram1_depth) ++ ram_depth = dwc3_gadget_calc_ram_depth(dwc); ++ if (fifo_size > ram_depth) + return -ENOMEM; + + return 0; +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index 50f58801140045..0d628af5c3ba50 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -52,6 +52,7 @@ + * endpoint rings; it generates events on the event ring for these. + */ + ++#include + #include + #include + #include +@@ -1091,6 +1092,19 @@ static int xhci_invalidate_cancelled_tds(struct xhci_virt_ep *ep) + return 0; + } + ++/* ++ * Erase queued TDs from transfer ring(s) and give back those the xHC didn't ++ * stop on. If necessary, queue commands to move the xHC off cancelled TDs it ++ * stopped on. Those will be given back later when the commands complete. ++ * ++ * Call under xhci->lock on a stopped endpoint. ++ */ ++void xhci_process_cancelled_tds(struct xhci_virt_ep *ep) ++{ ++ xhci_invalidate_cancelled_tds(ep); ++ xhci_giveback_invalidated_tds(ep); ++} ++ + /* + * Returns the TD the endpoint ring halted on. + * Only call for non-running rings without streams. +@@ -1180,9 +1194,35 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id, + break; + ep->ep_state &= ~EP_STOP_CMD_PENDING; + return; ++ case EP_STATE_STOPPED: ++ /* ++ * Per xHCI 4.6.9, Stop Endpoint command on a Stopped ++ * EP is a Context State Error, and EP stays Stopped. ++ * ++ * But maybe it failed on Halted, and somebody ran Reset ++ * Endpoint later. EP state is now Stopped and EP_HALTED ++ * still set because Reset EP handler will run after us. ++ */ ++ if (ep->ep_state & EP_HALTED) ++ break; ++ /* ++ * On some HCs EP state remains Stopped for some tens of ++ * us to a few ms or more after a doorbell ring, and any ++ * new Stop Endpoint fails without aborting the restart. ++ * This handler may run quickly enough to still see this ++ * Stopped state, but it will soon change to Running. ++ * ++ * Assume this bug on unexpected Stop Endpoint failures. ++ * Keep retrying until the EP starts and stops again, on ++ * chips where this is known to help. Wait for 100ms. ++ */ ++ if (time_is_before_jiffies(ep->stop_time + msecs_to_jiffies(100))) ++ break; ++ fallthrough; + case EP_STATE_RUNNING: + /* Race, HW handled stop ep cmd before ep was running */ +- xhci_dbg(xhci, "Stop ep completion ctx error, ep is running\n"); ++ xhci_dbg(xhci, "Stop ep completion ctx error, ctx_state %d\n", ++ GET_EP_CTX_STATE(ep_ctx)); + + command = xhci_alloc_command(xhci, false, GFP_ATOMIC); + if (!command) { +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 3bd70e6ad64baf..70e6c240a5409f 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -8,6 +8,7 @@ + * Some code borrowed from the Linux EHCI driver. + */ + ++#include + #include + #include + #include +@@ -1737,15 +1738,27 @@ static int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) + } + } + +- /* Queue a stop endpoint command, but only if this is +- * the first cancellation to be handled. +- */ +- if (!(ep->ep_state & EP_STOP_CMD_PENDING)) { ++ /* These completion handlers will sort out cancelled TDs for us */ ++ if (ep->ep_state & (EP_STOP_CMD_PENDING | EP_HALTED | SET_DEQ_PENDING)) { ++ xhci_dbg(xhci, "Not queuing Stop Endpoint on slot %d ep %d in state 0x%x\n", ++ urb->dev->slot_id, ep_index, ep->ep_state); ++ goto done; ++ } ++ ++ /* In this case no commands are pending but the endpoint is stopped */ ++ if (ep->ep_state & EP_CLEARING_TT) { ++ /* and cancelled TDs can be given back right away */ ++ xhci_dbg(xhci, "Invalidating TDs instantly on slot %d ep %d in state 0x%x\n", ++ urb->dev->slot_id, ep_index, ep->ep_state); ++ xhci_process_cancelled_tds(ep); ++ } else { ++ /* Otherwise, queue a new Stop Endpoint command */ + command = xhci_alloc_command(xhci, false, GFP_ATOMIC); + if (!command) { + ret = -ENOMEM; + goto done; + } ++ ep->stop_time = jiffies; + ep->ep_state |= EP_STOP_CMD_PENDING; + xhci_queue_stop_endpoint(xhci, command, urb->dev->slot_id, + ep_index, 0); +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index 4bbd12db7239ab..fddb3a90dae3df 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -717,6 +717,7 @@ struct xhci_virt_ep { + /* Bandwidth checking storage */ + struct xhci_bw_info bw_info; + struct list_head bw_endpoint_list; ++ unsigned long stop_time; + /* Isoch Frame ID checking storage */ + int next_frame_id; + /* Use new Isoch TRB layout needed for extended TBC support */ +@@ -1951,6 +1952,7 @@ void xhci_ring_doorbell_for_active_rings(struct xhci_hcd *xhci, + void xhci_cleanup_command_queue(struct xhci_hcd *xhci); + void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring); + unsigned int count_trbs(u64 addr, u64 len); ++void xhci_process_cancelled_tds(struct xhci_virt_ep *ep); + + /* xHCI roothub code */ + void xhci_set_link_state(struct xhci_hcd *xhci, struct xhci_port *port, +diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c +index f6fb5575d4f0ac..d6a3fd00c3a5c4 100644 +--- a/drivers/usb/typec/ucsi/ucsi.c ++++ b/drivers/usb/typec/ucsi/ucsi.c +@@ -903,6 +903,9 @@ static void ucsi_handle_connector_change(struct work_struct *work) + + trace_ucsi_connector_change(con->num, &con->status); + ++ if (ucsi->ops->connector_status) ++ ucsi->ops->connector_status(con); ++ + role = !!(con->status.flags & UCSI_CONSTAT_PWR_DIR); + + if (con->status.change & UCSI_CONSTAT_POWER_DIR_CHANGE) { +@@ -1258,6 +1261,9 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con) + cap->driver_data = con; + cap->ops = &ucsi_ops; + ++ if (ucsi->ops->update_connector) ++ ucsi->ops->update_connector(con); ++ + ret = ucsi_register_port_psy(con); + if (ret) + goto out; +@@ -1322,6 +1328,9 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con) + } + ret = 0; /* ucsi_send_command() returns length on success */ + ++ if (ucsi->ops->connector_status) ++ ucsi->ops->connector_status(con); ++ + switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) { + case UCSI_CONSTAT_PARTNER_TYPE_UFP: + case UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP: +diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h +index 42c60eba5fb6ee..921ef0e115cffc 100644 +--- a/drivers/usb/typec/ucsi/ucsi.h ++++ b/drivers/usb/typec/ucsi/ucsi.h +@@ -15,6 +15,7 @@ + + struct ucsi; + struct ucsi_altmode; ++struct ucsi_connector; + struct dentry; + + /* UCSI offsets (Bytes) */ +@@ -52,6 +53,8 @@ struct dentry; + * @sync_write: Blocking write operation + * @async_write: Non-blocking write operation + * @update_altmodes: Squashes duplicate DP altmodes ++ * @update_connector: Update connector capabilities before registering ++ * @connector_status: Updates connector status, called holding connector lock + * + * Read and write routines for UCSI interface. @sync_write must wait for the + * Command Completion Event from the PPM before returning, and @async_write must +@@ -66,6 +69,8 @@ struct ucsi_operations { + const void *val, size_t val_len); + bool (*update_altmodes)(struct ucsi *ucsi, struct ucsi_altmode *orig, + struct ucsi_altmode *updated); ++ void (*update_connector)(struct ucsi_connector *con); ++ void (*connector_status)(struct ucsi_connector *con); + }; + + struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops); +diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c +index 94f2df02f06eeb..82a1081d44f1f0 100644 +--- a/drivers/usb/typec/ucsi/ucsi_glink.c ++++ b/drivers/usb/typec/ucsi/ucsi_glink.c +@@ -186,10 +186,40 @@ static int pmic_glink_ucsi_sync_write(struct ucsi *__ucsi, unsigned int offset, + return ret; + } + ++static void pmic_glink_ucsi_update_connector(struct ucsi_connector *con) ++{ ++ struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(con->ucsi); ++ ++ if (con->num > PMIC_GLINK_MAX_PORTS || ++ !ucsi->port_orientation[con->num - 1]) ++ return; ++ ++ con->typec_cap.orientation_aware = true; ++} ++ ++static void pmic_glink_ucsi_connector_status(struct ucsi_connector *con) ++{ ++ struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(con->ucsi); ++ int orientation; ++ ++ if (con->num > PMIC_GLINK_MAX_PORTS || ++ !ucsi->port_orientation[con->num - 1]) ++ return; ++ ++ orientation = gpiod_get_value(ucsi->port_orientation[con->num - 1]); ++ if (orientation >= 0) { ++ typec_switch_set(ucsi->port_switch[con->num - 1], ++ orientation ? TYPEC_ORIENTATION_REVERSE ++ : TYPEC_ORIENTATION_NORMAL); ++ } ++} ++ + static const struct ucsi_operations pmic_glink_ucsi_ops = { + .read = pmic_glink_ucsi_read, + .sync_write = pmic_glink_ucsi_sync_write, +- .async_write = pmic_glink_ucsi_async_write ++ .async_write = pmic_glink_ucsi_async_write, ++ .update_connector = pmic_glink_ucsi_update_connector, ++ .connector_status = pmic_glink_ucsi_connector_status, + }; + + static void pmic_glink_ucsi_read_ack(struct pmic_glink_ucsi *ucsi, const void *data, int len) +@@ -228,20 +258,8 @@ static void pmic_glink_ucsi_notify(struct work_struct *work) + } + + con_num = UCSI_CCI_CONNECTOR(cci); +- if (con_num) { +- if (con_num <= PMIC_GLINK_MAX_PORTS && +- ucsi->port_orientation[con_num - 1]) { +- int orientation = gpiod_get_value(ucsi->port_orientation[con_num - 1]); +- +- if (orientation >= 0) { +- typec_switch_set(ucsi->port_switch[con_num - 1], +- orientation ? TYPEC_ORIENTATION_REVERSE +- : TYPEC_ORIENTATION_NORMAL); +- } +- } +- ++ if (con_num) + ucsi_connector_change(ucsi->ucsi, con_num); +- } + + if (ucsi->sync_pending && + (cci & (UCSI_CCI_ACK_COMPLETE | UCSI_CCI_COMMAND_COMPLETE))) { +@@ -252,20 +270,6 @@ static void pmic_glink_ucsi_notify(struct work_struct *work) + static void pmic_glink_ucsi_register(struct work_struct *work) + { + struct pmic_glink_ucsi *ucsi = container_of(work, struct pmic_glink_ucsi, register_work); +- int orientation; +- int i; +- +- for (i = 0; i < PMIC_GLINK_MAX_PORTS; i++) { +- if (!ucsi->port_orientation[i]) +- continue; +- orientation = gpiod_get_value(ucsi->port_orientation[i]); +- +- if (orientation >= 0) { +- typec_switch_set(ucsi->port_switch[i], +- orientation ? TYPEC_ORIENTATION_REVERSE +- : TYPEC_ORIENTATION_NORMAL); +- } +- } + + ucsi_register(ucsi->ucsi); + } +diff --git a/drivers/watchdog/rzg2l_wdt.c b/drivers/watchdog/rzg2l_wdt.c +index 7bce093316c4d7..525a72d8d746e3 100644 +--- a/drivers/watchdog/rzg2l_wdt.c ++++ b/drivers/watchdog/rzg2l_wdt.c +@@ -8,11 +8,11 @@ + #include + #include + #include +-#include + #include + #include + #include + #include ++#include + #include + #include + #include +@@ -54,35 +54,11 @@ struct rzg2l_wdt_priv { + struct reset_control *rstc; + unsigned long osc_clk_rate; + unsigned long delay; +- unsigned long minimum_assertion_period; + struct clk *pclk; + struct clk *osc_clk; + enum rz_wdt_type devtype; + }; + +-static int rzg2l_wdt_reset(struct rzg2l_wdt_priv *priv) +-{ +- int err, status; +- +- if (priv->devtype == WDT_RZV2M) { +- /* WDT needs TYPE-B reset control */ +- err = reset_control_assert(priv->rstc); +- if (err) +- return err; +- ndelay(priv->minimum_assertion_period); +- err = reset_control_deassert(priv->rstc); +- if (err) +- return err; +- err = read_poll_timeout(reset_control_status, status, +- status != 1, 0, 1000, false, +- priv->rstc); +- } else { +- err = reset_control_reset(priv->rstc); +- } +- +- return err; +-} +- + static void rzg2l_wdt_wait_delay(struct rzg2l_wdt_priv *priv) + { + /* delay timer when change the setting register */ +@@ -129,6 +105,12 @@ static int rzg2l_wdt_start(struct watchdog_device *wdev) + if (ret) + return ret; + ++ ret = reset_control_deassert(priv->rstc); ++ if (ret) { ++ pm_runtime_put(wdev->parent); ++ return ret; ++ } ++ + /* Initialize time out */ + rzg2l_wdt_init_timeout(wdev); + +@@ -146,7 +128,9 @@ static int rzg2l_wdt_stop(struct watchdog_device *wdev) + struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); + int ret; + +- rzg2l_wdt_reset(priv); ++ ret = reset_control_assert(priv->rstc); ++ if (ret) ++ return ret; + + ret = pm_runtime_put(wdev->parent); + if (ret < 0) +@@ -181,11 +165,30 @@ static int rzg2l_wdt_restart(struct watchdog_device *wdev, + unsigned long action, void *data) + { + struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); ++ int ret; + +- clk_prepare_enable(priv->pclk); +- clk_prepare_enable(priv->osc_clk); ++ /* ++ * In case of RZ/G3S the watchdog device may be part of an IRQ safe power ++ * domain that is currently powered off. In this case we need to power ++ * it on before accessing registers. Along with this the clocks will be ++ * enabled. We don't undo the pm_runtime_resume_and_get() as the device ++ * need to be on for the reboot to happen. ++ * ++ * For the rest of SoCs not registering a watchdog IRQ safe power ++ * domain it is safe to call pm_runtime_resume_and_get() as the ++ * irq_safe_dev_in_sleep_domain() call in genpd_runtime_resume() ++ * returns non zero value and the genpd_lock() is avoided, thus, there ++ * will be no invalid wait context reported by lockdep. ++ */ ++ ret = pm_runtime_resume_and_get(wdev->parent); ++ if (ret) ++ return ret; + + if (priv->devtype == WDT_RZG2L) { ++ ret = reset_control_deassert(priv->rstc); ++ if (ret) ++ return ret; ++ + /* Generate Reset (WDTRSTB) Signal on parity error */ + rzg2l_wdt_write(priv, 0, PECR); + +@@ -193,7 +196,9 @@ static int rzg2l_wdt_restart(struct watchdog_device *wdev, + rzg2l_wdt_write(priv, PEEN_FORCE, PEEN); + } else { + /* RZ/V2M doesn't have parity error registers */ +- rzg2l_wdt_reset(priv); ++ ret = reset_control_reset(priv->rstc); ++ if (ret) ++ return ret; + + wdev->timeout = 0; + +@@ -236,13 +241,11 @@ static const struct watchdog_ops rzg2l_wdt_ops = { + .restart = rzg2l_wdt_restart, + }; + +-static void rzg2l_wdt_reset_assert_pm_disable(void *data) ++static void rzg2l_wdt_pm_disable(void *data) + { + struct watchdog_device *wdev = data; +- struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); + + pm_runtime_disable(wdev->parent); +- reset_control_assert(priv->rstc); + } + + static int rzg2l_wdt_probe(struct platform_device *pdev) +@@ -285,19 +288,9 @@ static int rzg2l_wdt_probe(struct platform_device *pdev) + return dev_err_probe(&pdev->dev, PTR_ERR(priv->rstc), + "failed to get cpg reset"); + +- ret = reset_control_deassert(priv->rstc); +- if (ret) +- return dev_err_probe(dev, ret, "failed to deassert"); +- + priv->devtype = (uintptr_t)of_device_get_match_data(dev); + +- if (priv->devtype == WDT_RZV2M) { +- priv->minimum_assertion_period = RZV2M_A_NSEC + +- 3 * F2CYCLE_NSEC(pclk_rate) + 5 * +- max(F2CYCLE_NSEC(priv->osc_clk_rate), +- F2CYCLE_NSEC(pclk_rate)); +- } +- ++ pm_runtime_irq_safe(&pdev->dev); + pm_runtime_enable(&pdev->dev); + + priv->wdev.info = &rzg2l_wdt_ident; +@@ -309,9 +302,7 @@ static int rzg2l_wdt_probe(struct platform_device *pdev) + priv->wdev.timeout = WDT_DEFAULT_TIMEOUT; + + watchdog_set_drvdata(&priv->wdev, priv); +- ret = devm_add_action_or_reset(&pdev->dev, +- rzg2l_wdt_reset_assert_pm_disable, +- &priv->wdev); ++ ret = devm_add_action_or_reset(&pdev->dev, rzg2l_wdt_pm_disable, &priv->wdev); + if (ret < 0) + return ret; + +diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c +index 25c902e7556d57..4b21ca49b6665d 100644 +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -526,13 +526,13 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, + * bytes the allocator should try to find free next to the block it returns. + * This is just a hint and may be ignored by the allocator. + */ +-static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, +- struct btrfs_root *root, +- struct extent_buffer *buf, +- struct extent_buffer *parent, int parent_slot, +- struct extent_buffer **cow_ret, +- u64 search_start, u64 empty_size, +- enum btrfs_lock_nesting nest) ++int btrfs_force_cow_block(struct btrfs_trans_handle *trans, ++ struct btrfs_root *root, ++ struct extent_buffer *buf, ++ struct extent_buffer *parent, int parent_slot, ++ struct extent_buffer **cow_ret, ++ u64 search_start, u64 empty_size, ++ enum btrfs_lock_nesting nest) + { + struct btrfs_fs_info *fs_info = root->fs_info; + struct btrfs_disk_key disk_key; +@@ -660,6 +660,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, + return ret; + } + } ++ ++ trace_btrfs_cow_block(root, buf, cow); + if (unlock_orig) + btrfs_tree_unlock(buf); + free_extent_buffer_stale(buf); +@@ -699,7 +701,7 @@ static inline int should_cow_block(struct btrfs_trans_handle *trans, + } + + /* +- * cows a single block, see __btrfs_cow_block for the real work. ++ * COWs a single block, see btrfs_force_cow_block() for the real work. + * This version of it has extra checks so that a block isn't COWed more than + * once per transaction, as long as it hasn't been written yet + */ +@@ -711,7 +713,6 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, + { + struct btrfs_fs_info *fs_info = root->fs_info; + u64 search_start; +- int ret; + + if (unlikely(test_bit(BTRFS_ROOT_DELETING, &root->state))) { + btrfs_abort_transaction(trans, -EUCLEAN); +@@ -752,12 +753,8 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, + * Also We don't care about the error, as it's handled internally. + */ + btrfs_qgroup_trace_subtree_after_cow(trans, root, buf); +- ret = __btrfs_cow_block(trans, root, buf, parent, +- parent_slot, cow_ret, search_start, 0, nest); +- +- trace_btrfs_cow_block(root, buf, *cow_ret); +- +- return ret; ++ return btrfs_force_cow_block(trans, root, buf, parent, parent_slot, ++ cow_ret, search_start, 0, nest); + } + ALLOW_ERROR_INJECTION(btrfs_cow_block, ERRNO); + +@@ -904,11 +901,11 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, + search_start = last_block; + + btrfs_tree_lock(cur); +- err = __btrfs_cow_block(trans, root, cur, parent, i, +- &cur, search_start, +- min(16 * blocksize, +- (end_slot - i) * blocksize), +- BTRFS_NESTING_COW); ++ err = btrfs_force_cow_block(trans, root, cur, parent, i, ++ &cur, search_start, ++ min(16 * blocksize, ++ (end_slot - i) * blocksize), ++ BTRFS_NESTING_COW); + if (err) { + btrfs_tree_unlock(cur); + free_extent_buffer(cur); +diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h +index f7bb4c34b984b3..7df3ed2945b049 100644 +--- a/fs/btrfs/ctree.h ++++ b/fs/btrfs/ctree.h +@@ -538,6 +538,13 @@ int btrfs_cow_block(struct btrfs_trans_handle *trans, + struct extent_buffer *parent, int parent_slot, + struct extent_buffer **cow_ret, + enum btrfs_lock_nesting nest); ++int btrfs_force_cow_block(struct btrfs_trans_handle *trans, ++ struct btrfs_root *root, ++ struct extent_buffer *buf, ++ struct extent_buffer *parent, int parent_slot, ++ struct extent_buffer **cow_ret, ++ u64 search_start, u64 empty_size, ++ enum btrfs_lock_nesting nest); + int btrfs_copy_root(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct extent_buffer *buf, +diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c +index 8ec411eb9c9b0c..967c6b5dd0a434 100644 +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -4323,6 +4323,15 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info) + * already the cleaner, but below we run all pending delayed iputs. + */ + btrfs_flush_workqueue(fs_info->fixup_workers); ++ /* ++ * Similar case here, we have to wait for delalloc workers before we ++ * proceed below and stop the cleaner kthread, otherwise we trigger a ++ * use-after-tree on the cleaner kthread task_struct when a delalloc ++ * worker running submit_compressed_extents() adds a delayed iput, which ++ * does a wake up on the cleaner kthread, which was already freed below ++ * when we call kthread_stop(). ++ */ ++ btrfs_flush_workqueue(fs_info->delalloc_workers); + + /* + * After we parked the cleaner kthread, ordered extents may have +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index d6767f728c079d..eb9319d856f2d8 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -9972,7 +9972,7 @@ static void btrfs_encoded_read_endio(struct btrfs_bio *bbio) + */ + WRITE_ONCE(priv->status, bbio->bio.bi_status); + } +- if (!atomic_dec_return(&priv->pending)) ++ if (atomic_dec_and_test(&priv->pending)) + wake_up(&priv->wait); + bio_put(&bbio->bio); + } +diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c +index 11289ce8a8cc81..dfa1b3c82b53ac 100644 +--- a/fs/ceph/mds_client.c ++++ b/fs/ceph/mds_client.c +@@ -2713,12 +2713,11 @@ char *ceph_mdsc_build_path(struct ceph_mds_client *mdsc, struct dentry *dentry, + + if (pos < 0) { + /* +- * A rename didn't occur, but somehow we didn't end up where +- * we thought we would. Throw a warning and try again. ++ * The path is longer than PATH_MAX and this function ++ * cannot ever succeed. Creating paths that long is ++ * possible with Ceph, but Linux cannot use them. + */ +- pr_warn("build_path did not end path lookup where expected (pos = %d)\n", +- pos); +- goto retry; ++ return ERR_PTR(-ENAMETOOLONG); + } + + *pbase = base; +diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h +index 3db01b933c3e8b..60455c84a93742 100644 +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -891,10 +891,13 @@ do { \ + (raw_inode)->xtime = cpu_to_le32(clamp_t(int32_t, (ts).tv_sec, S32_MIN, S32_MAX)); \ + } while (0) + +-#define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode) \ +- EXT4_INODE_SET_XTIME_VAL(xtime, inode, raw_inode, (inode)->xtime) ++#define EXT4_INODE_SET_ATIME(inode, raw_inode) \ ++ EXT4_INODE_SET_XTIME_VAL(i_atime, inode, raw_inode, inode_get_atime(inode)) + +-#define EXT4_INODE_SET_CTIME(inode, raw_inode) \ ++#define EXT4_INODE_SET_MTIME(inode, raw_inode) \ ++ EXT4_INODE_SET_XTIME_VAL(i_mtime, inode, raw_inode, inode_get_mtime(inode)) ++ ++#define EXT4_INODE_SET_CTIME(inode, raw_inode) \ + EXT4_INODE_SET_XTIME_VAL(i_ctime, inode, raw_inode, inode_get_ctime(inode)) + + #define EXT4_EINODE_SET_XTIME(xtime, einode, raw_inode) \ +@@ -910,9 +913,16 @@ do { \ + .tv_sec = (signed)le32_to_cpu((raw_inode)->xtime) \ + }) + +-#define EXT4_INODE_GET_XTIME(xtime, inode, raw_inode) \ ++#define EXT4_INODE_GET_ATIME(inode, raw_inode) \ ++do { \ ++ inode_set_atime_to_ts(inode, \ ++ EXT4_INODE_GET_XTIME_VAL(i_atime, inode, raw_inode)); \ ++} while (0) ++ ++#define EXT4_INODE_GET_MTIME(inode, raw_inode) \ + do { \ +- (inode)->xtime = EXT4_INODE_GET_XTIME_VAL(xtime, inode, raw_inode); \ ++ inode_set_mtime_to_ts(inode, \ ++ EXT4_INODE_GET_XTIME_VAL(i_mtime, inode, raw_inode)); \ + } while (0) + + #define EXT4_INODE_GET_CTIME(inode, raw_inode) \ +diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c +index 5ea75af6ca2239..32218ac7f50fe2 100644 +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -4475,7 +4475,7 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, + int depth = 0; + struct ext4_map_blocks map; + unsigned int credits; +- loff_t epos; ++ loff_t epos, old_size = i_size_read(inode); + + BUG_ON(!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)); + map.m_lblk = offset; +@@ -4532,7 +4532,13 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, + if (epos > new_size) + epos = new_size; + if (ext4_update_inode_size(inode, epos) & 0x1) +- inode->i_mtime = inode_get_ctime(inode); ++ inode_set_mtime_to_ts(inode, ++ inode_get_ctime(inode)); ++ if (epos > old_size) { ++ pagecache_isize_extended(inode, old_size, epos); ++ ext4_zero_partial_blocks(handle, inode, ++ old_size, epos - old_size); ++ } + } + ret2 = ext4_mark_inode_dirty(handle, inode); + ext4_update_inode_fsync_trans(handle, inode, 1); +@@ -4670,7 +4676,7 @@ static long ext4_zero_range(struct file *file, loff_t offset, + + /* Now release the pages and zero block aligned part of pages */ + truncate_pagecache_range(inode, start, end - 1); +- inode->i_mtime = inode_set_ctime_current(inode); ++ inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); + + ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, + flags); +@@ -4695,7 +4701,7 @@ static long ext4_zero_range(struct file *file, loff_t offset, + goto out_mutex; + } + +- inode->i_mtime = inode_set_ctime_current(inode); ++ inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); + if (new_size) + ext4_update_inode_size(inode, new_size); + ret = ext4_mark_inode_dirty(handle, inode); +@@ -5431,7 +5437,7 @@ static int ext4_collapse_range(struct file *file, loff_t offset, loff_t len) + up_write(&EXT4_I(inode)->i_data_sem); + if (IS_SYNC(inode)) + ext4_handle_sync(handle); +- inode->i_mtime = inode_set_ctime_current(inode); ++ inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); + ret = ext4_mark_inode_dirty(handle, inode); + ext4_update_inode_fsync_trans(handle, inode, 1); + +@@ -5541,7 +5547,7 @@ static int ext4_insert_range(struct file *file, loff_t offset, loff_t len) + /* Expand file to avoid data loss if there is error while shifting */ + inode->i_size += len; + EXT4_I(inode)->i_disksize += len; +- inode->i_mtime = inode_set_ctime_current(inode); ++ inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); + ret = ext4_mark_inode_dirty(handle, inode); + if (ret) + goto out_stop; +diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c +index d4d0ad689d3c1c..52f2959d29e6e0 100644 +--- a/fs/ext4/ialloc.c ++++ b/fs/ext4/ialloc.c +@@ -1255,8 +1255,8 @@ struct inode *__ext4_new_inode(struct mnt_idmap *idmap, + inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb); + /* This is the optimal IO size (for stat), not the fs block size */ + inode->i_blocks = 0; +- inode->i_mtime = inode->i_atime = inode_set_ctime_current(inode); +- ei->i_crtime = inode->i_mtime; ++ simple_inode_init_ts(inode); ++ ei->i_crtime = inode_get_mtime(inode); + + memset(ei->i_data, 0, sizeof(ei->i_data)); + ei->i_dir_start_lookup = 0; +diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c +index cb65052ee3dec6..3f363276ddd360 100644 +--- a/fs/ext4/inline.c ++++ b/fs/ext4/inline.c +@@ -1037,7 +1037,7 @@ static int ext4_add_dirent_to_inline(handle_t *handle, + * happen is that the times are slightly out of date + * and/or different from the directory change time. + */ +- dir->i_mtime = inode_set_ctime_current(dir); ++ inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir)); + ext4_update_dx_flag(dir); + inode_inc_iversion(dir); + return 1; +@@ -2010,7 +2010,7 @@ int ext4_inline_data_truncate(struct inode *inode, int *has_inline) + ext4_orphan_del(handle, inode); + + if (err == 0) { +- inode->i_mtime = inode_set_ctime_current(inode); ++ inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); + err = ext4_mark_inode_dirty(handle, inode); + if (IS_SYNC(inode)) + ext4_handle_sync(handle); +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index 18ec9106c5b09f..19d7bcf16ebb88 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -1328,8 +1328,10 @@ static int ext4_write_end(struct file *file, + folio_unlock(folio); + folio_put(folio); + +- if (old_size < pos && !verity) ++ if (old_size < pos && !verity) { + pagecache_isize_extended(inode, old_size, pos); ++ ext4_zero_partial_blocks(handle, inode, old_size, pos - old_size); ++ } + /* + * Don't mark the inode dirty under folio lock. First, it unnecessarily + * makes the holding time of folio lock longer. Second, it forces lock +@@ -1445,8 +1447,10 @@ static int ext4_journalled_write_end(struct file *file, + folio_unlock(folio); + folio_put(folio); + +- if (old_size < pos && !verity) ++ if (old_size < pos && !verity) { + pagecache_isize_extended(inode, old_size, pos); ++ ext4_zero_partial_blocks(handle, inode, old_size, pos - old_size); ++ } + + if (size_changed) { + ret2 = ext4_mark_inode_dirty(handle, inode); +@@ -2971,7 +2975,8 @@ static int ext4_da_do_write_end(struct address_space *mapping, + struct inode *inode = mapping->host; + loff_t old_size = inode->i_size; + bool disksize_changed = false; +- loff_t new_i_size; ++ loff_t new_i_size, zero_len = 0; ++ handle_t *handle; + + if (unlikely(!folio_buffers(folio))) { + folio_unlock(folio); +@@ -3015,18 +3020,21 @@ static int ext4_da_do_write_end(struct address_space *mapping, + folio_unlock(folio); + folio_put(folio); + +- if (old_size < pos) ++ if (pos > old_size) { + pagecache_isize_extended(inode, old_size, pos); ++ zero_len = pos - old_size; ++ } + +- if (disksize_changed) { +- handle_t *handle; ++ if (!disksize_changed && !zero_len) ++ return copied; + +- handle = ext4_journal_start(inode, EXT4_HT_INODE, 2); +- if (IS_ERR(handle)) +- return PTR_ERR(handle); +- ext4_mark_inode_dirty(handle, inode); +- ext4_journal_stop(handle); +- } ++ handle = ext4_journal_start(inode, EXT4_HT_INODE, 2); ++ if (IS_ERR(handle)) ++ return PTR_ERR(handle); ++ if (zero_len) ++ ext4_zero_partial_blocks(handle, inode, old_size, zero_len); ++ ext4_mark_inode_dirty(handle, inode); ++ ext4_journal_stop(handle); + + return copied; + } +@@ -4055,7 +4063,7 @@ int ext4_punch_hole(struct file *file, loff_t offset, loff_t length) + if (IS_SYNC(inode)) + ext4_handle_sync(handle); + +- inode->i_mtime = inode_set_ctime_current(inode); ++ inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); + ret2 = ext4_mark_inode_dirty(handle, inode); + if (unlikely(ret2)) + ret = ret2; +@@ -4215,7 +4223,7 @@ int ext4_truncate(struct inode *inode) + if (inode->i_nlink) + ext4_orphan_del(handle, inode); + +- inode->i_mtime = inode_set_ctime_current(inode); ++ inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); + err2 = ext4_mark_inode_dirty(handle, inode); + if (unlikely(err2 && !err)) + err = err2; +@@ -4319,8 +4327,8 @@ static int ext4_fill_raw_inode(struct inode *inode, struct ext4_inode *raw_inode + raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); + + EXT4_INODE_SET_CTIME(inode, raw_inode); +- EXT4_INODE_SET_XTIME(i_mtime, inode, raw_inode); +- EXT4_INODE_SET_XTIME(i_atime, inode, raw_inode); ++ EXT4_INODE_SET_MTIME(inode, raw_inode); ++ EXT4_INODE_SET_ATIME(inode, raw_inode); + EXT4_EINODE_SET_XTIME(i_crtime, ei, raw_inode); + + raw_inode->i_dtime = cpu_to_le32(ei->i_dtime); +@@ -4928,8 +4936,8 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, + } + + EXT4_INODE_GET_CTIME(inode, raw_inode); +- EXT4_INODE_GET_XTIME(i_mtime, inode, raw_inode); +- EXT4_INODE_GET_XTIME(i_atime, inode, raw_inode); ++ EXT4_INODE_GET_ATIME(inode, raw_inode); ++ EXT4_INODE_GET_MTIME(inode, raw_inode); + EXT4_EINODE_GET_XTIME(i_crtime, ei, raw_inode); + + if (likely(!test_opt2(inode->i_sb, HURD_COMPAT))) { +@@ -5054,8 +5062,8 @@ static void __ext4_update_other_inode_time(struct super_block *sb, + + spin_lock(&ei->i_raw_lock); + EXT4_INODE_SET_CTIME(inode, raw_inode); +- EXT4_INODE_SET_XTIME(i_mtime, inode, raw_inode); +- EXT4_INODE_SET_XTIME(i_atime, inode, raw_inode); ++ EXT4_INODE_SET_MTIME(inode, raw_inode); ++ EXT4_INODE_SET_ATIME(inode, raw_inode); + ext4_inode_csum_set(inode, raw_inode, ei); + spin_unlock(&ei->i_raw_lock); + trace_ext4_other_inode_update_time(inode, orig_ino); +@@ -5437,6 +5445,14 @@ int ext4_setattr(struct mnt_idmap *idmap, struct dentry *dentry, + } + + if (attr->ia_size != inode->i_size) { ++ /* attach jbd2 jinode for EOF folio tail zeroing */ ++ if (attr->ia_size & (inode->i_sb->s_blocksize - 1) || ++ oldsize & (inode->i_sb->s_blocksize - 1)) { ++ error = ext4_inode_attach_jinode(inode); ++ if (error) ++ goto err_out; ++ } ++ + handle = ext4_journal_start(inode, EXT4_HT_INODE, 3); + if (IS_ERR(handle)) { + error = PTR_ERR(handle); +@@ -5447,11 +5463,17 @@ int ext4_setattr(struct mnt_idmap *idmap, struct dentry *dentry, + orphan = 1; + } + /* +- * Update c/mtime on truncate up, ext4_truncate() will +- * update c/mtime in shrink case below ++ * Update c/mtime and tail zero the EOF folio on ++ * truncate up. ext4_truncate() handles the shrink case ++ * below. + */ +- if (!shrink) +- inode->i_mtime = inode_set_ctime_current(inode); ++ if (!shrink) { ++ inode_set_mtime_to_ts(inode, ++ inode_set_ctime_current(inode)); ++ if (oldsize & (inode->i_sb->s_blocksize - 1)) ++ ext4_block_truncate_page(handle, ++ inode->i_mapping, oldsize); ++ } + + if (shrink) + ext4_fc_track_range(handle, inode, +diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c +index 0bfe2ce589e224..4f931f80cb3489 100644 +--- a/fs/ext4/ioctl.c ++++ b/fs/ext4/ioctl.c +@@ -312,13 +312,22 @@ static void swap_inode_data(struct inode *inode1, struct inode *inode2) + struct ext4_inode_info *ei1; + struct ext4_inode_info *ei2; + unsigned long tmp; ++ struct timespec64 ts1, ts2; + + ei1 = EXT4_I(inode1); + ei2 = EXT4_I(inode2); + + swap(inode1->i_version, inode2->i_version); +- swap(inode1->i_atime, inode2->i_atime); +- swap(inode1->i_mtime, inode2->i_mtime); ++ ++ ts1 = inode_get_atime(inode1); ++ ts2 = inode_get_atime(inode2); ++ inode_set_atime_to_ts(inode1, ts2); ++ inode_set_atime_to_ts(inode2, ts1); ++ ++ ts1 = inode_get_mtime(inode1); ++ ts2 = inode_get_mtime(inode2); ++ inode_set_mtime_to_ts(inode1, ts2); ++ inode_set_mtime_to_ts(inode2, ts1); + + memswap(ei1->i_data, ei2->i_data, sizeof(ei1->i_data)); + tmp = ei1->i_flags & EXT4_FL_SHOULD_SWAP; +diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c +index 4de1f61bba76b3..96a048d3f51bf5 100644 +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -2210,7 +2210,7 @@ static int add_dirent_to_buf(handle_t *handle, struct ext4_filename *fname, + * happen is that the times are slightly out of date + * and/or different from the directory change time. + */ +- dir->i_mtime = inode_set_ctime_current(dir); ++ inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir)); + ext4_update_dx_flag(dir); + inode_inc_iversion(dir); + err2 = ext4_mark_inode_dirty(handle, dir); +@@ -3248,7 +3248,7 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry) + * recovery. */ + inode->i_size = 0; + ext4_orphan_add(handle, inode); +- dir->i_mtime = inode_set_ctime_current(dir); ++ inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir)); + inode_set_ctime_current(inode); + retval = ext4_mark_inode_dirty(handle, inode); + if (retval) +@@ -3323,7 +3323,7 @@ int __ext4_unlink(struct inode *dir, const struct qstr *d_name, + retval = ext4_delete_entry(handle, dir, de, bh); + if (retval) + goto out_handle; +- dir->i_mtime = inode_set_ctime_current(dir); ++ inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir)); + ext4_update_dx_flag(dir); + retval = ext4_mark_inode_dirty(handle, dir); + if (retval) +@@ -3691,7 +3691,7 @@ static int ext4_setent(handle_t *handle, struct ext4_renament *ent, + if (ext4_has_feature_filetype(ent->dir->i_sb)) + ent->de->file_type = file_type; + inode_inc_iversion(ent->dir); +- ent->dir->i_mtime = inode_set_ctime_current(ent->dir); ++ inode_set_mtime_to_ts(ent->dir, inode_set_ctime_current(ent->dir)); + retval = ext4_mark_inode_dirty(handle, ent->dir); + BUFFER_TRACE(ent->bh, "call ext4_handle_dirty_metadata"); + if (!ent->inlined) { +@@ -4006,7 +4006,7 @@ static int ext4_rename(struct mnt_idmap *idmap, struct inode *old_dir, + ext4_dec_count(new.inode); + inode_set_ctime_current(new.inode); + } +- old.dir->i_mtime = inode_set_ctime_current(old.dir); ++ inode_set_mtime_to_ts(old.dir, inode_set_ctime_current(old.dir)); + ext4_update_dx_flag(old.dir); + if (old.dir_bh) { + retval = ext4_rename_dir_finish(handle, &old, new.dir->i_ino); +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 2346ef071b2421..71ced0ada9a2e5 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -7180,7 +7180,7 @@ static int ext4_quota_off(struct super_block *sb, int type) + } + EXT4_I(inode)->i_flags &= ~(EXT4_NOATIME_FL | EXT4_IMMUTABLE_FL); + inode_set_flags(inode, 0, S_NOATIME | S_IMMUTABLE); +- inode->i_mtime = inode_set_ctime_current(inode); ++ inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); + err = ext4_mark_inode_dirty(handle, inode); + ext4_journal_stop(handle); + out_unlock: +diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c +index f40785bc4e5549..df5ab1a75fc482 100644 +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -356,7 +356,7 @@ ext4_xattr_inode_hash(struct ext4_sb_info *sbi, const void *buffer, size_t size) + + static u64 ext4_xattr_inode_get_ref(struct inode *ea_inode) + { +- return ((u64) inode_get_ctime(ea_inode).tv_sec << 32) | ++ return ((u64) inode_get_ctime_sec(ea_inode) << 32) | + (u32) inode_peek_iversion_raw(ea_inode); + } + +@@ -368,12 +368,12 @@ static void ext4_xattr_inode_set_ref(struct inode *ea_inode, u64 ref_count) + + static u32 ext4_xattr_inode_get_hash(struct inode *ea_inode) + { +- return (u32)ea_inode->i_atime.tv_sec; ++ return (u32) inode_get_atime_sec(ea_inode); + } + + static void ext4_xattr_inode_set_hash(struct inode *ea_inode, u32 hash) + { +- ea_inode->i_atime.tv_sec = hash; ++ inode_set_atime(ea_inode, hash, 0); + } + + /* +@@ -418,7 +418,7 @@ static int ext4_xattr_inode_read(struct inode *ea_inode, void *buf, size_t size) + return ret; + } + +-#define EXT4_XATTR_INODE_GET_PARENT(inode) ((__u32)(inode)->i_mtime.tv_sec) ++#define EXT4_XATTR_INODE_GET_PARENT(inode) ((__u32)(inode_get_mtime_sec(inode))) + + static int ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino, + u32 ea_inode_hash, struct inode **ea_inode) +diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c +index 196755a34833d2..ae129044c52f42 100644 +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -1037,6 +1037,13 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, + return err; + } + ++ /* ++ * wait for inflight dio, blocks should be removed after ++ * IO completion. ++ */ ++ if (attr->ia_size < old_size) ++ inode_dio_wait(inode); ++ + f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + filemap_invalidate_lock(inode->i_mapping); + +@@ -1873,6 +1880,12 @@ static long f2fs_fallocate(struct file *file, int mode, + if (ret) + goto out; + ++ /* ++ * wait for inflight dio, blocks should be removed after IO ++ * completion. ++ */ ++ inode_dio_wait(inode); ++ + if (mode & FALLOC_FL_PUNCH_HOLE) { + if (offset >= inode->i_size) + goto out; +diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c +index fc6cea60044edf..e25989dd2c6bba 100644 +--- a/fs/ntfs3/attrib.c ++++ b/fs/ntfs3/attrib.c +@@ -977,15 +977,17 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn, + goto out; + + /* Check for compressed frame. */ +- err = attr_is_frame_compressed(ni, attr, vcn >> NTFS_LZNT_CUNIT, &hint); ++ err = attr_is_frame_compressed(ni, attr_b, vcn >> NTFS_LZNT_CUNIT, ++ &hint, run); + if (err) + goto out; + + if (hint) { + /* if frame is compressed - don't touch it. */ + *lcn = COMPRESSED_LCN; +- *len = hint; +- err = -EOPNOTSUPP; ++ /* length to the end of frame. */ ++ *len = NTFS_LZNT_CLUSTERS - (vcn & (NTFS_LZNT_CLUSTERS - 1)); ++ err = 0; + goto out; + } + +@@ -1028,16 +1030,16 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn, + + /* Check if 'vcn' and 'vcn0' in different attribute segments. */ + if (vcn < svcn || evcn1 <= vcn) { +- /* Load attribute for truncated vcn. */ +- attr = ni_find_attr(ni, attr_b, &le, ATTR_DATA, NULL, 0, +- &vcn, &mi); +- if (!attr) { ++ struct ATTRIB *attr2; ++ /* Load runs for truncated vcn. */ ++ attr2 = ni_find_attr(ni, attr_b, &le_b, ATTR_DATA, NULL, ++ 0, &vcn, &mi); ++ if (!attr2) { + err = -EINVAL; + goto out; + } +- svcn = le64_to_cpu(attr->nres.svcn); +- evcn1 = le64_to_cpu(attr->nres.evcn) + 1; +- err = attr_load_runs(attr, ni, run, NULL); ++ evcn1 = le64_to_cpu(attr2->nres.evcn) + 1; ++ err = attr_load_runs(attr2, ni, run, NULL); + if (err) + goto out; + } +@@ -1530,15 +1532,18 @@ int attr_wof_frame_info(struct ntfs_inode *ni, struct ATTRIB *attr, + + /* + * attr_is_frame_compressed - Used to detect compressed frame. ++ * ++ * attr - base (primary) attribute segment. ++ * run - run to use, usually == &ni->file.run. ++ * Only base segments contains valid 'attr->nres.c_unit' + */ + int attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr, +- CLST frame, CLST *clst_data) ++ CLST frame, CLST *clst_data, struct runs_tree *run) + { + int err; + u32 clst_frame; + CLST clen, lcn, vcn, alen, slen, vcn_next; + size_t idx; +- struct runs_tree *run; + + *clst_data = 0; + +@@ -1550,7 +1555,6 @@ int attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr, + + clst_frame = 1u << attr->nres.c_unit; + vcn = frame * clst_frame; +- run = &ni->file.run; + + if (!run_lookup_entry(run, vcn, &lcn, &clen, &idx)) { + err = attr_load_runs_vcn(ni, attr->type, attr_name(attr), +@@ -1686,7 +1690,7 @@ int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size, + if (err) + goto out; + +- err = attr_is_frame_compressed(ni, attr_b, frame, &clst_data); ++ err = attr_is_frame_compressed(ni, attr_b, frame, &clst_data, run); + if (err) + goto out; + +diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c +index 12e03feb3074a0..3c876c468c2c47 100644 +--- a/fs/ntfs3/frecord.c ++++ b/fs/ntfs3/frecord.c +@@ -1900,46 +1900,6 @@ enum REPARSE_SIGN ni_parse_reparse(struct ntfs_inode *ni, struct ATTRIB *attr, + return REPARSE_LINK; + } + +-/* +- * fiemap_fill_next_extent_k - a copy of fiemap_fill_next_extent +- * but it uses 'fe_k' instead of fieinfo->fi_extents_start +- */ +-static int fiemap_fill_next_extent_k(struct fiemap_extent_info *fieinfo, +- struct fiemap_extent *fe_k, u64 logical, +- u64 phys, u64 len, u32 flags) +-{ +- struct fiemap_extent extent; +- +- /* only count the extents */ +- if (fieinfo->fi_extents_max == 0) { +- fieinfo->fi_extents_mapped++; +- return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0; +- } +- +- if (fieinfo->fi_extents_mapped >= fieinfo->fi_extents_max) +- return 1; +- +- if (flags & FIEMAP_EXTENT_DELALLOC) +- flags |= FIEMAP_EXTENT_UNKNOWN; +- if (flags & FIEMAP_EXTENT_DATA_ENCRYPTED) +- flags |= FIEMAP_EXTENT_ENCODED; +- if (flags & (FIEMAP_EXTENT_DATA_TAIL | FIEMAP_EXTENT_DATA_INLINE)) +- flags |= FIEMAP_EXTENT_NOT_ALIGNED; +- +- memset(&extent, 0, sizeof(extent)); +- extent.fe_logical = logical; +- extent.fe_physical = phys; +- extent.fe_length = len; +- extent.fe_flags = flags; +- +- memcpy(fe_k + fieinfo->fi_extents_mapped, &extent, sizeof(extent)); +- +- fieinfo->fi_extents_mapped++; +- if (fieinfo->fi_extents_mapped == fieinfo->fi_extents_max) +- return 1; +- return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0; +-} +- + /* + * ni_fiemap - Helper for file_fiemap(). + * +@@ -1950,11 +1910,9 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, + __u64 vbo, __u64 len) + { + int err = 0; +- struct fiemap_extent *fe_k = NULL; + struct ntfs_sb_info *sbi = ni->mi.sbi; + u8 cluster_bits = sbi->cluster_bits; +- struct runs_tree *run; +- struct rw_semaphore *run_lock; ++ struct runs_tree run; + struct ATTRIB *attr; + CLST vcn = vbo >> cluster_bits; + CLST lcn, clen; +@@ -1965,13 +1923,11 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, + u32 flags; + bool ok; + ++ run_init(&run); + if (S_ISDIR(ni->vfs_inode.i_mode)) { +- run = &ni->dir.alloc_run; + attr = ni_find_attr(ni, NULL, NULL, ATTR_ALLOC, I30_NAME, + ARRAY_SIZE(I30_NAME), NULL, NULL); +- run_lock = &ni->dir.run_lock; + } else { +- run = &ni->file.run; + attr = ni_find_attr(ni, NULL, NULL, ATTR_DATA, NULL, 0, NULL, + NULL); + if (!attr) { +@@ -1986,7 +1942,6 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, + "fiemap is not supported for compressed file (cp -r)"); + goto out; + } +- run_lock = &ni->file.run_lock; + } + + if (!attr || !attr->non_res) { +@@ -1998,51 +1953,33 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, + goto out; + } + +- /* +- * To avoid lock problems replace pointer to user memory by pointer to kernel memory. +- */ +- fe_k = kmalloc_array(fieinfo->fi_extents_max, +- sizeof(struct fiemap_extent), +- GFP_NOFS | __GFP_ZERO); +- if (!fe_k) { +- err = -ENOMEM; +- goto out; +- } +- + end = vbo + len; + alloc_size = le64_to_cpu(attr->nres.alloc_size); + if (end > alloc_size) + end = alloc_size; + +- down_read(run_lock); + + while (vbo < end) { + if (idx == -1) { +- ok = run_lookup_entry(run, vcn, &lcn, &clen, &idx); ++ ok = run_lookup_entry(&run, vcn, &lcn, &clen, &idx); + } else { + CLST vcn_next = vcn; + +- ok = run_get_entry(run, ++idx, &vcn, &lcn, &clen) && ++ ok = run_get_entry(&run, ++idx, &vcn, &lcn, &clen) && + vcn == vcn_next; + if (!ok) + vcn = vcn_next; + } + + if (!ok) { +- up_read(run_lock); +- down_write(run_lock); +- + err = attr_load_runs_vcn(ni, attr->type, + attr_name(attr), +- attr->name_len, run, vcn); +- +- up_write(run_lock); +- down_read(run_lock); ++ attr->name_len, &run, vcn); + + if (err) + break; + +- ok = run_lookup_entry(run, vcn, &lcn, &clen, &idx); ++ ok = run_lookup_entry(&run, vcn, &lcn, &clen, &idx); + + if (!ok) { + err = -EINVAL; +@@ -2067,8 +2004,9 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, + } else if (is_attr_compressed(attr)) { + CLST clst_data; + +- err = attr_is_frame_compressed( +- ni, attr, vcn >> attr->nres.c_unit, &clst_data); ++ err = attr_is_frame_compressed(ni, attr, ++ vcn >> attr->nres.c_unit, ++ &clst_data, &run); + if (err) + break; + if (clst_data < NTFS_LZNT_CLUSTERS) +@@ -2097,8 +2035,8 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, + if (vbo + dlen >= end) + flags |= FIEMAP_EXTENT_LAST; + +- err = fiemap_fill_next_extent_k(fieinfo, fe_k, vbo, lbo, +- dlen, flags); ++ err = fiemap_fill_next_extent(fieinfo, vbo, lbo, dlen, ++ flags); + + if (err < 0) + break; +@@ -2119,8 +2057,7 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, + if (vbo + bytes >= end) + flags |= FIEMAP_EXTENT_LAST; + +- err = fiemap_fill_next_extent_k(fieinfo, fe_k, vbo, lbo, bytes, +- flags); ++ err = fiemap_fill_next_extent(fieinfo, vbo, lbo, bytes, flags); + if (err < 0) + break; + if (err == 1) { +@@ -2131,19 +2068,8 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, + vbo += bytes; + } + +- up_read(run_lock); +- +- /* +- * Copy to user memory out of lock +- */ +- if (copy_to_user(fieinfo->fi_extents_start, fe_k, +- fieinfo->fi_extents_max * +- sizeof(struct fiemap_extent))) { +- err = -EFAULT; +- } +- + out: +- kfree(fe_k); ++ run_close(&run); + return err; + } + +@@ -2674,7 +2600,8 @@ int ni_read_frame(struct ntfs_inode *ni, u64 frame_vbo, struct page **pages, + down_write(&ni->file.run_lock); + run_truncate_around(run, le64_to_cpu(attr->nres.svcn)); + frame = frame_vbo >> (cluster_bits + NTFS_LZNT_CUNIT); +- err = attr_is_frame_compressed(ni, attr, frame, &clst_data); ++ err = attr_is_frame_compressed(ni, attr, frame, &clst_data, ++ run); + up_write(&ni->file.run_lock); + if (err) + goto out1; +diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c +index 52b80fd1591478..af7c0cbba74e3d 100644 +--- a/fs/ntfs3/inode.c ++++ b/fs/ntfs3/inode.c +@@ -604,7 +604,8 @@ static noinline int ntfs_get_block_vbo(struct inode *inode, u64 vbo, + + bytes = ((u64)len << cluster_bits) - off; + +- if (lcn == SPARSE_LCN) { ++ if (lcn >= sbi->used.bitmap.nbits) { ++ /* This case includes resident/compressed/sparse. */ + if (!create) { + if (bh->b_size > bytes) + bh->b_size = bytes; +diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h +index cfe9d3bf07f910..c98e6868bfbadb 100644 +--- a/fs/ntfs3/ntfs_fs.h ++++ b/fs/ntfs3/ntfs_fs.h +@@ -446,7 +446,8 @@ int attr_wof_frame_info(struct ntfs_inode *ni, struct ATTRIB *attr, + struct runs_tree *run, u64 frame, u64 frames, + u8 frame_bits, u32 *ondisk_size, u64 *vbo_data); + int attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr, +- CLST frame, CLST *clst_data); ++ CLST frame, CLST *clst_data, ++ struct runs_tree *run); + int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size, + u64 new_valid); + int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes); +diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c +index dc9f76ab7e13c3..0dffd6a44d39dc 100644 +--- a/fs/ocfs2/quota_global.c ++++ b/fs/ocfs2/quota_global.c +@@ -881,7 +881,7 @@ static int ocfs2_get_next_id(struct super_block *sb, struct kqid *qid) + int status = 0; + + trace_ocfs2_get_next_id(from_kqid(&init_user_ns, *qid), type); +- if (!sb_has_quota_loaded(sb, type)) { ++ if (!sb_has_quota_active(sb, type)) { + status = -ESRCH; + goto out; + } +diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c +index 257f13cdd14c1f..4b4fa58cd32ff0 100644 +--- a/fs/ocfs2/quota_local.c ++++ b/fs/ocfs2/quota_local.c +@@ -864,6 +864,7 @@ static int ocfs2_local_free_info(struct super_block *sb, int type) + brelse(oinfo->dqi_libh); + brelse(oinfo->dqi_lqi_bh); + kfree(oinfo); ++ info->dqi_priv = NULL; + return status; + } + +diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c +index 59571737e16771..b8640f36ebf8ab 100644 +--- a/fs/proc/task_mmu.c ++++ b/fs/proc/task_mmu.c +@@ -1516,7 +1516,7 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end, + flags |= PM_FILE; + + for (; addr != end; addr += PAGE_SIZE, idx++) { +- unsigned long cur_flags = flags; ++ u64 cur_flags = flags; + pagemap_entry_t pme; + + if (page && (flags & PM_PRESENT) && +diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c +index f5b6df82e8570a..bff8d0dd74fe7d 100644 +--- a/fs/smb/client/cifsacl.c ++++ b/fs/smb/client/cifsacl.c +@@ -27,18 +27,18 @@ + #include "cifs_unicode.h" + + /* security id for everyone/world system group */ +-static const struct cifs_sid sid_everyone = { ++static const struct smb_sid sid_everyone = { + 1, 1, {0, 0, 0, 0, 0, 1}, {0} }; + /* security id for Authenticated Users system group */ +-static const struct cifs_sid sid_authusers = { ++static const struct smb_sid sid_authusers = { + 1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} }; + + /* S-1-22-1 Unmapped Unix users */ +-static const struct cifs_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22}, ++static const struct smb_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22}, + {cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; + + /* S-1-22-2 Unmapped Unix groups */ +-static const struct cifs_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22}, ++static const struct smb_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22}, + {cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; + + /* +@@ -48,17 +48,17 @@ static const struct cifs_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22}, + /* S-1-5-88 MS NFS and Apple style UID/GID/mode */ + + /* S-1-5-88-1 Unix uid */ +-static const struct cifs_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5}, ++static const struct smb_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5}, + {cpu_to_le32(88), + cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; + + /* S-1-5-88-2 Unix gid */ +-static const struct cifs_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5}, ++static const struct smb_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5}, + {cpu_to_le32(88), + cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; + + /* S-1-5-88-3 Unix mode */ +-static const struct cifs_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5}, ++static const struct smb_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5}, + {cpu_to_le32(88), + cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; + +@@ -106,7 +106,7 @@ static struct key_type cifs_idmap_key_type = { + }; + + static char * +-sid_to_key_str(struct cifs_sid *sidptr, unsigned int type) ++sid_to_key_str(struct smb_sid *sidptr, unsigned int type) + { + int i, len; + unsigned int saval; +@@ -158,7 +158,7 @@ sid_to_key_str(struct cifs_sid *sidptr, unsigned int type) + * the same returns zero, if they do not match returns non-zero. + */ + static int +-compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid) ++compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid) + { + int i; + int num_subauth, num_sat, num_saw; +@@ -204,11 +204,11 @@ compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid) + } + + static bool +-is_well_known_sid(const struct cifs_sid *psid, uint32_t *puid, bool is_group) ++is_well_known_sid(const struct smb_sid *psid, uint32_t *puid, bool is_group) + { + int i; + int num_subauth; +- const struct cifs_sid *pwell_known_sid; ++ const struct smb_sid *pwell_known_sid; + + if (!psid || (puid == NULL)) + return false; +@@ -260,7 +260,7 @@ is_well_known_sid(const struct cifs_sid *psid, uint32_t *puid, bool is_group) + } + + static __u16 +-cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src) ++cifs_copy_sid(struct smb_sid *dst, const struct smb_sid *src) + { + int i; + __u16 size = 1 + 1 + 6; +@@ -277,11 +277,11 @@ cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src) + } + + static int +-id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid) ++id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid) + { + int rc; + struct key *sidkey; +- struct cifs_sid *ksid; ++ struct smb_sid *ksid; + unsigned int ksid_size; + char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */ + const struct cred *saved_cred; +@@ -312,8 +312,8 @@ id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid) + * it could be. + */ + ksid = sidkey->datalen <= sizeof(sidkey->payload) ? +- (struct cifs_sid *)&sidkey->payload : +- (struct cifs_sid *)sidkey->payload.data[0]; ++ (struct smb_sid *)&sidkey->payload : ++ (struct smb_sid *)sidkey->payload.data[0]; + + ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32)); + if (ksid_size > sidkey->datalen) { +@@ -336,7 +336,7 @@ id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid) + } + + int +-sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid, ++sid_to_id(struct cifs_sb_info *cifs_sb, struct smb_sid *psid, + struct cifs_fattr *fattr, uint sidtype) + { + int rc = 0; +@@ -515,43 +515,43 @@ exit_cifs_idmap(void) + } + + /* copy ntsd, owner sid, and group sid from a security descriptor to another */ +-static __u32 copy_sec_desc(const struct cifs_ntsd *pntsd, +- struct cifs_ntsd *pnntsd, ++static __u32 copy_sec_desc(const struct smb_ntsd *pntsd, ++ struct smb_ntsd *pnntsd, + __u32 sidsoffset, +- struct cifs_sid *pownersid, +- struct cifs_sid *pgrpsid) ++ struct smb_sid *pownersid, ++ struct smb_sid *pgrpsid) + { +- struct cifs_sid *owner_sid_ptr, *group_sid_ptr; +- struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr; ++ struct smb_sid *owner_sid_ptr, *group_sid_ptr; ++ struct smb_sid *nowner_sid_ptr, *ngroup_sid_ptr; + + /* copy security descriptor control portion */ + pnntsd->revision = pntsd->revision; + pnntsd->type = pntsd->type; +- pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd)); ++ pnntsd->dacloffset = cpu_to_le32(sizeof(struct smb_ntsd)); + pnntsd->sacloffset = 0; + pnntsd->osidoffset = cpu_to_le32(sidsoffset); +- pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid)); ++ pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct smb_sid)); + + /* copy owner sid */ + if (pownersid) + owner_sid_ptr = pownersid; + else +- owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + ++ owner_sid_ptr = (struct smb_sid *)((char *)pntsd + + le32_to_cpu(pntsd->osidoffset)); +- nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset); ++ nowner_sid_ptr = (struct smb_sid *)((char *)pnntsd + sidsoffset); + cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr); + + /* copy group sid */ + if (pgrpsid) + group_sid_ptr = pgrpsid; + else +- group_sid_ptr = (struct cifs_sid *)((char *)pntsd + ++ group_sid_ptr = (struct smb_sid *)((char *)pntsd + + le32_to_cpu(pntsd->gsidoffset)); +- ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset + +- sizeof(struct cifs_sid)); ++ ngroup_sid_ptr = (struct smb_sid *)((char *)pnntsd + sidsoffset + ++ sizeof(struct smb_sid)); + cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr); + +- return sidsoffset + (2 * sizeof(struct cifs_sid)); ++ return sidsoffset + (2 * sizeof(struct smb_sid)); + } + + +@@ -666,7 +666,7 @@ static void mode_to_access_flags(umode_t mode, umode_t bits_to_use, + return; + } + +-static __u16 cifs_copy_ace(struct cifs_ace *dst, struct cifs_ace *src, struct cifs_sid *psid) ++static __u16 cifs_copy_ace(struct smb_ace *dst, struct smb_ace *src, struct smb_sid *psid) + { + __u16 size = 1 + 1 + 2 + 4; + +@@ -685,8 +685,8 @@ static __u16 cifs_copy_ace(struct cifs_ace *dst, struct cifs_ace *src, struct ci + return size; + } + +-static __u16 fill_ace_for_sid(struct cifs_ace *pntace, +- const struct cifs_sid *psid, __u64 nmode, ++static __u16 fill_ace_for_sid(struct smb_ace *pntace, ++ const struct smb_sid *psid, __u64 nmode, + umode_t bits, __u8 access_type, + bool allow_delete_child) + { +@@ -723,7 +723,7 @@ static __u16 fill_ace_for_sid(struct cifs_ace *pntace, + + + #ifdef CONFIG_CIFS_DEBUG2 +-static void dump_ace(struct cifs_ace *pace, char *end_of_acl) ++static void dump_ace(struct smb_ace *pace, char *end_of_acl) + { + int num_subauth; + +@@ -758,15 +758,15 @@ static void dump_ace(struct cifs_ace *pace, char *end_of_acl) + } + #endif + +-static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, +- struct cifs_sid *pownersid, struct cifs_sid *pgrpsid, ++static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, ++ struct smb_sid *pownersid, struct smb_sid *pgrpsid, + struct cifs_fattr *fattr, bool mode_from_special_sid) + { + int i; + int num_aces = 0; + int acl_size; + char *acl_base; +- struct cifs_ace **ppace; ++ struct smb_ace **ppace; + + /* BB need to add parm so we can store the SID BB */ + +@@ -793,21 +793,21 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, + fattr->cf_mode &= ~(0777); + + acl_base = (char *)pdacl; +- acl_size = sizeof(struct cifs_acl); ++ acl_size = sizeof(struct smb_acl); + + num_aces = le32_to_cpu(pdacl->num_aces); + if (num_aces > 0) { + umode_t denied_mode = 0; + +- if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *)) ++ if (num_aces > ULONG_MAX / sizeof(struct smb_ace *)) + return; +- ppace = kmalloc_array(num_aces, sizeof(struct cifs_ace *), ++ ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *), + GFP_KERNEL); + if (!ppace) + return; + + for (i = 0; i < num_aces; ++i) { +- ppace[i] = (struct cifs_ace *) (acl_base + acl_size); ++ ppace[i] = (struct smb_ace *) (acl_base + acl_size); + #ifdef CONFIG_CIFS_DEBUG2 + dump_ace(ppace[i], end_of_acl); + #endif +@@ -849,7 +849,7 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, + + /* memcpy((void *)(&(cifscred->aces[i])), + (void *)ppace[i], +- sizeof(struct cifs_ace)); */ ++ sizeof(struct smb_ace)); */ + + acl_base = (char *)ppace[i]; + acl_size = le16_to_cpu(ppace[i]->size); +@@ -861,7 +861,7 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, + return; + } + +-unsigned int setup_authusers_ACE(struct cifs_ace *pntace) ++unsigned int setup_authusers_ACE(struct smb_ace *pntace) + { + int i; + unsigned int ace_size = 20; +@@ -885,12 +885,17 @@ unsigned int setup_authusers_ACE(struct cifs_ace *pntace) + * Fill in the special SID based on the mode. See + * https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx + */ +-unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode) ++unsigned int setup_special_mode_ACE(struct smb_ace *pntace, ++ bool posix, ++ __u64 nmode) + { + int i; + unsigned int ace_size = 28; + +- pntace->type = ACCESS_DENIED_ACE_TYPE; ++ if (posix) ++ pntace->type = ACCESS_ALLOWED_ACE_TYPE; ++ else ++ pntace->type = ACCESS_DENIED_ACE_TYPE; + pntace->flags = 0x0; + pntace->access_req = 0; + pntace->sid.num_subauth = 3; +@@ -907,7 +912,7 @@ unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode) + return ace_size; + } + +-unsigned int setup_special_user_owner_ACE(struct cifs_ace *pntace) ++unsigned int setup_special_user_owner_ACE(struct smb_ace *pntace) + { + int i; + unsigned int ace_size = 28; +@@ -930,10 +935,11 @@ unsigned int setup_special_user_owner_ACE(struct cifs_ace *pntace) + } + + static void populate_new_aces(char *nacl_base, +- struct cifs_sid *pownersid, +- struct cifs_sid *pgrpsid, ++ struct smb_sid *pownersid, ++ struct smb_sid *pgrpsid, + __u64 *pnmode, u32 *pnum_aces, u16 *pnsize, +- bool modefromsid) ++ bool modefromsid, ++ bool posix) + { + __u64 nmode; + u32 num_aces = 0; +@@ -944,19 +950,21 @@ static void populate_new_aces(char *nacl_base, + __u64 deny_user_mode = 0; + __u64 deny_group_mode = 0; + bool sticky_set = false; +- struct cifs_ace *pnntace = NULL; ++ struct smb_ace *pnntace = NULL; + + nmode = *pnmode; + num_aces = *pnum_aces; + nsize = *pnsize; + +- if (modefromsid) { +- pnntace = (struct cifs_ace *) (nacl_base + nsize); +- nsize += setup_special_mode_ACE(pnntace, nmode); +- num_aces++; +- pnntace = (struct cifs_ace *) (nacl_base + nsize); +- nsize += setup_authusers_ACE(pnntace); ++ if (modefromsid || posix) { ++ pnntace = (struct smb_ace *) (nacl_base + nsize); ++ nsize += setup_special_mode_ACE(pnntace, posix, nmode); + num_aces++; ++ if (modefromsid) { ++ pnntace = (struct smb_ace *) (nacl_base + nsize); ++ nsize += setup_authusers_ACE(pnntace); ++ num_aces++; ++ } + goto set_size; + } + +@@ -967,7 +975,7 @@ static void populate_new_aces(char *nacl_base, + * updated in the inode. + */ + +- if (!memcmp(pownersid, pgrpsid, sizeof(struct cifs_sid))) { ++ if (!memcmp(pownersid, pgrpsid, sizeof(struct smb_sid))) { + /* + * Case when owner and group SIDs are the same. + * Set the more restrictive of the two modes. +@@ -992,7 +1000,7 @@ static void populate_new_aces(char *nacl_base, + sticky_set = true; + + if (deny_user_mode) { +- pnntace = (struct cifs_ace *) (nacl_base + nsize); ++ pnntace = (struct smb_ace *) (nacl_base + nsize); + nsize += fill_ace_for_sid(pnntace, pownersid, deny_user_mode, + 0700, ACCESS_DENIED, false); + num_aces++; +@@ -1000,31 +1008,31 @@ static void populate_new_aces(char *nacl_base, + + /* Group DENY ACE does not conflict with owner ALLOW ACE. Keep in preferred order*/ + if (deny_group_mode && !(deny_group_mode & (user_mode >> 3))) { +- pnntace = (struct cifs_ace *) (nacl_base + nsize); ++ pnntace = (struct smb_ace *) (nacl_base + nsize); + nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode, + 0070, ACCESS_DENIED, false); + num_aces++; + } + +- pnntace = (struct cifs_ace *) (nacl_base + nsize); ++ pnntace = (struct smb_ace *) (nacl_base + nsize); + nsize += fill_ace_for_sid(pnntace, pownersid, user_mode, + 0700, ACCESS_ALLOWED, true); + num_aces++; + + /* Group DENY ACE conflicts with owner ALLOW ACE. So keep it after. */ + if (deny_group_mode && (deny_group_mode & (user_mode >> 3))) { +- pnntace = (struct cifs_ace *) (nacl_base + nsize); ++ pnntace = (struct smb_ace *) (nacl_base + nsize); + nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode, + 0070, ACCESS_DENIED, false); + num_aces++; + } + +- pnntace = (struct cifs_ace *) (nacl_base + nsize); ++ pnntace = (struct smb_ace *) (nacl_base + nsize); + nsize += fill_ace_for_sid(pnntace, pgrpsid, group_mode, + 0070, ACCESS_ALLOWED, !sticky_set); + num_aces++; + +- pnntace = (struct cifs_ace *) (nacl_base + nsize); ++ pnntace = (struct smb_ace *) (nacl_base + nsize); + nsize += fill_ace_for_sid(pnntace, &sid_everyone, other_mode, + 0007, ACCESS_ALLOWED, !sticky_set); + num_aces++; +@@ -1034,31 +1042,31 @@ static void populate_new_aces(char *nacl_base, + *pnsize = nsize; + } + +-static __u16 replace_sids_and_copy_aces(struct cifs_acl *pdacl, struct cifs_acl *pndacl, +- struct cifs_sid *pownersid, struct cifs_sid *pgrpsid, +- struct cifs_sid *pnownersid, struct cifs_sid *pngrpsid) ++static __u16 replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *pndacl, ++ struct smb_sid *pownersid, struct smb_sid *pgrpsid, ++ struct smb_sid *pnownersid, struct smb_sid *pngrpsid) + { + int i; + u16 size = 0; +- struct cifs_ace *pntace = NULL; ++ struct smb_ace *pntace = NULL; + char *acl_base = NULL; + u32 src_num_aces = 0; + u16 nsize = 0; +- struct cifs_ace *pnntace = NULL; ++ struct smb_ace *pnntace = NULL; + char *nacl_base = NULL; + u16 ace_size = 0; + + acl_base = (char *)pdacl; +- size = sizeof(struct cifs_acl); ++ size = sizeof(struct smb_acl); + src_num_aces = le32_to_cpu(pdacl->num_aces); + + nacl_base = (char *)pndacl; +- nsize = sizeof(struct cifs_acl); ++ nsize = sizeof(struct smb_acl); + + /* Go through all the ACEs */ + for (i = 0; i < src_num_aces; ++i) { +- pntace = (struct cifs_ace *) (acl_base + size); +- pnntace = (struct cifs_ace *) (nacl_base + nsize); ++ pntace = (struct smb_ace *) (acl_base + size); ++ pnntace = (struct smb_ace *) (nacl_base + nsize); + + if (pnownersid && compare_sids(&pntace->sid, pownersid) == 0) + ace_size = cifs_copy_ace(pnntace, pntace, pnownersid); +@@ -1074,48 +1082,48 @@ static __u16 replace_sids_and_copy_aces(struct cifs_acl *pdacl, struct cifs_acl + return nsize; + } + +-static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl, +- struct cifs_sid *pownersid, struct cifs_sid *pgrpsid, +- __u64 *pnmode, bool mode_from_sid) ++static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl, ++ struct smb_sid *pownersid, struct smb_sid *pgrpsid, ++ __u64 *pnmode, bool mode_from_sid, bool posix) + { + int i; + u16 size = 0; +- struct cifs_ace *pntace = NULL; ++ struct smb_ace *pntace = NULL; + char *acl_base = NULL; + u32 src_num_aces = 0; + u16 nsize = 0; +- struct cifs_ace *pnntace = NULL; ++ struct smb_ace *pnntace = NULL; + char *nacl_base = NULL; + u32 num_aces = 0; + bool new_aces_set = false; + + /* Assuming that pndacl and pnmode are never NULL */ + nacl_base = (char *)pndacl; +- nsize = sizeof(struct cifs_acl); ++ nsize = sizeof(struct smb_acl); + + /* If pdacl is NULL, we don't have a src. Simply populate new ACL. */ +- if (!pdacl) { ++ if (!pdacl || posix) { + populate_new_aces(nacl_base, + pownersid, pgrpsid, + pnmode, &num_aces, &nsize, +- mode_from_sid); ++ mode_from_sid, posix); + goto finalize_dacl; + } + + acl_base = (char *)pdacl; +- size = sizeof(struct cifs_acl); ++ size = sizeof(struct smb_acl); + src_num_aces = le32_to_cpu(pdacl->num_aces); + + /* Retain old ACEs which we can retain */ + for (i = 0; i < src_num_aces; ++i) { +- pntace = (struct cifs_ace *) (acl_base + size); ++ pntace = (struct smb_ace *) (acl_base + size); + + if (!new_aces_set && (pntace->flags & INHERITED_ACE)) { + /* Place the new ACEs in between existing explicit and inherited */ + populate_new_aces(nacl_base, + pownersid, pgrpsid, + pnmode, &num_aces, &nsize, +- mode_from_sid); ++ mode_from_sid, posix); + + new_aces_set = true; + } +@@ -1130,7 +1138,7 @@ static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl, + } + + /* update the pointer to the next ACE to populate*/ +- pnntace = (struct cifs_ace *) (nacl_base + nsize); ++ pnntace = (struct smb_ace *) (nacl_base + nsize); + + nsize += cifs_copy_ace(pnntace, pntace, NULL); + num_aces++; +@@ -1144,7 +1152,7 @@ static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl, + populate_new_aces(nacl_base, + pownersid, pgrpsid, + pnmode, &num_aces, &nsize, +- mode_from_sid); ++ mode_from_sid, posix); + + new_aces_set = true; + } +@@ -1156,7 +1164,7 @@ static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl, + return 0; + } + +-static int parse_sid(struct cifs_sid *psid, char *end_of_acl) ++static int parse_sid(struct smb_sid *psid, char *end_of_acl) + { + /* BB need to add parm so we can store the SID BB */ + +@@ -1191,24 +1199,24 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl) + + /* Convert CIFS ACL to POSIX form */ + static int parse_sec_desc(struct cifs_sb_info *cifs_sb, +- struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr, ++ struct smb_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr, + bool get_mode_from_special_sid) + { + int rc = 0; +- struct cifs_sid *owner_sid_ptr, *group_sid_ptr; +- struct cifs_acl *dacl_ptr; /* no need for SACL ptr */ ++ struct smb_sid *owner_sid_ptr, *group_sid_ptr; ++ struct smb_acl *dacl_ptr; /* no need for SACL ptr */ + char *end_of_acl = ((char *)pntsd) + acl_len; + __u32 dacloffset; + + if (pntsd == NULL) + return -EIO; + +- owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + ++ owner_sid_ptr = (struct smb_sid *)((char *)pntsd + + le32_to_cpu(pntsd->osidoffset)); +- group_sid_ptr = (struct cifs_sid *)((char *)pntsd + ++ group_sid_ptr = (struct smb_sid *)((char *)pntsd + + le32_to_cpu(pntsd->gsidoffset)); + dacloffset = le32_to_cpu(pntsd->dacloffset); +- dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset); ++ dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset); + cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n", + pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset), + le32_to_cpu(pntsd->gsidoffset), +@@ -1249,38 +1257,38 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb, + } + + /* Convert permission bits from mode to equivalent CIFS ACL */ +-static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, ++static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd, + __u32 secdesclen, __u32 *pnsecdesclen, __u64 *pnmode, kuid_t uid, kgid_t gid, +- bool mode_from_sid, bool id_from_sid, int *aclflag) ++ bool mode_from_sid, bool id_from_sid, bool posix, int *aclflag) + { + int rc = 0; + __u32 dacloffset; + __u32 ndacloffset; + __u32 sidsoffset; +- struct cifs_sid *owner_sid_ptr, *group_sid_ptr; +- struct cifs_sid *nowner_sid_ptr = NULL, *ngroup_sid_ptr = NULL; +- struct cifs_acl *dacl_ptr = NULL; /* no need for SACL ptr */ +- struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */ ++ struct smb_sid *owner_sid_ptr, *group_sid_ptr; ++ struct smb_sid *nowner_sid_ptr = NULL, *ngroup_sid_ptr = NULL; ++ struct smb_acl *dacl_ptr = NULL; /* no need for SACL ptr */ ++ struct smb_acl *ndacl_ptr = NULL; /* no need for SACL ptr */ + char *end_of_acl = ((char *)pntsd) + secdesclen; + u16 size = 0; + + dacloffset = le32_to_cpu(pntsd->dacloffset); + if (dacloffset) { +- dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset); ++ dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset); + if (end_of_acl < (char *)dacl_ptr + le16_to_cpu(dacl_ptr->size)) { + cifs_dbg(VFS, "Server returned illegal ACL size\n"); + return -EINVAL; + } + } + +- owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + ++ owner_sid_ptr = (struct smb_sid *)((char *)pntsd + + le32_to_cpu(pntsd->osidoffset)); +- group_sid_ptr = (struct cifs_sid *)((char *)pntsd + ++ group_sid_ptr = (struct smb_sid *)((char *)pntsd + + le32_to_cpu(pntsd->gsidoffset)); + + if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */ +- ndacloffset = sizeof(struct cifs_ntsd); +- ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset); ++ ndacloffset = sizeof(struct smb_ntsd); ++ ndacl_ptr = (struct smb_acl *)((char *)pnntsd + ndacloffset); + ndacl_ptr->revision = + dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION); + +@@ -1288,7 +1296,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, + ndacl_ptr->num_aces = cpu_to_le32(0); + + rc = set_chmod_dacl(dacl_ptr, ndacl_ptr, owner_sid_ptr, group_sid_ptr, +- pnmode, mode_from_sid); ++ pnmode, mode_from_sid, posix); + + sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size); + /* copy the non-dacl portion of secdesc */ +@@ -1297,15 +1305,15 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, + + *aclflag |= CIFS_ACL_DACL; + } else { +- ndacloffset = sizeof(struct cifs_ntsd); +- ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset); ++ ndacloffset = sizeof(struct smb_ntsd); ++ ndacl_ptr = (struct smb_acl *)((char *)pnntsd + ndacloffset); + ndacl_ptr->revision = + dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION); + ndacl_ptr->num_aces = dacl_ptr ? dacl_ptr->num_aces : 0; + + if (uid_valid(uid)) { /* chown */ + uid_t id; +- nowner_sid_ptr = kzalloc(sizeof(struct cifs_sid), ++ nowner_sid_ptr = kzalloc(sizeof(struct smb_sid), + GFP_KERNEL); + if (!nowner_sid_ptr) { + rc = -ENOMEM; +@@ -1334,7 +1342,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, + } + if (gid_valid(gid)) { /* chgrp */ + gid_t id; +- ngroup_sid_ptr = kzalloc(sizeof(struct cifs_sid), ++ ngroup_sid_ptr = kzalloc(sizeof(struct smb_sid), + GFP_KERNEL); + if (!ngroup_sid_ptr) { + rc = -ENOMEM; +@@ -1385,11 +1393,11 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, + } + + #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY +-struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, ++struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, + const struct cifs_fid *cifsfid, u32 *pacllen, + u32 __maybe_unused unused) + { +- struct cifs_ntsd *pntsd = NULL; ++ struct smb_ntsd *pntsd = NULL; + unsigned int xid; + int rc; + struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); +@@ -1410,10 +1418,10 @@ struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, + return pntsd; + } + +-static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, ++static struct smb_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, + const char *path, u32 *pacllen) + { +- struct cifs_ntsd *pntsd = NULL; ++ struct smb_ntsd *pntsd = NULL; + int oplock = 0; + unsigned int xid; + int rc; +@@ -1454,11 +1462,11 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, + } + + /* Retrieve an ACL from the server */ +-struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb, ++struct smb_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb, + struct inode *inode, const char *path, + u32 *pacllen, u32 info) + { +- struct cifs_ntsd *pntsd = NULL; ++ struct smb_ntsd *pntsd = NULL; + struct cifsFileInfo *open_file = NULL; + + if (inode) +@@ -1472,7 +1480,7 @@ struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb, + } + + /* Set an ACL on the server */ +-int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, ++int set_cifs_acl(struct smb_ntsd *pnntsd, __u32 acllen, + struct inode *inode, const char *path, int aclflag) + { + int oplock = 0; +@@ -1528,7 +1536,7 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, + struct inode *inode, bool mode_from_special_sid, + const char *path, const struct cifs_fid *pfid) + { +- struct cifs_ntsd *pntsd = NULL; ++ struct smb_ntsd *pntsd = NULL; + u32 acllen = 0; + int rc = 0; + struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); +@@ -1580,13 +1588,14 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, + __u32 secdesclen = 0; + __u32 nsecdesclen = 0; + __u32 dacloffset = 0; +- struct cifs_acl *dacl_ptr = NULL; +- struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */ +- struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ ++ struct smb_acl *dacl_ptr = NULL; ++ struct smb_ntsd *pntsd = NULL; /* acl obtained from server */ ++ struct smb_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); + struct smb_version_operations *ops; + bool mode_from_sid, id_from_sid; ++ bool posix = tlink_tcon(tlink)->posix_extensions; + const u32 info = 0; + + if (IS_ERR(tlink)) +@@ -1622,21 +1631,22 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, + id_from_sid = false; + + /* Potentially, five new ACEs can be added to the ACL for U,G,O mapping */ +- nsecdesclen = secdesclen; + if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */ +- if (mode_from_sid) +- nsecdesclen += 2 * sizeof(struct cifs_ace); ++ if (posix) ++ nsecdesclen = 1 * sizeof(struct smb_ace); ++ else if (mode_from_sid) ++ nsecdesclen = secdesclen + (2 * sizeof(struct smb_ace)); + else /* cifsacl */ +- nsecdesclen += 5 * sizeof(struct cifs_ace); ++ nsecdesclen = secdesclen + (5 * sizeof(struct smb_ace)); + } else { /* chown */ + /* When ownership changes, changes new owner sid length could be different */ +- nsecdesclen = sizeof(struct cifs_ntsd) + (sizeof(struct cifs_sid) * 2); ++ nsecdesclen = sizeof(struct smb_ntsd) + (sizeof(struct smb_sid) * 2); + dacloffset = le32_to_cpu(pntsd->dacloffset); + if (dacloffset) { +- dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset); ++ dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset); + if (mode_from_sid) + nsecdesclen += +- le32_to_cpu(dacl_ptr->num_aces) * sizeof(struct cifs_ace); ++ le32_to_cpu(dacl_ptr->num_aces) * sizeof(struct smb_ace); + else /* cifsacl */ + nsecdesclen += le16_to_cpu(dacl_ptr->size); + } +@@ -1657,7 +1667,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, + } + + rc = build_sec_desc(pntsd, pnntsd, secdesclen, &nsecdesclen, pnmode, uid, gid, +- mode_from_sid, id_from_sid, &aclflag); ++ mode_from_sid, id_from_sid, posix, &aclflag); + + cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc); + +diff --git a/fs/smb/client/cifsacl.h b/fs/smb/client/cifsacl.h +index ccbfc754bd3c7f..cbaed8038e3654 100644 +--- a/fs/smb/client/cifsacl.h ++++ b/fs/smb/client/cifsacl.h +@@ -33,9 +33,9 @@ + * Security Descriptor length containing DACL with 3 ACEs (one each for + * owner, group and world). + */ +-#define DEFAULT_SEC_DESC_LEN (sizeof(struct cifs_ntsd) + \ +- sizeof(struct cifs_acl) + \ +- (sizeof(struct cifs_ace) * 4)) ++#define DEFAULT_SEC_DESC_LEN (sizeof(struct smb_ntsd) + \ ++ sizeof(struct smb_acl) + \ ++ (sizeof(struct smb_ace) * 4)) + + /* + * Maximum size of a string representation of a SID: +@@ -55,7 +55,7 @@ + #define SID_STRING_BASE_SIZE (2 + 3 + 15 + 1) + #define SID_STRING_SUBAUTH_SIZE (11) /* size of a single subauth string */ + +-struct cifs_ntsd { ++struct smb_ntsd { + __le16 revision; /* revision level */ + __le16 type; + __le32 osidoffset; +@@ -64,17 +64,17 @@ struct cifs_ntsd { + __le32 dacloffset; + } __attribute__((packed)); + +-struct cifs_sid { ++struct smb_sid { + __u8 revision; /* revision level */ + __u8 num_subauth; + __u8 authority[NUM_AUTHS]; + __le32 sub_auth[SID_MAX_SUB_AUTHORITIES]; /* sub_auth[num_subauth] */ + } __attribute__((packed)); + +-/* size of a struct cifs_sid, sans sub_auth array */ ++/* size of a struct smb_sid, sans sub_auth array */ + #define CIFS_SID_BASE_SIZE (1 + 1 + NUM_AUTHS) + +-struct cifs_acl { ++struct smb_acl { + __le16 revision; /* revision level */ + __le16 size; + __le32 num_aces; +@@ -111,12 +111,12 @@ struct cifs_acl { + #define SUCCESSFUL_ACCESS_ACE_FLAG 0x40 + #define FAILED_ACCESS_ACE_FLAG 0x80 + +-struct cifs_ace { ++struct smb_ace { + __u8 type; /* see above and MS-DTYP 2.4.4.1 */ + __u8 flags; + __le16 size; + __le32 access_req; +- struct cifs_sid sid; /* ie UUID of user or group who gets these perms */ ++ struct smb_sid sid; /* ie UUID of user or group who gets these perms */ + } __attribute__((packed)); + + /* +@@ -194,6 +194,6 @@ struct owner_group_sids { + * Minimum security descriptor can be one without any SACL and DACL and can + * consist of revision, type, and two sids of minimum size for owner and group + */ +-#define MIN_SEC_DESC_LEN (sizeof(struct cifs_ntsd) + (2 * MIN_SID_LEN)) ++#define MIN_SEC_DESC_LEN (sizeof(struct smb_ntsd) + (2 * MIN_SID_LEN)) + + #endif /* _CIFSACL_H */ +diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c +index 6ed0f2548232f9..bbb0ef18d7b8c8 100644 +--- a/fs/smb/client/cifsfs.c ++++ b/fs/smb/client/cifsfs.c +@@ -2015,6 +2015,7 @@ exit_cifs(void) + destroy_workqueue(decrypt_wq); + destroy_workqueue(fileinfo_put_wq); + destroy_workqueue(serverclose_wq); ++ destroy_workqueue(cfid_put_wq); + destroy_workqueue(cifsiod_wq); + cifs_proc_clean(); + } +diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h +index 6b57b167a49d80..43b42eca6780cf 100644 +--- a/fs/smb/client/cifsglob.h ++++ b/fs/smb/client/cifsglob.h +@@ -202,10 +202,10 @@ struct cifs_cred { + int gid; + int mode; + int cecount; +- struct cifs_sid osid; +- struct cifs_sid gsid; ++ struct smb_sid osid; ++ struct smb_sid gsid; + struct cifs_ntace *ntaces; +- struct cifs_ace *aces; ++ struct smb_ace *aces; + }; + + struct cifs_open_info_data { +@@ -231,8 +231,8 @@ struct cifs_open_info_data { + unsigned int eas_len; + } wsl; + char *symlink_target; +- struct cifs_sid posix_owner; +- struct cifs_sid posix_group; ++ struct smb_sid posix_owner; ++ struct smb_sid posix_group; + union { + struct smb2_file_all_info fi; + struct smb311_posix_qinfo posix_fi; +@@ -539,12 +539,12 @@ struct smb_version_operations { + int (*set_EA)(const unsigned int, struct cifs_tcon *, const char *, + const char *, const void *, const __u16, + const struct nls_table *, struct cifs_sb_info *); +- struct cifs_ntsd * (*get_acl)(struct cifs_sb_info *, struct inode *, +- const char *, u32 *, u32); +- struct cifs_ntsd * (*get_acl_by_fid)(struct cifs_sb_info *, +- const struct cifs_fid *, u32 *, u32); +- int (*set_acl)(struct cifs_ntsd *, __u32, struct inode *, const char *, +- int); ++ struct smb_ntsd * (*get_acl)(struct cifs_sb_info *cifssb, struct inode *ino, ++ const char *patch, u32 *plen, u32 info); ++ struct smb_ntsd * (*get_acl_by_fid)(struct cifs_sb_info *cifssmb, ++ const struct cifs_fid *pfid, u32 *plen, u32 info); ++ int (*set_acl)(struct smb_ntsd *pntsd, __u32 len, struct inode *ino, const char *path, ++ int flag); + /* writepages retry size */ + unsigned int (*wp_retry_size)(struct inode *); + /* get mtu credits */ +diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h +index 83692bf60007a0..a151ffffc6f38e 100644 +--- a/fs/smb/client/cifsproto.h ++++ b/fs/smb/client/cifsproto.h +@@ -223,7 +223,7 @@ extern int cifs_set_file_info(struct inode *inode, struct iattr *attrs, + extern int cifs_rename_pending_delete(const char *full_path, + struct dentry *dentry, + const unsigned int xid); +-extern int sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid, ++extern int sid_to_id(struct cifs_sb_info *cifs_sb, struct smb_sid *psid, + struct cifs_fattr *fattr, uint sidtype); + extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, + struct cifs_fattr *fattr, struct inode *inode, +@@ -231,19 +231,21 @@ extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, + const char *path, const struct cifs_fid *pfid); + extern int id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, + kuid_t uid, kgid_t gid); +-extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *, +- const char *, u32 *, u32); +-extern struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *, +- const struct cifs_fid *, u32 *, u32); ++extern struct smb_ntsd *get_cifs_acl(struct cifs_sb_info *cifssmb, struct inode *ino, ++ const char *path, u32 *plen, u32 info); ++extern struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifssb, ++ const struct cifs_fid *pfid, u32 *plen, u32 info); + extern struct posix_acl *cifs_get_acl(struct mnt_idmap *idmap, + struct dentry *dentry, int type); + extern int cifs_set_acl(struct mnt_idmap *idmap, + struct dentry *dentry, struct posix_acl *acl, int type); +-extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *, +- const char *, int); +-extern unsigned int setup_authusers_ACE(struct cifs_ace *pace); +-extern unsigned int setup_special_mode_ACE(struct cifs_ace *pace, __u64 nmode); +-extern unsigned int setup_special_user_owner_ACE(struct cifs_ace *pace); ++extern int set_cifs_acl(struct smb_ntsd *pntsd, __u32 len, struct inode *ino, ++ const char *path, int flag); ++extern unsigned int setup_authusers_ACE(struct smb_ace *pace); ++extern unsigned int setup_special_mode_ACE(struct smb_ace *pace, ++ bool posix, ++ __u64 nmode); ++extern unsigned int setup_special_user_owner_ACE(struct smb_ace *pace); + + extern void dequeue_mid(struct mid_q_entry *mid, bool malformed); + extern int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf, +@@ -568,9 +570,9 @@ extern int CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon, + const struct nls_table *nls_codepage, + struct cifs_sb_info *cifs_sb); + extern int CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, +- __u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen); ++ __u16 fid, struct smb_ntsd **acl_inf, __u32 *buflen); + extern int CIFSSMBSetCIFSACL(const unsigned int, struct cifs_tcon *, __u16, +- struct cifs_ntsd *, __u32, int); ++ struct smb_ntsd *pntsd, __u32 len, int aclflag); + extern int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon, + const unsigned char *searchName, + struct posix_acl **acl, const int acl_type, +diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c +index a34db419e46f7f..2f8745736dbb02 100644 +--- a/fs/smb/client/cifssmb.c ++++ b/fs/smb/client/cifssmb.c +@@ -3385,7 +3385,7 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata, + /* Get Security Descriptor (by handle) from remote server for a file or dir */ + int + CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, +- struct cifs_ntsd **acl_inf, __u32 *pbuflen) ++ struct smb_ntsd **acl_inf, __u32 *pbuflen) + { + int rc = 0; + int buf_type = 0; +@@ -3455,7 +3455,7 @@ CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, + + /* check if buffer is big enough for the acl + header followed by the smallest SID */ +- if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) || ++ if ((*pbuflen < sizeof(struct smb_ntsd) + 8) || + (*pbuflen >= 64 * 1024)) { + cifs_dbg(VFS, "bad acl length %d\n", *pbuflen); + rc = -EINVAL; +@@ -3475,7 +3475,7 @@ CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, + + int + CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, +- struct cifs_ntsd *pntsd, __u32 acllen, int aclflag) ++ struct smb_ntsd *pntsd, __u32 acllen, int aclflag) + { + __u16 byte_count, param_count, data_count, param_offset, data_offset; + int rc = 0; +diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c +index ce7e0aed8f7d2b..b3e59a7c71205f 100644 +--- a/fs/smb/client/inode.c ++++ b/fs/smb/client/inode.c +@@ -3087,6 +3087,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) + int rc = -EACCES; + __u32 dosattr = 0; + __u64 mode = NO_CHANGE_64; ++ bool posix = cifs_sb_master_tcon(cifs_sb)->posix_extensions; + + xid = get_xid(); + +@@ -3177,7 +3178,8 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) + mode = attrs->ia_mode; + rc = 0; + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) || +- (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)) { ++ (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) || ++ posix) { + rc = id_mode_to_cifs_acl(inode, full_path, &mode, + INVALID_UID, INVALID_GID); + if (rc) { +diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c +index 2a292736c89a2a..e695df1dbb23b2 100644 +--- a/fs/smb/client/smb2inode.c ++++ b/fs/smb/client/smb2inode.c +@@ -315,7 +315,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + SMB2_O_INFO_FILE, 0, + sizeof(struct smb311_posix_qinfo *) + + (PATH_MAX * 2) + +- (sizeof(struct cifs_sid) * 2), 0, NULL); ++ (sizeof(struct smb_sid) * 2), 0, NULL); + } else { + rc = SMB2_query_info_init(tcon, server, + &rqst[num_rqst], +@@ -325,7 +325,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + SMB2_O_INFO_FILE, 0, + sizeof(struct smb311_posix_qinfo *) + + (PATH_MAX * 2) + +- (sizeof(struct cifs_sid) * 2), 0, NULL); ++ (sizeof(struct smb_sid) * 2), 0, NULL); + } + if (!rc && (!cfile || num_rqst > 1)) { + smb2_set_next_command(tcon, &rqst[num_rqst]); +diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c +index 6645f147d57c29..fc6d00344c50ea 100644 +--- a/fs/smb/client/smb2ops.c ++++ b/fs/smb/client/smb2ops.c +@@ -3001,11 +3001,11 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses, + return rc; + } + +-static struct cifs_ntsd * ++static struct smb_ntsd * + get_smb2_acl_by_fid(struct cifs_sb_info *cifs_sb, + const struct cifs_fid *cifsfid, u32 *pacllen, u32 info) + { +- struct cifs_ntsd *pntsd = NULL; ++ struct smb_ntsd *pntsd = NULL; + unsigned int xid; + int rc = -EOPNOTSUPP; + struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); +@@ -3030,11 +3030,11 @@ get_smb2_acl_by_fid(struct cifs_sb_info *cifs_sb, + + } + +-static struct cifs_ntsd * ++static struct smb_ntsd * + get_smb2_acl_by_path(struct cifs_sb_info *cifs_sb, + const char *path, u32 *pacllen, u32 info) + { +- struct cifs_ntsd *pntsd = NULL; ++ struct smb_ntsd *pntsd = NULL; + u8 oplock = SMB2_OPLOCK_LEVEL_NONE; + unsigned int xid; + int rc; +@@ -3097,7 +3097,7 @@ get_smb2_acl_by_path(struct cifs_sb_info *cifs_sb, + } + + static int +-set_smb2_acl(struct cifs_ntsd *pnntsd, __u32 acllen, ++set_smb2_acl(struct smb_ntsd *pnntsd, __u32 acllen, + struct inode *inode, const char *path, int aclflag) + { + u8 oplock = SMB2_OPLOCK_LEVEL_NONE; +@@ -3155,12 +3155,12 @@ set_smb2_acl(struct cifs_ntsd *pnntsd, __u32 acllen, + } + + /* Retrieve an ACL from the server */ +-static struct cifs_ntsd * ++static struct smb_ntsd * + get_smb2_acl(struct cifs_sb_info *cifs_sb, + struct inode *inode, const char *path, + u32 *pacllen, u32 info) + { +- struct cifs_ntsd *pntsd = NULL; ++ struct smb_ntsd *pntsd = NULL; + struct cifsFileInfo *open_file = NULL; + + if (inode && !(info & SACL_SECINFO)) +diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c +index 38b26468eb0c53..c012fbc2638ed5 100644 +--- a/fs/smb/client/smb2pdu.c ++++ b/fs/smb/client/smb2pdu.c +@@ -2623,7 +2623,7 @@ create_sd_buf(umode_t mode, bool set_owner, unsigned int *len) + unsigned int group_offset = 0; + struct smb3_acl acl = {}; + +- *len = round_up(sizeof(struct crt_sd_ctxt) + (sizeof(struct cifs_ace) * 4), 8); ++ *len = round_up(sizeof(struct crt_sd_ctxt) + (sizeof(struct smb_ace) * 4), 8); + + if (set_owner) { + /* sizeof(struct owner_group_sids) is already multiple of 8 so no need to round */ +@@ -2672,21 +2672,21 @@ create_sd_buf(umode_t mode, bool set_owner, unsigned int *len) + ptr += sizeof(struct smb3_acl); + + /* create one ACE to hold the mode embedded in reserved special SID */ +- acelen = setup_special_mode_ACE((struct cifs_ace *)ptr, (__u64)mode); ++ acelen = setup_special_mode_ACE((struct smb_ace *)ptr, false, (__u64)mode); + ptr += acelen; + acl_size = acelen + sizeof(struct smb3_acl); + ace_count = 1; + + if (set_owner) { + /* we do not need to reallocate buffer to add the two more ACEs. plenty of space */ +- acelen = setup_special_user_owner_ACE((struct cifs_ace *)ptr); ++ acelen = setup_special_user_owner_ACE((struct smb_ace *)ptr); + ptr += acelen; + acl_size += acelen; + ace_count += 1; + } + + /* and one more ACE to allow access for authenticated users */ +- acelen = setup_authusers_ACE((struct cifs_ace *)ptr); ++ acelen = setup_authusers_ACE((struct smb_ace *)ptr); + ptr += acelen; + acl_size += acelen; + ace_count += 1; +@@ -3915,7 +3915,7 @@ SMB311_posix_query_info(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_fid, u64 volatile_fid, struct smb311_posix_qinfo *data, u32 *plen) + { + size_t output_len = sizeof(struct smb311_posix_qinfo *) + +- (sizeof(struct cifs_sid) * 2) + (PATH_MAX * 2); ++ (sizeof(struct smb_sid) * 2) + (PATH_MAX * 2); + *plen = 0; + + return query_info(xid, tcon, persistent_fid, volatile_fid, +@@ -5626,7 +5626,7 @@ SMB2_set_eof(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, + int + SMB2_set_acl(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_fid, u64 volatile_fid, +- struct cifs_ntsd *pnntsd, int pacllen, int aclflag) ++ struct smb_ntsd *pnntsd, int pacllen, int aclflag) + { + return send_set_info(xid, tcon, persistent_fid, volatile_fid, + current->tgid, 0, SMB2_O_INFO_SECURITY, aclflag, +diff --git a/fs/smb/client/smb2pdu.h b/fs/smb/client/smb2pdu.h +index 5c458ab3b05a44..076d9e83e1a044 100644 +--- a/fs/smb/client/smb2pdu.h ++++ b/fs/smb/client/smb2pdu.h +@@ -364,8 +364,8 @@ struct create_posix_rsp { + u32 nlink; + u32 reparse_tag; + u32 mode; +- struct cifs_sid owner; /* var-sized on the wire */ +- struct cifs_sid group; /* var-sized on the wire */ ++ struct smb_sid owner; /* var-sized on the wire */ ++ struct smb_sid group; /* var-sized on the wire */ + } __packed; + + #define SMB2_QUERY_DIRECTORY_IOV_SIZE 2 +@@ -408,8 +408,8 @@ struct smb2_posix_info { + struct smb2_posix_info_parsed { + const struct smb2_posix_info *base; + size_t size; +- struct cifs_sid owner; +- struct cifs_sid group; ++ struct smb_sid owner; ++ struct smb_sid group; + int name_len; + const u8 *name; + }; +diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h +index 613667b46c5802..750e4e397b1393 100644 +--- a/fs/smb/client/smb2proto.h ++++ b/fs/smb/client/smb2proto.h +@@ -37,8 +37,6 @@ extern struct mid_q_entry *smb2_setup_request(struct cifs_ses *ses, + struct smb_rqst *rqst); + extern struct mid_q_entry *smb2_setup_async_request( + struct TCP_Server_Info *server, struct smb_rqst *rqst); +-extern struct cifs_ses *smb2_find_smb_ses(struct TCP_Server_Info *server, +- __u64 ses_id); + extern struct cifs_tcon *smb2_find_smb_tcon(struct TCP_Server_Info *server, + __u64 ses_id, __u32 tid); + extern int smb2_calc_signature(struct smb_rqst *rqst, +@@ -247,7 +245,7 @@ extern int SMB2_set_info_init(struct cifs_tcon *tcon, + extern void SMB2_set_info_free(struct smb_rqst *rqst); + extern int SMB2_set_acl(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_fid, u64 volatile_fid, +- struct cifs_ntsd *pnntsd, int pacllen, int aclflag); ++ struct smb_ntsd *pnntsd, int pacllen, int aclflag); + extern int SMB2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_fid, u64 volatile_fid, + struct smb2_file_full_ea_info *buf, int len); +diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c +index 4ca04e62a993cf..4a43802375b3a3 100644 +--- a/fs/smb/client/smb2transport.c ++++ b/fs/smb/client/smb2transport.c +@@ -74,7 +74,7 @@ smb311_crypto_shash_allocate(struct TCP_Server_Info *server) + + + static +-int smb2_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key) ++int smb3_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key) + { + struct cifs_chan *chan; + struct TCP_Server_Info *pserver; +@@ -168,16 +168,41 @@ smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id) + return NULL; + } + +-struct cifs_ses * +-smb2_find_smb_ses(struct TCP_Server_Info *server, __u64 ses_id) ++static int smb2_get_sign_key(struct TCP_Server_Info *server, ++ __u64 ses_id, u8 *key) + { + struct cifs_ses *ses; ++ int rc = -ENOENT; ++ ++ if (SERVER_IS_CHAN(server)) ++ server = server->primary_server; + + spin_lock(&cifs_tcp_ses_lock); +- ses = smb2_find_smb_ses_unlocked(server, ses_id); +- spin_unlock(&cifs_tcp_ses_lock); ++ list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { ++ if (ses->Suid != ses_id) ++ continue; + +- return ses; ++ rc = 0; ++ spin_lock(&ses->ses_lock); ++ switch (ses->ses_status) { ++ case SES_EXITING: /* SMB2_LOGOFF */ ++ case SES_GOOD: ++ if (likely(ses->auth_key.response)) { ++ memcpy(key, ses->auth_key.response, ++ SMB2_NTLMV2_SESSKEY_SIZE); ++ } else { ++ rc = -EIO; ++ } ++ break; ++ default: ++ rc = -EAGAIN; ++ break; ++ } ++ spin_unlock(&ses->ses_lock); ++ break; ++ } ++ spin_unlock(&cifs_tcp_ses_lock); ++ return rc; + } + + static struct cifs_tcon * +@@ -236,14 +261,16 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, + unsigned char *sigptr = smb2_signature; + struct kvec *iov = rqst->rq_iov; + struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base; +- struct cifs_ses *ses; + struct shash_desc *shash = NULL; + struct smb_rqst drqst; ++ __u64 sid = le64_to_cpu(shdr->SessionId); ++ u8 key[SMB2_NTLMV2_SESSKEY_SIZE]; + +- ses = smb2_find_smb_ses(server, le64_to_cpu(shdr->SessionId)); +- if (unlikely(!ses)) { +- cifs_server_dbg(VFS, "%s: Could not find session\n", __func__); +- return -ENOENT; ++ rc = smb2_get_sign_key(server, sid, key); ++ if (unlikely(rc)) { ++ cifs_server_dbg(FYI, "%s: [sesid=0x%llx] couldn't find signing key: %d\n", ++ __func__, sid, rc); ++ return rc; + } + + memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE); +@@ -260,8 +287,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, + shash = server->secmech.hmacsha256; + } + +- rc = crypto_shash_setkey(shash->tfm, ses->auth_key.response, +- SMB2_NTLMV2_SESSKEY_SIZE); ++ rc = crypto_shash_setkey(shash->tfm, key, sizeof(key)); + if (rc) { + cifs_server_dbg(VFS, + "%s: Could not update with response\n", +@@ -303,8 +329,6 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, + out: + if (allocate_crypto) + cifs_free_hash(&shash); +- if (ses) +- cifs_put_smb_ses(ses); + return rc; + } + +@@ -570,7 +594,7 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, + struct smb_rqst drqst; + u8 key[SMB3_SIGN_KEY_SIZE]; + +- rc = smb2_get_sign_key(le64_to_cpu(shdr->SessionId), server, key); ++ rc = smb3_get_sign_key(le64_to_cpu(shdr->SessionId), server, key); + if (unlikely(rc)) { + cifs_server_dbg(FYI, "%s: Could not get signing key\n", __func__); + return rc; +diff --git a/fs/smb/client/xattr.c b/fs/smb/client/xattr.c +index c2bf829310bee2..e8696ad4da994e 100644 +--- a/fs/smb/client/xattr.c ++++ b/fs/smb/client/xattr.c +@@ -162,7 +162,7 @@ static int cifs_xattr_set(const struct xattr_handler *handler, + case XATTR_CIFS_ACL: + case XATTR_CIFS_NTSD: + case XATTR_CIFS_NTSD_FULL: { +- struct cifs_ntsd *pacl; ++ struct smb_ntsd *pacl; + + if (!value) + goto out; +@@ -315,7 +315,7 @@ static int cifs_xattr_get(const struct xattr_handler *handler, + * fetch owner and DACL otherwise + */ + u32 acllen, extra_info; +- struct cifs_ntsd *pacl; ++ struct smb_ntsd *pacl; + + if (pTcon->ses->server->ops->get_acl == NULL) + goto out; /* rc already EOPNOTSUPP */ +diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c +index cd530b9a00caa3..2884ebdc0eda02 100644 +--- a/fs/smb/server/smb2pdu.c ++++ b/fs/smb/server/smb2pdu.c +@@ -4225,6 +4225,7 @@ static bool __query_dir(struct dir_context *ctx, const char *name, int namlen, + /* dot and dotdot entries are already reserved */ + if (!strcmp(".", name) || !strcmp("..", name)) + return true; ++ d_info->num_scan++; + if (ksmbd_share_veto_filename(priv->work->tcon->share_conf, name)) + return true; + if (!match_pattern(name, namlen, priv->search_pattern)) +@@ -4385,8 +4386,17 @@ int smb2_query_dir(struct ksmbd_work *work) + query_dir_private.info_level = req->FileInformationClass; + dir_fp->readdir_data.private = &query_dir_private; + set_ctx_actor(&dir_fp->readdir_data.ctx, __query_dir); +- ++again: ++ d_info.num_scan = 0; + rc = iterate_dir(dir_fp->filp, &dir_fp->readdir_data.ctx); ++ /* ++ * num_entry can be 0 if the directory iteration stops before reaching ++ * the end of the directory and no file is matched with the search ++ * pattern. ++ */ ++ if (rc >= 0 && !d_info.num_entry && d_info.num_scan && ++ d_info.out_buf_len > 0) ++ goto again; + /* + * req->OutputBufferLength is too small to contain even one entry. + * In this case, it immediately returns OutputBufferLength 0 to client. +@@ -6007,15 +6017,13 @@ static int set_file_basic_info(struct ksmbd_file *fp, + attrs.ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET); + } + +- attrs.ia_valid |= ATTR_CTIME; + if (file_info->ChangeTime) +- attrs.ia_ctime = ksmbd_NTtimeToUnix(file_info->ChangeTime); +- else +- attrs.ia_ctime = inode_get_ctime(inode); ++ inode_set_ctime_to_ts(inode, ++ ksmbd_NTtimeToUnix(file_info->ChangeTime)); + + if (file_info->LastWriteTime) { + attrs.ia_mtime = ksmbd_NTtimeToUnix(file_info->LastWriteTime); +- attrs.ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET); ++ attrs.ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET | ATTR_CTIME); + } + + if (file_info->Attributes) { +@@ -6057,8 +6065,6 @@ static int set_file_basic_info(struct ksmbd_file *fp, + return -EACCES; + + inode_lock(inode); +- inode_set_ctime_to_ts(inode, attrs.ia_ctime); +- attrs.ia_valid &= ~ATTR_CTIME; + rc = notify_change(idmap, dentry, &attrs, NULL); + inode_unlock(inode); + } +diff --git a/fs/smb/server/vfs.h b/fs/smb/server/vfs.h +index cb76f4b5bafe8c..06903024a2d88b 100644 +--- a/fs/smb/server/vfs.h ++++ b/fs/smb/server/vfs.h +@@ -43,6 +43,7 @@ struct ksmbd_dir_info { + char *rptr; + int name_len; + int out_buf_len; ++ int num_scan; + int num_entry; + int data_count; + int last_entry_offset; +diff --git a/fs/udf/namei.c b/fs/udf/namei.c +index b3f57ad2b869ff..8ac73f41d6ebe6 100644 +--- a/fs/udf/namei.c ++++ b/fs/udf/namei.c +@@ -770,7 +770,7 @@ static int udf_rename(struct mnt_idmap *idmap, struct inode *old_dir, + struct inode *old_inode = d_inode(old_dentry); + struct inode *new_inode = d_inode(new_dentry); + struct udf_fileident_iter oiter, niter, diriter; +- bool has_diriter = false; ++ bool has_diriter = false, is_dir = false; + int retval; + struct kernel_lb_addr tloc; + +@@ -792,7 +792,20 @@ static int udf_rename(struct mnt_idmap *idmap, struct inode *old_dir, + retval = -ENOTEMPTY; + if (!empty_dir(new_inode)) + goto out_oiter; ++ retval = -EFSCORRUPTED; ++ if (new_inode->i_nlink != 2) ++ goto out_oiter; + } ++ retval = -EFSCORRUPTED; ++ if (old_dir->i_nlink < 3) ++ goto out_oiter; ++ is_dir = true; ++ } else if (new_inode) { ++ retval = -EFSCORRUPTED; ++ if (new_inode->i_nlink < 1) ++ goto out_oiter; ++ } ++ if (is_dir && old_dir != new_dir) { + retval = udf_fiiter_find_entry(old_inode, &dotdot_name, + &diriter); + if (retval == -ENOENT) { +@@ -880,7 +893,9 @@ static int udf_rename(struct mnt_idmap *idmap, struct inode *old_dir, + cpu_to_lelb(UDF_I(new_dir)->i_location); + udf_fiiter_write_fi(&diriter, NULL); + udf_fiiter_release(&diriter); ++ } + ++ if (is_dir) { + inode_dec_link_count(old_dir); + if (new_inode) + inode_dec_link_count(new_inode); +diff --git a/include/acpi/pcc.h b/include/acpi/pcc.h +index 73e806fe7ce707..699c1a37b8e784 100644 +--- a/include/acpi/pcc.h ++++ b/include/acpi/pcc.h +@@ -12,17 +12,33 @@ + struct pcc_mbox_chan { + struct mbox_chan *mchan; + u64 shmem_base_addr; ++ void __iomem *shmem; + u64 shmem_size; + u32 latency; + u32 max_access_rate; + u16 min_turnaround_time; + }; + ++/* Generic Communications Channel Shared Memory Region */ ++#define PCC_SIGNATURE 0x50434300 ++/* Generic Communications Channel Command Field */ ++#define PCC_CMD_GENERATE_DB_INTR BIT(15) ++/* Generic Communications Channel Status Field */ ++#define PCC_STATUS_CMD_COMPLETE BIT(0) ++#define PCC_STATUS_SCI_DOORBELL BIT(1) ++#define PCC_STATUS_ERROR BIT(2) ++#define PCC_STATUS_PLATFORM_NOTIFY BIT(3) ++/* Initiator Responder Communications Channel Flags */ ++#define PCC_CMD_COMPLETION_NOTIFY BIT(0) ++ + #define MAX_PCC_SUBSPACES 256 ++#define PCC_ACK_FLAG_MASK 0x1 ++ + #ifdef CONFIG_PCC + extern struct pcc_mbox_chan * + pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id); + extern void pcc_mbox_free_channel(struct pcc_mbox_chan *chan); ++extern int pcc_mbox_ioremap(struct mbox_chan *chan); + #else + static inline struct pcc_mbox_chan * + pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id) +@@ -30,6 +46,10 @@ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id) + return ERR_PTR(-ENODEV); + } + static inline void pcc_mbox_free_channel(struct pcc_mbox_chan *chan) { } ++static inline int pcc_mbox_ioremap(struct mbox_chan *chan) ++{ ++ return 0; ++}; + #endif + + #endif /* _PCC_H */ +diff --git a/include/clocksource/hyperv_timer.h b/include/clocksource/hyperv_timer.h +index 6cdc873ac907f5..aa5233b1eba970 100644 +--- a/include/clocksource/hyperv_timer.h ++++ b/include/clocksource/hyperv_timer.h +@@ -38,6 +38,8 @@ extern void hv_remap_tsc_clocksource(void); + extern unsigned long hv_get_tsc_pfn(void); + extern struct ms_hyperv_tsc_page *hv_get_tsc_page(void); + ++extern void hv_adj_sched_clock_offset(u64 offset); ++ + static __always_inline bool + hv_read_tsc_page_tsc(const struct ms_hyperv_tsc_page *tsc_pg, + u64 *cur_tsc, u64 *time) +diff --git a/include/crypto/internal/ecc.h b/include/crypto/internal/ecc.h +index 4f6c1a68882fa1..c0b8be63cbde7c 100644 +--- a/include/crypto/internal/ecc.h ++++ b/include/crypto/internal/ecc.h +@@ -56,6 +56,16 @@ static inline void ecc_swap_digits(const void *in, u64 *out, unsigned int ndigit + out[i] = get_unaligned_be64(&src[ndigits - 1 - i]); + } + ++/** ++ * ecc_digits_from_bytes() - Create ndigits-sized digits array from byte array ++ * @in: Input byte array ++ * @nbytes Size of input byte array ++ * @out Output digits array ++ * @ndigits: Number of digits to create from byte array ++ */ ++void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes, ++ u64 *out, unsigned int ndigits); ++ + /** + * ecc_is_key_valid() - Validate a given ECDH private key + * +diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h +index cb8e97665eaa59..92919d52f7e1b2 100644 +--- a/include/linux/bpf_verifier.h ++++ b/include/linux/bpf_verifier.h +@@ -319,34 +319,12 @@ struct bpf_func_state { + struct bpf_stack_state *stack; + }; + +-#define MAX_CALL_FRAMES 8 +- +-/* instruction history flags, used in bpf_jmp_history_entry.flags field */ +-enum { +- /* instruction references stack slot through PTR_TO_STACK register; +- * we also store stack's frame number in lower 3 bits (MAX_CALL_FRAMES is 8) +- * and accessed stack slot's index in next 6 bits (MAX_BPF_STACK is 512, +- * 8 bytes per slot, so slot index (spi) is [0, 63]) +- */ +- INSN_F_FRAMENO_MASK = 0x7, /* 3 bits */ +- +- INSN_F_SPI_MASK = 0x3f, /* 6 bits */ +- INSN_F_SPI_SHIFT = 3, /* shifted 3 bits to the left */ +- +- INSN_F_STACK_ACCESS = BIT(9), /* we need 10 bits total */ +-}; +- +-static_assert(INSN_F_FRAMENO_MASK + 1 >= MAX_CALL_FRAMES); +-static_assert(INSN_F_SPI_MASK + 1 >= MAX_BPF_STACK / 8); +- +-struct bpf_jmp_history_entry { ++struct bpf_idx_pair { ++ u32 prev_idx; + u32 idx; +- /* insn idx can't be bigger than 1 million */ +- u32 prev_idx : 22; +- /* special flags, e.g., whether insn is doing register stack spill/load */ +- u32 flags : 10; + }; + ++#define MAX_CALL_FRAMES 8 + /* Maximum number of register states that can exist at once */ + #define BPF_ID_MAP_SIZE ((MAX_BPF_REG + MAX_BPF_STACK / BPF_REG_SIZE) * MAX_CALL_FRAMES) + struct bpf_verifier_state { +@@ -429,7 +407,7 @@ struct bpf_verifier_state { + * For most states jmp_history_cnt is [0-3]. + * For loops can go up to ~40. + */ +- struct bpf_jmp_history_entry *jmp_history; ++ struct bpf_idx_pair *jmp_history; + u32 jmp_history_cnt; + u32 dfs_depth; + u32 callback_unroll_depth; +@@ -662,7 +640,6 @@ struct bpf_verifier_env { + int cur_stack; + } cfg; + struct backtrack_state bt; +- struct bpf_jmp_history_entry *cur_hist_ent; + u32 pass_cnt; /* number of times do_check() was called */ + u32 subprog_cnt; + /* number of instructions analyzed by the verifier */ +diff --git a/include/linux/cleanup.h b/include/linux/cleanup.h +index 53f1a7a932b08c..64b8600eb8c0e4 100644 +--- a/include/linux/cleanup.h ++++ b/include/linux/cleanup.h +@@ -92,26 +92,85 @@ static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \ + * trivial wrapper around DEFINE_CLASS() above specifically + * for locks. + * ++ * DEFINE_GUARD_COND(name, ext, condlock) ++ * wrapper around EXTEND_CLASS above to add conditional lock ++ * variants to a base class, eg. mutex_trylock() or ++ * mutex_lock_interruptible(). ++ * + * guard(name): +- * an anonymous instance of the (guard) class ++ * an anonymous instance of the (guard) class, not recommended for ++ * conditional locks. + * + * scoped_guard (name, args...) { }: + * similar to CLASS(name, scope)(args), except the variable (with the + * explicit name 'scope') is declard in a for-loop such that its scope is + * bound to the next (compound) statement. + * ++ * for conditional locks the loop body is skipped when the lock is not ++ * acquired. ++ * ++ * scoped_cond_guard (name, fail, args...) { }: ++ * similar to scoped_guard(), except it does fail when the lock ++ * acquire fails. ++ * ++ * Only for conditional locks. + */ + ++#define __DEFINE_CLASS_IS_CONDITIONAL(_name, _is_cond) \ ++static __maybe_unused const bool class_##_name##_is_conditional = _is_cond ++ + #define DEFINE_GUARD(_name, _type, _lock, _unlock) \ +- DEFINE_CLASS(_name, _type, _unlock, ({ _lock; _T; }), _type _T) ++ __DEFINE_CLASS_IS_CONDITIONAL(_name, false); \ ++ DEFINE_CLASS(_name, _type, if (_T) { _unlock; }, ({ _lock; _T; }), _type _T); \ ++ static inline void * class_##_name##_lock_ptr(class_##_name##_t *_T) \ ++ { return (void *)(__force unsigned long)*_T; } ++ ++#define DEFINE_GUARD_COND(_name, _ext, _condlock) \ ++ __DEFINE_CLASS_IS_CONDITIONAL(_name##_ext, true); \ ++ EXTEND_CLASS(_name, _ext, \ ++ ({ void *_t = _T; if (_T && !(_condlock)) _t = NULL; _t; }), \ ++ class_##_name##_t _T) \ ++ static inline void * class_##_name##_ext##_lock_ptr(class_##_name##_t *_T) \ ++ { return class_##_name##_lock_ptr(_T); } + + #define guard(_name) \ + CLASS(_name, __UNIQUE_ID(guard)) + +-#define scoped_guard(_name, args...) \ +- for (CLASS(_name, scope)(args), \ +- *done = NULL; !done; done = (void *)1) ++#define __guard_ptr(_name) class_##_name##_lock_ptr ++#define __is_cond_ptr(_name) class_##_name##_is_conditional + ++/* ++ * Helper macro for scoped_guard(). ++ * ++ * Note that the "!__is_cond_ptr(_name)" part of the condition ensures that ++ * compiler would be sure that for the unconditional locks the body of the ++ * loop (caller-provided code glued to the else clause) could not be skipped. ++ * It is needed because the other part - "__guard_ptr(_name)(&scope)" - is too ++ * hard to deduce (even if could be proven true for unconditional locks). ++ */ ++#define __scoped_guard(_name, _label, args...) \ ++ for (CLASS(_name, scope)(args); \ ++ __guard_ptr(_name)(&scope) || !__is_cond_ptr(_name); \ ++ ({ goto _label; })) \ ++ if (0) { \ ++_label: \ ++ break; \ ++ } else ++ ++#define scoped_guard(_name, args...) \ ++ __scoped_guard(_name, __UNIQUE_ID(label), args) ++ ++#define __scoped_cond_guard(_name, _fail, _label, args...) \ ++ for (CLASS(_name, scope)(args); true; ({ goto _label; })) \ ++ if (!__guard_ptr(_name)(&scope)) { \ ++ BUILD_BUG_ON(!__is_cond_ptr(_name)); \ ++ _fail; \ ++_label: \ ++ break; \ ++ } else ++ ++#define scoped_cond_guard(_name, _fail, args...) \ ++ __scoped_cond_guard(_name, _fail, __UNIQUE_ID(label), args) + /* + * Additional helper macros for generating lock guards with types, either for + * locks that don't have a native type (eg. RCU, preempt) or those that need a +@@ -119,6 +178,7 @@ static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \ + * + * DEFINE_LOCK_GUARD_0(name, lock, unlock, ...) + * DEFINE_LOCK_GUARD_1(name, type, lock, unlock, ...) ++ * DEFINE_LOCK_GUARD_1_COND(name, ext, condlock) + * + * will result in the following type: + * +@@ -140,6 +200,11 @@ typedef struct { \ + static inline void class_##_name##_destructor(class_##_name##_t *_T) \ + { \ + if (_T->lock) { _unlock; } \ ++} \ ++ \ ++static inline void *class_##_name##_lock_ptr(class_##_name##_t *_T) \ ++{ \ ++ return (void *)(__force unsigned long)_T->lock; \ + } + + +@@ -161,11 +226,24 @@ static inline class_##_name##_t class_##_name##_constructor(void) \ + } + + #define DEFINE_LOCK_GUARD_1(_name, _type, _lock, _unlock, ...) \ ++__DEFINE_CLASS_IS_CONDITIONAL(_name, false); \ + __DEFINE_UNLOCK_GUARD(_name, _type, _unlock, __VA_ARGS__) \ + __DEFINE_LOCK_GUARD_1(_name, _type, _lock) + + #define DEFINE_LOCK_GUARD_0(_name, _lock, _unlock, ...) \ ++__DEFINE_CLASS_IS_CONDITIONAL(_name, false); \ + __DEFINE_UNLOCK_GUARD(_name, void, _unlock, __VA_ARGS__) \ + __DEFINE_LOCK_GUARD_0(_name, _lock) + ++#define DEFINE_LOCK_GUARD_1_COND(_name, _ext, _condlock) \ ++ __DEFINE_CLASS_IS_CONDITIONAL(_name##_ext, true); \ ++ EXTEND_CLASS(_name, _ext, \ ++ ({ class_##_name##_t _t = { .lock = l }, *_T = &_t;\ ++ if (_T->lock && !(_condlock)) _T->lock = NULL; \ ++ _t; }), \ ++ typeof_member(class_##_name##_t, lock) l) \ ++ static inline void * class_##_name##_ext##_lock_ptr(class_##_name##_t *_T) \ ++ { return class_##_name##_lock_ptr(_T); } ++ ++ + #endif /* __LINUX_GUARDS_H */ +diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h +index 3028af87716e29..430749a0f362aa 100644 +--- a/include/linux/if_vlan.h ++++ b/include/linux/if_vlan.h +@@ -585,13 +585,16 @@ static inline int vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci) + * vlan_get_protocol - get protocol EtherType. + * @skb: skbuff to query + * @type: first vlan protocol ++ * @mac_offset: MAC offset + * @depth: buffer to store length of eth and vlan tags in bytes + * + * Returns the EtherType of the packet, regardless of whether it is + * vlan encapsulated (normal or hardware accelerated) or not. + */ +-static inline __be16 __vlan_get_protocol(const struct sk_buff *skb, __be16 type, +- int *depth) ++static inline __be16 __vlan_get_protocol_offset(const struct sk_buff *skb, ++ __be16 type, ++ int mac_offset, ++ int *depth) + { + unsigned int vlan_depth = skb->mac_len, parse_depth = VLAN_MAX_DEPTH; + +@@ -610,7 +613,8 @@ static inline __be16 __vlan_get_protocol(const struct sk_buff *skb, __be16 type, + do { + struct vlan_hdr vhdr, *vh; + +- vh = skb_header_pointer(skb, vlan_depth, sizeof(vhdr), &vhdr); ++ vh = skb_header_pointer(skb, mac_offset + vlan_depth, ++ sizeof(vhdr), &vhdr); + if (unlikely(!vh || !--parse_depth)) + return 0; + +@@ -625,6 +629,12 @@ static inline __be16 __vlan_get_protocol(const struct sk_buff *skb, __be16 type, + return type; + } + ++static inline __be16 __vlan_get_protocol(const struct sk_buff *skb, __be16 type, ++ int *depth) ++{ ++ return __vlan_get_protocol_offset(skb, type, 0, depth); ++} ++ + /** + * vlan_get_protocol - get protocol EtherType. + * @skb: skbuff to query +diff --git a/include/linux/memblock.h b/include/linux/memblock.h +index ed57c23f80ac2b..ed64240041e857 100644 +--- a/include/linux/memblock.h ++++ b/include/linux/memblock.h +@@ -122,6 +122,7 @@ unsigned long memblock_addrs_overlap(phys_addr_t base1, phys_addr_t size1, + phys_addr_t base2, phys_addr_t size2); + bool memblock_overlaps_region(struct memblock_type *type, + phys_addr_t base, phys_addr_t size); ++bool memblock_validate_numa_coverage(unsigned long threshold_bytes); + int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size); + int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size); + int memblock_mark_mirror(phys_addr_t base, phys_addr_t size); +diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h +index ffb98bc43b2db2..38a8ff9c685cb8 100644 +--- a/include/linux/mlx5/driver.h ++++ b/include/linux/mlx5/driver.h +@@ -1225,6 +1225,12 @@ static inline bool mlx5_core_is_vf(const struct mlx5_core_dev *dev) + return dev->coredev_type == MLX5_COREDEV_VF; + } + ++static inline bool mlx5_core_same_coredev_type(const struct mlx5_core_dev *dev1, ++ const struct mlx5_core_dev *dev2) ++{ ++ return dev1->coredev_type == dev2->coredev_type; ++} ++ + static inline bool mlx5_core_is_ecpf(const struct mlx5_core_dev *dev) + { + return dev->caps.embedded_cpu; +diff --git a/include/linux/mutex.h b/include/linux/mutex.h +index 5b5630e58407a5..e1c323c7d75ba9 100644 +--- a/include/linux/mutex.h ++++ b/include/linux/mutex.h +@@ -248,6 +248,7 @@ extern void mutex_unlock(struct mutex *lock); + extern int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock); + + DEFINE_GUARD(mutex, struct mutex *, mutex_lock(_T), mutex_unlock(_T)) +-DEFINE_FREE(mutex, struct mutex *, if (_T) mutex_unlock(_T)) ++DEFINE_GUARD_COND(mutex, _try, mutex_trylock(_T)) ++DEFINE_GUARD_COND(mutex, _intr, mutex_lock_interruptible(_T) == 0) + + #endif /* __LINUX_MUTEX_H */ +diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h +index 1dd530ce8b45b9..9c29689ff505e0 100644 +--- a/include/linux/rwsem.h ++++ b/include/linux/rwsem.h +@@ -203,11 +203,11 @@ extern void up_read(struct rw_semaphore *sem); + extern void up_write(struct rw_semaphore *sem); + + DEFINE_GUARD(rwsem_read, struct rw_semaphore *, down_read(_T), up_read(_T)) +-DEFINE_GUARD(rwsem_write, struct rw_semaphore *, down_write(_T), up_write(_T)) +- +-DEFINE_FREE(up_read, struct rw_semaphore *, if (_T) up_read(_T)) +-DEFINE_FREE(up_write, struct rw_semaphore *, if (_T) up_write(_T)) ++DEFINE_GUARD_COND(rwsem_read, _try, down_read_trylock(_T)) ++DEFINE_GUARD_COND(rwsem_read, _intr, down_read_interruptible(_T) == 0) + ++DEFINE_GUARD(rwsem_write, struct rw_semaphore *, down_write(_T), up_write(_T)) ++DEFINE_GUARD_COND(rwsem_write, _try, down_write_trylock(_T)) + + /* + * downgrade write lock to read lock +diff --git a/include/linux/seq_buf.h b/include/linux/seq_buf.h +index 515d7fcb9634b5..468d8c5eef4a08 100644 +--- a/include/linux/seq_buf.h ++++ b/include/linux/seq_buf.h +@@ -14,19 +14,24 @@ + * @buffer: pointer to the buffer + * @size: size of the buffer + * @len: the amount of data inside the buffer +- * @readpos: The next position to read in the buffer. + */ + struct seq_buf { + char *buffer; + size_t size; + size_t len; +- loff_t readpos; + }; + ++#define DECLARE_SEQ_BUF(NAME, SIZE) \ ++ struct seq_buf NAME = { \ ++ .buffer = (char[SIZE]) { 0 }, \ ++ .size = SIZE, \ ++ } ++ + static inline void seq_buf_clear(struct seq_buf *s) + { + s->len = 0; +- s->readpos = 0; ++ if (s->size) ++ s->buffer[0] = '\0'; + } + + static inline void +@@ -72,8 +77,8 @@ static inline unsigned int seq_buf_used(struct seq_buf *s) + } + + /** +- * seq_buf_terminate - Make sure buffer is nul terminated +- * @s: the seq_buf descriptor to terminate. ++ * seq_buf_str - get %NUL-terminated C string from seq_buf ++ * @s: the seq_buf handle + * + * This makes sure that the buffer in @s is nul terminated and + * safe to read as a string. +@@ -84,16 +89,20 @@ static inline unsigned int seq_buf_used(struct seq_buf *s) + * + * After this function is called, s->buffer is safe to use + * in string operations. ++ * ++ * Returns @s->buf after making sure it is terminated. + */ +-static inline void seq_buf_terminate(struct seq_buf *s) ++static inline const char *seq_buf_str(struct seq_buf *s) + { + if (WARN_ON(s->size == 0)) +- return; ++ return ""; + + if (seq_buf_buffer_left(s)) + s->buffer[s->len] = 0; + else + s->buffer[s->size - 1] = 0; ++ ++ return s->buffer; + } + + /** +@@ -143,7 +152,7 @@ extern __printf(2, 0) + int seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args); + extern int seq_buf_print_seq(struct seq_file *m, struct seq_buf *s); + extern int seq_buf_to_user(struct seq_buf *s, char __user *ubuf, +- int cnt); ++ size_t start, int cnt); + extern int seq_buf_puts(struct seq_buf *s, const char *str); + extern int seq_buf_putc(struct seq_buf *s, unsigned char c); + extern int seq_buf_putmem(struct seq_buf *s, const void *mem, unsigned int len); +diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h +index 31d3d747a9db78..ceb56b39c70f77 100644 +--- a/include/linux/spinlock.h ++++ b/include/linux/spinlock.h +@@ -507,6 +507,8 @@ DEFINE_LOCK_GUARD_1(raw_spinlock, raw_spinlock_t, + raw_spin_lock(_T->lock), + raw_spin_unlock(_T->lock)) + ++DEFINE_LOCK_GUARD_1_COND(raw_spinlock, _try, raw_spin_trylock(_T->lock)) ++ + DEFINE_LOCK_GUARD_1(raw_spinlock_nested, raw_spinlock_t, + raw_spin_lock_nested(_T->lock, SINGLE_DEPTH_NESTING), + raw_spin_unlock(_T->lock)) +@@ -515,23 +517,36 @@ DEFINE_LOCK_GUARD_1(raw_spinlock_irq, raw_spinlock_t, + raw_spin_lock_irq(_T->lock), + raw_spin_unlock_irq(_T->lock)) + ++DEFINE_LOCK_GUARD_1_COND(raw_spinlock_irq, _try, raw_spin_trylock_irq(_T->lock)) ++ + DEFINE_LOCK_GUARD_1(raw_spinlock_irqsave, raw_spinlock_t, + raw_spin_lock_irqsave(_T->lock, _T->flags), + raw_spin_unlock_irqrestore(_T->lock, _T->flags), + unsigned long flags) + ++DEFINE_LOCK_GUARD_1_COND(raw_spinlock_irqsave, _try, ++ raw_spin_trylock_irqsave(_T->lock, _T->flags)) ++ + DEFINE_LOCK_GUARD_1(spinlock, spinlock_t, + spin_lock(_T->lock), + spin_unlock(_T->lock)) + ++DEFINE_LOCK_GUARD_1_COND(spinlock, _try, spin_trylock(_T->lock)) ++ + DEFINE_LOCK_GUARD_1(spinlock_irq, spinlock_t, + spin_lock_irq(_T->lock), + spin_unlock_irq(_T->lock)) + ++DEFINE_LOCK_GUARD_1_COND(spinlock_irq, _try, ++ spin_trylock_irq(_T->lock)) ++ + DEFINE_LOCK_GUARD_1(spinlock_irqsave, spinlock_t, + spin_lock_irqsave(_T->lock, _T->flags), + spin_unlock_irqrestore(_T->lock, _T->flags), + unsigned long flags) + ++DEFINE_LOCK_GUARD_1_COND(spinlock_irqsave, _try, ++ spin_trylock_irqsave(_T->lock, _T->flags)) ++ + #undef __LINUX_INSIDE_SPINLOCK_H + #endif /* __LINUX_SPINLOCK_H */ +diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h +index 9df2524fff33ae..aa1bc417266208 100644 +--- a/include/linux/trace_events.h ++++ b/include/linux/trace_events.h +@@ -279,7 +279,8 @@ struct trace_event_fields { + const char *name; + const int size; + const int align; +- const int is_signed; ++ const unsigned int is_signed:1; ++ unsigned int needs_test:1; + const int filter_type; + const int len; + }; +@@ -331,6 +332,7 @@ enum { + TRACE_EVENT_FL_EPROBE_BIT, + TRACE_EVENT_FL_FPROBE_BIT, + TRACE_EVENT_FL_CUSTOM_BIT, ++ TRACE_EVENT_FL_TEST_STR_BIT, + }; + + /* +@@ -348,6 +350,7 @@ enum { + * CUSTOM - Event is a custom event (to be attached to an exsiting tracepoint) + * This is set when the custom event has not been attached + * to a tracepoint yet, then it is cleared when it is. ++ * TEST_STR - The event has a "%s" that points to a string outside the event + */ + enum { + TRACE_EVENT_FL_FILTERED = (1 << TRACE_EVENT_FL_FILTERED_BIT), +@@ -361,6 +364,7 @@ enum { + TRACE_EVENT_FL_EPROBE = (1 << TRACE_EVENT_FL_EPROBE_BIT), + TRACE_EVENT_FL_FPROBE = (1 << TRACE_EVENT_FL_FPROBE_BIT), + TRACE_EVENT_FL_CUSTOM = (1 << TRACE_EVENT_FL_CUSTOM_BIT), ++ TRACE_EVENT_FL_TEST_STR = (1 << TRACE_EVENT_FL_TEST_STR_BIT), + }; + + #define TRACE_EVENT_FL_UKPROBE (TRACE_EVENT_FL_KPROBE | TRACE_EVENT_FL_UPROBE) +diff --git a/include/linux/trace_seq.h b/include/linux/trace_seq.h +index 6be92bf559fe7c..3691e0e76a1a20 100644 +--- a/include/linux/trace_seq.h ++++ b/include/linux/trace_seq.h +@@ -14,6 +14,7 @@ + struct trace_seq { + char buffer[PAGE_SIZE]; + struct seq_buf seq; ++ size_t readpos; + int full; + }; + +@@ -22,6 +23,7 @@ trace_seq_init(struct trace_seq *s) + { + seq_buf_init(&s->seq, s->buffer, PAGE_SIZE); + s->full = 0; ++ s->readpos = 0; + } + + /** +diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h +index 0b4f2d5faa080d..ebdfef124b2bc0 100644 +--- a/include/linux/usb/chipidea.h ++++ b/include/linux/usb/chipidea.h +@@ -64,6 +64,8 @@ struct ci_hdrc_platform_data { + #define CI_HDRC_PMQOS BIT(15) + #define CI_HDRC_PHY_VBUS_CONTROL BIT(16) + #define CI_HDRC_HAS_PORTSC_PEC_MISSED BIT(17) ++#define CI_HDRC_FORCE_VBUS_ACTIVE_ALWAYS BIT(18) ++#define CI_HDRC_HAS_SHORT_PKT_LIMIT BIT(19) + enum usb_dr_mode dr_mode; + #define CI_HDRC_CONTROLLER_RESET_EVENT 0 + #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 +diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h +index e9214ccfde2d72..4fcee6b734b74c 100644 +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -800,7 +800,6 @@ struct hci_conn_params { + extern struct list_head hci_dev_list; + extern struct list_head hci_cb_list; + extern rwlock_t hci_dev_list_lock; +-extern struct mutex hci_cb_list_lock; + + #define hci_dev_set_flag(hdev, nr) set_bit((nr), (hdev)->dev_flags) + #define hci_dev_clear_flag(hdev, nr) clear_bit((nr), (hdev)->dev_flags) +@@ -1949,24 +1948,47 @@ struct hci_cb { + + char *name; + ++ bool (*match) (struct hci_conn *conn); + void (*connect_cfm) (struct hci_conn *conn, __u8 status); + void (*disconn_cfm) (struct hci_conn *conn, __u8 status); + void (*security_cfm) (struct hci_conn *conn, __u8 status, +- __u8 encrypt); ++ __u8 encrypt); + void (*key_change_cfm) (struct hci_conn *conn, __u8 status); + void (*role_switch_cfm) (struct hci_conn *conn, __u8 status, __u8 role); + }; + ++static inline void hci_cb_lookup(struct hci_conn *conn, struct list_head *list) ++{ ++ struct hci_cb *cb, *cpy; ++ ++ rcu_read_lock(); ++ list_for_each_entry_rcu(cb, &hci_cb_list, list) { ++ if (cb->match && cb->match(conn)) { ++ cpy = kmalloc(sizeof(*cpy), GFP_ATOMIC); ++ if (!cpy) ++ break; ++ ++ *cpy = *cb; ++ INIT_LIST_HEAD(&cpy->list); ++ list_add_rcu(&cpy->list, list); ++ } ++ } ++ rcu_read_unlock(); ++} ++ + static inline void hci_connect_cfm(struct hci_conn *conn, __u8 status) + { +- struct hci_cb *cb; ++ struct list_head list; ++ struct hci_cb *cb, *tmp; ++ ++ INIT_LIST_HEAD(&list); ++ hci_cb_lookup(conn, &list); + +- mutex_lock(&hci_cb_list_lock); +- list_for_each_entry(cb, &hci_cb_list, list) { ++ list_for_each_entry_safe(cb, tmp, &list, list) { + if (cb->connect_cfm) + cb->connect_cfm(conn, status); ++ kfree(cb); + } +- mutex_unlock(&hci_cb_list_lock); + + if (conn->connect_cfm_cb) + conn->connect_cfm_cb(conn, status); +@@ -1974,43 +1996,55 @@ static inline void hci_connect_cfm(struct hci_conn *conn, __u8 status) + + static inline void hci_disconn_cfm(struct hci_conn *conn, __u8 reason) + { +- struct hci_cb *cb; ++ struct list_head list; ++ struct hci_cb *cb, *tmp; ++ ++ INIT_LIST_HEAD(&list); ++ hci_cb_lookup(conn, &list); + +- mutex_lock(&hci_cb_list_lock); +- list_for_each_entry(cb, &hci_cb_list, list) { ++ list_for_each_entry_safe(cb, tmp, &list, list) { + if (cb->disconn_cfm) + cb->disconn_cfm(conn, reason); ++ kfree(cb); + } +- mutex_unlock(&hci_cb_list_lock); + + if (conn->disconn_cfm_cb) + conn->disconn_cfm_cb(conn, reason); + } + +-static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) ++static inline void hci_security_cfm(struct hci_conn *conn, __u8 status, ++ __u8 encrypt) + { +- struct hci_cb *cb; +- __u8 encrypt; +- +- if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) +- return; ++ struct list_head list; ++ struct hci_cb *cb, *tmp; + +- encrypt = test_bit(HCI_CONN_ENCRYPT, &conn->flags) ? 0x01 : 0x00; ++ INIT_LIST_HEAD(&list); ++ hci_cb_lookup(conn, &list); + +- mutex_lock(&hci_cb_list_lock); +- list_for_each_entry(cb, &hci_cb_list, list) { ++ list_for_each_entry_safe(cb, tmp, &list, list) { + if (cb->security_cfm) + cb->security_cfm(conn, status, encrypt); ++ kfree(cb); + } +- mutex_unlock(&hci_cb_list_lock); + + if (conn->security_cfm_cb) + conn->security_cfm_cb(conn, status); + } + ++static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) ++{ ++ __u8 encrypt; ++ ++ if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) ++ return; ++ ++ encrypt = test_bit(HCI_CONN_ENCRYPT, &conn->flags) ? 0x01 : 0x00; ++ ++ hci_security_cfm(conn, status, encrypt); ++} ++ + static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status) + { +- struct hci_cb *cb; + __u8 encrypt; + + if (conn->state == BT_CONFIG) { +@@ -2037,40 +2071,38 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status) + conn->sec_level = conn->pending_sec_level; + } + +- mutex_lock(&hci_cb_list_lock); +- list_for_each_entry(cb, &hci_cb_list, list) { +- if (cb->security_cfm) +- cb->security_cfm(conn, status, encrypt); +- } +- mutex_unlock(&hci_cb_list_lock); +- +- if (conn->security_cfm_cb) +- conn->security_cfm_cb(conn, status); ++ hci_security_cfm(conn, status, encrypt); + } + + static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status) + { +- struct hci_cb *cb; ++ struct list_head list; ++ struct hci_cb *cb, *tmp; ++ ++ INIT_LIST_HEAD(&list); ++ hci_cb_lookup(conn, &list); + +- mutex_lock(&hci_cb_list_lock); +- list_for_each_entry(cb, &hci_cb_list, list) { ++ list_for_each_entry_safe(cb, tmp, &list, list) { + if (cb->key_change_cfm) + cb->key_change_cfm(conn, status); ++ kfree(cb); + } +- mutex_unlock(&hci_cb_list_lock); + } + + static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, + __u8 role) + { +- struct hci_cb *cb; ++ struct list_head list; ++ struct hci_cb *cb, *tmp; ++ ++ INIT_LIST_HEAD(&list); ++ hci_cb_lookup(conn, &list); + +- mutex_lock(&hci_cb_list_lock); +- list_for_each_entry(cb, &hci_cb_list, list) { ++ list_for_each_entry_safe(cb, tmp, &list, list) { + if (cb->role_switch_cfm) + cb->role_switch_cfm(conn, status, role); ++ kfree(cb); + } +- mutex_unlock(&hci_cb_list_lock); + } + + static inline bool hci_bdaddr_is_rpa(bdaddr_t *bdaddr, u8 addr_type) +diff --git a/include/net/mac80211.h b/include/net/mac80211.h +index 47ade676565dbc..835a58ce9ca57c 100644 +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -3039,6 +3039,19 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, + */ + void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb); + ++/** ++ * ieee80211_purge_tx_queue - purge TX skb queue ++ * @hw: the hardware ++ * @skbs: the skbs ++ * ++ * Free a set of transmit skbs. Use this function when device is going to stop ++ * but some transmit skbs without TX status are still queued. ++ * This function does not take the list lock and the caller must hold the ++ * relevant locks to use it. ++ */ ++void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, ++ struct sk_buff_head *skbs); ++ + /** + * DOC: Hardware crypto acceleration + * +@@ -6067,6 +6080,24 @@ void ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw, + void (*iterator)(void *data, + struct ieee80211_sta *sta), + void *data); ++ ++/** ++ * ieee80211_iterate_stations_mtx - iterate stations ++ * ++ * This function iterates over all stations associated with a given ++ * hardware that are currently uploaded to the driver and calls the callback ++ * function for them. This version can only be used while holding the wiphy ++ * mutex. ++ * ++ * @hw: the hardware struct of which the interfaces should be iterated over ++ * @iterator: the iterator function to call ++ * @data: first argument of the iterator function ++ */ ++void ieee80211_iterate_stations_mtx(struct ieee80211_hw *hw, ++ void (*iterator)(void *data, ++ struct ieee80211_sta *sta), ++ void *data); ++ + /** + * ieee80211_queue_work - add work onto the mac80211 workqueue + * +diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h +index b5f9ee5810a347..8321915dddb284 100644 +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -721,15 +721,18 @@ struct nft_set_ext_tmpl { + /** + * struct nft_set_ext - set extensions + * +- * @genmask: generation mask ++ * @genmask: generation mask, but also flags (see NFT_SET_ELEM_DEAD_BIT) + * @offset: offsets of individual extension types + * @data: beginning of extension data ++ * ++ * This structure must be aligned to word size, otherwise atomic bitops ++ * on genmask field can cause alignment failure on some archs. + */ + struct nft_set_ext { + u8 genmask; + u8 offset[NFT_SET_EXT_NUM]; + char data[]; +-}; ++} __aligned(BITS_PER_LONG / 8); + + static inline void nft_set_ext_prepare(struct nft_set_ext_tmpl *tmpl) + { +diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c +index 58ee17f429a33a..02f327f05fd619 100644 +--- a/kernel/bpf/core.c ++++ b/kernel/bpf/core.c +@@ -529,6 +529,8 @@ struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off, + + int bpf_remove_insns(struct bpf_prog *prog, u32 off, u32 cnt) + { ++ int err; ++ + /* Branch offsets can't overflow when program is shrinking, no need + * to call bpf_adj_branches(..., true) here + */ +@@ -536,7 +538,9 @@ int bpf_remove_insns(struct bpf_prog *prog, u32 off, u32 cnt) + sizeof(struct bpf_insn) * (prog->len - off - cnt)); + prog->len -= cnt; + +- return WARN_ON_ONCE(bpf_adj_branches(prog, off, off + cnt, off, false)); ++ err = bpf_adj_branches(prog, off, off + cnt, off, false); ++ WARN_ON_ONCE(err); ++ return err; + } + + static void bpf_prog_kallsyms_del_subprogs(struct bpf_prog *fp) +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index a3c3c66ca04759..d6a4102312fadd 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -1762,8 +1762,8 @@ static int copy_verifier_state(struct bpf_verifier_state *dst_state, + int i, err; + + dst_state->jmp_history = copy_array(dst_state->jmp_history, src->jmp_history, +- src->jmp_history_cnt, sizeof(*dst_state->jmp_history), +- GFP_USER); ++ src->jmp_history_cnt, sizeof(struct bpf_idx_pair), ++ GFP_USER); + if (!dst_state->jmp_history) + return -ENOMEM; + dst_state->jmp_history_cnt = src->jmp_history_cnt; +@@ -3397,21 +3397,6 @@ static int check_reg_arg(struct bpf_verifier_env *env, u32 regno, + return __check_reg_arg(env, state->regs, regno, t); + } + +-static int insn_stack_access_flags(int frameno, int spi) +-{ +- return INSN_F_STACK_ACCESS | (spi << INSN_F_SPI_SHIFT) | frameno; +-} +- +-static int insn_stack_access_spi(int insn_flags) +-{ +- return (insn_flags >> INSN_F_SPI_SHIFT) & INSN_F_SPI_MASK; +-} +- +-static int insn_stack_access_frameno(int insn_flags) +-{ +- return insn_flags & INSN_F_FRAMENO_MASK; +-} +- + static void mark_jmp_point(struct bpf_verifier_env *env, int idx) + { + env->insn_aux_data[idx].jmp_point = true; +@@ -3423,51 +3408,28 @@ static bool is_jmp_point(struct bpf_verifier_env *env, int insn_idx) + } + + /* for any branch, call, exit record the history of jmps in the given state */ +-static int push_jmp_history(struct bpf_verifier_env *env, struct bpf_verifier_state *cur, +- int insn_flags) ++static int push_jmp_history(struct bpf_verifier_env *env, ++ struct bpf_verifier_state *cur) + { + u32 cnt = cur->jmp_history_cnt; +- struct bpf_jmp_history_entry *p; ++ struct bpf_idx_pair *p; + size_t alloc_size; + +- /* combine instruction flags if we already recorded this instruction */ +- if (env->cur_hist_ent) { +- /* atomic instructions push insn_flags twice, for READ and +- * WRITE sides, but they should agree on stack slot +- */ +- WARN_ONCE((env->cur_hist_ent->flags & insn_flags) && +- (env->cur_hist_ent->flags & insn_flags) != insn_flags, +- "verifier insn history bug: insn_idx %d cur flags %x new flags %x\n", +- env->insn_idx, env->cur_hist_ent->flags, insn_flags); +- env->cur_hist_ent->flags |= insn_flags; ++ if (!is_jmp_point(env, env->insn_idx)) + return 0; +- } + + cnt++; + alloc_size = kmalloc_size_roundup(size_mul(cnt, sizeof(*p))); + p = krealloc(cur->jmp_history, alloc_size, GFP_USER); + if (!p) + return -ENOMEM; ++ p[cnt - 1].idx = env->insn_idx; ++ p[cnt - 1].prev_idx = env->prev_insn_idx; + cur->jmp_history = p; +- +- p = &cur->jmp_history[cnt - 1]; +- p->idx = env->insn_idx; +- p->prev_idx = env->prev_insn_idx; +- p->flags = insn_flags; + cur->jmp_history_cnt = cnt; +- env->cur_hist_ent = p; +- + return 0; + } + +-static struct bpf_jmp_history_entry *get_jmp_hist_entry(struct bpf_verifier_state *st, +- u32 hist_end, int insn_idx) +-{ +- if (hist_end > 0 && st->jmp_history[hist_end - 1].idx == insn_idx) +- return &st->jmp_history[hist_end - 1]; +- return NULL; +-} +- + /* Backtrack one insn at a time. If idx is not at the top of recorded + * history then previous instruction came from straight line execution. + * Return -ENOENT if we exhausted all instructions within given state. +@@ -3629,14 +3591,9 @@ static inline bool bt_is_reg_set(struct backtrack_state *bt, u32 reg) + return bt->reg_masks[bt->frame] & (1 << reg); + } + +-static inline bool bt_is_frame_slot_set(struct backtrack_state *bt, u32 frame, u32 slot) +-{ +- return bt->stack_masks[frame] & (1ull << slot); +-} +- + static inline bool bt_is_slot_set(struct backtrack_state *bt, u32 slot) + { +- return bt_is_frame_slot_set(bt, bt->frame, slot); ++ return bt->stack_masks[bt->frame] & (1ull << slot); + } + + /* format registers bitmask, e.g., "r0,r2,r4" for 0x15 mask */ +@@ -3690,7 +3647,7 @@ static bool calls_callback(struct bpf_verifier_env *env, int insn_idx); + * - *was* processed previously during backtracking. + */ + static int backtrack_insn(struct bpf_verifier_env *env, int idx, int subseq_idx, +- struct bpf_jmp_history_entry *hist, struct backtrack_state *bt) ++ struct backtrack_state *bt) + { + const struct bpf_insn_cbs cbs = { + .cb_call = disasm_kfunc_name, +@@ -3703,7 +3660,7 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx, int subseq_idx, + u8 mode = BPF_MODE(insn->code); + u32 dreg = insn->dst_reg; + u32 sreg = insn->src_reg; +- u32 spi, i, fr; ++ u32 spi, i; + + if (insn->code == 0) + return 0; +@@ -3766,15 +3723,20 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx, int subseq_idx, + * by 'precise' mark in corresponding register of this state. + * No further tracking necessary. + */ +- if (!hist || !(hist->flags & INSN_F_STACK_ACCESS)) ++ if (insn->src_reg != BPF_REG_FP) + return 0; ++ + /* dreg = *(u64 *)[fp - off] was a fill from the stack. + * that [fp - off] slot contains scalar that needs to be + * tracked with precision + */ +- spi = insn_stack_access_spi(hist->flags); +- fr = insn_stack_access_frameno(hist->flags); +- bt_set_frame_slot(bt, fr, spi); ++ spi = (-insn->off - 1) / BPF_REG_SIZE; ++ if (spi >= 64) { ++ verbose(env, "BUG spi %d\n", spi); ++ WARN_ONCE(1, "verifier backtracking bug"); ++ return -EFAULT; ++ } ++ bt_set_slot(bt, spi); + } else if (class == BPF_STX || class == BPF_ST) { + if (bt_is_reg_set(bt, dreg)) + /* stx & st shouldn't be using _scalar_ dst_reg +@@ -3783,13 +3745,17 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx, int subseq_idx, + */ + return -ENOTSUPP; + /* scalars can only be spilled into stack */ +- if (!hist || !(hist->flags & INSN_F_STACK_ACCESS)) ++ if (insn->dst_reg != BPF_REG_FP) + return 0; +- spi = insn_stack_access_spi(hist->flags); +- fr = insn_stack_access_frameno(hist->flags); +- if (!bt_is_frame_slot_set(bt, fr, spi)) ++ spi = (-insn->off - 1) / BPF_REG_SIZE; ++ if (spi >= 64) { ++ verbose(env, "BUG spi %d\n", spi); ++ WARN_ONCE(1, "verifier backtracking bug"); ++ return -EFAULT; ++ } ++ if (!bt_is_slot_set(bt, spi)) + return 0; +- bt_clear_frame_slot(bt, fr, spi); ++ bt_clear_slot(bt, spi); + if (class == BPF_STX) + bt_set_reg(bt, sreg); + } else if (class == BPF_JMP || class == BPF_JMP32) { +@@ -3833,14 +3799,10 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx, int subseq_idx, + WARN_ONCE(1, "verifier backtracking bug"); + return -EFAULT; + } +- /* we are now tracking register spills correctly, +- * so any instance of leftover slots is a bug +- */ +- if (bt_stack_mask(bt) != 0) { +- verbose(env, "BUG stack slots %llx\n", bt_stack_mask(bt)); +- WARN_ONCE(1, "verifier backtracking bug (subprog leftover stack slots)"); +- return -EFAULT; +- } ++ /* we don't track register spills perfectly, ++ * so fallback to force-precise instead of failing */ ++ if (bt_stack_mask(bt) != 0) ++ return -ENOTSUPP; + /* propagate r1-r5 to the caller */ + for (i = BPF_REG_1; i <= BPF_REG_5; i++) { + if (bt_is_reg_set(bt, i)) { +@@ -3865,11 +3827,8 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx, int subseq_idx, + WARN_ONCE(1, "verifier backtracking bug"); + return -EFAULT; + } +- if (bt_stack_mask(bt) != 0) { +- verbose(env, "BUG stack slots %llx\n", bt_stack_mask(bt)); +- WARN_ONCE(1, "verifier backtracking bug (callback leftover stack slots)"); +- return -EFAULT; +- } ++ if (bt_stack_mask(bt) != 0) ++ return -ENOTSUPP; + /* clear r1-r5 in callback subprog's mask */ + for (i = BPF_REG_1; i <= BPF_REG_5; i++) + bt_clear_reg(bt, i); +@@ -4306,7 +4265,6 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno) + for (;;) { + DECLARE_BITMAP(mask, 64); + u32 history = st->jmp_history_cnt; +- struct bpf_jmp_history_entry *hist; + + if (env->log.level & BPF_LOG_LEVEL2) { + verbose(env, "mark_precise: frame%d: last_idx %d first_idx %d subseq_idx %d \n", +@@ -4370,8 +4328,7 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno) + err = 0; + skip_first = false; + } else { +- hist = get_jmp_hist_entry(st, history, i); +- err = backtrack_insn(env, i, subseq_idx, hist, bt); ++ err = backtrack_insn(env, i, subseq_idx, bt); + } + if (err == -ENOTSUPP) { + mark_all_scalars_precise(env, env->cur_state); +@@ -4424,10 +4381,22 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno) + bitmap_from_u64(mask, bt_frame_stack_mask(bt, fr)); + for_each_set_bit(i, mask, 64) { + if (i >= func->allocated_stack / BPF_REG_SIZE) { +- verbose(env, "BUG backtracking (stack slot %d, total slots %d)\n", +- i, func->allocated_stack / BPF_REG_SIZE); +- WARN_ONCE(1, "verifier backtracking bug (stack slot out of bounds)"); +- return -EFAULT; ++ /* the sequence of instructions: ++ * 2: (bf) r3 = r10 ++ * 3: (7b) *(u64 *)(r3 -8) = r0 ++ * 4: (79) r4 = *(u64 *)(r10 -8) ++ * doesn't contain jmps. It's backtracked ++ * as a single block. ++ * During backtracking insn 3 is not recognized as ++ * stack access, so at the end of backtracking ++ * stack slot fp-8 is still marked in stack_mask. ++ * However the parent state may not have accessed ++ * fp-8 and it's "unallocated" stack space. ++ * In such case fallback to conservative. ++ */ ++ mark_all_scalars_precise(env, env->cur_state); ++ bt_reset(bt); ++ return 0; + } + + if (!is_spilled_scalar_reg(&func->stack[i])) { +@@ -4592,7 +4561,7 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env, + int i, slot = -off - 1, spi = slot / BPF_REG_SIZE, err; + struct bpf_insn *insn = &env->prog->insnsi[insn_idx]; + struct bpf_reg_state *reg = NULL; +- int insn_flags = insn_stack_access_flags(state->frameno, spi); ++ u32 dst_reg = insn->dst_reg; + + /* caller checked that off % size == 0 and -MAX_BPF_STACK <= off < 0, + * so it's aligned access and [off, off + size) are within stack limits +@@ -4631,6 +4600,17 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env, + mark_stack_slot_scratched(env, spi); + if (reg && !(off % BPF_REG_SIZE) && register_is_bounded(reg) && + !register_is_null(reg) && env->bpf_capable) { ++ if (dst_reg != BPF_REG_FP) { ++ /* The backtracking logic can only recognize explicit ++ * stack slot address like [fp - 8]. Other spill of ++ * scalar via different register has to be conservative. ++ * Backtrack from here and mark all registers as precise ++ * that contributed into 'reg' being a constant. ++ */ ++ err = mark_chain_precision(env, value_regno); ++ if (err) ++ return err; ++ } + save_register_state(state, spi, reg, size); + /* Break the relation on a narrowing spill. */ + if (fls64(reg->umax_value) > BITS_PER_BYTE * size) +@@ -4642,7 +4622,6 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env, + __mark_reg_known(&fake_reg, insn->imm); + fake_reg.type = SCALAR_VALUE; + save_register_state(state, spi, &fake_reg, size); +- insn_flags = 0; /* not a register spill */ + } else if (reg && is_spillable_regtype(reg->type)) { + /* register containing pointer is being spilled into stack */ + if (size != BPF_REG_SIZE) { +@@ -4688,12 +4667,9 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env, + + /* Mark slots affected by this stack write. */ + for (i = 0; i < size; i++) +- state->stack[spi].slot_type[(slot - i) % BPF_REG_SIZE] = type; +- insn_flags = 0; /* not a register spill */ ++ state->stack[spi].slot_type[(slot - i) % BPF_REG_SIZE] = ++ type; + } +- +- if (insn_flags) +- return push_jmp_history(env, env->cur_state, insn_flags); + return 0; + } + +@@ -4882,7 +4858,6 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env, + int i, slot = -off - 1, spi = slot / BPF_REG_SIZE; + struct bpf_reg_state *reg; + u8 *stype, type; +- int insn_flags = insn_stack_access_flags(reg_state->frameno, spi); + + stype = reg_state->stack[spi].slot_type; + reg = ®_state->stack[spi].spilled_ptr; +@@ -4928,10 +4903,12 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env, + return -EACCES; + } + mark_reg_unknown(env, state->regs, dst_regno); +- insn_flags = 0; /* not restoring original register state */ + } + state->regs[dst_regno].live |= REG_LIVE_WRITTEN; +- } else if (dst_regno >= 0) { ++ return 0; ++ } ++ ++ if (dst_regno >= 0) { + /* restore register state from stack */ + copy_register_state(&state->regs[dst_regno], reg); + /* mark reg as written since spilled pointer state likely +@@ -4967,10 +4944,7 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env, + mark_reg_read(env, reg, reg->parent, REG_LIVE_READ64); + if (dst_regno >= 0) + mark_reg_stack_read(env, reg_state, off, off + size, dst_regno); +- insn_flags = 0; /* we are not restoring spilled register */ + } +- if (insn_flags) +- return push_jmp_history(env, env->cur_state, insn_flags); + return 0; + } + +@@ -7054,6 +7028,7 @@ static int check_atomic(struct bpf_verifier_env *env, int insn_idx, struct bpf_i + BPF_SIZE(insn->code), BPF_WRITE, -1, true, false); + if (err) + return err; ++ + return 0; + } + +@@ -16802,8 +16777,7 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx) + * the precision needs to be propagated back in + * the current state. + */ +- if (is_jmp_point(env, env->insn_idx)) +- err = err ? : push_jmp_history(env, cur, 0); ++ err = err ? : push_jmp_history(env, cur); + err = err ? : propagate_precision(env, &sl->state); + if (err) + return err; +@@ -17027,9 +17001,6 @@ static int do_check(struct bpf_verifier_env *env) + u8 class; + int err; + +- /* reset current history entry on each new instruction */ +- env->cur_hist_ent = NULL; +- + env->prev_insn_idx = prev_insn_idx; + if (env->insn_idx >= insn_cnt) { + verbose(env, "invalid insn idx %d insn_cnt %d\n", +@@ -17069,7 +17040,7 @@ static int do_check(struct bpf_verifier_env *env) + } + + if (is_jmp_point(env, env->insn_idx)) { +- err = push_jmp_history(env, state, 0); ++ err = push_jmp_history(env, state); + if (err) + return err; + } +diff --git a/kernel/kcov.c b/kernel/kcov.c +index 72d9aa6fb50c3e..097c8afa675578 100644 +--- a/kernel/kcov.c ++++ b/kernel/kcov.c +@@ -165,7 +165,7 @@ static void kcov_remote_area_put(struct kcov_remote_area *area, + * Unlike in_serving_softirq(), this function returns false when called during + * a hardirq or an NMI that happened in the softirq context. + */ +-static inline bool in_softirq_really(void) ++static __always_inline bool in_softirq_really(void) + { + return in_serving_softirq() && !in_hardirq() && !in_nmi(); + } +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index 228f7c07da7284..86606fb9e6bc6c 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -4488,7 +4488,8 @@ int wake_up_state(struct task_struct *p, unsigned int state) + * Perform scheduler related setup for a newly forked process p. + * p is forked by current. + * +- * __sched_fork() is basic setup used by init_idle() too: ++ * __sched_fork() is basic setup which is also used by sched_init() to ++ * initialize the boot CPU's idle task. + */ + static void __sched_fork(unsigned long clone_flags, struct task_struct *p) + { +@@ -9257,8 +9258,6 @@ void __init init_idle(struct task_struct *idle, int cpu) + struct rq *rq = cpu_rq(cpu); + unsigned long flags; + +- __sched_fork(0, idle); +- + raw_spin_lock_irqsave(&idle->pi_lock, flags); + raw_spin_rq_lock(rq); + +@@ -9273,10 +9272,8 @@ void __init init_idle(struct task_struct *idle, int cpu) + + #ifdef CONFIG_SMP + /* +- * It's possible that init_idle() gets called multiple times on a task, +- * in that case do_set_cpus_allowed() will not do the right thing. +- * +- * And since this is boot we can forgo the serialization. ++ * No validation and serialization required at boot time and for ++ * setting up the idle tasks of not yet online CPUs. + */ + set_cpus_allowed_common(idle, &ac); + #endif +@@ -10105,6 +10102,7 @@ void __init sched_init(void) + * but because we are the idle thread, we just pick up running again + * when this runqueue becomes "idle". + */ ++ __sched_fork(0, current); + init_idle(current, smp_processor_id()); + + calc_load_update = jiffies + LOAD_FREQ; +diff --git a/kernel/softirq.c b/kernel/softirq.c +index bd9716d7bb6383..f24d80cf20bd35 100644 +--- a/kernel/softirq.c ++++ b/kernel/softirq.c +@@ -279,17 +279,24 @@ static inline void invoke_softirq(void) + wakeup_softirqd(); + } + ++#define SCHED_SOFTIRQ_MASK BIT(SCHED_SOFTIRQ) ++ + /* + * flush_smp_call_function_queue() can raise a soft interrupt in a function +- * call. On RT kernels this is undesired and the only known functionality +- * in the block layer which does this is disabled on RT. If soft interrupts +- * get raised which haven't been raised before the flush, warn so it can be ++ * call. On RT kernels this is undesired and the only known functionalities ++ * are in the block layer which is disabled on RT, and in the scheduler for ++ * idle load balancing. If soft interrupts get raised which haven't been ++ * raised before the flush, warn if it is not a SCHED_SOFTIRQ so it can be + * investigated. + */ + void do_softirq_post_smp_call_flush(unsigned int was_pending) + { +- if (WARN_ON_ONCE(was_pending != local_softirq_pending())) ++ unsigned int is_pending = local_softirq_pending(); ++ ++ if (unlikely(was_pending != is_pending)) { ++ WARN_ON_ONCE(was_pending != (is_pending & ~SCHED_SOFTIRQ_MASK)); + invoke_softirq(); ++ } + } + + #else /* CONFIG_PREEMPT_RT */ +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index 220903117c5139..9d9af60b238e27 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -1731,15 +1731,15 @@ static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt) + { + int len; + +- if (trace_seq_used(s) <= s->seq.readpos) ++ if (trace_seq_used(s) <= s->readpos) + return -EBUSY; + +- len = trace_seq_used(s) - s->seq.readpos; ++ len = trace_seq_used(s) - s->readpos; + if (cnt > len) + cnt = len; +- memcpy(buf, s->buffer + s->seq.readpos, cnt); ++ memcpy(buf, s->buffer + s->readpos, cnt); + +- s->seq.readpos += cnt; ++ s->readpos += cnt; + return cnt; + } + +@@ -3760,17 +3760,12 @@ char *trace_iter_expand_format(struct trace_iterator *iter) + } + + /* Returns true if the string is safe to dereference from an event */ +-static bool trace_safe_str(struct trace_iterator *iter, const char *str, +- bool star, int len) ++static bool trace_safe_str(struct trace_iterator *iter, const char *str) + { + unsigned long addr = (unsigned long)str; + struct trace_event *trace_event; + struct trace_event_call *event; + +- /* Ignore strings with no length */ +- if (star && !len) +- return true; +- + /* OK if part of the event data */ + if ((addr >= (unsigned long)iter->ent) && + (addr < (unsigned long)iter->ent + iter->ent_size)) +@@ -3810,142 +3805,69 @@ static bool trace_safe_str(struct trace_iterator *iter, const char *str, + return false; + } + +-static const char *show_buffer(struct trace_seq *s) +-{ +- struct seq_buf *seq = &s->seq; +- +- seq_buf_terminate(seq); +- +- return seq->buffer; +-} +- +-static DEFINE_STATIC_KEY_FALSE(trace_no_verify); +- +-static int test_can_verify_check(const char *fmt, ...) +-{ +- char buf[16]; +- va_list ap; +- int ret; +- +- /* +- * The verifier is dependent on vsnprintf() modifies the va_list +- * passed to it, where it is sent as a reference. Some architectures +- * (like x86_32) passes it by value, which means that vsnprintf() +- * does not modify the va_list passed to it, and the verifier +- * would then need to be able to understand all the values that +- * vsnprintf can use. If it is passed by value, then the verifier +- * is disabled. +- */ +- va_start(ap, fmt); +- vsnprintf(buf, 16, "%d", ap); +- ret = va_arg(ap, int); +- va_end(ap); +- +- return ret; +-} +- +-static void test_can_verify(void) +-{ +- if (!test_can_verify_check("%d %d", 0, 1)) { +- pr_info("trace event string verifier disabled\n"); +- static_branch_inc(&trace_no_verify); +- } +-} +- + /** +- * trace_check_vprintf - Check dereferenced strings while writing to the seq buffer ++ * ignore_event - Check dereferenced fields while writing to the seq buffer + * @iter: The iterator that holds the seq buffer and the event being printed +- * @fmt: The format used to print the event +- * @ap: The va_list holding the data to print from @fmt. + * +- * This writes the data into the @iter->seq buffer using the data from +- * @fmt and @ap. If the format has a %s, then the source of the string +- * is examined to make sure it is safe to print, otherwise it will +- * warn and print "[UNSAFE MEMORY]" in place of the dereferenced string +- * pointer. ++ * At boot up, test_event_printk() will flag any event that dereferences ++ * a string with "%s" that does exist in the ring buffer. It may still ++ * be valid, as the string may point to a static string in the kernel ++ * rodata that never gets freed. But if the string pointer is pointing ++ * to something that was allocated, there's a chance that it can be freed ++ * by the time the user reads the trace. This would cause a bad memory ++ * access by the kernel and possibly crash the system. ++ * ++ * This function will check if the event has any fields flagged as needing ++ * to be checked at runtime and perform those checks. ++ * ++ * If it is found that a field is unsafe, it will write into the @iter->seq ++ * a message stating what was found to be unsafe. ++ * ++ * @return: true if the event is unsafe and should be ignored, ++ * false otherwise. + */ +-void trace_check_vprintf(struct trace_iterator *iter, const char *fmt, +- va_list ap) ++bool ignore_event(struct trace_iterator *iter) + { +- const char *p = fmt; +- const char *str; +- int i, j; ++ struct ftrace_event_field *field; ++ struct trace_event *trace_event; ++ struct trace_event_call *event; ++ struct list_head *head; ++ struct trace_seq *seq; ++ const void *ptr; + +- if (WARN_ON_ONCE(!fmt)) +- return; ++ trace_event = ftrace_find_event(iter->ent->type); + +- if (static_branch_unlikely(&trace_no_verify)) +- goto print; ++ seq = &iter->seq; + +- /* Don't bother checking when doing a ftrace_dump() */ +- if (iter->fmt == static_fmt_buf) +- goto print; ++ if (!trace_event) { ++ trace_seq_printf(seq, "EVENT ID %d NOT FOUND?\n", iter->ent->type); ++ return true; ++ } + +- while (*p) { +- bool star = false; +- int len = 0; +- +- j = 0; +- +- /* We only care about %s and variants */ +- for (i = 0; p[i]; i++) { +- if (i + 1 >= iter->fmt_size) { +- /* +- * If we can't expand the copy buffer, +- * just print it. +- */ +- if (!trace_iter_expand_format(iter)) +- goto print; +- } ++ event = container_of(trace_event, struct trace_event_call, event); ++ if (!(event->flags & TRACE_EVENT_FL_TEST_STR)) ++ return false; + +- if (p[i] == '\\' && p[i+1]) { +- i++; +- continue; +- } +- if (p[i] == '%') { +- /* Need to test cases like %08.*s */ +- for (j = 1; p[i+j]; j++) { +- if (isdigit(p[i+j]) || +- p[i+j] == '.') +- continue; +- if (p[i+j] == '*') { +- star = true; +- continue; +- } +- break; +- } +- if (p[i+j] == 's') +- break; +- star = false; +- } +- j = 0; +- } +- /* If no %s found then just print normally */ +- if (!p[i]) +- break; ++ head = trace_get_fields(event); ++ if (!head) { ++ trace_seq_printf(seq, "FIELDS FOR EVENT '%s' NOT FOUND?\n", ++ trace_event_name(event)); ++ return true; ++ } + +- /* Copy up to the %s, and print that */ +- strncpy(iter->fmt, p, i); +- iter->fmt[i] = '\0'; +- trace_seq_vprintf(&iter->seq, iter->fmt, ap); ++ /* Offsets are from the iter->ent that points to the raw event */ ++ ptr = iter->ent; + +- /* +- * If iter->seq is full, the above call no longer guarantees +- * that ap is in sync with fmt processing, and further calls +- * to va_arg() can return wrong positional arguments. +- * +- * Ensure that ap is no longer used in this case. +- */ +- if (iter->seq.full) { +- p = ""; +- break; +- } ++ list_for_each_entry(field, head, link) { ++ const char *str; ++ bool good; ++ ++ if (!field->needs_test) ++ continue; + +- if (star) +- len = va_arg(ap, int); ++ str = *(const char **)(ptr + field->offset); + +- /* The ap now points to the string data of the %s */ +- str = va_arg(ap, const char *); ++ good = trace_safe_str(iter, str); + + /* + * If you hit this warning, it is likely that the +@@ -3956,45 +3878,14 @@ void trace_check_vprintf(struct trace_iterator *iter, const char *fmt, + * instead. See samples/trace_events/trace-events-sample.h + * for reference. + */ +- if (WARN_ONCE(!trace_safe_str(iter, str, star, len), +- "fmt: '%s' current_buffer: '%s'", +- fmt, show_buffer(&iter->seq))) { +- int ret; +- +- /* Try to safely read the string */ +- if (star) { +- if (len + 1 > iter->fmt_size) +- len = iter->fmt_size - 1; +- if (len < 0) +- len = 0; +- ret = copy_from_kernel_nofault(iter->fmt, str, len); +- iter->fmt[len] = 0; +- star = false; +- } else { +- ret = strncpy_from_kernel_nofault(iter->fmt, str, +- iter->fmt_size); +- } +- if (ret < 0) +- trace_seq_printf(&iter->seq, "(0x%px)", str); +- else +- trace_seq_printf(&iter->seq, "(0x%px:%s)", +- str, iter->fmt); +- str = "[UNSAFE-MEMORY]"; +- strcpy(iter->fmt, "%s"); +- } else { +- strncpy(iter->fmt, p + i, j + 1); +- iter->fmt[j+1] = '\0'; ++ if (WARN_ONCE(!good, "event '%s' has unsafe pointer field '%s'", ++ trace_event_name(event), field->name)) { ++ trace_seq_printf(seq, "EVENT %s: HAS UNSAFE POINTER FIELD '%s'\n", ++ trace_event_name(event), field->name); ++ return true; + } +- if (star) +- trace_seq_printf(&iter->seq, iter->fmt, len, str); +- else +- trace_seq_printf(&iter->seq, iter->fmt, str); +- +- p += i + j + 1; + } +- print: +- if (*p) +- trace_seq_vprintf(&iter->seq, p, ap); ++ return false; + } + + const char *trace_event_format(struct trace_iterator *iter, const char *fmt) +@@ -7011,7 +6902,7 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, + + /* Now copy what we have to the user */ + sret = trace_seq_to_user(&iter->seq, ubuf, cnt); +- if (iter->seq.seq.readpos >= trace_seq_used(&iter->seq)) ++ if (iter->seq.readpos >= trace_seq_used(&iter->seq)) + trace_seq_init(&iter->seq); + + /* +@@ -10539,8 +10430,6 @@ __init static int tracer_alloc_buffers(void) + + register_snapshot_cmd(); + +- test_can_verify(); +- + return 0; + + out_free_pipe_cpumask: +diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h +index 3db42bae73f8e0..e45756f1ac2b12 100644 +--- a/kernel/trace/trace.h ++++ b/kernel/trace/trace.h +@@ -644,9 +644,8 @@ void trace_buffer_unlock_commit_nostack(struct trace_buffer *buffer, + + bool trace_is_tracepoint_string(const char *str); + const char *trace_event_format(struct trace_iterator *iter, const char *fmt); +-void trace_check_vprintf(struct trace_iterator *iter, const char *fmt, +- va_list ap) __printf(2, 0); + char *trace_iter_expand_format(struct trace_iterator *iter); ++bool ignore_event(struct trace_iterator *iter); + + int trace_empty(struct trace_iterator *iter); + +@@ -1323,7 +1322,8 @@ struct ftrace_event_field { + int filter_type; + int offset; + int size; +- int is_signed; ++ unsigned int is_signed:1; ++ unsigned int needs_test:1; + int len; + }; + +diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c +index 64cd856308e77c..9d22745cdea5aa 100644 +--- a/kernel/trace/trace_events.c ++++ b/kernel/trace/trace_events.c +@@ -82,7 +82,7 @@ static int system_refcount_dec(struct event_subsystem *system) + } + + static struct ftrace_event_field * +-__find_event_field(struct list_head *head, char *name) ++__find_event_field(struct list_head *head, const char *name) + { + struct ftrace_event_field *field; + +@@ -114,7 +114,8 @@ trace_find_event_field(struct trace_event_call *call, char *name) + + static int __trace_define_field(struct list_head *head, const char *type, + const char *name, int offset, int size, +- int is_signed, int filter_type, int len) ++ int is_signed, int filter_type, int len, ++ int need_test) + { + struct ftrace_event_field *field; + +@@ -133,6 +134,7 @@ static int __trace_define_field(struct list_head *head, const char *type, + field->offset = offset; + field->size = size; + field->is_signed = is_signed; ++ field->needs_test = need_test; + field->len = len; + + list_add(&field->link, head); +@@ -151,13 +153,13 @@ int trace_define_field(struct trace_event_call *call, const char *type, + + head = trace_get_fields(call); + return __trace_define_field(head, type, name, offset, size, +- is_signed, filter_type, 0); ++ is_signed, filter_type, 0, 0); + } + EXPORT_SYMBOL_GPL(trace_define_field); + + static int trace_define_field_ext(struct trace_event_call *call, const char *type, + const char *name, int offset, int size, int is_signed, +- int filter_type, int len) ++ int filter_type, int len, int need_test) + { + struct list_head *head; + +@@ -166,13 +168,13 @@ static int trace_define_field_ext(struct trace_event_call *call, const char *typ + + head = trace_get_fields(call); + return __trace_define_field(head, type, name, offset, size, +- is_signed, filter_type, len); ++ is_signed, filter_type, len, need_test); + } + + #define __generic_field(type, item, filter_type) \ + ret = __trace_define_field(&ftrace_generic_fields, #type, \ + #item, 0, 0, is_signed_type(type), \ +- filter_type, 0); \ ++ filter_type, 0, 0); \ + if (ret) \ + return ret; + +@@ -181,7 +183,8 @@ static int trace_define_field_ext(struct trace_event_call *call, const char *typ + "common_" #item, \ + offsetof(typeof(ent), item), \ + sizeof(ent.item), \ +- is_signed_type(type), FILTER_OTHER, 0); \ ++ is_signed_type(type), FILTER_OTHER, \ ++ 0, 0); \ + if (ret) \ + return ret; + +@@ -332,6 +335,7 @@ static bool process_pointer(const char *fmt, int len, struct trace_event_call *c + /* Return true if the string is safe */ + static bool process_string(const char *fmt, int len, struct trace_event_call *call) + { ++ struct trace_event_fields *field; + const char *r, *e, *s; + + e = fmt + len; +@@ -360,6 +364,18 @@ static bool process_string(const char *fmt, int len, struct trace_event_call *ca + s = r + 1; + } while (s < e); + ++ /* ++ * Check for arrays. If the argument has: foo[REC->val] ++ * then it is very likely that foo is an array of strings ++ * that are safe to use. ++ */ ++ r = strstr(s, "["); ++ if (r && r < e) { ++ r = strstr(r, "REC->"); ++ if (r && r < e) ++ return true; ++ } ++ + /* + * If there's any strings in the argument consider this arg OK as it + * could be: REC->field ? "foo" : "bar" and we don't want to get into +@@ -372,8 +388,16 @@ static bool process_string(const char *fmt, int len, struct trace_event_call *ca + if (process_pointer(fmt, len, call)) + return true; + +- /* Make sure the field is found, and consider it OK for now if it is */ +- return find_event_field(fmt, call) != NULL; ++ /* Make sure the field is found */ ++ field = find_event_field(fmt, call); ++ if (!field) ++ return false; ++ ++ /* Test this field's string before printing the event */ ++ call->flags |= TRACE_EVENT_FL_TEST_STR; ++ field->needs_test = 1; ++ ++ return true; + } + + /* +@@ -2552,7 +2576,7 @@ event_define_fields(struct trace_event_call *call) + ret = trace_define_field_ext(call, field->type, field->name, + offset, field->size, + field->is_signed, field->filter_type, +- field->len); ++ field->len, field->needs_test); + if (WARN_ON_ONCE(ret)) { + pr_err("error code is %d\n", ret); + break; +diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c +index db575094c49825..2b948d35fb59ea 100644 +--- a/kernel/trace/trace_output.c ++++ b/kernel/trace/trace_output.c +@@ -317,10 +317,14 @@ EXPORT_SYMBOL(trace_raw_output_prep); + + void trace_event_printf(struct trace_iterator *iter, const char *fmt, ...) + { ++ struct trace_seq *s = &iter->seq; + va_list ap; + ++ if (ignore_event(iter)) ++ return; ++ + va_start(ap, fmt); +- trace_check_vprintf(iter, trace_event_format(iter, fmt), ap); ++ trace_seq_vprintf(s, trace_event_format(iter, fmt), ap); + va_end(ap); + } + EXPORT_SYMBOL(trace_event_printf); +diff --git a/kernel/trace/trace_seq.c b/kernel/trace/trace_seq.c +index bac06ee3b98b81..7be97229ddf860 100644 +--- a/kernel/trace/trace_seq.c ++++ b/kernel/trace/trace_seq.c +@@ -370,8 +370,12 @@ EXPORT_SYMBOL_GPL(trace_seq_path); + */ + int trace_seq_to_user(struct trace_seq *s, char __user *ubuf, int cnt) + { ++ int ret; + __trace_seq_init(s); +- return seq_buf_to_user(&s->seq, ubuf, cnt); ++ ret = seq_buf_to_user(&s->seq, ubuf, s->readpos, cnt); ++ if (ret > 0) ++ s->readpos += ret; ++ return ret; + } + EXPORT_SYMBOL_GPL(trace_seq_to_user); + +diff --git a/lib/seq_buf.c b/lib/seq_buf.c +index 45c450f423fa87..23518f77ea9c53 100644 +--- a/lib/seq_buf.c ++++ b/lib/seq_buf.c +@@ -109,9 +109,7 @@ void seq_buf_do_printk(struct seq_buf *s, const char *lvl) + if (s->size == 0 || s->len == 0) + return; + +- seq_buf_terminate(s); +- +- start = s->buffer; ++ start = seq_buf_str(s); + while ((lf = strchr(start, '\n'))) { + int len = lf - start + 1; + +@@ -324,23 +322,24 @@ int seq_buf_path(struct seq_buf *s, const struct path *path, const char *esc) + * seq_buf_to_user - copy the sequence buffer to user space + * @s: seq_buf descriptor + * @ubuf: The userspace memory location to copy to ++ * @start: The first byte in the buffer to copy + * @cnt: The amount to copy + * + * Copies the sequence buffer into the userspace memory pointed to +- * by @ubuf. It starts from the last read position (@s->readpos) +- * and writes up to @cnt characters or till it reaches the end of +- * the content in the buffer (@s->len), which ever comes first. ++ * by @ubuf. It starts from @start and writes up to @cnt characters ++ * or until it reaches the end of the content in the buffer (@s->len), ++ * whichever comes first. + * + * On success, it returns a positive number of the number of bytes + * it copied. + * + * On failure it returns -EBUSY if all of the content in the + * sequence has been already read, which includes nothing in the +- * sequence (@s->len == @s->readpos). ++ * sequence (@s->len == @start). + * + * Returns -EFAULT if the copy to userspace fails. + */ +-int seq_buf_to_user(struct seq_buf *s, char __user *ubuf, int cnt) ++int seq_buf_to_user(struct seq_buf *s, char __user *ubuf, size_t start, int cnt) + { + int len; + int ret; +@@ -350,20 +349,17 @@ int seq_buf_to_user(struct seq_buf *s, char __user *ubuf, int cnt) + + len = seq_buf_used(s); + +- if (len <= s->readpos) ++ if (len <= start) + return -EBUSY; + +- len -= s->readpos; ++ len -= start; + if (cnt > len) + cnt = len; +- ret = copy_to_user(ubuf, s->buffer + s->readpos, cnt); ++ ret = copy_to_user(ubuf, s->buffer + start, cnt); + if (ret == cnt) + return -EFAULT; + +- cnt -= ret; +- +- s->readpos += cnt; +- return cnt; ++ return cnt - ret; + } + + /** +diff --git a/mm/kmemleak.c b/mm/kmemleak.c +index 54c2c90d3abc9d..5811a11cc53a6d 100644 +--- a/mm/kmemleak.c ++++ b/mm/kmemleak.c +@@ -368,7 +368,7 @@ static void print_unreferenced(struct seq_file *seq, + + for (i = 0; i < nr_entries; i++) { + void *ptr = (void *)entries[i]; +- warn_or_seq_printf(seq, " [<%pK>] %pS\n", ptr, ptr); ++ warn_or_seq_printf(seq, " %pS\n", ptr); + } + } + +diff --git a/mm/memblock.c b/mm/memblock.c +index d630f5c2bdb90e..87a2b4340ce4ea 100644 +--- a/mm/memblock.c ++++ b/mm/memblock.c +@@ -735,6 +735,40 @@ int __init_memblock memblock_add(phys_addr_t base, phys_addr_t size) + return memblock_add_range(&memblock.memory, base, size, MAX_NUMNODES, 0); + } + ++/** ++ * memblock_validate_numa_coverage - check if amount of memory with ++ * no node ID assigned is less than a threshold ++ * @threshold_bytes: maximal memory size that can have unassigned node ++ * ID (in bytes). ++ * ++ * A buggy firmware may report memory that does not belong to any node. ++ * Check if amount of such memory is below @threshold_bytes. ++ * ++ * Return: true on success, false on failure. ++ */ ++bool __init_memblock memblock_validate_numa_coverage(unsigned long threshold_bytes) ++{ ++ unsigned long nr_pages = 0; ++ unsigned long start_pfn, end_pfn, mem_size_mb; ++ int nid, i; ++ ++ /* calculate lose page */ ++ for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, &nid) { ++ if (nid == NUMA_NO_NODE) ++ nr_pages += end_pfn - start_pfn; ++ } ++ ++ if ((nr_pages << PAGE_SHIFT) > threshold_bytes) { ++ mem_size_mb = memblock_phys_mem_size() >> 20; ++ pr_err("NUMA: no nodes coverage for %luMB of %luMB RAM\n", ++ (nr_pages << PAGE_SHIFT) >> 20, mem_size_mb); ++ return false; ++ } ++ ++ return true; ++} ++ ++ + /** + * memblock_isolate_range - isolate given range into disjoint memblocks + * @type: memblock type to isolate range for +diff --git a/mm/readahead.c b/mm/readahead.c +index e9b11d928b0c48..f1595c032ce7e3 100644 +--- a/mm/readahead.c ++++ b/mm/readahead.c +@@ -580,7 +580,11 @@ static void ondemand_readahead(struct readahead_control *ractl, + 1UL << order); + if (index == expected || index == (ra->start + ra->size)) { + ra->start += ra->size; +- ra->size = get_next_ra_size(ra, max_pages); ++ /* ++ * In the case of MADV_HUGEPAGE, the actual size might exceed ++ * the readahead window. ++ */ ++ ra->size = max(ra->size, get_next_ra_size(ra, max_pages)); + ra->async_size = ra->size; + goto readit; + } +diff --git a/mm/vmscan.c b/mm/vmscan.c +index 3c91b86d59e935..49456b72575529 100644 +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -641,7 +641,14 @@ unsigned long zone_reclaimable_pages(struct zone *zone) + if (can_reclaim_anon_pages(NULL, zone_to_nid(zone), NULL)) + nr += zone_page_state_snapshot(zone, NR_ZONE_INACTIVE_ANON) + + zone_page_state_snapshot(zone, NR_ZONE_ACTIVE_ANON); +- ++ /* ++ * If there are no reclaimable file-backed or anonymous pages, ++ * ensure zones with sufficient free pages are not skipped. ++ * This prevents zones like DMA32 from being ignored in reclaim ++ * scenarios where they can still help alleviate memory pressure. ++ */ ++ if (nr == 0) ++ nr = zone_page_state_snapshot(zone, NR_FREE_PAGES); + return nr; + } + +diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c +index 6178ae8feafc0f..549ee9e87d6366 100644 +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -2178,13 +2178,9 @@ struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst, + conn->iso_qos.bcast.big); + if (parent && parent != conn) { + link = hci_conn_link(parent, conn); +- if (!link) { +- hci_conn_drop(conn); +- return ERR_PTR(-ENOLINK); +- } +- +- /* Link takes the refcount */ + hci_conn_drop(conn); ++ if (!link) ++ return ERR_PTR(-ENOLINK); + } + + return conn; +@@ -2274,15 +2270,12 @@ struct hci_conn *hci_connect_cis(struct hci_dev *hdev, bdaddr_t *dst, + } + + link = hci_conn_link(le, cis); ++ hci_conn_drop(cis); + if (!link) { + hci_conn_drop(le); +- hci_conn_drop(cis); + return ERR_PTR(-ENOLINK); + } + +- /* Link takes the refcount */ +- hci_conn_drop(cis); +- + cis->state = BT_CONNECT; + + hci_le_create_cis_pending(hdev); +diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c +index 30519d47e8a695..f29fd326440115 100644 +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -58,7 +58,6 @@ DEFINE_RWLOCK(hci_dev_list_lock); + + /* HCI callback list */ + LIST_HEAD(hci_cb_list); +-DEFINE_MUTEX(hci_cb_list_lock); + + /* HCI ID Numbering */ + static DEFINE_IDA(hci_index_ida); +@@ -2957,9 +2956,7 @@ int hci_register_cb(struct hci_cb *cb) + { + BT_DBG("%p name %s", cb, cb->name); + +- mutex_lock(&hci_cb_list_lock); +- list_add_tail(&cb->list, &hci_cb_list); +- mutex_unlock(&hci_cb_list_lock); ++ list_add_tail_rcu(&cb->list, &hci_cb_list); + + return 0; + } +@@ -2969,9 +2966,8 @@ int hci_unregister_cb(struct hci_cb *cb) + { + BT_DBG("%p name %s", cb, cb->name); + +- mutex_lock(&hci_cb_list_lock); +- list_del(&cb->list); +- mutex_unlock(&hci_cb_list_lock); ++ list_del_rcu(&cb->list); ++ synchronize_rcu(); + + return 0; + } +diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c +index b94d202bf3745c..f165cafa3aa98b 100644 +--- a/net/bluetooth/iso.c ++++ b/net/bluetooth/iso.c +@@ -1929,6 +1929,11 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags) + return lm; + } + ++static bool iso_match(struct hci_conn *hcon) ++{ ++ return hcon->type == ISO_LINK || hcon->type == LE_LINK; ++} ++ + static void iso_connect_cfm(struct hci_conn *hcon, __u8 status) + { + if (hcon->type != ISO_LINK) { +@@ -2110,6 +2115,7 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) + + static struct hci_cb iso_cb = { + .name = "ISO", ++ .match = iso_match, + .connect_cfm = iso_connect_cfm, + .disconn_cfm = iso_disconn_cfm, + }; +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index 93651c421767a0..acb148759bd049 100644 +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -7223,6 +7223,11 @@ static struct l2cap_chan *l2cap_global_fixed_chan(struct l2cap_chan *c, + return NULL; + } + ++static bool l2cap_match(struct hci_conn *hcon) ++{ ++ return hcon->type == ACL_LINK || hcon->type == LE_LINK; ++} ++ + static void l2cap_connect_cfm(struct hci_conn *hcon, u8 status) + { + struct hci_dev *hdev = hcon->hdev; +@@ -7230,9 +7235,6 @@ static void l2cap_connect_cfm(struct hci_conn *hcon, u8 status) + struct l2cap_chan *pchan; + u8 dst_type; + +- if (hcon->type != ACL_LINK && hcon->type != LE_LINK) +- return; +- + BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status); + + if (status) { +@@ -7297,9 +7299,6 @@ int l2cap_disconn_ind(struct hci_conn *hcon) + + static void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason) + { +- if (hcon->type != ACL_LINK && hcon->type != LE_LINK) +- return; +- + BT_DBG("hcon %p reason %d", hcon, reason); + + l2cap_conn_del(hcon, bt_to_errno(reason)); +@@ -7578,6 +7577,7 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) + + static struct hci_cb l2cap_cb = { + .name = "L2CAP", ++ .match = l2cap_match, + .connect_cfm = l2cap_connect_cfm, + .disconn_cfm = l2cap_disconn_cfm, + .security_cfm = l2cap_security_cfm, +diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c +index 1d34d849703329..9d46afb24caf07 100644 +--- a/net/bluetooth/rfcomm/core.c ++++ b/net/bluetooth/rfcomm/core.c +@@ -2134,6 +2134,11 @@ static int rfcomm_run(void *unused) + return 0; + } + ++static bool rfcomm_match(struct hci_conn *hcon) ++{ ++ return hcon->type == ACL_LINK; ++} ++ + static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt) + { + struct rfcomm_session *s; +@@ -2180,6 +2185,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt) + + static struct hci_cb rfcomm_cb = { + .name = "RFCOMM", ++ .match = rfcomm_match, + .security_cfm = rfcomm_security_cfm + }; + +diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c +index 64d4d57c7033a3..c4c36ff25fb202 100644 +--- a/net/bluetooth/sco.c ++++ b/net/bluetooth/sco.c +@@ -1353,11 +1353,13 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags) + return lm; + } + +-static void sco_connect_cfm(struct hci_conn *hcon, __u8 status) ++static bool sco_match(struct hci_conn *hcon) + { +- if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) +- return; ++ return hcon->type == SCO_LINK || hcon->type == ESCO_LINK; ++} + ++static void sco_connect_cfm(struct hci_conn *hcon, __u8 status) ++{ + BT_DBG("hcon %p bdaddr %pMR status %u", hcon, &hcon->dst, status); + + if (!status) { +@@ -1372,9 +1374,6 @@ static void sco_connect_cfm(struct hci_conn *hcon, __u8 status) + + static void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason) + { +- if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) +- return; +- + BT_DBG("hcon %p reason %d", hcon, reason); + + sco_conn_del(hcon, bt_to_errno(reason)); +@@ -1400,6 +1399,7 @@ void sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb) + + static struct hci_cb sco_cb = { + .name = "SCO", ++ .match = sco_match, + .connect_cfm = sco_connect_cfm, + .disconn_cfm = sco_disconn_cfm, + }; +diff --git a/net/core/dev.c b/net/core/dev.c +index 4beb9acf2c1839..69da7b009f8b98 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -3628,8 +3628,10 @@ int skb_csum_hwoffload_help(struct sk_buff *skb, + + if (features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)) { + if (vlan_get_protocol(skb) == htons(ETH_P_IPV6) && +- skb_network_header_len(skb) != sizeof(struct ipv6hdr)) ++ skb_network_header_len(skb) != sizeof(struct ipv6hdr) && ++ !ipv6_has_hopopt_jumbo(skb)) + goto sw_checksum; ++ + switch (skb->csum_offset) { + case offsetof(struct tcphdr, check): + case offsetof(struct udphdr, check): +diff --git a/net/core/sock.c b/net/core/sock.c +index bc2a4e38dcea8e..84ba3f67bca97b 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -1133,7 +1133,10 @@ int sk_setsockopt(struct sock *sk, int level, int optname, + sk->sk_reuse = (valbool ? SK_CAN_REUSE : SK_NO_REUSE); + break; + case SO_REUSEPORT: +- sk->sk_reuseport = valbool; ++ if (valbool && !sk_is_inet(sk)) ++ ret = -EOPNOTSUPP; ++ else ++ sk->sk_reuseport = valbool; + break; + case SO_TYPE: + case SO_PROTOCOL: +diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c +index 72b2d68ef4da5f..dd1803bf9c5c63 100644 +--- a/net/ipv4/ip_tunnel.c ++++ b/net/ipv4/ip_tunnel.c +@@ -43,6 +43,7 @@ + #include + #include + #include ++#include + + #if IS_ENABLED(CONFIG_IPV6) + #include +@@ -102,10 +103,9 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, + if (!ip_tunnel_key_match(&t->parms, flags, key)) + continue; + +- if (t->parms.link == link) ++ if (READ_ONCE(t->parms.link) == link) + return t; +- else +- cand = t; ++ cand = t; + } + + hlist_for_each_entry_rcu(t, head, hash_node) { +@@ -117,9 +117,9 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, + if (!ip_tunnel_key_match(&t->parms, flags, key)) + continue; + +- if (t->parms.link == link) ++ if (READ_ONCE(t->parms.link) == link) + return t; +- else if (!cand) ++ if (!cand) + cand = t; + } + +@@ -137,9 +137,9 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, + if (!ip_tunnel_key_match(&t->parms, flags, key)) + continue; + +- if (t->parms.link == link) ++ if (READ_ONCE(t->parms.link) == link) + return t; +- else if (!cand) ++ if (!cand) + cand = t; + } + +@@ -150,9 +150,9 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, + !(t->dev->flags & IFF_UP)) + continue; + +- if (t->parms.link == link) ++ if (READ_ONCE(t->parms.link) == link) + return t; +- else if (!cand) ++ if (!cand) + cand = t; + } + +@@ -221,7 +221,7 @@ static struct ip_tunnel *ip_tunnel_find(struct ip_tunnel_net *itn, + hlist_for_each_entry_rcu(t, head, hash_node) { + if (local == t->parms.iph.saddr && + remote == t->parms.iph.daddr && +- link == t->parms.link && ++ link == READ_ONCE(t->parms.link) && + type == t->dev->type && + ip_tunnel_key_match(&t->parms, flags, key)) + break; +@@ -294,7 +294,7 @@ static int ip_tunnel_bind_dev(struct net_device *dev) + + ip_tunnel_init_flow(&fl4, iph->protocol, iph->daddr, + iph->saddr, tunnel->parms.o_key, +- RT_TOS(iph->tos), dev_net(dev), ++ iph->tos & INET_DSCP_MASK, tunnel->net, + tunnel->parms.link, tunnel->fwmark, 0, 0); + rt = ip_route_output_key(tunnel->net, &fl4); + +@@ -610,9 +610,9 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, + tos = ipv6_get_dsfield((const struct ipv6hdr *)inner_iph); + } + ip_tunnel_init_flow(&fl4, proto, key->u.ipv4.dst, key->u.ipv4.src, +- tunnel_id_to_key32(key->tun_id), RT_TOS(tos), +- dev_net(dev), 0, skb->mark, skb_get_hash(skb), +- key->flow_flags); ++ tunnel_id_to_key32(key->tun_id), ++ tos & INET_DSCP_MASK, tunnel->net, 0, skb->mark, ++ skb_get_hash(skb), key->flow_flags); + + if (!tunnel_hlen) + tunnel_hlen = ip_encap_hlen(&tun_info->encap); +@@ -773,8 +773,8 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, + } + + ip_tunnel_init_flow(&fl4, protocol, dst, tnl_params->saddr, +- tunnel->parms.o_key, RT_TOS(tos), +- dev_net(dev), tunnel->parms.link, ++ tunnel->parms.o_key, tos & INET_DSCP_MASK, ++ tunnel->net, READ_ONCE(tunnel->parms.link), + tunnel->fwmark, skb_get_hash(skb), 0); + + if (ip_tunnel_encap(skb, &tunnel->encap, &protocol, &fl4) < 0) +@@ -894,7 +894,7 @@ static void ip_tunnel_update(struct ip_tunnel_net *itn, + if (t->parms.link != p->link || t->fwmark != fwmark) { + int mtu; + +- t->parms.link = p->link; ++ WRITE_ONCE(t->parms.link, p->link); + t->fwmark = fwmark; + mtu = ip_tunnel_bind_dev(dev); + if (set_mtu) +@@ -1084,9 +1084,9 @@ EXPORT_SYMBOL(ip_tunnel_get_link_net); + + int ip_tunnel_get_iflink(const struct net_device *dev) + { +- struct ip_tunnel *tunnel = netdev_priv(dev); ++ const struct ip_tunnel *tunnel = netdev_priv(dev); + +- return tunnel->parms.link; ++ return READ_ONCE(tunnel->parms.link); + } + EXPORT_SYMBOL(ip_tunnel_get_iflink); + +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index fb053942dba2a1..f6a213bae5cccb 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -7192,6 +7192,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, + if (unlikely(!inet_csk_reqsk_queue_hash_add(sk, req, + req->timeout))) { + reqsk_free(req); ++ dst_release(dst); + return 0; + } + +diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c +index 534a4498e280d7..fff09f5a796a75 100644 +--- a/net/ipv6/ila/ila_xlat.c ++++ b/net/ipv6/ila/ila_xlat.c +@@ -200,6 +200,8 @@ static const struct nf_hook_ops ila_nf_hook_ops[] = { + }, + }; + ++static DEFINE_MUTEX(ila_mutex); ++ + static int ila_add_mapping(struct net *net, struct ila_xlat_params *xp) + { + struct ila_net *ilan = net_generic(net, ila_net_id); +@@ -207,16 +209,20 @@ static int ila_add_mapping(struct net *net, struct ila_xlat_params *xp) + spinlock_t *lock = ila_get_lock(ilan, xp->ip.locator_match); + int err = 0, order; + +- if (!ilan->xlat.hooks_registered) { ++ if (!READ_ONCE(ilan->xlat.hooks_registered)) { + /* We defer registering net hooks in the namespace until the + * first mapping is added. + */ +- err = nf_register_net_hooks(net, ila_nf_hook_ops, +- ARRAY_SIZE(ila_nf_hook_ops)); ++ mutex_lock(&ila_mutex); ++ if (!ilan->xlat.hooks_registered) { ++ err = nf_register_net_hooks(net, ila_nf_hook_ops, ++ ARRAY_SIZE(ila_nf_hook_ops)); ++ if (!err) ++ WRITE_ONCE(ilan->xlat.hooks_registered, true); ++ } ++ mutex_unlock(&ila_mutex); + if (err) + return err; +- +- ilan->xlat.hooks_registered = true; + } + + ila = kzalloc(sizeof(*ila), GFP_KERNEL); +diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c +index 51bccfb00a9cd9..61b0159b2fbee6 100644 +--- a/net/llc/llc_input.c ++++ b/net/llc/llc_input.c +@@ -124,8 +124,8 @@ static inline int llc_fixup_skb(struct sk_buff *skb) + if (unlikely(!pskb_may_pull(skb, llc_len))) + return 0; + +- skb->transport_header += llc_len; + skb_pull(skb, llc_len); ++ skb_reset_transport_header(skb); + if (skb->protocol == htons(ETH_P_802_2)) { + __be16 pdulen; + s32 data_size; +diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h +index daea061d0fc136..04c876d78d3bf0 100644 +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -2057,8 +2057,6 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, + u32 info_flags, + u32 ctrl_flags, + u64 *cookie); +-void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, +- struct sk_buff_head *skbs); + struct sk_buff * + ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb, u32 info_flags); +diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c +index 25223184d6e5b0..a5e7edd2f2d137 100644 +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -1173,14 +1173,14 @@ void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata, + u64 changed) + { + struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; +- unsigned long bits = changed; ++ unsigned long bits[] = { BITMAP_FROM_U64(changed) }; + u32 bit; + +- if (!bits) ++ if (!changed) + return; + + /* if we race with running work, worst case this work becomes a noop */ +- for_each_set_bit(bit, &bits, sizeof(changed) * BITS_PER_BYTE) ++ for_each_set_bit(bit, bits, sizeof(changed) * BITS_PER_BYTE) + set_bit(bit, ifmsh->mbss_changed); + set_bit(MESH_WORK_MBSS_CHANGED, &ifmsh->wrkq_flags); + wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); +diff --git a/net/mac80211/status.c b/net/mac80211/status.c +index 44d83da60aee44..9676ed15efecc8 100644 +--- a/net/mac80211/status.c ++++ b/net/mac80211/status.c +@@ -1270,3 +1270,4 @@ void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, + while ((skb = __skb_dequeue(skbs))) + ieee80211_free_txskb(hw, skb); + } ++EXPORT_SYMBOL(ieee80211_purge_tx_queue); +diff --git a/net/mac80211/util.c b/net/mac80211/util.c +index d682c32821a110..154b41af4157d0 100644 +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -827,7 +827,8 @@ static void __iterate_stations(struct ieee80211_local *local, + { + struct sta_info *sta; + +- list_for_each_entry_rcu(sta, &local->sta_list, list) { ++ list_for_each_entry_rcu(sta, &local->sta_list, list, ++ lockdep_is_held(&local->hw.wiphy->mtx)) { + if (!sta->uploaded) + continue; + +@@ -848,6 +849,19 @@ void ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw, + } + EXPORT_SYMBOL_GPL(ieee80211_iterate_stations_atomic); + ++void ieee80211_iterate_stations_mtx(struct ieee80211_hw *hw, ++ void (*iterator)(void *data, ++ struct ieee80211_sta *sta), ++ void *data) ++{ ++ struct ieee80211_local *local = hw_to_local(hw); ++ ++ lockdep_assert_wiphy(local->hw.wiphy); ++ ++ __iterate_stations(local, iterator, data); ++} ++EXPORT_SYMBOL_GPL(ieee80211_iterate_stations_mtx); ++ + struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev) + { + struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); +@@ -2572,6 +2586,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) + WARN(1, "Hardware became unavailable upon resume. This could be a software issue prior to suspend or a hardware issue.\n"); + else + WARN(1, "Hardware became unavailable during restart.\n"); ++ ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP, ++ IEEE80211_QUEUE_STOP_REASON_SUSPEND, ++ false); + ieee80211_handle_reconfig_failure(local); + return res; + } +diff --git a/net/mctp/route.c b/net/mctp/route.c +index c6a815df9d358c..d3c1f54386efc1 100644 +--- a/net/mctp/route.c ++++ b/net/mctp/route.c +@@ -334,8 +334,13 @@ static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb) + msk = NULL; + rc = -EINVAL; + +- /* we may be receiving a locally-routed packet; drop source sk +- * accounting ++ /* We may be receiving a locally-routed packet; drop source sk ++ * accounting. ++ * ++ * From here, we will either queue the skb - either to a frag_queue, or ++ * to a receiving socket. When that succeeds, we clear the skb pointer; ++ * a non-NULL skb on exit will be otherwise unowned, and hence ++ * kfree_skb()-ed. + */ + skb_orphan(skb); + +@@ -389,7 +394,9 @@ static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb) + * pending key. + */ + if (flags & MCTP_HDR_FLAG_EOM) { +- sock_queue_rcv_skb(&msk->sk, skb); ++ rc = sock_queue_rcv_skb(&msk->sk, skb); ++ if (!rc) ++ skb = NULL; + if (key) { + /* we've hit a pending reassembly; not much we + * can do but drop it +@@ -398,7 +405,6 @@ static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb) + MCTP_TRACE_KEY_REPLIED); + key = NULL; + } +- rc = 0; + goto out_unlock; + } + +@@ -425,8 +431,10 @@ static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb) + * this function. + */ + rc = mctp_key_add(key, msk); +- if (!rc) ++ if (!rc) { + trace_mctp_key_acquire(key); ++ skb = NULL; ++ } + + /* we don't need to release key->lock on exit, so + * clean up here and suppress the unlock via +@@ -444,6 +452,8 @@ static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb) + key = NULL; + } else { + rc = mctp_frag_queue(key, skb); ++ if (!rc) ++ skb = NULL; + } + } + +@@ -458,12 +468,19 @@ static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb) + else + rc = mctp_frag_queue(key, skb); + ++ if (rc) ++ goto out_unlock; ++ ++ /* we've queued; the queue owns the skb now */ ++ skb = NULL; ++ + /* end of message? deliver to socket, and we're done with + * the reassembly/response key + */ +- if (!rc && flags & MCTP_HDR_FLAG_EOM) { +- sock_queue_rcv_skb(key->sk, key->reasm_head); +- key->reasm_head = NULL; ++ if (flags & MCTP_HDR_FLAG_EOM) { ++ rc = sock_queue_rcv_skb(key->sk, key->reasm_head); ++ if (!rc) ++ key->reasm_head = NULL; + __mctp_key_done_in(key, net, f, MCTP_TRACE_KEY_REPLIED); + key = NULL; + } +@@ -482,8 +499,7 @@ static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb) + if (any_key) + mctp_key_unref(any_key); + out: +- if (rc) +- kfree_skb(skb); ++ kfree_skb(skb); + return rc; + } + +diff --git a/net/mptcp/options.c b/net/mptcp/options.c +index 2ad9006a157aef..2e1539027e6d33 100644 +--- a/net/mptcp/options.c ++++ b/net/mptcp/options.c +@@ -667,8 +667,15 @@ static bool mptcp_established_options_add_addr(struct sock *sk, struct sk_buff * + &echo, &drop_other_suboptions)) + return false; + ++ /* ++ * Later on, mptcp_write_options() will enforce mutually exclusion with ++ * DSS, bail out if such option is set and we can't drop it. ++ */ + if (drop_other_suboptions) + remaining += opt_size; ++ else if (opts->suboptions & OPTION_MPTCP_DSS) ++ return false; ++ + len = mptcp_add_addr_len(opts->addr.family, echo, !!opts->addr.port); + if (remaining < len) + return false; +diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c +index 01f6ce970918c5..07f3a9703312e5 100644 +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -528,13 +528,13 @@ static void mptcp_send_ack(struct mptcp_sock *msk) + mptcp_subflow_send_ack(mptcp_subflow_tcp_sock(subflow)); + } + +-static void mptcp_subflow_cleanup_rbuf(struct sock *ssk) ++static void mptcp_subflow_cleanup_rbuf(struct sock *ssk, int copied) + { + bool slow; + + slow = lock_sock_fast(ssk); + if (tcp_can_send_ack(ssk)) +- tcp_cleanup_rbuf(ssk, 1); ++ tcp_cleanup_rbuf(ssk, copied); + unlock_sock_fast(ssk, slow); + } + +@@ -551,7 +551,7 @@ static bool mptcp_subflow_could_cleanup(const struct sock *ssk, bool rx_empty) + (ICSK_ACK_PUSHED2 | ICSK_ACK_PUSHED))); + } + +-static void mptcp_cleanup_rbuf(struct mptcp_sock *msk) ++static void mptcp_cleanup_rbuf(struct mptcp_sock *msk, int copied) + { + int old_space = READ_ONCE(msk->old_wspace); + struct mptcp_subflow_context *subflow; +@@ -559,14 +559,14 @@ static void mptcp_cleanup_rbuf(struct mptcp_sock *msk) + int space = __mptcp_space(sk); + bool cleanup, rx_empty; + +- cleanup = (space > 0) && (space >= (old_space << 1)); +- rx_empty = !__mptcp_rmem(sk); ++ cleanup = (space > 0) && (space >= (old_space << 1)) && copied; ++ rx_empty = !__mptcp_rmem(sk) && copied; + + mptcp_for_each_subflow(msk, subflow) { + struct sock *ssk = mptcp_subflow_tcp_sock(subflow); + + if (cleanup || mptcp_subflow_could_cleanup(ssk, rx_empty)) +- mptcp_subflow_cleanup_rbuf(ssk); ++ mptcp_subflow_cleanup_rbuf(ssk, copied); + } + } + +@@ -1902,6 +1902,8 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + goto out; + } + ++static void mptcp_rcv_space_adjust(struct mptcp_sock *msk, int copied); ++ + static int __mptcp_recvmsg_mskq(struct mptcp_sock *msk, + struct msghdr *msg, + size_t len, int flags, +@@ -1955,6 +1957,7 @@ static int __mptcp_recvmsg_mskq(struct mptcp_sock *msk, + break; + } + ++ mptcp_rcv_space_adjust(msk, copied); + return copied; + } + +@@ -2180,9 +2183,6 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, + + copied += bytes_read; + +- /* be sure to advertise window change */ +- mptcp_cleanup_rbuf(msk); +- + if (skb_queue_empty(&msk->receive_queue) && __mptcp_move_skbs(msk)) + continue; + +@@ -2231,7 +2231,7 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, + } + + pr_debug("block timeout %ld\n", timeo); +- mptcp_rcv_space_adjust(msk, copied); ++ mptcp_cleanup_rbuf(msk, copied); + err = sk_wait_data(sk, &timeo, NULL); + if (err < 0) { + err = copied ? : err; +@@ -2239,7 +2239,7 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, + } + } + +- mptcp_rcv_space_adjust(msk, copied); ++ mptcp_cleanup_rbuf(msk, copied); + + out_err: + if (cmsg_flags && copied >= 0) { +diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c +index bd2b17b219ae90..0b270893ee14c5 100644 +--- a/net/netrom/nr_route.c ++++ b/net/netrom/nr_route.c +@@ -754,6 +754,12 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25) + int ret; + struct sk_buff *skbn; + ++ /* ++ * Reject malformed packets early. Check that it contains at least 2 ++ * addresses and 1 byte more for Time-To-Live ++ */ ++ if (skb->len < 2 * sizeof(ax25_address) + 1) ++ return 0; + + nr_src = (ax25_address *)(skb->data + 0); + nr_dest = (ax25_address *)(skb->data + 7); +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 56e3ae3b6be93f..4abf7e9ac4f2f7 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -538,10 +538,8 @@ static void *packet_current_frame(struct packet_sock *po, + return packet_lookup_frame(po, rb, rb->head, status); + } + +-static u16 vlan_get_tci(struct sk_buff *skb, struct net_device *dev) ++static u16 vlan_get_tci(const struct sk_buff *skb, struct net_device *dev) + { +- u8 *skb_orig_data = skb->data; +- int skb_orig_len = skb->len; + struct vlan_hdr vhdr, *vh; + unsigned int header_len; + +@@ -562,33 +560,21 @@ static u16 vlan_get_tci(struct sk_buff *skb, struct net_device *dev) + else + return 0; + +- skb_push(skb, skb->data - skb_mac_header(skb)); +- vh = skb_header_pointer(skb, header_len, sizeof(vhdr), &vhdr); +- if (skb_orig_data != skb->data) { +- skb->data = skb_orig_data; +- skb->len = skb_orig_len; +- } ++ vh = skb_header_pointer(skb, skb_mac_offset(skb) + header_len, ++ sizeof(vhdr), &vhdr); + if (unlikely(!vh)) + return 0; + + return ntohs(vh->h_vlan_TCI); + } + +-static __be16 vlan_get_protocol_dgram(struct sk_buff *skb) ++static __be16 vlan_get_protocol_dgram(const struct sk_buff *skb) + { + __be16 proto = skb->protocol; + +- if (unlikely(eth_type_vlan(proto))) { +- u8 *skb_orig_data = skb->data; +- int skb_orig_len = skb->len; +- +- skb_push(skb, skb->data - skb_mac_header(skb)); +- proto = __vlan_get_protocol(skb, proto, NULL); +- if (skb_orig_data != skb->data) { +- skb->data = skb_orig_data; +- skb->len = skb_orig_len; +- } +- } ++ if (unlikely(eth_type_vlan(proto))) ++ proto = __vlan_get_protocol_offset(skb, proto, ++ skb_mac_offset(skb), NULL); + + return proto; + } +diff --git a/net/sctp/associola.c b/net/sctp/associola.c +index c45c192b787873..0b0794f164cf2e 100644 +--- a/net/sctp/associola.c ++++ b/net/sctp/associola.c +@@ -137,7 +137,8 @@ static struct sctp_association *sctp_association_init( + = 5 * asoc->rto_max; + + asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay; +- asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = sp->autoclose * HZ; ++ asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = ++ (unsigned long)sp->autoclose * HZ; + + /* Initializes the timers */ + for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i) +diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c +index efbb4836ec668f..ea498eff1f2ae5 100644 +--- a/scripts/mod/file2alias.c ++++ b/scripts/mod/file2alias.c +@@ -742,8 +742,8 @@ static void do_input(char *alias, + + for (i = min / BITS_PER_LONG; i < max / BITS_PER_LONG + 1; i++) + arr[i] = TO_NATIVE(arr[i]); +- for (i = min; i < max; i++) +- if (arr[i / BITS_PER_LONG] & (1L << (i%BITS_PER_LONG))) ++ for (i = min; i <= max; i++) ++ if (arr[i / BITS_PER_LONG] & (1ULL << (i%BITS_PER_LONG))) + sprintf(alias + strlen(alias), "%X,*", i); + } + +diff --git a/scripts/sorttable.h b/scripts/sorttable.h +index 7bd0184380d3b9..a7c5445baf0027 100644 +--- a/scripts/sorttable.h ++++ b/scripts/sorttable.h +@@ -110,7 +110,7 @@ static inline unsigned long orc_ip(const int *ip) + + static int orc_sort_cmp(const void *_a, const void *_b) + { +- struct orc_entry *orc_a; ++ struct orc_entry *orc_a, *orc_b; + const int *a = g_orc_ip_table + *(int *)_a; + const int *b = g_orc_ip_table + *(int *)_b; + unsigned long a_val = orc_ip(a); +@@ -128,6 +128,9 @@ static int orc_sort_cmp(const void *_a, const void *_b) + * whitelisted .o files which didn't get objtool generation. + */ + orc_a = g_orc_table + (a - g_orc_ip_table); ++ orc_b = g_orc_table + (b - g_orc_ip_table); ++ if (orc_a->type == ORC_TYPE_UNDEFINED && orc_b->type == ORC_TYPE_UNDEFINED) ++ return 0; + return orc_a->type == ORC_TYPE_UNDEFINED ? -1 : 1; + } + +diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c +index 379ac7b5c7098c..f5eead8af2e210 100644 +--- a/security/selinux/ss/services.c ++++ b/security/selinux/ss/services.c +@@ -956,7 +956,10 @@ void services_compute_xperms_decision(struct extended_perms_decision *xpermd, + xpermd->driver)) + return; + } else { +- BUG(); ++ pr_warn_once( ++ "SELinux: unknown extended permission (%u) will be ignored\n", ++ node->datum.u.xperms->specified); ++ return; + } + + if (node->key.specified == AVTAB_XPERMS_ALLOWED) { +@@ -993,7 +996,8 @@ void services_compute_xperms_decision(struct extended_perms_decision *xpermd, + node->datum.u.xperms->perms.p[i]; + } + } else { +- BUG(); ++ pr_warn_once("SELinux: unknown specified key (%u)\n", ++ node->key.specified); + } + } + +diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c +index e3394919daa09a..51ee4c00a84310 100644 +--- a/sound/core/seq/oss/seq_oss_synth.c ++++ b/sound/core/seq/oss/seq_oss_synth.c +@@ -66,6 +66,7 @@ static struct seq_oss_synth midi_synth_dev = { + }; + + static DEFINE_SPINLOCK(register_lock); ++static DEFINE_MUTEX(sysex_mutex); + + /* + * prototypes +@@ -497,6 +498,7 @@ snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf, + if (!info) + return -ENXIO; + ++ guard(mutex)(&sysex_mutex); + sysex = info->sysex; + if (sysex == NULL) { + sysex = kzalloc(sizeof(*sysex), GFP_KERNEL); +diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c +index e115fe18363495..8b7dfbc8e82075 100644 +--- a/sound/core/seq/seq_clientmgr.c ++++ b/sound/core/seq/seq_clientmgr.c +@@ -1280,10 +1280,16 @@ static int snd_seq_ioctl_set_client_info(struct snd_seq_client *client, + if (client->type != client_info->type) + return -EINVAL; + +- /* check validity of midi_version field */ +- if (client->user_pversion >= SNDRV_PROTOCOL_VERSION(1, 0, 3) && +- client_info->midi_version > SNDRV_SEQ_CLIENT_UMP_MIDI_2_0) +- return -EINVAL; ++ if (client->user_pversion >= SNDRV_PROTOCOL_VERSION(1, 0, 3)) { ++ /* check validity of midi_version field */ ++ if (client_info->midi_version > SNDRV_SEQ_CLIENT_UMP_MIDI_2_0) ++ return -EINVAL; ++ ++ /* check if UMP is supported in kernel */ ++ if (!IS_ENABLED(CONFIG_SND_SEQ_UMP) && ++ client_info->midi_version > 0) ++ return -EINVAL; ++ } + + /* fill the info fields */ + if (client_info->name[0]) +diff --git a/sound/core/ump.c b/sound/core/ump.c +index 83856b2f88b89f..32d27e58416aa3 100644 +--- a/sound/core/ump.c ++++ b/sound/core/ump.c +@@ -37,6 +37,7 @@ static int process_legacy_output(struct snd_ump_endpoint *ump, + u32 *buffer, int count); + static void process_legacy_input(struct snd_ump_endpoint *ump, const u32 *src, + int words); ++static void update_legacy_names(struct snd_ump_endpoint *ump); + #else + static inline int process_legacy_output(struct snd_ump_endpoint *ump, + u32 *buffer, int count) +@@ -47,6 +48,9 @@ static inline void process_legacy_input(struct snd_ump_endpoint *ump, + const u32 *src, int words) + { + } ++static inline void update_legacy_names(struct snd_ump_endpoint *ump) ++{ ++} + #endif + + static const struct snd_rawmidi_global_ops snd_ump_rawmidi_ops = { +@@ -850,6 +854,7 @@ static int ump_handle_fb_info_msg(struct snd_ump_endpoint *ump, + fill_fb_info(ump, &fb->info, buf); + if (ump->parsed) { + snd_ump_update_group_attrs(ump); ++ update_legacy_names(ump); + seq_notify_fb_change(ump, fb); + } + } +@@ -882,6 +887,7 @@ static int ump_handle_fb_name_msg(struct snd_ump_endpoint *ump, + /* notify the FB name update to sequencer, too */ + if (ret > 0 && ump->parsed) { + snd_ump_update_group_attrs(ump); ++ update_legacy_names(ump); + seq_notify_fb_change(ump, fb); + } + return ret; +@@ -1076,13 +1082,13 @@ static int snd_ump_legacy_open(struct snd_rawmidi_substream *substream) + struct snd_ump_endpoint *ump = substream->rmidi->private_data; + int dir = substream->stream; + int group = ump->legacy_mapping[substream->number]; +- int err = 0; ++ int err; + +- mutex_lock(&ump->open_mutex); +- if (ump->legacy_substreams[dir][group]) { +- err = -EBUSY; +- goto unlock; +- } ++ guard(mutex)(&ump->open_mutex); ++ if (ump->legacy_substreams[dir][group]) ++ return -EBUSY; ++ if (!ump->groups[group].active) ++ return -ENODEV; + if (dir == SNDRV_RAWMIDI_STREAM_OUTPUT) { + if (!ump->legacy_out_opens) { + err = snd_rawmidi_kernel_open(&ump->core, 0, +@@ -1090,17 +1096,14 @@ static int snd_ump_legacy_open(struct snd_rawmidi_substream *substream) + SNDRV_RAWMIDI_LFLG_APPEND, + &ump->legacy_out_rfile); + if (err < 0) +- goto unlock; ++ return err; + } + ump->legacy_out_opens++; + snd_ump_convert_reset(&ump->out_cvts[group]); + } +- spin_lock_irq(&ump->legacy_locks[dir]); ++ guard(spinlock_irq)(&ump->legacy_locks[dir]); + ump->legacy_substreams[dir][group] = substream; +- spin_unlock_irq(&ump->legacy_locks[dir]); +- unlock: +- mutex_unlock(&ump->open_mutex); +- return err; ++ return 0; + } + + static int snd_ump_legacy_close(struct snd_rawmidi_substream *substream) +@@ -1109,15 +1112,13 @@ static int snd_ump_legacy_close(struct snd_rawmidi_substream *substream) + int dir = substream->stream; + int group = ump->legacy_mapping[substream->number]; + +- mutex_lock(&ump->open_mutex); +- spin_lock_irq(&ump->legacy_locks[dir]); +- ump->legacy_substreams[dir][group] = NULL; +- spin_unlock_irq(&ump->legacy_locks[dir]); ++ guard(mutex)(&ump->open_mutex); ++ scoped_guard(spinlock_irq, &ump->legacy_locks[dir]) ++ ump->legacy_substreams[dir][group] = NULL; + if (dir == SNDRV_RAWMIDI_STREAM_OUTPUT) { + if (!--ump->legacy_out_opens) + snd_rawmidi_kernel_release(&ump->legacy_out_rfile); + } +- mutex_unlock(&ump->open_mutex); + return 0; + } + +@@ -1169,12 +1170,11 @@ static int process_legacy_output(struct snd_ump_endpoint *ump, + const int dir = SNDRV_RAWMIDI_STREAM_OUTPUT; + unsigned char c; + int group, size = 0; +- unsigned long flags; + + if (!ump->out_cvts || !ump->legacy_out_opens) + return 0; + +- spin_lock_irqsave(&ump->legacy_locks[dir], flags); ++ guard(spinlock_irqsave)(&ump->legacy_locks[dir]); + for (group = 0; group < SNDRV_UMP_MAX_GROUPS; group++) { + substream = ump->legacy_substreams[dir][group]; + if (!substream) +@@ -1190,7 +1190,6 @@ static int process_legacy_output(struct snd_ump_endpoint *ump, + break; + } + } +- spin_unlock_irqrestore(&ump->legacy_locks[dir], flags); + return size; + } + +@@ -1200,18 +1199,16 @@ static void process_legacy_input(struct snd_ump_endpoint *ump, const u32 *src, + struct snd_rawmidi_substream *substream; + unsigned char buf[16]; + unsigned char group; +- unsigned long flags; + const int dir = SNDRV_RAWMIDI_STREAM_INPUT; + int size; + + size = snd_ump_convert_from_ump(src, buf, &group); + if (size <= 0) + return; +- spin_lock_irqsave(&ump->legacy_locks[dir], flags); ++ guard(spinlock_irqsave)(&ump->legacy_locks[dir]); + substream = ump->legacy_substreams[dir][group]; + if (substream) + snd_rawmidi_receive(substream, buf, size); +- spin_unlock_irqrestore(&ump->legacy_locks[dir], flags); + } + + /* Fill ump->legacy_mapping[] for groups to be used for legacy rawmidi */ +@@ -1254,11 +1251,20 @@ static void fill_substream_names(struct snd_ump_endpoint *ump, + name = ump->groups[idx].name; + if (!*name) + name = ump->info.name; +- snprintf(s->name, sizeof(s->name), "Group %d (%.16s)", +- idx + 1, name); ++ scnprintf(s->name, sizeof(s->name), "Group %d (%.16s)%s", ++ idx + 1, name, ++ ump->groups[idx].active ? "" : " [Inactive]"); + } + } + ++static void update_legacy_names(struct snd_ump_endpoint *ump) ++{ ++ struct snd_rawmidi *rmidi = ump->legacy_rmidi; ++ ++ fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_INPUT); ++ fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT); ++} ++ + int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump, + char *id, int device) + { +@@ -1295,10 +1301,7 @@ int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump, + rmidi->ops = &snd_ump_legacy_ops; + rmidi->private_data = ump; + ump->legacy_rmidi = rmidi; +- if (input) +- fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_INPUT); +- if (output) +- fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT); ++ update_legacy_names(ump); + + ump_dbg(ump, "Created a legacy rawmidi #%d (%s)\n", device, id); + return 0; +diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c +index 748a3c40966e97..27e48fdbbf3aa0 100644 +--- a/sound/pci/hda/patch_ca0132.c ++++ b/sound/pci/hda/patch_ca0132.c +@@ -1134,7 +1134,6 @@ struct ca0132_spec { + + struct hda_codec *codec; + struct delayed_work unsol_hp_work; +- int quirk; + + #ifdef ENABLE_TUNING_CONTROLS + long cur_ctl_vals[TUNING_CTLS_COUNT]; +@@ -1166,7 +1165,6 @@ struct ca0132_spec { + * CA0132 quirks table + */ + enum { +- QUIRK_NONE, + QUIRK_ALIENWARE, + QUIRK_ALIENWARE_M17XR4, + QUIRK_SBZ, +@@ -1176,10 +1174,11 @@ enum { + QUIRK_R3D, + QUIRK_AE5, + QUIRK_AE7, ++ QUIRK_NONE = HDA_FIXUP_ID_NOT_SET, + }; + + #ifdef CONFIG_PCI +-#define ca0132_quirk(spec) ((spec)->quirk) ++#define ca0132_quirk(spec) ((spec)->codec->fixup_id) + #define ca0132_use_pci_mmio(spec) ((spec)->use_pci_mmio) + #define ca0132_use_alt_functions(spec) ((spec)->use_alt_functions) + #define ca0132_use_alt_controls(spec) ((spec)->use_alt_controls) +@@ -1293,7 +1292,7 @@ static const struct hda_pintbl ae7_pincfgs[] = { + {} + }; + +-static const struct snd_pci_quirk ca0132_quirks[] = { ++static const struct hda_quirk ca0132_quirks[] = { + SND_PCI_QUIRK(0x1028, 0x057b, "Alienware M17x R4", QUIRK_ALIENWARE_M17XR4), + SND_PCI_QUIRK(0x1028, 0x0685, "Alienware 15 2015", QUIRK_ALIENWARE), + SND_PCI_QUIRK(0x1028, 0x0688, "Alienware 17 2015", QUIRK_ALIENWARE), +@@ -1316,6 +1315,19 @@ static const struct snd_pci_quirk ca0132_quirks[] = { + {} + }; + ++static const struct hda_model_fixup ca0132_quirk_models[] = { ++ { .id = QUIRK_ALIENWARE, .name = "alienware" }, ++ { .id = QUIRK_ALIENWARE_M17XR4, .name = "alienware-m17xr4" }, ++ { .id = QUIRK_SBZ, .name = "sbz" }, ++ { .id = QUIRK_ZXR, .name = "zxr" }, ++ { .id = QUIRK_ZXR_DBPRO, .name = "zxr-dbpro" }, ++ { .id = QUIRK_R3DI, .name = "r3di" }, ++ { .id = QUIRK_R3D, .name = "r3d" }, ++ { .id = QUIRK_AE5, .name = "ae5" }, ++ { .id = QUIRK_AE7, .name = "ae7" }, ++ {} ++}; ++ + /* Output selection quirk info structures. */ + #define MAX_QUIRK_MMIO_GPIO_SET_VALS 3 + #define MAX_QUIRK_SCP_SET_VALS 2 +@@ -9962,17 +9974,15 @@ static int ca0132_prepare_verbs(struct hda_codec *codec) + */ + static void sbz_detect_quirk(struct hda_codec *codec) + { +- struct ca0132_spec *spec = codec->spec; +- + switch (codec->core.subsystem_id) { + case 0x11020033: +- spec->quirk = QUIRK_ZXR; ++ codec->fixup_id = QUIRK_ZXR; + break; + case 0x1102003f: +- spec->quirk = QUIRK_ZXR_DBPRO; ++ codec->fixup_id = QUIRK_ZXR_DBPRO; + break; + default: +- spec->quirk = QUIRK_SBZ; ++ codec->fixup_id = QUIRK_SBZ; + break; + } + } +@@ -9981,7 +9991,6 @@ static int patch_ca0132(struct hda_codec *codec) + { + struct ca0132_spec *spec; + int err; +- const struct snd_pci_quirk *quirk; + + codec_dbg(codec, "patch_ca0132\n"); + +@@ -9992,11 +10001,7 @@ static int patch_ca0132(struct hda_codec *codec) + spec->codec = codec; + + /* Detect codec quirk */ +- quirk = snd_pci_quirk_lookup(codec->bus->pci, ca0132_quirks); +- if (quirk) +- spec->quirk = quirk->value; +- else +- spec->quirk = QUIRK_NONE; ++ snd_hda_pick_fixup(codec, ca0132_quirk_models, ca0132_quirks, NULL); + if (ca0132_quirk(spec) == QUIRK_SBZ) + sbz_detect_quirk(codec); + +@@ -10073,7 +10078,7 @@ static int patch_ca0132(struct hda_codec *codec) + spec->mem_base = pci_iomap(codec->bus->pci, 2, 0xC20); + if (spec->mem_base == NULL) { + codec_warn(codec, "pci_iomap failed! Setting quirk to QUIRK_NONE."); +- spec->quirk = QUIRK_NONE; ++ codec->fixup_id = QUIRK_NONE; + } + } + #endif +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 29d7eb8c6bec3e..fc93af80f0bffe 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -10443,6 +10443,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0xf111, 0x0001, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0xf111, 0x0006, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0xf111, 0x0009, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE), ++ SND_PCI_QUIRK(0xf111, 0x000c, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE), + + #if 0 + /* Below is a quirk table taken from the old code. +@@ -10631,6 +10632,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = { + {.id = ALC255_FIXUP_ACER_HEADPHONE_AND_MIC, .name = "alc255-acer-headphone-and-mic"}, + {.id = ALC285_FIXUP_HP_GPIO_AMP_INIT, .name = "alc285-hp-amp-init"}, + {.id = ALC236_FIXUP_LENOVO_INV_DMIC, .name = "alc236-fixup-lenovo-inv-mic"}, ++ {.id = ALC2XX_FIXUP_HEADSET_MIC, .name = "alc2xx-fixup-headset-mic"}, + {} + }; + #define ALC225_STANDARD_PINS \ +diff --git a/sound/usb/format.c b/sound/usb/format.c +index 3b45d0ee769389..3b3a5ea6fcbfc0 100644 +--- a/sound/usb/format.c ++++ b/sound/usb/format.c +@@ -60,6 +60,8 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip, + pcm_formats |= SNDRV_PCM_FMTBIT_SPECIAL; + /* flag potentially raw DSD capable altsettings */ + fp->dsd_raw = true; ++ /* clear special format bit to avoid "unsupported format" msg below */ ++ format &= ~UAC2_FORMAT_TYPE_I_RAW_DATA; + } + + format <<= 1; +@@ -71,8 +73,11 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip, + sample_width = as->bBitResolution; + sample_bytes = as->bSubslotSize; + +- if (format & UAC3_FORMAT_TYPE_I_RAW_DATA) ++ if (format & UAC3_FORMAT_TYPE_I_RAW_DATA) { + pcm_formats |= SNDRV_PCM_FMTBIT_SPECIAL; ++ /* clear special format bit to avoid "unsupported format" msg below */ ++ format &= ~UAC3_FORMAT_TYPE_I_RAW_DATA; ++ } + + format <<= 1; + break; +diff --git a/sound/usb/mixer_us16x08.c b/sound/usb/mixer_us16x08.c +index 6eb7d93b358d99..20ac32635f1f50 100644 +--- a/sound/usb/mixer_us16x08.c ++++ b/sound/usb/mixer_us16x08.c +@@ -687,7 +687,7 @@ static int snd_us16x08_meter_get(struct snd_kcontrol *kcontrol, + struct usb_mixer_elem_info *elem = kcontrol->private_data; + struct snd_usb_audio *chip = elem->head.mixer->chip; + struct snd_us16x08_meter_store *store = elem->private_data; +- u8 meter_urb[64]; ++ u8 meter_urb[64] = {0}; + + switch (kcontrol->private_value) { + case 0: { +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index 8eed8d9742fda9..ec81b47c41c9ea 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -2225,6 +2225,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_DSD_RAW), + DEVICE_FLG(0x2522, 0x0007, /* LH Labs Geek Out HD Audio 1V5 */ + QUIRK_FLAG_SET_IFACE_FIRST), ++ DEVICE_FLG(0x262a, 0x9302, /* ddHiFi TC44C */ ++ QUIRK_FLAG_DSD_RAW), + DEVICE_FLG(0x2708, 0x0002, /* Audient iD14 */ + QUIRK_FLAG_IGNORE_CTL_ERROR), + DEVICE_FLG(0x2912, 0x30c8, /* Audioengine D1 */ +diff --git a/tools/testing/selftests/bpf/progs/verifier_subprog_precision.c b/tools/testing/selftests/bpf/progs/verifier_subprog_precision.c +index f87365f7599bf7..f61d623b1ce8df 100644 +--- a/tools/testing/selftests/bpf/progs/verifier_subprog_precision.c ++++ b/tools/testing/selftests/bpf/progs/verifier_subprog_precision.c +@@ -541,24 +541,11 @@ static __u64 subprog_spill_reg_precise(void) + + SEC("?raw_tp") + __success __log_level(2) +-__msg("10: (0f) r1 += r7") +-__msg("mark_precise: frame0: last_idx 10 first_idx 7 subseq_idx -1") +-__msg("mark_precise: frame0: regs=r7 stack= before 9: (bf) r1 = r8") +-__msg("mark_precise: frame0: regs=r7 stack= before 8: (27) r7 *= 4") +-__msg("mark_precise: frame0: regs=r7 stack= before 7: (79) r7 = *(u64 *)(r10 -8)") +-__msg("mark_precise: frame0: parent state regs= stack=-8: R0_w=2 R6_w=1 R8_rw=map_value(map=.data.vals,ks=4,vs=16) R10=fp0 fp-8_rw=P1") +-__msg("mark_precise: frame0: last_idx 18 first_idx 0 subseq_idx 7") +-__msg("mark_precise: frame0: regs= stack=-8 before 18: (95) exit") +-__msg("mark_precise: frame1: regs= stack= before 17: (0f) r0 += r2") +-__msg("mark_precise: frame1: regs= stack= before 16: (79) r2 = *(u64 *)(r1 +0)") +-__msg("mark_precise: frame1: regs= stack= before 15: (79) r0 = *(u64 *)(r10 -16)") +-__msg("mark_precise: frame1: regs= stack= before 14: (7b) *(u64 *)(r10 -16) = r2") +-__msg("mark_precise: frame1: regs= stack= before 13: (7b) *(u64 *)(r1 +0) = r2") +-__msg("mark_precise: frame1: regs=r2 stack= before 6: (85) call pc+6") +-__msg("mark_precise: frame0: regs=r2 stack= before 5: (bf) r2 = r6") +-__msg("mark_precise: frame0: regs=r6 stack= before 4: (07) r1 += -8") +-__msg("mark_precise: frame0: regs=r6 stack= before 3: (bf) r1 = r10") +-__msg("mark_precise: frame0: regs=r6 stack= before 2: (b7) r6 = 1") ++/* precision backtracking can't currently handle stack access not through r10, ++ * so we won't be able to mark stack slot fp-8 as precise, and so will ++ * fallback to forcing all as precise ++ */ ++__msg("mark_precise: frame0: falling back to forcing all scalars precise") + __naked int subprog_spill_into_parent_stack_slot_precise(void) + { + asm volatile ( +diff --git a/tools/testing/selftests/bpf/verifier/precise.c b/tools/testing/selftests/bpf/verifier/precise.c +index 8a2ff81d835088..0d84dd1f38b6b0 100644 +--- a/tools/testing/selftests/bpf/verifier/precise.c ++++ b/tools/testing/selftests/bpf/verifier/precise.c +@@ -140,11 +140,10 @@ + .result = REJECT, + }, + { +- "precise: ST zero to stack insn is supported", ++ "precise: ST insn causing spi > allocated_stack", + .insns = { + BPF_MOV64_REG(BPF_REG_3, BPF_REG_10), + BPF_JMP_IMM(BPF_JNE, BPF_REG_3, 123, 0), +- /* not a register spill, so we stop precision propagation for R4 here */ + BPF_ST_MEM(BPF_DW, BPF_REG_3, -8, 0), + BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), + BPF_MOV64_IMM(BPF_REG_0, -1), +@@ -158,11 +157,11 @@ + mark_precise: frame0: last_idx 4 first_idx 2\ + mark_precise: frame0: regs=r4 stack= before 4\ + mark_precise: frame0: regs=r4 stack= before 3\ ++ mark_precise: frame0: regs= stack=-8 before 2\ ++ mark_precise: frame0: falling back to forcing all scalars precise\ ++ force_precise: frame0: forcing r0 to be precise\ + mark_precise: frame0: last_idx 5 first_idx 5\ +- mark_precise: frame0: parent state regs=r0 stack=:\ +- mark_precise: frame0: last_idx 4 first_idx 2\ +- mark_precise: frame0: regs=r0 stack= before 4\ +- 5: R0=-1 R4=0", ++ mark_precise: frame0: parent state regs= stack=:", + .result = VERBOSE_ACCEPT, + .retval = -1, + }, +@@ -170,8 +169,6 @@ + "precise: STX insn causing spi > allocated_stack", + .insns = { + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32), +- /* make later reg spill more interesting by having somewhat known scalar */ +- BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xff), + BPF_MOV64_REG(BPF_REG_3, BPF_REG_10), + BPF_JMP_IMM(BPF_JNE, BPF_REG_3, 123, 0), + BPF_STX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, -8), +@@ -182,21 +179,18 @@ + }, + .prog_type = BPF_PROG_TYPE_XDP, + .flags = BPF_F_TEST_STATE_FREQ, +- .errstr = "mark_precise: frame0: last_idx 7 first_idx 7\ ++ .errstr = "mark_precise: frame0: last_idx 6 first_idx 6\ + mark_precise: frame0: parent state regs=r4 stack=:\ +- mark_precise: frame0: last_idx 6 first_idx 4\ +- mark_precise: frame0: regs=r4 stack= before 6: (b7) r0 = -1\ +- mark_precise: frame0: regs=r4 stack= before 5: (79) r4 = *(u64 *)(r10 -8)\ +- mark_precise: frame0: regs= stack=-8 before 4: (7b) *(u64 *)(r3 -8) = r0\ +- mark_precise: frame0: parent state regs=r0 stack=:\ +- mark_precise: frame0: last_idx 3 first_idx 3\ +- mark_precise: frame0: regs=r0 stack= before 3: (55) if r3 != 0x7b goto pc+0\ +- mark_precise: frame0: regs=r0 stack= before 2: (bf) r3 = r10\ +- mark_precise: frame0: regs=r0 stack= before 1: (57) r0 &= 255\ +- mark_precise: frame0: parent state regs=r0 stack=:\ +- mark_precise: frame0: last_idx 0 first_idx 0\ +- mark_precise: frame0: regs=r0 stack= before 0: (85) call bpf_get_prandom_u32#7\ +- mark_precise: frame0: last_idx 7 first_idx 7\ ++ mark_precise: frame0: last_idx 5 first_idx 3\ ++ mark_precise: frame0: regs=r4 stack= before 5\ ++ mark_precise: frame0: regs=r4 stack= before 4\ ++ mark_precise: frame0: regs= stack=-8 before 3\ ++ mark_precise: frame0: falling back to forcing all scalars precise\ ++ force_precise: frame0: forcing r0 to be precise\ ++ force_precise: frame0: forcing r0 to be precise\ ++ force_precise: frame0: forcing r0 to be precise\ ++ force_precise: frame0: forcing r0 to be precise\ ++ mark_precise: frame0: last_idx 6 first_idx 6\ + mark_precise: frame0: parent state regs= stack=:", + .result = VERBOSE_ACCEPT, + .retval = -1, diff --git a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.70-71.patch b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.70-71.patch new file mode 100644 index 000000000000..9e3ccd9c837c --- /dev/null +++ b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.70-71.patch @@ -0,0 +1,227 @@ +diff --git a/Makefile b/Makefile +index 4c0dd62e02e465..9476e4502bbb0b 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 70 ++SUBLEVEL = 71 + EXTRAVERSION = + NAME = Pinguïn Aangedreven + +diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile +index 15fc9fc3dcf052..3269a0e23d3ab8 100644 +--- a/arch/x86/kernel/Makefile ++++ b/arch/x86/kernel/Makefile +@@ -99,9 +99,9 @@ obj-$(CONFIG_TRACING) += trace.o + obj-$(CONFIG_RETHOOK) += rethook.o + obj-$(CONFIG_CRASH_CORE) += crash_core_$(BITS).o + obj-$(CONFIG_KEXEC_CORE) += machine_kexec_$(BITS).o +-obj-$(CONFIG_KEXEC_CORE) += relocate_kernel_$(BITS).o ++obj-$(CONFIG_KEXEC_CORE) += relocate_kernel_$(BITS).o crash.o + obj-$(CONFIG_KEXEC_FILE) += kexec-bzimage64.o +-obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o crash.o ++obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o + obj-y += kprobes/ + obj-$(CONFIG_MODULES) += module.o + obj-$(CONFIG_X86_32) += doublefault_32.o +diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c +index 6328cf56e59be2..5ae77d966cafea 100644 +--- a/arch/x86/kernel/cpu/mshyperv.c ++++ b/arch/x86/kernel/cpu/mshyperv.c +@@ -209,9 +209,7 @@ static void hv_machine_shutdown(void) + if (kexec_in_progress) + hyperv_cleanup(); + } +-#endif /* CONFIG_KEXEC_CORE */ + +-#ifdef CONFIG_CRASH_DUMP + static void hv_machine_crash_shutdown(struct pt_regs *regs) + { + if (hv_crash_handler) +@@ -223,7 +221,7 @@ static void hv_machine_crash_shutdown(struct pt_regs *regs) + /* Disable the hypercall page when there is only 1 active CPU. */ + hyperv_cleanup(); + } +-#endif /* CONFIG_CRASH_DUMP */ ++#endif /* CONFIG_KEXEC_CORE */ + + static u64 hv_ref_counter_at_suspend; + static void (*old_save_sched_clock_state)(void); +@@ -552,13 +550,9 @@ static void __init ms_hyperv_init_platform(void) + no_timer_check = 1; + #endif + +-#if IS_ENABLED(CONFIG_HYPERV) +-#if defined(CONFIG_KEXEC_CORE) ++#if IS_ENABLED(CONFIG_HYPERV) && defined(CONFIG_KEXEC_CORE) + machine_ops.shutdown = hv_machine_shutdown; +-#endif +-#if defined(CONFIG_CRASH_DUMP) + machine_ops.crash_shutdown = hv_machine_crash_shutdown; +-#endif + #endif + if (ms_hyperv.features & HV_ACCESS_TSC_INVARIANT) { + /* +diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c +index 0de509c02d18b9..a61c12c0127097 100644 +--- a/arch/x86/kernel/kexec-bzimage64.c ++++ b/arch/x86/kernel/kexec-bzimage64.c +@@ -263,13 +263,11 @@ setup_boot_parameters(struct kimage *image, struct boot_params *params, + memset(¶ms->hd0_info, 0, sizeof(params->hd0_info)); + memset(¶ms->hd1_info, 0, sizeof(params->hd1_info)); + +-#ifdef CONFIG_CRASH_DUMP + if (image->type == KEXEC_TYPE_CRASH) { + ret = crash_setup_memmap_entries(image, params); + if (ret) + return ret; + } else +-#endif + setup_e820_entries(params); + + nr_e820_entries = params->e820_entries; +@@ -430,14 +428,12 @@ static void *bzImage64_load(struct kimage *image, char *kernel, + return ERR_PTR(-EINVAL); + } + +-#ifdef CONFIG_CRASH_DUMP + /* Allocate and load backup region */ + if (image->type == KEXEC_TYPE_CRASH) { + ret = crash_load_segments(image); + if (ret) + return ERR_PTR(ret); + } +-#endif + + /* + * Load purgatory. For 64bit entry point, purgatory code can be +diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c +index 38d88c8b56ec07..b8ab9ee5896c19 100644 +--- a/arch/x86/kernel/kvm.c ++++ b/arch/x86/kernel/kvm.c +@@ -769,7 +769,7 @@ static struct notifier_block kvm_pv_reboot_nb = { + * won't be valid. In cases like kexec, in which you install a new kernel, this + * means a random memory location will be kept being written. + */ +-#ifdef CONFIG_CRASH_DUMP ++#ifdef CONFIG_KEXEC_CORE + static void kvm_crash_shutdown(struct pt_regs *regs) + { + kvm_guest_cpu_offline(true); +@@ -852,7 +852,7 @@ static void __init kvm_guest_init(void) + kvm_guest_cpu_init(); + #endif + +-#ifdef CONFIG_CRASH_DUMP ++#ifdef CONFIG_KEXEC_CORE + machine_ops.crash_shutdown = kvm_crash_shutdown; + #endif + +diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c +index aaeac2deb85dc6..2fa12d1dc67602 100644 +--- a/arch/x86/kernel/machine_kexec_64.c ++++ b/arch/x86/kernel/machine_kexec_64.c +@@ -545,8 +545,6 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image) + } + #endif /* CONFIG_KEXEC_FILE */ + +-#ifdef CONFIG_CRASH_DUMP +- + static int + kexec_mark_range(unsigned long start, unsigned long end, bool protect) + { +@@ -591,7 +589,6 @@ void arch_kexec_unprotect_crashkres(void) + { + kexec_mark_crashkres(false); + } +-#endif + + /* + * During a traditional boot under SME, SME will encrypt the kernel, +diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c +index f3130f762784a1..830425e6d38e2f 100644 +--- a/arch/x86/kernel/reboot.c ++++ b/arch/x86/kernel/reboot.c +@@ -796,7 +796,7 @@ struct machine_ops machine_ops __ro_after_init = { + .emergency_restart = native_machine_emergency_restart, + .restart = native_machine_restart, + .halt = native_machine_halt, +-#ifdef CONFIG_CRASH_DUMP ++#ifdef CONFIG_KEXEC_CORE + .crash_shutdown = native_machine_crash_shutdown, + #endif + }; +@@ -826,7 +826,7 @@ void machine_halt(void) + machine_ops.halt(); + } + +-#ifdef CONFIG_CRASH_DUMP ++#ifdef CONFIG_KEXEC_CORE + void machine_crash_shutdown(struct pt_regs *regs) + { + machine_ops.crash_shutdown(regs); +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index 8bcecabd475bdf..eb129277dcdd64 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -547,7 +547,7 @@ static void __init reserve_crashkernel(void) + bool high = false; + int ret; + +- if (!IS_ENABLED(CONFIG_CRASH_RESERVE)) ++ if (!IS_ENABLED(CONFIG_KEXEC_CORE)) + return; + + total_mem = memblock_phys_mem_size(); +diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c +index 52c3823b721191..96a771f9f930a6 100644 +--- a/arch/x86/kernel/smp.c ++++ b/arch/x86/kernel/smp.c +@@ -282,7 +282,7 @@ struct smp_ops smp_ops = { + .smp_cpus_done = native_smp_cpus_done, + + .stop_other_cpus = native_stop_other_cpus, +-#if defined(CONFIG_CRASH_DUMP) ++#if defined(CONFIG_KEXEC_CORE) + .crash_stop_other_cpus = kdump_nmi_shootdown_cpus, + #endif + .smp_send_reschedule = native_smp_send_reschedule, +diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c +index ade22feee7aeb1..70be57e8f51caa 100644 +--- a/arch/x86/xen/enlighten_hvm.c ++++ b/arch/x86/xen/enlighten_hvm.c +@@ -141,9 +141,7 @@ static void xen_hvm_shutdown(void) + if (kexec_in_progress) + xen_reboot(SHUTDOWN_soft_reset); + } +-#endif + +-#ifdef CONFIG_CRASH_DUMP + static void xen_hvm_crash_shutdown(struct pt_regs *regs) + { + native_machine_crash_shutdown(regs); +@@ -231,8 +229,6 @@ static void __init xen_hvm_guest_init(void) + + #ifdef CONFIG_KEXEC_CORE + machine_ops.shutdown = xen_hvm_shutdown; +-#endif +-#ifdef CONFIG_CRASH_DUMP + machine_ops.crash_shutdown = xen_hvm_crash_shutdown; + #endif + } +diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c +index bfd57d07f4b5ee..6b201e64d8abc8 100644 +--- a/arch/x86/xen/mmu_pv.c ++++ b/arch/x86/xen/mmu_pv.c +@@ -2517,7 +2517,7 @@ int xen_remap_pfn(struct vm_area_struct *vma, unsigned long addr, + } + EXPORT_SYMBOL_GPL(xen_remap_pfn); + +-#ifdef CONFIG_VMCORE_INFO ++#ifdef CONFIG_KEXEC_CORE + phys_addr_t paddr_vmcoreinfo_note(void) + { + if (xen_pv_domain()) diff --git a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.71-72.patch b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.71-72.patch new file mode 100644 index 000000000000..891def085e08 --- /dev/null +++ b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.71-72.patch @@ -0,0 +1,4467 @@ +diff --git a/Makefile b/Makefile +index 9476e4502bbb0b..fb4949cac6ffbf 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 71 ++SUBLEVEL = 72 + EXTRAVERSION = + NAME = Pinguïn Aangedreven + +diff --git a/arch/arm/boot/dts/nxp/imx/imxrt1050.dtsi b/arch/arm/boot/dts/nxp/imx/imxrt1050.dtsi +index dd714d235d5f6a..b0bad0d1ba36f4 100644 +--- a/arch/arm/boot/dts/nxp/imx/imxrt1050.dtsi ++++ b/arch/arm/boot/dts/nxp/imx/imxrt1050.dtsi +@@ -87,7 +87,7 @@ usdhc1: mmc@402c0000 { + reg = <0x402c0000 0x4000>; + interrupts = <110>; + clocks = <&clks IMXRT1050_CLK_IPG_PDOF>, +- <&clks IMXRT1050_CLK_OSC>, ++ <&clks IMXRT1050_CLK_AHB_PODF>, + <&clks IMXRT1050_CLK_USDHC1>; + clock-names = "ipg", "ahb", "per"; + bus-width = <4>; +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index 5d47acbf4a2497..82eb7c49e825e4 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -304,6 +304,7 @@ power: power-controller { + + power-domain@RK3328_PD_HEVC { + reg = ; ++ clocks = <&cru SCLK_VENC_CORE>; + #power-domain-cells = <0>; + }; + power-domain@RK3328_PD_VIDEO { +diff --git a/arch/riscv/include/asm/cacheflush.h b/arch/riscv/include/asm/cacheflush.h +index a129dac4521d35..3f65acd0ef7560 100644 +--- a/arch/riscv/include/asm/cacheflush.h ++++ b/arch/riscv/include/asm/cacheflush.h +@@ -13,6 +13,12 @@ static inline void local_flush_icache_all(void) + asm volatile ("fence.i" ::: "memory"); + } + ++static inline void local_flush_icache_range(unsigned long start, ++ unsigned long end) ++{ ++ local_flush_icache_all(); ++} ++ + #define PG_dcache_clean PG_arch_1 + + static inline void flush_dcache_folio(struct folio *folio) +diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h +index 94b3d6930fc370..4d1f58848129e8 100644 +--- a/arch/riscv/include/asm/page.h ++++ b/arch/riscv/include/asm/page.h +@@ -122,6 +122,7 @@ struct kernel_mapping { + + extern struct kernel_mapping kernel_map; + extern phys_addr_t phys_ram_base; ++extern unsigned long vmemmap_start_pfn; + + #define is_kernel_mapping(x) \ + ((x) >= kernel_map.virt_addr && (x) < (kernel_map.virt_addr + kernel_map.size)) +diff --git a/arch/riscv/include/asm/patch.h b/arch/riscv/include/asm/patch.h +index e88b52d39eac76..9f5d6e14c40553 100644 +--- a/arch/riscv/include/asm/patch.h ++++ b/arch/riscv/include/asm/patch.h +@@ -6,6 +6,7 @@ + #ifndef _ASM_RISCV_PATCH_H + #define _ASM_RISCV_PATCH_H + ++int patch_insn_write(void *addr, const void *insn, size_t len); + int patch_text_nosync(void *addr, const void *insns, size_t len); + int patch_text_set_nosync(void *addr, u8 c, size_t len); + int patch_text(void *addr, u32 *insns, int ninsns); +diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h +index 37829dab4a0a48..f540b2625714d0 100644 +--- a/arch/riscv/include/asm/pgtable.h ++++ b/arch/riscv/include/asm/pgtable.h +@@ -84,7 +84,7 @@ + * Define vmemmap for pfn_to_page & page_to_pfn calls. Needed if kernel + * is configured with CONFIG_SPARSEMEM_VMEMMAP enabled. + */ +-#define vmemmap ((struct page *)VMEMMAP_START - (phys_ram_base >> PAGE_SHIFT)) ++#define vmemmap ((struct page *)VMEMMAP_START - vmemmap_start_pfn) + + #define PCI_IO_SIZE SZ_16M + #define PCI_IO_END VMEMMAP_START +diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c +index 03a6434a8cdd00..4c58c2f8098401 100644 +--- a/arch/riscv/kernel/ftrace.c ++++ b/arch/riscv/kernel/ftrace.c +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -75,8 +76,7 @@ static int __ftrace_modify_call(unsigned long hook_pos, unsigned long target, + make_call_t0(hook_pos, target, call); + + /* Replace the auipc-jalr pair at once. Return -EPERM on write error. */ +- if (patch_text_nosync +- ((void *)hook_pos, enable ? call : nops, MCOUNT_INSN_SIZE)) ++ if (patch_insn_write((void *)hook_pos, enable ? call : nops, MCOUNT_INSN_SIZE)) + return -EPERM; + + return 0; +@@ -88,7 +88,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) + + make_call_t0(rec->ip, addr, call); + +- if (patch_text_nosync((void *)rec->ip, call, MCOUNT_INSN_SIZE)) ++ if (patch_insn_write((void *)rec->ip, call, MCOUNT_INSN_SIZE)) + return -EPERM; + + return 0; +@@ -99,7 +99,7 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, + { + unsigned int nops[2] = {NOP4, NOP4}; + +- if (patch_text_nosync((void *)rec->ip, nops, MCOUNT_INSN_SIZE)) ++ if (patch_insn_write((void *)rec->ip, nops, MCOUNT_INSN_SIZE)) + return -EPERM; + + return 0; +@@ -120,6 +120,9 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec) + out = ftrace_make_nop(mod, rec, MCOUNT_ADDR); + mutex_unlock(&text_mutex); + ++ if (!mod) ++ local_flush_icache_range(rec->ip, rec->ip + MCOUNT_INSN_SIZE); ++ + return out; + } + +@@ -134,6 +137,42 @@ int ftrace_update_ftrace_func(ftrace_func_t func) + + return ret; + } ++ ++struct ftrace_modify_param { ++ int command; ++ atomic_t cpu_count; ++}; ++ ++static int __ftrace_modify_code(void *data) ++{ ++ struct ftrace_modify_param *param = data; ++ ++ if (atomic_inc_return(¶m->cpu_count) == num_online_cpus()) { ++ ftrace_modify_all_code(param->command); ++ /* ++ * Make sure the patching store is effective *before* we ++ * increment the counter which releases all waiting CPUs ++ * by using the release variant of atomic increment. The ++ * release pairs with the call to local_flush_icache_all() ++ * on the waiting CPU. ++ */ ++ atomic_inc_return_release(¶m->cpu_count); ++ } else { ++ while (atomic_read(¶m->cpu_count) <= num_online_cpus()) ++ cpu_relax(); ++ } ++ ++ local_flush_icache_all(); ++ ++ return 0; ++} ++ ++void arch_ftrace_update_code(int command) ++{ ++ struct ftrace_modify_param param = { command, ATOMIC_INIT(0) }; ++ ++ stop_machine(__ftrace_modify_code, ¶m, cpu_online_mask); ++} + #endif + + #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS +diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c +index 30e12b310cab73..78387d843aa56b 100644 +--- a/arch/riscv/kernel/patch.c ++++ b/arch/riscv/kernel/patch.c +@@ -196,7 +196,7 @@ int patch_text_set_nosync(void *addr, u8 c, size_t len) + } + NOKPROBE_SYMBOL(patch_text_set_nosync); + +-static int patch_insn_write(void *addr, const void *insn, size_t len) ++int patch_insn_write(void *addr, const void *insn, size_t len) + { + size_t patched = 0; + size_t size; +@@ -240,16 +240,24 @@ static int patch_text_cb(void *data) + if (atomic_inc_return(&patch->cpu_count) == num_online_cpus()) { + for (i = 0; ret == 0 && i < patch->ninsns; i++) { + len = GET_INSN_LENGTH(patch->insns[i]); +- ret = patch_text_nosync(patch->addr + i * len, +- &patch->insns[i], len); ++ ret = patch_insn_write(patch->addr + i * len, &patch->insns[i], len); + } +- atomic_inc(&patch->cpu_count); ++ /* ++ * Make sure the patching store is effective *before* we ++ * increment the counter which releases all waiting CPUs ++ * by using the release variant of atomic increment. The ++ * release pairs with the call to local_flush_icache_all() ++ * on the waiting CPU. ++ */ ++ atomic_inc_return_release(&patch->cpu_count); + } else { + while (atomic_read(&patch->cpu_count) <= num_online_cpus()) + cpu_relax(); + smp_mb(); + } + ++ local_flush_icache_all(); ++ + return ret; + } + NOKPROBE_SYMBOL(patch_text_cb); +diff --git a/arch/riscv/kernel/probes/kprobes.c b/arch/riscv/kernel/probes/kprobes.c +index fecbbcf40ac3fe..4fbc70e823f0fa 100644 +--- a/arch/riscv/kernel/probes/kprobes.c ++++ b/arch/riscv/kernel/probes/kprobes.c +@@ -29,7 +29,7 @@ static void __kprobes arch_prepare_ss_slot(struct kprobe *p) + p->ainsn.api.restore = (unsigned long)p->addr + offset; + + patch_text_nosync(p->ainsn.api.insn, &p->opcode, 1); +- patch_text_nosync(p->ainsn.api.insn + offset, &insn, 1); ++ patch_text_nosync((void *)p->ainsn.api.insn + offset, &insn, 1); + } + + static void __kprobes arch_prepare_simulate(struct kprobe *p) +diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c +index 2158b7a65d74f7..53c7de4878c227 100644 +--- a/arch/riscv/kernel/traps.c ++++ b/arch/riscv/kernel/traps.c +@@ -34,7 +34,7 @@ + + int show_unhandled_signals = 1; + +-static DEFINE_SPINLOCK(die_lock); ++static DEFINE_RAW_SPINLOCK(die_lock); + + static void dump_kernel_instr(const char *loglvl, struct pt_regs *regs) + { +@@ -66,7 +66,7 @@ void die(struct pt_regs *regs, const char *str) + + oops_enter(); + +- spin_lock_irqsave(&die_lock, flags); ++ raw_spin_lock_irqsave(&die_lock, flags); + console_verbose(); + bust_spinlocks(1); + +@@ -85,7 +85,7 @@ void die(struct pt_regs *regs, const char *str) + + bust_spinlocks(0); + add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); +- spin_unlock_irqrestore(&die_lock, flags); ++ raw_spin_unlock_irqrestore(&die_lock, flags); + oops_exit(); + + if (in_interrupt()) +diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c +index 3245bb525212e3..bdf8ac6c7e309d 100644 +--- a/arch/riscv/mm/init.c ++++ b/arch/riscv/mm/init.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + #include + + #include "../kernel/head.h" +@@ -57,6 +58,13 @@ EXPORT_SYMBOL(pgtable_l5_enabled); + phys_addr_t phys_ram_base __ro_after_init; + EXPORT_SYMBOL(phys_ram_base); + ++#ifdef CONFIG_SPARSEMEM_VMEMMAP ++#define VMEMMAP_ADDR_ALIGN (1ULL << SECTION_SIZE_BITS) ++ ++unsigned long vmemmap_start_pfn __ro_after_init; ++EXPORT_SYMBOL(vmemmap_start_pfn); ++#endif ++ + unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)] + __page_aligned_bss; + EXPORT_SYMBOL(empty_zero_page); +@@ -221,8 +229,12 @@ static void __init setup_bootmem(void) + * Make sure we align the start of the memory on a PMD boundary so that + * at worst, we map the linear mapping with PMD mappings. + */ +- if (!IS_ENABLED(CONFIG_XIP_KERNEL)) ++ if (!IS_ENABLED(CONFIG_XIP_KERNEL)) { + phys_ram_base = memblock_start_of_DRAM() & PMD_MASK; ++#ifdef CONFIG_SPARSEMEM_VMEMMAP ++ vmemmap_start_pfn = round_down(phys_ram_base, VMEMMAP_ADDR_ALIGN) >> PAGE_SHIFT; ++#endif ++ } + + /* + * In 64-bit, any use of __va/__pa before this point is wrong as we +@@ -1080,6 +1092,9 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) + kernel_map.xiprom_sz = (uintptr_t)(&_exiprom) - (uintptr_t)(&_xiprom); + + phys_ram_base = CONFIG_PHYS_RAM_BASE; ++#ifdef CONFIG_SPARSEMEM_VMEMMAP ++ vmemmap_start_pfn = round_down(phys_ram_base, VMEMMAP_ADDR_ALIGN) >> PAGE_SHIFT; ++#endif + kernel_map.phys_addr = (uintptr_t)CONFIG_PHYS_RAM_BASE; + kernel_map.size = (uintptr_t)(&_end) - (uintptr_t)(&_start); + +diff --git a/arch/x86/kernel/fpu/regset.c b/arch/x86/kernel/fpu/regset.c +index 6bc1eb2a21bd92..887b0b8e21e364 100644 +--- a/arch/x86/kernel/fpu/regset.c ++++ b/arch/x86/kernel/fpu/regset.c +@@ -190,7 +190,8 @@ int ssp_get(struct task_struct *target, const struct user_regset *regset, + struct fpu *fpu = &target->thread.fpu; + struct cet_user_state *cetregs; + +- if (!cpu_feature_enabled(X86_FEATURE_USER_SHSTK)) ++ if (!cpu_feature_enabled(X86_FEATURE_USER_SHSTK) || ++ !ssp_active(target, regset)) + return -ENODEV; + + sync_fpstate(fpu); +diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c +index 2c67bfc3cf3204..8b374c6919e604 100644 +--- a/arch/x86/mm/numa.c ++++ b/arch/x86/mm/numa.c +@@ -492,7 +492,7 @@ static void __init numa_clear_kernel_node_hotplug(void) + for_each_reserved_mem_region(mb_region) { + int nid = memblock_get_region_node(mb_region); + +- if (nid != MAX_NUMNODES) ++ if (nid != NUMA_NO_NODE) + node_set(nid, reserved_nodemask); + } + +@@ -613,9 +613,9 @@ static int __init numa_init(int (*init_func)(void)) + nodes_clear(node_online_map); + memset(&numa_meminfo, 0, sizeof(numa_meminfo)); + WARN_ON(memblock_set_node(0, ULLONG_MAX, &memblock.memory, +- MAX_NUMNODES)); ++ NUMA_NO_NODE)); + WARN_ON(memblock_set_node(0, ULLONG_MAX, &memblock.reserved, +- MAX_NUMNODES)); ++ NUMA_NO_NODE)); + /* In case that parsing SRAT failed. */ + WARN_ON(memblock_clear_hotplug(0, ULLONG_MAX)); + numa_reset_distance(); +diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c +index dd8ca3f7ba60a1..617d6802b8a0c7 100644 +--- a/block/bfq-iosched.c ++++ b/block/bfq-iosched.c +@@ -6843,16 +6843,24 @@ static struct bfq_queue *bfq_waker_bfqq(struct bfq_queue *bfqq) + if (new_bfqq == waker_bfqq) { + /* + * If waker_bfqq is in the merge chain, and current +- * is the only procress. ++ * is the only process, waker_bfqq can be freed. + */ + if (bfqq_process_refs(waker_bfqq) == 1) + return NULL; +- break; ++ ++ return waker_bfqq; + } + + new_bfqq = new_bfqq->new_bfqq; + } + ++ /* ++ * If waker_bfqq is not in the merge chain, and it's procress reference ++ * is 0, waker_bfqq can be freed. ++ */ ++ if (bfqq_process_refs(waker_bfqq) == 0) ++ return NULL; ++ + return waker_bfqq; + } + +diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c +index df598de0cb184f..c82b255f82bc41 100644 +--- a/drivers/acpi/resource.c ++++ b/drivers/acpi/resource.c +@@ -439,6 +439,13 @@ static const struct dmi_system_id asus_laptop[] = { + DMI_MATCH(DMI_BOARD_NAME, "S5602ZA"), + }, + }, ++ { ++ /* Asus Vivobook X1504VAP */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_BOARD_NAME, "X1504VAP"), ++ }, ++ }, + { + /* Asus Vivobook X1704VAP */ + .matches = { +@@ -633,6 +640,17 @@ static const struct dmi_system_id lg_laptop[] = { + DMI_MATCH(DMI_BOARD_NAME, "GMxHGxx"), + }, + }, ++ { ++ /* ++ * TongFang GM5HG0A in case of the SKIKK Vanaheim relabel the ++ * board-name is changed, so check OEM strings instead. Note ++ * OEM string matches are always exact matches. ++ * https://bugzilla.kernel.org/show_bug.cgi?id=219614 ++ */ ++ .matches = { ++ DMI_EXACT_MATCH(DMI_OEM_STRING, "GM5HG0A"), ++ }, ++ }, + { } + }; + +diff --git a/drivers/base/topology.c b/drivers/base/topology.c +index 89f98be5c5b991..d293cbd253e4f9 100644 +--- a/drivers/base/topology.c ++++ b/drivers/base/topology.c +@@ -27,9 +27,17 @@ static ssize_t name##_read(struct file *file, struct kobject *kobj, \ + loff_t off, size_t count) \ + { \ + struct device *dev = kobj_to_dev(kobj); \ ++ cpumask_var_t mask; \ ++ ssize_t n; \ + \ +- return cpumap_print_bitmask_to_buf(buf, topology_##mask(dev->id), \ +- off, count); \ ++ if (!alloc_cpumask_var(&mask, GFP_KERNEL)) \ ++ return -ENOMEM; \ ++ \ ++ cpumask_copy(mask, topology_##mask(dev->id)); \ ++ n = cpumap_print_bitmask_to_buf(buf, mask, off, count); \ ++ free_cpumask_var(mask); \ ++ \ ++ return n; \ + } \ + \ + static ssize_t name##_list_read(struct file *file, struct kobject *kobj, \ +@@ -37,9 +45,17 @@ static ssize_t name##_list_read(struct file *file, struct kobject *kobj, \ + loff_t off, size_t count) \ + { \ + struct device *dev = kobj_to_dev(kobj); \ ++ cpumask_var_t mask; \ ++ ssize_t n; \ ++ \ ++ if (!alloc_cpumask_var(&mask, GFP_KERNEL)) \ ++ return -ENOMEM; \ ++ \ ++ cpumask_copy(mask, topology_##mask(dev->id)); \ ++ n = cpumap_print_list_to_buf(buf, mask, off, count); \ ++ free_cpumask_var(mask); \ + \ +- return cpumap_print_list_to_buf(buf, topology_##mask(dev->id), \ +- off, count); \ ++ return n; \ + } + + define_id_show_func(physical_package_id, "%d"); +diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c +index 5ee9a8b8dcfdb8..e809bb2dbe5e07 100644 +--- a/drivers/bluetooth/btnxpuart.c ++++ b/drivers/bluetooth/btnxpuart.c +@@ -1280,6 +1280,7 @@ static void btnxpuart_tx_work(struct work_struct *work) + + while ((skb = nxp_dequeue(nxpdev))) { + len = serdev_device_write_buf(serdev, skb->data, skb->len); ++ serdev_device_wait_until_sent(serdev, 0); + hdev->stat.byte_tx += len; + + skb_pull(skb, len); +diff --git a/drivers/cpuidle/cpuidle-riscv-sbi.c b/drivers/cpuidle/cpuidle-riscv-sbi.c +index c0fe92409175a4..71d433bb0ce694 100644 +--- a/drivers/cpuidle/cpuidle-riscv-sbi.c ++++ b/drivers/cpuidle/cpuidle-riscv-sbi.c +@@ -534,12 +534,12 @@ static int sbi_cpuidle_probe(struct platform_device *pdev) + int cpu, ret; + struct cpuidle_driver *drv; + struct cpuidle_device *dev; +- struct device_node *np, *pds_node; ++ struct device_node *pds_node; + + /* Detect OSI support based on CPU DT nodes */ + sbi_cpuidle_use_osi = true; + for_each_possible_cpu(cpu) { +- np = of_cpu_device_node_get(cpu); ++ struct device_node *np __free(device_node) = of_cpu_device_node_get(cpu); + if (np && + of_property_present(np, "power-domains") && + of_property_present(np, "power-domain-names")) { +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c +index 94aaf2fc556ca1..9c32c64c407fa9 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c +@@ -349,10 +349,27 @@ int kfd_dbg_set_mes_debug_mode(struct kfd_process_device *pdd, bool sq_trap_en) + { + uint32_t spi_dbg_cntl = pdd->spi_dbg_override | pdd->spi_dbg_launch_mode; + uint32_t flags = pdd->process->dbg_flags; ++ struct amdgpu_device *adev = pdd->dev->adev; ++ int r; + + if (!kfd_dbg_is_per_vmid_supported(pdd->dev)) + return 0; + ++ if (!pdd->proc_ctx_cpu_ptr) { ++ r = amdgpu_amdkfd_alloc_gtt_mem(adev, ++ AMDGPU_MES_PROC_CTX_SIZE, ++ &pdd->proc_ctx_bo, ++ &pdd->proc_ctx_gpu_addr, ++ &pdd->proc_ctx_cpu_ptr, ++ false); ++ if (r) { ++ dev_err(adev->dev, ++ "failed to allocate process context bo\n"); ++ return r; ++ } ++ memset(pdd->proc_ctx_cpu_ptr, 0, AMDGPU_MES_PROC_CTX_SIZE); ++ } ++ + return amdgpu_mes_set_shader_debugger(pdd->dev->adev, pdd->proc_ctx_gpu_addr, spi_dbg_cntl, + pdd->watch_points, flags, sq_trap_en); + } +diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h +index 5f2eac868b7472..cc5e01df151356 100644 +--- a/drivers/gpu/drm/amd/display/dc/dc.h ++++ b/drivers/gpu/drm/amd/display/dc/dc.h +@@ -49,7 +49,7 @@ struct dmub_notification; + + #define DC_VER "3.2.247" + +-#define MAX_SURFACES 3 ++#define MAX_SURFACES 4 + #define MAX_PLANES 6 + #define MAX_STREAMS 6 + #define MIN_VIEWPORT_SIZE 12 +diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h b/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h +index 072bd053960594..6b2ab4ec2b5ffe 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h ++++ b/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h +@@ -66,11 +66,15 @@ static inline double dml_max5(double a, double b, double c, double d, double e) + + static inline double dml_ceil(double a, double granularity) + { ++ if (granularity == 0) ++ return 0; + return (double) dcn_bw_ceil2(a, granularity); + } + + static inline double dml_floor(double a, double granularity) + { ++ if (granularity == 0) ++ return 0; + return (double) dcn_bw_floor2(a, granularity); + } + +@@ -114,11 +118,15 @@ static inline double dml_ceil_2(double f) + + static inline double dml_ceil_ex(double x, double granularity) + { ++ if (granularity == 0) ++ return 0; + return (double) dcn_bw_ceil2(x, granularity); + } + + static inline double dml_floor_ex(double x, double granularity) + { ++ if (granularity == 0) ++ return 0; + return (double) dcn_bw_floor2(x, granularity); + } + +diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig +index 76cab28e010c51..d2652751d1904c 100644 +--- a/drivers/gpu/drm/mediatek/Kconfig ++++ b/drivers/gpu/drm/mediatek/Kconfig +@@ -10,9 +10,6 @@ config DRM_MEDIATEK + select DRM_KMS_HELPER + select DRM_MIPI_DSI + select DRM_PANEL +- select MEMORY +- select MTK_SMI +- select PHY_MTK_MIPI_DSI + select VIDEOMODE_HELPERS + help + Choose this option if you have a Mediatek SoCs. +@@ -23,7 +20,6 @@ config DRM_MEDIATEK + config DRM_MEDIATEK_DP + tristate "DRM DPTX Support for MediaTek SoCs" + depends on DRM_MEDIATEK +- select PHY_MTK_DP + select DRM_DISPLAY_HELPER + select DRM_DISPLAY_DP_HELPER + select DRM_DP_AUX_BUS +@@ -34,6 +30,5 @@ config DRM_MEDIATEK_HDMI + tristate "DRM HDMI Support for Mediatek SoCs" + depends on DRM_MEDIATEK + select SND_SOC_HDMI_CODEC if SND_SOC +- select PHY_MTK_HDMI + help + DRM/KMS HDMI driver for Mediatek SoCs +diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +index 6f15069da8b020..ce0f441e3f136c 100644 +--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c ++++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +@@ -403,6 +403,29 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt) + } + } + ++static void mtk_ovl_afbc_layer_config(struct mtk_disp_ovl *ovl, ++ unsigned int idx, ++ struct mtk_plane_pending_state *pending, ++ struct cmdq_pkt *cmdq_pkt) ++{ ++ unsigned int pitch_msb = pending->pitch >> 16; ++ unsigned int hdr_pitch = pending->hdr_pitch; ++ unsigned int hdr_addr = pending->hdr_addr; ++ ++ if (pending->modifier != DRM_FORMAT_MOD_LINEAR) { ++ mtk_ddp_write_relaxed(cmdq_pkt, hdr_addr, &ovl->cmdq_reg, ovl->regs, ++ DISP_REG_OVL_HDR_ADDR(ovl, idx)); ++ mtk_ddp_write_relaxed(cmdq_pkt, ++ OVL_PITCH_MSB_2ND_SUBBUF | pitch_msb, ++ &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx)); ++ mtk_ddp_write_relaxed(cmdq_pkt, hdr_pitch, &ovl->cmdq_reg, ovl->regs, ++ DISP_REG_OVL_HDR_PITCH(ovl, idx)); ++ } else { ++ mtk_ddp_write_relaxed(cmdq_pkt, pitch_msb, ++ &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx)); ++ } ++} ++ + void mtk_ovl_layer_config(struct device *dev, unsigned int idx, + struct mtk_plane_state *state, + struct cmdq_pkt *cmdq_pkt) +@@ -410,24 +433,12 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + struct mtk_plane_pending_state *pending = &state->pending; + unsigned int addr = pending->addr; +- unsigned int hdr_addr = pending->hdr_addr; +- unsigned int pitch = pending->pitch; +- unsigned int hdr_pitch = pending->hdr_pitch; ++ unsigned int pitch_lsb = pending->pitch & GENMASK(15, 0); + unsigned int fmt = pending->format; + unsigned int offset = (pending->y << 16) | pending->x; + unsigned int src_size = (pending->height << 16) | pending->width; + unsigned int ignore_pixel_alpha = 0; + unsigned int con; +- bool is_afbc = pending->modifier != DRM_FORMAT_MOD_LINEAR; +- union overlay_pitch { +- struct split_pitch { +- u16 lsb; +- u16 msb; +- } split_pitch; +- u32 pitch; +- } overlay_pitch; +- +- overlay_pitch.pitch = pitch; + + if (!pending->enable) { + mtk_ovl_layer_off(dev, idx, cmdq_pkt); +@@ -457,11 +468,12 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, + } + + if (ovl->data->supports_afbc) +- mtk_ovl_set_afbc(ovl, cmdq_pkt, idx, is_afbc); ++ mtk_ovl_set_afbc(ovl, cmdq_pkt, idx, ++ pending->modifier != DRM_FORMAT_MOD_LINEAR); + + mtk_ddp_write_relaxed(cmdq_pkt, con, &ovl->cmdq_reg, ovl->regs, + DISP_REG_OVL_CON(idx)); +- mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb | ignore_pixel_alpha, ++ mtk_ddp_write_relaxed(cmdq_pkt, pitch_lsb | ignore_pixel_alpha, + &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH(idx)); + mtk_ddp_write_relaxed(cmdq_pkt, src_size, &ovl->cmdq_reg, ovl->regs, + DISP_REG_OVL_SRC_SIZE(idx)); +@@ -470,19 +482,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, + mtk_ddp_write_relaxed(cmdq_pkt, addr, &ovl->cmdq_reg, ovl->regs, + DISP_REG_OVL_ADDR(ovl, idx)); + +- if (is_afbc) { +- mtk_ddp_write_relaxed(cmdq_pkt, hdr_addr, &ovl->cmdq_reg, ovl->regs, +- DISP_REG_OVL_HDR_ADDR(ovl, idx)); +- mtk_ddp_write_relaxed(cmdq_pkt, +- OVL_PITCH_MSB_2ND_SUBBUF | overlay_pitch.split_pitch.msb, +- &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx)); +- mtk_ddp_write_relaxed(cmdq_pkt, hdr_pitch, &ovl->cmdq_reg, ovl->regs, +- DISP_REG_OVL_HDR_PITCH(ovl, idx)); +- } else { +- mtk_ddp_write_relaxed(cmdq_pkt, +- overlay_pitch.split_pitch.msb, +- &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx)); +- } ++ if (ovl->data->supports_afbc) ++ mtk_ovl_afbc_layer_config(ovl, idx, pending, cmdq_pkt); + + mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt); + mtk_ovl_layer_on(dev, idx, cmdq_pkt); +diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c +index 48a4defbc66cc8..be4de26c77f917 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dp.c ++++ b/drivers/gpu/drm/mediatek/mtk_dp.c +@@ -458,18 +458,16 @@ static int mtk_dp_set_color_format(struct mtk_dp *mtk_dp, + enum dp_pixelformat color_format) + { + u32 val; +- +- /* update MISC0 */ +- mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3034, +- color_format << DP_TEST_COLOR_FORMAT_SHIFT, +- DP_TEST_COLOR_FORMAT_MASK); ++ u32 misc0_color; + + switch (color_format) { + case DP_PIXELFORMAT_YUV422: + val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR422; ++ misc0_color = DP_COLOR_FORMAT_YCbCr422; + break; + case DP_PIXELFORMAT_RGB: + val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_RGB; ++ misc0_color = DP_COLOR_FORMAT_RGB; + break; + default: + drm_warn(mtk_dp->drm_dev, "Unsupported color format: %d\n", +@@ -477,6 +475,11 @@ static int mtk_dp_set_color_format(struct mtk_dp *mtk_dp, + return -EINVAL; + } + ++ /* update MISC0 */ ++ mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3034, ++ misc0_color, ++ DP_TEST_COLOR_FORMAT_MASK); ++ + mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C, + val, PIXEL_ENCODE_FORMAT_DP_ENC0_P0_MASK); + return 0; +@@ -2002,7 +2005,6 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge) + struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge); + enum drm_connector_status ret = connector_status_disconnected; + bool enabled = mtk_dp->enabled; +- u8 sink_count = 0; + + if (!mtk_dp->train_info.cable_plugged_in) + return ret; +@@ -2017,8 +2019,8 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge) + * function, we just need to check the HPD connection to check + * whether we connect to a sink device. + */ +- drm_dp_dpcd_readb(&mtk_dp->aux, DP_SINK_COUNT, &sink_count); +- if (DP_GET_SINK_COUNT(sink_count)) ++ ++ if (drm_dp_read_sink_count(&mtk_dp->aux) > 0) + ret = connector_status_connected; + + if (!enabled) +@@ -2310,12 +2312,19 @@ mtk_dp_bridge_mode_valid(struct drm_bridge *bridge, + { + struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge); + u32 bpp = info->color_formats & DRM_COLOR_FORMAT_YCBCR422 ? 16 : 24; +- u32 rate = min_t(u32, drm_dp_max_link_rate(mtk_dp->rx_cap) * +- drm_dp_max_lane_count(mtk_dp->rx_cap), +- drm_dp_bw_code_to_link_rate(mtk_dp->max_linkrate) * +- mtk_dp->max_lanes); ++ u32 lane_count_min = mtk_dp->train_info.lane_count; ++ u32 rate = drm_dp_bw_code_to_link_rate(mtk_dp->train_info.link_rate) * ++ lane_count_min; + +- if (rate < mode->clock * bpp / 8) ++ /* ++ *FEC overhead is approximately 2.4% from DP 1.4a spec 2.2.1.4.2. ++ *The down-spread amplitude shall either be disabled (0.0%) or up ++ *to 0.5% from 1.4a 3.5.2.6. Add up to approximately 3% total overhead. ++ * ++ *Because rate is already divided by 10, ++ *mode->clock does not need to be multiplied by 10 ++ */ ++ if ((rate * 97 / 100) < (mode->clock * bpp / 8)) + return MODE_CLOCK_HIGH; + + return MODE_OK; +@@ -2356,10 +2365,9 @@ static u32 *mtk_dp_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, + struct drm_display_mode *mode = &crtc_state->adjusted_mode; + struct drm_display_info *display_info = + &conn_state->connector->display_info; +- u32 rate = min_t(u32, drm_dp_max_link_rate(mtk_dp->rx_cap) * +- drm_dp_max_lane_count(mtk_dp->rx_cap), +- drm_dp_bw_code_to_link_rate(mtk_dp->max_linkrate) * +- mtk_dp->max_lanes); ++ u32 lane_count_min = mtk_dp->train_info.lane_count; ++ u32 rate = drm_dp_bw_code_to_link_rate(mtk_dp->train_info.link_rate) * ++ lane_count_min; + + *num_input_fmts = 0; + +@@ -2368,8 +2376,8 @@ static u32 *mtk_dp_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, + * datarate of YUV422 and sink device supports YUV422, we output YUV422 + * format. Use this condition, we can support more resolution. + */ +- if ((rate < (mode->clock * 24 / 8)) && +- (rate > (mode->clock * 16 / 8)) && ++ if (((rate * 97 / 100) < (mode->clock * 24 / 8)) && ++ ((rate * 97 / 100) > (mode->clock * 16 / 8)) && + (display_info->color_formats & DRM_COLOR_FORMAT_YCBCR422)) { + input_fmts = kcalloc(1, sizeof(*input_fmts), GFP_KERNEL); + if (!input_fmts) +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c +index 600f4ccc90d378..8b41a07c3641f5 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c ++++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c +@@ -633,6 +633,8 @@ static int mtk_drm_bind(struct device *dev) + err_free: + private->drm = NULL; + drm_dev_put(drm); ++ for (i = 0; i < private->data->mmsys_dev_num; i++) ++ private->all_drm_private[i]->drm = NULL; + return ret; + } + +diff --git a/drivers/hwmon/drivetemp.c b/drivers/hwmon/drivetemp.c +index 6bdd21aa005ab8..2a4ec55ddb47ed 100644 +--- a/drivers/hwmon/drivetemp.c ++++ b/drivers/hwmon/drivetemp.c +@@ -165,6 +165,7 @@ static int drivetemp_scsi_command(struct drivetemp_data *st, + { + u8 scsi_cmd[MAX_COMMAND_SIZE]; + enum req_op op; ++ int err; + + memset(scsi_cmd, 0, sizeof(scsi_cmd)); + scsi_cmd[0] = ATA_16; +@@ -192,8 +193,11 @@ static int drivetemp_scsi_command(struct drivetemp_data *st, + scsi_cmd[12] = lba_high; + scsi_cmd[14] = ata_command; + +- return scsi_execute_cmd(st->sdev, scsi_cmd, op, st->smartdata, +- ATA_SECT_SIZE, HZ, 5, NULL); ++ err = scsi_execute_cmd(st->sdev, scsi_cmd, op, st->smartdata, ++ ATA_SECT_SIZE, HZ, 5, NULL); ++ if (err > 0) ++ err = -EIO; ++ return err; + } + + static int drivetemp_ata_command(struct drivetemp_data *st, u8 feature, +diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c +index 34e06e2e51d625..d2060d394c8d27 100644 +--- a/drivers/iio/adc/ad7124.c ++++ b/drivers/iio/adc/ad7124.c +@@ -923,6 +923,9 @@ static int ad7124_setup(struct ad7124_state *st) + * set all channels to this default value. + */ + ad7124_set_channel_odr(st, i, 10); ++ ++ /* Disable all channels to prevent unintended conversions. */ ++ ad_sd_write_reg(&st->sd, AD7124_CHANNEL(i), 2, 0); + } + + return ret; +diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c +index de6650f9c4b1c2..55f0c1afe505e7 100644 +--- a/drivers/iio/adc/at91_adc.c ++++ b/drivers/iio/adc/at91_adc.c +@@ -984,7 +984,7 @@ static int at91_ts_register(struct iio_dev *idev, + return ret; + + err: +- input_free_device(st->ts_input); ++ input_free_device(input); + return ret; + } + +diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c +index 1c0042fbbb5481..929cba215d99ab 100644 +--- a/drivers/iio/adc/rockchip_saradc.c ++++ b/drivers/iio/adc/rockchip_saradc.c +@@ -368,6 +368,8 @@ static irqreturn_t rockchip_saradc_trigger_handler(int irq, void *p) + int ret; + int i, j = 0; + ++ memset(&data, 0, sizeof(data)); ++ + mutex_lock(&info->lock); + + for_each_set_bit(i, i_dev->active_scan_mask, i_dev->masklength) { +diff --git a/drivers/iio/adc/ti-ads124s08.c b/drivers/iio/adc/ti-ads124s08.c +index 4ca62121f0d176..c6004f2b5d3d1c 100644 +--- a/drivers/iio/adc/ti-ads124s08.c ++++ b/drivers/iio/adc/ti-ads124s08.c +@@ -183,9 +183,9 @@ static int ads124s_reset(struct iio_dev *indio_dev) + struct ads124s_private *priv = iio_priv(indio_dev); + + if (priv->reset_gpio) { +- gpiod_set_value(priv->reset_gpio, 0); ++ gpiod_set_value_cansleep(priv->reset_gpio, 0); + udelay(200); +- gpiod_set_value(priv->reset_gpio, 1); ++ gpiod_set_value_cansleep(priv->reset_gpio, 1); + } else { + return ads124s_write_cmd(indio_dev, ADS124S08_CMD_RESET); + } +diff --git a/drivers/iio/adc/ti-ads8688.c b/drivers/iio/adc/ti-ads8688.c +index ef06a897421ac4..66a3b67019b8d9 100644 +--- a/drivers/iio/adc/ti-ads8688.c ++++ b/drivers/iio/adc/ti-ads8688.c +@@ -382,7 +382,7 @@ static irqreturn_t ads8688_trigger_handler(int irq, void *p) + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + /* Ensure naturally aligned timestamp */ +- u16 buffer[ADS8688_MAX_CHANNELS + sizeof(s64)/sizeof(u16)] __aligned(8); ++ u16 buffer[ADS8688_MAX_CHANNELS + sizeof(s64)/sizeof(u16)] __aligned(8) = { }; + int i, j = 0; + + for (i = 0; i < indio_dev->masklength; i++) { +diff --git a/drivers/iio/dummy/iio_simple_dummy_buffer.c b/drivers/iio/dummy/iio_simple_dummy_buffer.c +index 9b2f99449a8292..bc85fe6610c138 100644 +--- a/drivers/iio/dummy/iio_simple_dummy_buffer.c ++++ b/drivers/iio/dummy/iio_simple_dummy_buffer.c +@@ -48,7 +48,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) + int i = 0, j; + u16 *data; + +- data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); ++ data = kzalloc(indio_dev->scan_bytes, GFP_KERNEL); + if (!data) + goto done; + +diff --git a/drivers/iio/gyro/fxas21002c_core.c b/drivers/iio/gyro/fxas21002c_core.c +index c28d17ca6f5ee0..aabc5e2d788d15 100644 +--- a/drivers/iio/gyro/fxas21002c_core.c ++++ b/drivers/iio/gyro/fxas21002c_core.c +@@ -730,14 +730,21 @@ static irqreturn_t fxas21002c_trigger_handler(int irq, void *p) + int ret; + + mutex_lock(&data->lock); ++ ret = fxas21002c_pm_get(data); ++ if (ret < 0) ++ goto out_unlock; ++ + ret = regmap_bulk_read(data->regmap, FXAS21002C_REG_OUT_X_MSB, + data->buffer, CHANNEL_SCAN_MAX * sizeof(s16)); + if (ret < 0) +- goto out_unlock; ++ goto out_pm_put; + + iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + data->timestamp); + ++out_pm_put: ++ fxas21002c_pm_put(data); ++ + out_unlock: + mutex_unlock(&data->lock); + +diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +index a5e81906e37ecf..d938bc45439729 100644 +--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c ++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +@@ -17,6 +17,7 @@ + #include + + #include ++#include + + #include "inv_icm42600.h" + #include "inv_icm42600_buffer.h" +@@ -725,6 +726,8 @@ static int inv_icm42600_suspend(struct device *dev) + static int inv_icm42600_resume(struct device *dev) + { + struct inv_icm42600_state *st = dev_get_drvdata(dev); ++ struct inv_sensors_timestamp *gyro_ts = iio_priv(st->indio_gyro); ++ struct inv_sensors_timestamp *accel_ts = iio_priv(st->indio_accel); + int ret; + + mutex_lock(&st->lock); +@@ -745,9 +748,12 @@ static int inv_icm42600_resume(struct device *dev) + goto out_unlock; + + /* restore FIFO data streaming */ +- if (st->fifo.on) ++ if (st->fifo.on) { ++ inv_sensors_timestamp_reset(gyro_ts); ++ inv_sensors_timestamp_reset(accel_ts); + ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG, + INV_ICM42600_FIFO_CONFIG_STREAM); ++ } + + out_unlock: + mutex_unlock(&st->lock); +diff --git a/drivers/iio/imu/kmx61.c b/drivers/iio/imu/kmx61.c +index 958167b31241e6..09d2db8f8bae14 100644 +--- a/drivers/iio/imu/kmx61.c ++++ b/drivers/iio/imu/kmx61.c +@@ -1192,7 +1192,7 @@ static irqreturn_t kmx61_trigger_handler(int irq, void *p) + struct kmx61_data *data = kmx61_get_data(indio_dev); + int bit, ret, i = 0; + u8 base; +- s16 buffer[8]; ++ s16 buffer[8] = { }; + + if (indio_dev == data->acc_indio_dev) + base = KMX61_ACC_XOUT_L; +diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c +index 079e30c522bbd0..8255035ff124f3 100644 +--- a/drivers/iio/inkern.c ++++ b/drivers/iio/inkern.c +@@ -514,7 +514,7 @@ struct iio_channel *iio_channel_get_all(struct device *dev) + return chans; + + error_free_chans: +- for (i = 0; i < nummaps; i++) ++ for (i = 0; i < mapind; i++) + iio_device_put(chans[i].indio_dev); + kfree(chans); + error_ret: +diff --git a/drivers/iio/light/vcnl4035.c b/drivers/iio/light/vcnl4035.c +index 56bbefbc0ae643..fe3c4c5db6205d 100644 +--- a/drivers/iio/light/vcnl4035.c ++++ b/drivers/iio/light/vcnl4035.c +@@ -105,7 +105,7 @@ static irqreturn_t vcnl4035_trigger_consumer_handler(int irq, void *p) + struct iio_dev *indio_dev = pf->indio_dev; + struct vcnl4035_data *data = iio_priv(indio_dev); + /* Ensure naturally aligned timestamp */ +- u8 buffer[ALIGN(sizeof(u16), sizeof(s64)) + sizeof(s64)] __aligned(8); ++ u8 buffer[ALIGN(sizeof(u16), sizeof(s64)) + sizeof(s64)] __aligned(8) = { }; + int ret; + + ret = regmap_read(data->regmap, VCNL4035_ALS_DATA, (int *)buffer); +diff --git a/drivers/iio/pressure/zpa2326.c b/drivers/iio/pressure/zpa2326.c +index 421e059d1f190a..ef1d0349f4247d 100644 +--- a/drivers/iio/pressure/zpa2326.c ++++ b/drivers/iio/pressure/zpa2326.c +@@ -586,6 +586,8 @@ static int zpa2326_fill_sample_buffer(struct iio_dev *indio_dev, + } sample; + int err; + ++ memset(&sample, 0, sizeof(sample)); ++ + if (test_bit(0, indio_dev->active_scan_mask)) { + /* Get current pressure from hardware FIFO. */ + err = zpa2326_dequeue_pressure(indio_dev, &sample.pressure); +diff --git a/drivers/md/dm-ebs-target.c b/drivers/md/dm-ebs-target.c +index 435b45201f4d61..66d9622b684dd4 100644 +--- a/drivers/md/dm-ebs-target.c ++++ b/drivers/md/dm-ebs-target.c +@@ -442,7 +442,7 @@ static int ebs_iterate_devices(struct dm_target *ti, + static struct target_type ebs_target = { + .name = "ebs", + .version = {1, 0, 1}, +- .features = DM_TARGET_PASSES_INTEGRITY, ++ .features = 0, + .module = THIS_MODULE, + .ctr = ebs_ctr, + .dtr = ebs_dtr, +diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c +index 032cefe3e351aa..7935363d13b1d0 100644 +--- a/drivers/md/dm-thin.c ++++ b/drivers/md/dm-thin.c +@@ -2334,10 +2334,9 @@ static struct thin_c *get_first_thin(struct pool *pool) + struct thin_c *tc = NULL; + + rcu_read_lock(); +- if (!list_empty(&pool->active_thins)) { +- tc = list_entry_rcu(pool->active_thins.next, struct thin_c, list); ++ tc = list_first_or_null_rcu(&pool->active_thins, struct thin_c, list); ++ if (tc) + thin_get(tc); +- } + rcu_read_unlock(); + + return tc; +diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c +index b475200d8586a6..6a7a17c489c998 100644 +--- a/drivers/md/dm-verity-fec.c ++++ b/drivers/md/dm-verity-fec.c +@@ -60,14 +60,19 @@ static int fec_decode_rs8(struct dm_verity *v, struct dm_verity_fec_io *fio, + * to the data block. Caller is responsible for releasing buf. + */ + static u8 *fec_read_parity(struct dm_verity *v, u64 rsb, int index, +- unsigned int *offset, struct dm_buffer **buf) ++ unsigned int *offset, unsigned int par_buf_offset, ++ struct dm_buffer **buf) + { + u64 position, block, rem; + u8 *res; + ++ /* We have already part of parity bytes read, skip to the next block */ ++ if (par_buf_offset) ++ index++; ++ + position = (index + rsb) * v->fec->roots; + block = div64_u64_rem(position, v->fec->io_size, &rem); +- *offset = (unsigned int)rem; ++ *offset = par_buf_offset ? 0 : (unsigned int)rem; + + res = dm_bufio_read(v->fec->bufio, block, buf); + if (IS_ERR(res)) { +@@ -127,10 +132,11 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio, + { + int r, corrected = 0, res; + struct dm_buffer *buf; +- unsigned int n, i, offset; +- u8 *par, *block; ++ unsigned int n, i, offset, par_buf_offset = 0; ++ u8 *par, *block, par_buf[DM_VERITY_FEC_RSM - DM_VERITY_FEC_MIN_RSN]; + +- par = fec_read_parity(v, rsb, block_offset, &offset, &buf); ++ par = fec_read_parity(v, rsb, block_offset, &offset, ++ par_buf_offset, &buf); + if (IS_ERR(par)) + return PTR_ERR(par); + +@@ -140,7 +146,8 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio, + */ + fec_for_each_buffer_rs_block(fio, n, i) { + block = fec_buffer_rs_block(v, fio, n, i); +- res = fec_decode_rs8(v, fio, block, &par[offset], neras); ++ memcpy(&par_buf[par_buf_offset], &par[offset], v->fec->roots - par_buf_offset); ++ res = fec_decode_rs8(v, fio, block, par_buf, neras); + if (res < 0) { + r = res; + goto error; +@@ -153,12 +160,21 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio, + if (block_offset >= 1 << v->data_dev_block_bits) + goto done; + +- /* read the next block when we run out of parity bytes */ +- offset += v->fec->roots; ++ /* Read the next block when we run out of parity bytes */ ++ offset += (v->fec->roots - par_buf_offset); ++ /* Check if parity bytes are split between blocks */ ++ if (offset < v->fec->io_size && (offset + v->fec->roots) > v->fec->io_size) { ++ par_buf_offset = v->fec->io_size - offset; ++ memcpy(par_buf, &par[offset], par_buf_offset); ++ offset += par_buf_offset; ++ } else ++ par_buf_offset = 0; ++ + if (offset >= v->fec->io_size) { + dm_bufio_release(buf); + +- par = fec_read_parity(v, rsb, block_offset, &offset, &buf); ++ par = fec_read_parity(v, rsb, block_offset, &offset, ++ par_buf_offset, &buf); + if (IS_ERR(par)) + return PTR_ERR(par); + } +@@ -743,10 +759,7 @@ int verity_fec_ctr(struct dm_verity *v) + return -E2BIG; + } + +- if ((f->roots << SECTOR_SHIFT) & ((1 << v->data_dev_block_bits) - 1)) +- f->io_size = 1 << v->data_dev_block_bits; +- else +- f->io_size = v->fec->roots << SECTOR_SHIFT; ++ f->io_size = 1 << v->data_dev_block_bits; + + f->bufio = dm_bufio_client_create(f->dev->bdev, + f->io_size, +diff --git a/drivers/md/persistent-data/dm-array.c b/drivers/md/persistent-data/dm-array.c +index 798c9c53a34353..b1fdfe53e93778 100644 +--- a/drivers/md/persistent-data/dm-array.c ++++ b/drivers/md/persistent-data/dm-array.c +@@ -917,23 +917,27 @@ static int load_ablock(struct dm_array_cursor *c) + if (c->block) + unlock_ablock(c->info, c->block); + +- c->block = NULL; +- c->ab = NULL; + c->index = 0; + + r = dm_btree_cursor_get_value(&c->cursor, &key, &value_le); + if (r) { + DMERR("dm_btree_cursor_get_value failed"); +- dm_btree_cursor_end(&c->cursor); ++ goto out; + + } else { + r = get_ablock(c->info, le64_to_cpu(value_le), &c->block, &c->ab); + if (r) { + DMERR("get_ablock failed"); +- dm_btree_cursor_end(&c->cursor); ++ goto out; + } + } + ++ return 0; ++ ++out: ++ dm_btree_cursor_end(&c->cursor); ++ c->block = NULL; ++ c->ab = NULL; + return r; + } + +@@ -956,10 +960,10 @@ EXPORT_SYMBOL_GPL(dm_array_cursor_begin); + + void dm_array_cursor_end(struct dm_array_cursor *c) + { +- if (c->block) { ++ if (c->block) + unlock_ablock(c->info, c->block); +- dm_btree_cursor_end(&c->cursor); +- } ++ ++ dm_btree_cursor_end(&c->cursor); + } + EXPORT_SYMBOL_GPL(dm_array_cursor_end); + +@@ -999,6 +1003,7 @@ int dm_array_cursor_skip(struct dm_array_cursor *c, uint32_t count) + } + + count -= remaining; ++ c->index += (remaining - 1); + r = dm_array_cursor_next(c); + + } while (!r); +diff --git a/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gpio.c b/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gpio.c +index e616e3ec2b42fd..3c1359d8d4e692 100644 +--- a/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gpio.c ++++ b/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gpio.c +@@ -148,7 +148,7 @@ static int pci1xxxx_gpio_set_config(struct gpio_chip *gpio, unsigned int offset, + pci1xxx_assign_bit(priv->reg_base, OPENDRAIN_OFFSET(offset), (offset % 32), true); + break; + default: +- ret = -EOPNOTSUPP; ++ ret = -ENOTSUPP; + break; + } + spin_unlock_irqrestore(&priv->lock, flags); +@@ -277,7 +277,7 @@ static irqreturn_t pci1xxxx_gpio_irq_handler(int irq, void *dev_id) + writel(BIT(bit), priv->reg_base + INTR_STATUS_OFFSET(gpiobank)); + spin_unlock_irqrestore(&priv->lock, flags); + irq = irq_find_mapping(gc->irq.domain, (bit + (gpiobank * 32))); +- generic_handle_irq(irq); ++ handle_nested_irq(irq); + } + } + spin_lock_irqsave(&priv->lock, flags); +diff --git a/drivers/net/ethernet/amd/pds_core/devlink.c b/drivers/net/ethernet/amd/pds_core/devlink.c +index d8218bb153d9ed..971d4278280d65 100644 +--- a/drivers/net/ethernet/amd/pds_core/devlink.c ++++ b/drivers/net/ethernet/amd/pds_core/devlink.c +@@ -117,7 +117,7 @@ int pdsc_dl_info_get(struct devlink *dl, struct devlink_info_req *req, + if (err && err != -EIO) + return err; + +- listlen = fw_list.num_fw_slots; ++ listlen = min(fw_list.num_fw_slots, ARRAY_SIZE(fw_list.fw_names)); + for (i = 0; i < listlen; i++) { + if (i < ARRAY_SIZE(fw_slotnames)) + strscpy(buf, fw_slotnames[i], sizeof(buf)); +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c +index 7689086371e03c..2980963208cbf4 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c +@@ -159,7 +159,7 @@ int bnxt_send_msg(struct bnxt_en_dev *edev, + + rc = hwrm_req_replace(bp, req, fw_msg->msg, fw_msg->msg_len); + if (rc) +- return rc; ++ goto drop_req; + + hwrm_req_timeout(bp, req, fw_msg->timeout); + resp = hwrm_req_hold(bp, req); +@@ -171,6 +171,7 @@ int bnxt_send_msg(struct bnxt_en_dev *edev, + + memcpy(fw_msg->resp, resp, resp_len); + } ++drop_req: + hwrm_req_drop(bp, req); + return rc; + } +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +index b215ff14da1bc4..3989c9491f0f1e 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +@@ -1799,7 +1799,10 @@ void cxgb4_remove_tid(struct tid_info *t, unsigned int chan, unsigned int tid, + struct adapter *adap = container_of(t, struct adapter, tids); + struct sk_buff *skb; + +- WARN_ON(tid_out_of_range(&adap->tids, tid)); ++ if (tid_out_of_range(&adap->tids, tid)) { ++ dev_err(adap->pdev_dev, "tid %d out of range\n", tid); ++ return; ++ } + + if (t->tid_tab[tid - adap->tids.tid_base]) { + t->tid_tab[tid - adap->tids.tid_base] = NULL; +diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c +index d70305654e7d07..90d433b36799fb 100644 +--- a/drivers/net/ethernet/google/gve/gve_main.c ++++ b/drivers/net/ethernet/google/gve/gve_main.c +@@ -2009,14 +2009,18 @@ static void gve_service_task(struct work_struct *work) + + static void gve_set_netdev_xdp_features(struct gve_priv *priv) + { ++ xdp_features_t xdp_features; ++ + if (priv->queue_format == GVE_GQI_QPL_FORMAT) { +- priv->dev->xdp_features = NETDEV_XDP_ACT_BASIC; +- priv->dev->xdp_features |= NETDEV_XDP_ACT_REDIRECT; +- priv->dev->xdp_features |= NETDEV_XDP_ACT_NDO_XMIT; +- priv->dev->xdp_features |= NETDEV_XDP_ACT_XSK_ZEROCOPY; ++ xdp_features = NETDEV_XDP_ACT_BASIC; ++ xdp_features |= NETDEV_XDP_ACT_REDIRECT; ++ xdp_features |= NETDEV_XDP_ACT_NDO_XMIT; ++ xdp_features |= NETDEV_XDP_ACT_XSK_ZEROCOPY; + } else { +- priv->dev->xdp_features = 0; ++ xdp_features = 0; + } ++ ++ xdp_set_features_flag(priv->dev, xdp_features); + } + + static int gve_init_priv(struct gve_priv *priv, bool skip_describe_device) +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_consts.h b/drivers/net/ethernet/intel/ice/ice_ptp_consts.h +index 4109aa3b2fcd33..87ce20540f572d 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp_consts.h ++++ b/drivers/net/ethernet/intel/ice/ice_ptp_consts.h +@@ -359,9 +359,9 @@ const struct ice_vernier_info_e822 e822_vernier[NUM_ICE_PTP_LNK_SPD] = { + /* rx_desk_rsgb_par */ + 644531250, /* 644.53125 MHz Reed Solomon gearbox */ + /* tx_desk_rsgb_pcs */ +- 644531250, /* 644.53125 MHz Reed Solomon gearbox */ ++ 390625000, /* 390.625 MHz Reed Solomon gearbox */ + /* rx_desk_rsgb_pcs */ +- 644531250, /* 644.53125 MHz Reed Solomon gearbox */ ++ 390625000, /* 390.625 MHz Reed Solomon gearbox */ + /* tx_fixed_delay */ + 1620, + /* pmd_adj_divisor */ +diff --git a/drivers/net/ethernet/intel/igc/igc_base.c b/drivers/net/ethernet/intel/igc/igc_base.c +index a1d815af507d90..1613b562d17c52 100644 +--- a/drivers/net/ethernet/intel/igc/igc_base.c ++++ b/drivers/net/ethernet/intel/igc/igc_base.c +@@ -68,8 +68,11 @@ static s32 igc_init_nvm_params_base(struct igc_hw *hw) + u32 eecd = rd32(IGC_EECD); + u16 size; + +- size = (u16)((eecd & IGC_EECD_SIZE_EX_MASK) >> +- IGC_EECD_SIZE_EX_SHIFT); ++ /* failed to read reg and got all F's */ ++ if (!(~eecd)) ++ return -ENXIO; ++ ++ size = FIELD_GET(IGC_EECD_SIZE_EX_MASK, eecd); + + /* Added to a constant, "size" becomes the left-shift value + * for setting word_size. +@@ -162,8 +165,7 @@ static s32 igc_init_phy_params_base(struct igc_hw *hw) + phy->reset_delay_us = 100; + + /* set lan id */ +- hw->bus.func = (rd32(IGC_STATUS) & IGC_STATUS_FUNC_MASK) >> +- IGC_STATUS_FUNC_SHIFT; ++ hw->bus.func = FIELD_GET(IGC_STATUS_FUNC_MASK, rd32(IGC_STATUS)); + + /* Make sure the PHY is in a good state. Several people have reported + * firmware leaving the PHY's page select register set to something +@@ -223,6 +225,8 @@ static s32 igc_get_invariants_base(struct igc_hw *hw) + + /* NVM initialization */ + ret_val = igc_init_nvm_params_base(hw); ++ if (ret_val) ++ goto out; + switch (hw->mac.type) { + case igc_i225: + ret_val = igc_init_nvm_params_i225(hw); +diff --git a/drivers/net/ethernet/intel/igc/igc_i225.c b/drivers/net/ethernet/intel/igc/igc_i225.c +index d2562c8e8015e7..0dd61719f1edc4 100644 +--- a/drivers/net/ethernet/intel/igc/igc_i225.c ++++ b/drivers/net/ethernet/intel/igc/igc_i225.c +@@ -579,9 +579,8 @@ s32 igc_set_ltr_i225(struct igc_hw *hw, bool link) + + /* Calculate tw_system (nsec). */ + if (speed == SPEED_100) { +- tw_system = ((rd32(IGC_EEE_SU) & +- IGC_TW_SYSTEM_100_MASK) >> +- IGC_TW_SYSTEM_100_SHIFT) * 500; ++ tw_system = FIELD_GET(IGC_TW_SYSTEM_100_MASK, ++ rd32(IGC_EEE_SU)) * 500; + } else { + tw_system = (rd32(IGC_EEE_SU) & + IGC_TW_SYSTEM_1000_MASK) * 500; +diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c +index da1018d8326220..91a4722460f66a 100644 +--- a/drivers/net/ethernet/intel/igc/igc_main.c ++++ b/drivers/net/ethernet/intel/igc/igc_main.c +@@ -3708,8 +3708,7 @@ static int igc_enable_nfc_rule(struct igc_adapter *adapter, + } + + if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) { +- int prio = (rule->filter.vlan_tci & VLAN_PRIO_MASK) >> +- VLAN_PRIO_SHIFT; ++ int prio = FIELD_GET(VLAN_PRIO_MASK, rule->filter.vlan_tci); + + err = igc_add_vlan_prio_filter(adapter, prio, rule->action); + if (err) +@@ -3731,8 +3730,7 @@ static void igc_disable_nfc_rule(struct igc_adapter *adapter, + igc_del_etype_filter(adapter, rule->filter.etype); + + if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) { +- int prio = (rule->filter.vlan_tci & VLAN_PRIO_MASK) >> +- VLAN_PRIO_SHIFT; ++ int prio = FIELD_GET(VLAN_PRIO_MASK, rule->filter.vlan_tci); + + igc_del_vlan_prio_filter(adapter, prio); + } +diff --git a/drivers/net/ethernet/intel/igc/igc_phy.c b/drivers/net/ethernet/intel/igc/igc_phy.c +index d0d9e7170154ca..7cd8716d2ffa3a 100644 +--- a/drivers/net/ethernet/intel/igc/igc_phy.c ++++ b/drivers/net/ethernet/intel/igc/igc_phy.c +@@ -727,7 +727,7 @@ static s32 igc_write_xmdio_reg(struct igc_hw *hw, u16 addr, + */ + s32 igc_write_phy_reg_gpy(struct igc_hw *hw, u32 offset, u16 data) + { +- u8 dev_addr = (offset & GPY_MMD_MASK) >> GPY_MMD_SHIFT; ++ u8 dev_addr = FIELD_GET(GPY_MMD_MASK, offset); + s32 ret_val; + + offset = offset & GPY_REG_MASK; +@@ -758,7 +758,7 @@ s32 igc_write_phy_reg_gpy(struct igc_hw *hw, u32 offset, u16 data) + */ + s32 igc_read_phy_reg_gpy(struct igc_hw *hw, u32 offset, u16 *data) + { +- u8 dev_addr = (offset & GPY_MMD_MASK) >> GPY_MMD_SHIFT; ++ u8 dev_addr = FIELD_GET(GPY_MMD_MASK, offset); + s32 ret_val; + + offset = offset & GPY_REG_MASK; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +index 80af0fc7101fdc..3e6bd27f6315d8 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +@@ -1006,6 +1006,7 @@ static void cmd_work_handler(struct work_struct *work) + complete(&ent->done); + } + up(&cmd->vars.sem); ++ complete(&ent->slotted); + return; + } + } else { +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c +index e2d61a3a7712d3..760405b805f40a 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c +@@ -1,4 +1,5 @@ + // SPDX-License-Identifier: GPL-2.0-only ++#include + #include + #include + #include +@@ -19,6 +20,8 @@ struct tegra_mgbe { + struct reset_control *rst_mac; + struct reset_control *rst_pcs; + ++ u32 iommu_sid; ++ + void __iomem *hv; + void __iomem *regs; + void __iomem *xpcs; +@@ -50,7 +53,6 @@ struct tegra_mgbe { + #define MGBE_WRAP_COMMON_INTR_ENABLE 0x8704 + #define MAC_SBD_INTR BIT(2) + #define MGBE_WRAP_AXI_ASID0_CTRL 0x8400 +-#define MGBE_SID 0x6 + + static int __maybe_unused tegra_mgbe_suspend(struct device *dev) + { +@@ -84,7 +86,7 @@ static int __maybe_unused tegra_mgbe_resume(struct device *dev) + writel(MAC_SBD_INTR, mgbe->regs + MGBE_WRAP_COMMON_INTR_ENABLE); + + /* Program SID */ +- writel(MGBE_SID, mgbe->hv + MGBE_WRAP_AXI_ASID0_CTRL); ++ writel(mgbe->iommu_sid, mgbe->hv + MGBE_WRAP_AXI_ASID0_CTRL); + + value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_STATUS); + if ((value & XPCS_WRAP_UPHY_STATUS_TX_P_UP) == 0) { +@@ -241,6 +243,12 @@ static int tegra_mgbe_probe(struct platform_device *pdev) + if (IS_ERR(mgbe->xpcs)) + return PTR_ERR(mgbe->xpcs); + ++ /* get controller's stream id from iommu property in device tree */ ++ if (!tegra_dev_iommu_get_stream_id(mgbe->dev, &mgbe->iommu_sid)) { ++ dev_err(mgbe->dev, "failed to get iommu stream id\n"); ++ return -EINVAL; ++ } ++ + res.addr = mgbe->regs; + res.irq = irq; + +@@ -346,7 +354,7 @@ static int tegra_mgbe_probe(struct platform_device *pdev) + writel(MAC_SBD_INTR, mgbe->regs + MGBE_WRAP_COMMON_INTR_ENABLE); + + /* Program SID */ +- writel(MGBE_SID, mgbe->hv + MGBE_WRAP_AXI_ASID0_CTRL); ++ writel(mgbe->iommu_sid, mgbe->hv + MGBE_WRAP_AXI_ASID0_CTRL); + + plat->flags |= STMMAC_FLAG_SERDES_UP_AFTER_PHY_LINKUP; + +diff --git a/drivers/net/ethernet/wangxun/libwx/wx_hw.c b/drivers/net/ethernet/wangxun/libwx/wx_hw.c +index 52130df26aee53..d6bc2309d2a388 100644 +--- a/drivers/net/ethernet/wangxun/libwx/wx_hw.c ++++ b/drivers/net/ethernet/wangxun/libwx/wx_hw.c +@@ -242,27 +242,25 @@ int wx_host_interface_command(struct wx *wx, u32 *buffer, + status = read_poll_timeout(rd32, hicr, hicr & WX_MNG_MBOX_CTL_FWRDY, 1000, + timeout * 1000, false, wx, WX_MNG_MBOX_CTL); + ++ buf[0] = rd32(wx, WX_MNG_MBOX); ++ if ((buf[0] & 0xff0000) >> 16 == 0x80) { ++ wx_err(wx, "Unknown FW command: 0x%x\n", buffer[0] & 0xff); ++ status = -EINVAL; ++ goto rel_out; ++ } ++ + /* Check command completion */ + if (status) { +- wx_dbg(wx, "Command has failed with no status valid.\n"); +- +- buf[0] = rd32(wx, WX_MNG_MBOX); +- if ((buffer[0] & 0xff) != (~buf[0] >> 24)) { +- status = -EINVAL; +- goto rel_out; +- } +- if ((buf[0] & 0xff0000) >> 16 == 0x80) { +- wx_dbg(wx, "It's unknown cmd.\n"); +- status = -EINVAL; +- goto rel_out; +- } +- ++ wx_err(wx, "Command has failed with no status valid.\n"); + wx_dbg(wx, "write value:\n"); + for (i = 0; i < dword_len; i++) + wx_dbg(wx, "%x ", buffer[i]); + wx_dbg(wx, "read value:\n"); + for (i = 0; i < dword_len; i++) + wx_dbg(wx, "%x ", buf[i]); ++ wx_dbg(wx, "\ncheck: %x %x\n", buffer[0] & 0xff, ~buf[0] >> 24); ++ ++ goto rel_out; + } + + if (!return_data) +diff --git a/drivers/net/ieee802154/ca8210.c b/drivers/net/ieee802154/ca8210.c +index 4ec0dab3887299..0a0ad3d77557f9 100644 +--- a/drivers/net/ieee802154/ca8210.c ++++ b/drivers/net/ieee802154/ca8210.c +@@ -3078,7 +3078,11 @@ static int ca8210_probe(struct spi_device *spi_device) + spi_set_drvdata(priv->spi, priv); + if (IS_ENABLED(CONFIG_IEEE802154_CA8210_DEBUGFS)) { + cascoda_api_upstream = ca8210_test_int_driver_write; +- ca8210_test_interface_init(priv); ++ ret = ca8210_test_interface_init(priv); ++ if (ret) { ++ dev_crit(&spi_device->dev, "ca8210_test_interface_init failed\n"); ++ goto error; ++ } + } else { + cascoda_api_upstream = NULL; + } +diff --git a/drivers/platform/x86/amd/pmc/pmc.c b/drivers/platform/x86/amd/pmc/pmc.c +index f49b1bb258c73d..70907e8f3ea96d 100644 +--- a/drivers/platform/x86/amd/pmc/pmc.c ++++ b/drivers/platform/x86/amd/pmc/pmc.c +@@ -878,6 +878,10 @@ static int amd_pmc_suspend_handler(struct device *dev) + { + struct amd_pmc_dev *pdev = dev_get_drvdata(dev); + ++ /* ++ * Must be called only from the same set of dev_pm_ops handlers ++ * as i8042_pm_suspend() is called: currently just from .suspend. ++ */ + if (pdev->disable_8042_wakeup && !disable_workarounds) { + int rc = amd_pmc_wa_irq1(pdev); + +@@ -890,7 +894,9 @@ static int amd_pmc_suspend_handler(struct device *dev) + return 0; + } + +-static DEFINE_SIMPLE_DEV_PM_OPS(amd_pmc_pm, amd_pmc_suspend_handler, NULL); ++static const struct dev_pm_ops amd_pmc_pm = { ++ .suspend = amd_pmc_suspend_handler, ++}; + + static const struct pci_device_id pmc_pci_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_PS) }, +diff --git a/drivers/pmdomain/imx/gpcv2.c b/drivers/pmdomain/imx/gpcv2.c +index fbd3d92f8cd8f2..13fce2b134f60a 100644 +--- a/drivers/pmdomain/imx/gpcv2.c ++++ b/drivers/pmdomain/imx/gpcv2.c +@@ -1449,12 +1449,12 @@ static int imx_gpcv2_probe(struct platform_device *pdev) + .max_register = SZ_4K, + }; + struct device *dev = &pdev->dev; +- struct device_node *pgc_np, *np; ++ struct device_node *pgc_np __free(device_node) = ++ of_get_child_by_name(dev->of_node, "pgc"); + struct regmap *regmap; + void __iomem *base; + int ret; + +- pgc_np = of_get_child_by_name(dev->of_node, "pgc"); + if (!pgc_np) { + dev_err(dev, "No power domains specified in DT\n"); + return -EINVAL; +@@ -1471,7 +1471,7 @@ static int imx_gpcv2_probe(struct platform_device *pdev) + return ret; + } + +- for_each_child_of_node(pgc_np, np) { ++ for_each_child_of_node_scoped(pgc_np, np) { + struct platform_device *pd_pdev; + struct imx_pgc_domain *domain; + u32 domain_index; +@@ -1482,7 +1482,6 @@ static int imx_gpcv2_probe(struct platform_device *pdev) + ret = of_property_read_u32(np, "reg", &domain_index); + if (ret) { + dev_err(dev, "Failed to read 'reg' property\n"); +- of_node_put(np); + return ret; + } + +@@ -1497,7 +1496,6 @@ static int imx_gpcv2_probe(struct platform_device *pdev) + domain_index); + if (!pd_pdev) { + dev_err(dev, "Failed to allocate platform device\n"); +- of_node_put(np); + return -ENOMEM; + } + +@@ -1506,7 +1504,6 @@ static int imx_gpcv2_probe(struct platform_device *pdev) + sizeof(domain_data->domains[domain_index])); + if (ret) { + platform_device_put(pd_pdev); +- of_node_put(np); + return ret; + } + +@@ -1523,7 +1520,6 @@ static int imx_gpcv2_probe(struct platform_device *pdev) + ret = platform_device_add(pd_pdev); + if (ret) { + platform_device_put(pd_pdev); +- of_node_put(np); + return ret; + } + } +diff --git a/drivers/staging/iio/frequency/ad9832.c b/drivers/staging/iio/frequency/ad9832.c +index d58d99d8375ea8..b40609b92980f5 100644 +--- a/drivers/staging/iio/frequency/ad9832.c ++++ b/drivers/staging/iio/frequency/ad9832.c +@@ -158,7 +158,7 @@ static int ad9832_write_frequency(struct ad9832_state *st, + static int ad9832_write_phase(struct ad9832_state *st, + unsigned long addr, unsigned long phase) + { +- if (phase > BIT(AD9832_PHASE_BITS)) ++ if (phase >= BIT(AD9832_PHASE_BITS)) + return -EINVAL; + + st->phase_data[0] = cpu_to_be16((AD9832_CMD_PHA8BITSW << CMD_SHIFT) | +diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c +index cfdfe66d74f17c..bc879f87237cb2 100644 +--- a/drivers/staging/iio/frequency/ad9834.c ++++ b/drivers/staging/iio/frequency/ad9834.c +@@ -131,7 +131,7 @@ static int ad9834_write_frequency(struct ad9834_state *st, + static int ad9834_write_phase(struct ad9834_state *st, + unsigned long addr, unsigned long phase) + { +- if (phase > BIT(AD9834_PHASE_BITS)) ++ if (phase >= BIT(AD9834_PHASE_BITS)) + return -EINVAL; + st->data = cpu_to_be16(addr | phase); + +diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c +index 4e5f86c2145616..0f520cf923a1e6 100644 +--- a/drivers/thermal/thermal_of.c ++++ b/drivers/thermal/thermal_of.c +@@ -203,6 +203,7 @@ static struct device_node *of_thermal_zone_find(struct device_node *sensor, int + goto out; + } + ++ of_node_put(sensor_specs.np); + if ((sensor == sensor_specs.np) && id == (sensor_specs.args_count ? + sensor_specs.args[0] : 0)) { + pr_debug("sensor %pOFn id=%d belongs to %pOFn\n", sensor, id, child); +diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c +index 3449f8790e462e..c536028e92dc2e 100644 +--- a/drivers/tty/serial/8250/8250_core.c ++++ b/drivers/tty/serial/8250/8250_core.c +@@ -1131,6 +1131,9 @@ int serial8250_register_8250_port(const struct uart_8250_port *up) + uart->dl_write = up->dl_write; + + if (uart->port.type != PORT_8250_CIR) { ++ if (uart_console_registered(&uart->port)) ++ pm_runtime_get_sync(uart->port.dev); ++ + if (serial8250_isa_config != NULL) + serial8250_isa_config(0, &uart->port, + &uart->capabilities); +diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h +index 099a54009a16f3..524863b157e8aa 100644 +--- a/drivers/ufs/core/ufshcd-priv.h ++++ b/drivers/ufs/core/ufshcd-priv.h +@@ -242,12 +242,6 @@ static inline void ufshcd_vops_config_scaling_param(struct ufs_hba *hba, + hba->vops->config_scaling_param(hba, p, data); + } + +-static inline void ufshcd_vops_reinit_notify(struct ufs_hba *hba) +-{ +- if (hba->vops && hba->vops->reinit_notify) +- hba->vops->reinit_notify(hba); +-} +- + static inline int ufshcd_vops_mcq_config_resource(struct ufs_hba *hba) + { + if (hba->vops && hba->vops->mcq_config_resource) +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index 84dac90500746b..02696c7f9beff9 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -8795,7 +8795,6 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool init_dev_params) + ufshcd_device_reset(hba); + ufs_put_device_desc(hba); + ufshcd_hba_stop(hba); +- ufshcd_vops_reinit_notify(hba); + ret = ufshcd_hba_enable(hba); + if (ret) { + dev_err(hba->dev, "Host controller enable failed\n"); +diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c +index 643157a92c62a7..c999acba0f30c3 100644 +--- a/drivers/ufs/host/ufs-qcom.c ++++ b/drivers/ufs/host/ufs-qcom.c +@@ -455,6 +455,11 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba) + dev_warn(hba->dev, "%s: host reset returned %d\n", + __func__, ret); + ++ if (phy->power_count) { ++ phy_power_off(phy); ++ phy_exit(phy); ++ } ++ + /* phy initialization - calibrate the phy */ + ret = phy_init(phy); + if (ret) { +@@ -1638,13 +1643,6 @@ static void ufs_qcom_config_scaling_param(struct ufs_hba *hba, + } + #endif + +-static void ufs_qcom_reinit_notify(struct ufs_hba *hba) +-{ +- struct ufs_qcom_host *host = ufshcd_get_variant(hba); +- +- phy_power_off(host->generic_phy); +-} +- + /* Resources */ + static const struct ufshcd_res_info ufs_res_info[RES_MAX] = { + {.name = "ufs_mem",}, +@@ -1887,7 +1885,6 @@ static const struct ufs_hba_variant_ops ufs_hba_qcom_vops = { + .device_reset = ufs_qcom_device_reset, + .config_scaling_param = ufs_qcom_config_scaling_param, + .program_key = ufs_qcom_ice_program_key, +- .reinit_notify = ufs_qcom_reinit_notify, + .mcq_config_resource = ufs_qcom_mcq_config_resource, + .get_hba_mac = ufs_qcom_get_hba_mac, + .op_runtime_config = ufs_qcom_op_runtime_config, +diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c +index 477af457c1a1f0..b3cbca361a9696 100644 +--- a/drivers/usb/chipidea/ci_hdrc_imx.c ++++ b/drivers/usb/chipidea/ci_hdrc_imx.c +@@ -362,25 +362,29 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) + data->pinctrl = devm_pinctrl_get(dev); + if (PTR_ERR(data->pinctrl) == -ENODEV) + data->pinctrl = NULL; +- else if (IS_ERR(data->pinctrl)) +- return dev_err_probe(dev, PTR_ERR(data->pinctrl), ++ else if (IS_ERR(data->pinctrl)) { ++ ret = dev_err_probe(dev, PTR_ERR(data->pinctrl), + "pinctrl get failed\n"); ++ goto err_put; ++ } + + data->hsic_pad_regulator = + devm_regulator_get_optional(dev, "hsic"); + if (PTR_ERR(data->hsic_pad_regulator) == -ENODEV) { + /* no pad regulator is needed */ + data->hsic_pad_regulator = NULL; +- } else if (IS_ERR(data->hsic_pad_regulator)) +- return dev_err_probe(dev, PTR_ERR(data->hsic_pad_regulator), ++ } else if (IS_ERR(data->hsic_pad_regulator)) { ++ ret = dev_err_probe(dev, PTR_ERR(data->hsic_pad_regulator), + "Get HSIC pad regulator error\n"); ++ goto err_put; ++ } + + if (data->hsic_pad_regulator) { + ret = regulator_enable(data->hsic_pad_regulator); + if (ret) { + dev_err(dev, + "Failed to enable HSIC pad regulator\n"); +- return ret; ++ goto err_put; + } + } + } +@@ -394,13 +398,14 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) + dev_err(dev, + "pinctrl_hsic_idle lookup failed, err=%ld\n", + PTR_ERR(pinctrl_hsic_idle)); +- return PTR_ERR(pinctrl_hsic_idle); ++ ret = PTR_ERR(pinctrl_hsic_idle); ++ goto err_put; + } + + ret = pinctrl_select_state(data->pinctrl, pinctrl_hsic_idle); + if (ret) { + dev_err(dev, "hsic_idle select failed, err=%d\n", ret); +- return ret; ++ goto err_put; + } + + data->pinctrl_hsic_active = pinctrl_lookup_state(data->pinctrl, +@@ -409,7 +414,8 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) + dev_err(dev, + "pinctrl_hsic_active lookup failed, err=%ld\n", + PTR_ERR(data->pinctrl_hsic_active)); +- return PTR_ERR(data->pinctrl_hsic_active); ++ ret = PTR_ERR(data->pinctrl_hsic_active); ++ goto err_put; + } + } + +@@ -513,6 +519,8 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) + if (pdata.flags & CI_HDRC_PMQOS) + cpu_latency_qos_remove_request(&data->pm_qos_req); + data->ci_pdev = NULL; ++err_put: ++ put_device(data->usbmisc_data->dev); + return ret; + } + +@@ -536,6 +544,7 @@ static void ci_hdrc_imx_remove(struct platform_device *pdev) + if (data->hsic_pad_regulator) + regulator_disable(data->hsic_pad_regulator); + } ++ put_device(data->usbmisc_data->dev); + } + + static void ci_hdrc_imx_shutdown(struct platform_device *pdev) +diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c +index 5a2e43331064eb..ff1a941fd2ede4 100644 +--- a/drivers/usb/class/usblp.c ++++ b/drivers/usb/class/usblp.c +@@ -1337,11 +1337,12 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol) + if (protocol < USBLP_FIRST_PROTOCOL || protocol > USBLP_LAST_PROTOCOL) + return -EINVAL; + ++ alts = usblp->protocol[protocol].alt_setting; ++ if (alts < 0) ++ return -EINVAL; ++ + /* Don't unnecessarily set the interface if there's a single alt. */ + if (usblp->intf->num_altsetting > 1) { +- alts = usblp->protocol[protocol].alt_setting; +- if (alts < 0) +- return -EINVAL; + r = usb_set_interface(usblp->dev, usblp->ifnum, alts); + if (r < 0) { + printk(KERN_ERR "usblp: can't set desired altsetting %d on interface %d\n", +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 1ba3feb5e19000..0944cfae8b5567 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -2633,13 +2633,13 @@ int usb_new_device(struct usb_device *udev) + err = sysfs_create_link(&udev->dev.kobj, + &port_dev->dev.kobj, "port"); + if (err) +- goto fail; ++ goto out_del_dev; + + err = sysfs_create_link(&port_dev->dev.kobj, + &udev->dev.kobj, "device"); + if (err) { + sysfs_remove_link(&udev->dev.kobj, "port"); +- goto fail; ++ goto out_del_dev; + } + + if (!test_and_set_bit(port1, hub->child_usage_bits)) +@@ -2651,6 +2651,8 @@ int usb_new_device(struct usb_device *udev) + pm_runtime_put_sync_autosuspend(&udev->dev); + return err; + ++out_del_dev: ++ device_del(&udev->dev); + fail: + usb_set_device_state(udev, USB_STATE_NOTATTACHED); + pm_runtime_disable(&udev->dev); +diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c +index 5fb3f55ef06db5..9dd4a4ee61e56b 100644 +--- a/drivers/usb/core/port.c ++++ b/drivers/usb/core/port.c +@@ -451,10 +451,11 @@ static int usb_port_runtime_suspend(struct device *dev) + static void usb_port_shutdown(struct device *dev) + { + struct usb_port *port_dev = to_usb_port(dev); ++ struct usb_device *udev = port_dev->child; + +- if (port_dev->child) { +- usb_disable_usb2_hardware_lpm(port_dev->child); +- usb_unlocked_disable_lpm(port_dev->child); ++ if (udev && !udev->port_is_suspended) { ++ usb_disable_usb2_hardware_lpm(udev); ++ usb_unlocked_disable_lpm(udev); + } + } + +diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h +index d00bf714a7ccfb..516bace7e1dced 100644 +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -451,6 +451,7 @@ + #define DWC3_DCTL_TRGTULST_SS_INACT (DWC3_DCTL_TRGTULST(6)) + + /* These apply for core versions 1.94a and later */ ++#define DWC3_DCTL_NYET_THRES_MASK (0xf << 20) + #define DWC3_DCTL_NYET_THRES(n) (((n) & 0xf) << 20) + + #define DWC3_DCTL_KEEP_CONNECT BIT(19) +diff --git a/drivers/usb/dwc3/dwc3-am62.c b/drivers/usb/dwc3/dwc3-am62.c +index ea6e29091c0c9a..056ab7246a3a2c 100644 +--- a/drivers/usb/dwc3/dwc3-am62.c ++++ b/drivers/usb/dwc3/dwc3-am62.c +@@ -284,6 +284,7 @@ static void dwc3_ti_remove(struct platform_device *pdev) + + pm_runtime_put_sync(dev); + pm_runtime_disable(dev); ++ pm_runtime_dont_use_autosuspend(dev); + pm_runtime_set_suspended(dev); + } + +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index 656460c0c1dd7e..9b8099cba41429 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -4208,8 +4208,10 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) + WARN_ONCE(DWC3_VER_IS_PRIOR(DWC3, 240A) && dwc->has_lpm_erratum, + "LPM Erratum not available on dwc3 revisions < 2.40a\n"); + +- if (dwc->has_lpm_erratum && !DWC3_VER_IS_PRIOR(DWC3, 240A)) ++ if (dwc->has_lpm_erratum && !DWC3_VER_IS_PRIOR(DWC3, 240A)) { ++ reg &= ~DWC3_DCTL_NYET_THRES_MASK; + reg |= DWC3_DCTL_NYET_THRES(dwc->lpm_nyet_threshold); ++ } + + dwc3_gadget_dctl_write_safe(dwc, reg); + } else { +diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig +index b3592bcb0f9668..c7fa0ec74f5e69 100644 +--- a/drivers/usb/gadget/Kconfig ++++ b/drivers/usb/gadget/Kconfig +@@ -210,6 +210,8 @@ config USB_F_MIDI + + config USB_F_MIDI2 + tristate ++ select SND_UMP ++ select SND_UMP_LEGACY_RAWMIDI + + config USB_F_HID + tristate +@@ -444,8 +446,6 @@ config USB_CONFIGFS_F_MIDI2 + depends on USB_CONFIGFS + depends on SND + select USB_LIBCOMPOSITE +- select SND_UMP +- select SND_UMP_LEGACY_RAWMIDI + select USB_F_MIDI2 + help + The MIDI 2.0 function driver provides the generic emulated +diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c +index 60a1abfc565474..3a80600d68068f 100644 +--- a/drivers/usb/gadget/configfs.c ++++ b/drivers/usb/gadget/configfs.c +@@ -824,11 +824,15 @@ static ssize_t gadget_string_s_store(struct config_item *item, const char *page, + { + struct gadget_string *string = to_gadget_string(item); + int size = min(sizeof(string->string), len + 1); ++ ssize_t cpy_len; + + if (len > USB_MAX_STRING_LEN) + return -EINVAL; + +- return strscpy(string->string, page, size); ++ cpy_len = strscpy(string->string, page, size); ++ if (cpy_len > 0 && string->string[cpy_len - 1] == '\n') ++ string->string[cpy_len - 1] = 0; ++ return len; + } + CONFIGFS_ATTR(gadget_string_, s); + +diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c +index fd0f4879f38e8b..4a88546b1b1576 100644 +--- a/drivers/usb/gadget/function/f_fs.c ++++ b/drivers/usb/gadget/function/f_fs.c +@@ -1810,7 +1810,7 @@ static int functionfs_bind(struct ffs_data *ffs, struct usb_composite_dev *cdev) + struct usb_gadget_strings **lang; + int first_id; + +- if (WARN_ON(ffs->state != FFS_ACTIVE ++ if ((ffs->state != FFS_ACTIVE + || test_and_set_bit(FFS_FL_BOUND, &ffs->flags))) + return -EBADFD; + +diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c +index b3dc5f5164f42c..eabd10817e1e7b 100644 +--- a/drivers/usb/gadget/function/f_uac2.c ++++ b/drivers/usb/gadget/function/f_uac2.c +@@ -1176,6 +1176,7 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) + uac2->as_in_alt = 0; + } + ++ std_ac_if_desc.bNumEndpoints = 0; + if (FUOUT_EN(uac2_opts) || FUIN_EN(uac2_opts)) { + uac2->int_ep = usb_ep_autoconfig(gadget, &fs_ep_int_desc); + if (!uac2->int_ep) { +diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c +index 729b0472bab098..fe2737e55f8e89 100644 +--- a/drivers/usb/gadget/function/u_serial.c ++++ b/drivers/usb/gadget/function/u_serial.c +@@ -1398,6 +1398,10 @@ void gserial_disconnect(struct gserial *gser) + /* REVISIT as above: how best to track this? */ + port->port_line_coding = gser->port_line_coding; + ++ /* disable endpoints, aborting down any active I/O */ ++ usb_ep_disable(gser->out); ++ usb_ep_disable(gser->in); ++ + port->port_usb = NULL; + gser->ioport = NULL; + if (port->port.count > 0) { +@@ -1409,10 +1413,6 @@ void gserial_disconnect(struct gserial *gser) + spin_unlock(&port->port_lock); + spin_unlock_irqrestore(&serial_port_lock, flags); + +- /* disable endpoints, aborting down any active I/O */ +- usb_ep_disable(gser->out); +- usb_ep_disable(gser->in); +- + /* finally, free any unused/unusable I/O buffers */ + spin_lock_irqsave(&port->port_lock, flags); + if (port->port.count == 0) +diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c +index 21fd26609252be..e3c391397e0f8c 100644 +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -223,6 +223,7 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */ + { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */ + { USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */ ++ { USB_DEVICE(0x1B93, 0x1013) }, /* Phoenix Contact UPS Device */ + { USB_DEVICE(0x1BA4, 0x0002) }, /* Silicon Labs 358x factory default */ + { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */ + { USB_DEVICE(0x1D6F, 0x0010) }, /* Seluxit ApS RF Dongle */ +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index ac1c13b269fc0b..86ac20e2874bab 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -621,7 +621,7 @@ static void option_instat_callback(struct urb *urb); + + /* MeiG Smart Technology products */ + #define MEIGSMART_VENDOR_ID 0x2dee +-/* MeiG Smart SRM825L based on Qualcomm 315 */ ++/* MeiG Smart SRM815/SRM825L based on Qualcomm 315 */ + #define MEIGSMART_PRODUCT_SRM825L 0x4d22 + /* MeiG Smart SLM320 based on UNISOC UIS8910 */ + #define MEIGSMART_PRODUCT_SLM320 0x4d41 +@@ -2405,6 +2405,7 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM320, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM770A, 0xff, 0, 0) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x30) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x40) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x60) }, +@@ -2412,6 +2413,7 @@ static const struct usb_device_id option_ids[] = { + .driver_info = NCTRL(1) }, + { USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0640, 0xff), /* TCL IK512 ECM */ + .driver_info = NCTRL(3) }, ++ { USB_DEVICE_INTERFACE_CLASS(0x2949, 0x8700, 0xff) }, /* Neoway N723-EA */ + { } /* Terminating entry */ + }; + MODULE_DEVICE_TABLE(usb, option_ids); +diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h +index e5ad23d86833d5..54f0b1c83317cd 100644 +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -255,6 +255,13 @@ UNUSUAL_DEV( 0x0421, 0x06aa, 0x1110, 0x1110, + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_MAX_SECTORS_64 ), + ++/* Added by Lubomir Rintel , a very fine chap */ ++UNUSUAL_DEV( 0x0421, 0x06c2, 0x0000, 0x0406, ++ "Nokia", ++ "Nokia 208", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_MAX_SECTORS_64 ), ++ + #ifdef NO_SDDR09 + UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100, + "Microtech", +diff --git a/drivers/usb/typec/tcpm/maxim_contaminant.c b/drivers/usb/typec/tcpm/maxim_contaminant.c +index f8504a90da2675..60f90272fed315 100644 +--- a/drivers/usb/typec/tcpm/maxim_contaminant.c ++++ b/drivers/usb/typec/tcpm/maxim_contaminant.c +@@ -137,7 +137,7 @@ static int max_contaminant_read_resistance_kohm(struct max_tcpci_chip *chip, + + mv = max_contaminant_read_adc_mv(chip, channel, sleep_msec, raw, true); + if (mv < 0) +- return ret; ++ return mv; + + /* OVP enable */ + ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, CCOVPDIS, 0); +@@ -159,7 +159,7 @@ static int max_contaminant_read_resistance_kohm(struct max_tcpci_chip *chip, + + mv = max_contaminant_read_adc_mv(chip, channel, sleep_msec, raw, true); + if (mv < 0) +- return ret; ++ return mv; + /* Disable current source */ + ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, SBURPCTRL, 0); + if (ret < 0) +diff --git a/fs/Kconfig b/fs/Kconfig +index aa7e03cc1941cb..02a9237807a779 100644 +--- a/fs/Kconfig ++++ b/fs/Kconfig +@@ -253,7 +253,7 @@ config TMPFS_QUOTA + config ARCH_SUPPORTS_HUGETLBFS + def_bool n + +-config HUGETLBFS ++menuconfig HUGETLBFS + bool "HugeTLB file system support" + depends on X86 || IA64 || SPARC64 || ARCH_SUPPORTS_HUGETLBFS || BROKEN + depends on (SYSFS || SYSCTL) +@@ -265,6 +265,17 @@ config HUGETLBFS + + If unsure, say N. + ++if HUGETLBFS ++config HUGETLB_PAGE_OPTIMIZE_VMEMMAP_DEFAULT_ON ++ bool "HugeTLB Vmemmap Optimization (HVO) defaults to on" ++ default n ++ depends on HUGETLB_PAGE_OPTIMIZE_VMEMMAP ++ help ++ The HugeTLB Vmemmap Optimization (HVO) defaults to off. Say Y here to ++ enable HVO by default. It can be disabled via hugetlb_free_vmemmap=off ++ (boot command line) or hugetlb_optimize_vmemmap (sysctl). ++endif # HUGETLBFS ++ + config HUGETLB_PAGE + def_bool HUGETLBFS + +@@ -273,14 +284,9 @@ config HUGETLB_PAGE_OPTIMIZE_VMEMMAP + depends on ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP + depends on SPARSEMEM_VMEMMAP + +-config HUGETLB_PAGE_OPTIMIZE_VMEMMAP_DEFAULT_ON +- bool "HugeTLB Vmemmap Optimization (HVO) defaults to on" +- default n +- depends on HUGETLB_PAGE_OPTIMIZE_VMEMMAP +- help +- The HugeTLB VmemmapvOptimization (HVO) defaults to off. Say Y here to +- enable HVO by default. It can be disabled via hugetlb_free_vmemmap=off +- (boot command line) or hugetlb_optimize_vmemmap (sysctl). ++config HUGETLB_PMD_PAGE_TABLE_SHARING ++ def_bool HUGETLB_PAGE ++ depends on ARCH_WANT_HUGE_PMD_SHARE && SPLIT_PMD_PTLOCKS + + config ARCH_HAS_GIGANTIC_PAGE + bool +diff --git a/fs/afs/afs.h b/fs/afs/afs.h +index 81815724db6c9b..25c17100798ba7 100644 +--- a/fs/afs/afs.h ++++ b/fs/afs/afs.h +@@ -10,7 +10,7 @@ + + #include + +-#define AFS_MAXCELLNAME 256 /* Maximum length of a cell name */ ++#define AFS_MAXCELLNAME 253 /* Maximum length of a cell name (DNS limited) */ + #define AFS_MAXVOLNAME 64 /* Maximum length of a volume name */ + #define AFS_MAXNSERVERS 8 /* Maximum servers in a basic volume record */ + #define AFS_NMAXNSERVERS 13 /* Maximum servers in a N/U-class volume record */ +diff --git a/fs/afs/afs_vl.h b/fs/afs/afs_vl.h +index 9c65ffb8a523bd..8da0899fbc0835 100644 +--- a/fs/afs/afs_vl.h ++++ b/fs/afs/afs_vl.h +@@ -13,6 +13,7 @@ + #define AFS_VL_PORT 7003 /* volume location service port */ + #define VL_SERVICE 52 /* RxRPC service ID for the Volume Location service */ + #define YFS_VL_SERVICE 2503 /* Service ID for AuriStor upgraded VL service */ ++#define YFS_VL_MAXCELLNAME 256 /* Maximum length of a cell name in YFS protocol */ + + enum AFSVL_Operations { + VLGETENTRYBYID = 503, /* AFS Get VLDB entry by ID */ +diff --git a/fs/afs/vl_alias.c b/fs/afs/vl_alias.c +index f04a80e4f5c3fa..83cf1bfbe343ae 100644 +--- a/fs/afs/vl_alias.c ++++ b/fs/afs/vl_alias.c +@@ -302,6 +302,7 @@ static char *afs_vl_get_cell_name(struct afs_cell *cell, struct key *key) + static int yfs_check_canonical_cell_name(struct afs_cell *cell, struct key *key) + { + struct afs_cell *master; ++ size_t name_len; + char *cell_name; + + cell_name = afs_vl_get_cell_name(cell, key); +@@ -313,8 +314,11 @@ static int yfs_check_canonical_cell_name(struct afs_cell *cell, struct key *key) + return 0; + } + +- master = afs_lookup_cell(cell->net, cell_name, strlen(cell_name), +- NULL, false); ++ name_len = strlen(cell_name); ++ if (!name_len || name_len > AFS_MAXCELLNAME) ++ master = ERR_PTR(-EOPNOTSUPP); ++ else ++ master = afs_lookup_cell(cell->net, cell_name, name_len, NULL, false); + kfree(cell_name); + if (IS_ERR(master)) + return PTR_ERR(master); +diff --git a/fs/afs/vlclient.c b/fs/afs/vlclient.c +index 00fca3c66ba616..16653f2ffe4f54 100644 +--- a/fs/afs/vlclient.c ++++ b/fs/afs/vlclient.c +@@ -671,7 +671,7 @@ static int afs_deliver_yfsvl_get_cell_name(struct afs_call *call) + return ret; + + namesz = ntohl(call->tmp); +- if (namesz > AFS_MAXCELLNAME) ++ if (namesz > YFS_VL_MAXCELLNAME) + return afs_protocol_error(call, afs_eproto_cellname_len); + paddedsz = (namesz + 3) & ~3; + call->count = namesz; +diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c +index a2d91d9f8a109d..6be092bb814fdc 100644 +--- a/fs/btrfs/scrub.c ++++ b/fs/btrfs/scrub.c +@@ -1538,6 +1538,10 @@ static int scrub_find_fill_first_stripe(struct btrfs_block_group *bg, + u64 extent_gen; + int ret; + ++ if (unlikely(!extent_root)) { ++ btrfs_err(fs_info, "no valid extent root for scrub"); ++ return -EUCLEAN; ++ } + memset(stripe->sectors, 0, sizeof(struct scrub_sector_verification) * + stripe->nr_sectors); + scrub_stripe_reset_bitmaps(stripe); +diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c +index 1c0e6167d8e73b..496e4c7c52a4e0 100644 +--- a/fs/erofs/zdata.c ++++ b/fs/erofs/zdata.c +@@ -1483,14 +1483,13 @@ static struct page *pickup_page_for_submission(struct z_erofs_pcluster *pcl, + goto out; + + lock_page(page); +- +- /* only true if page reclaim goes wrong, should never happen */ +- DBG_BUGON(justfound && PagePrivate(page)); +- +- /* the page is still in manage cache */ +- if (page->mapping == mc) { ++ if (likely(page->mapping == mc)) { + WRITE_ONCE(pcl->compressed_bvecs[nr].page, page); + ++ /* ++ * The cached folio is still in managed cache but without ++ * a valid `->private` pcluster hint. Let's reconnect them. ++ */ + if (!PagePrivate(page)) { + /* + * impossible to be !PagePrivate(page) for +@@ -1504,22 +1503,24 @@ static struct page *pickup_page_for_submission(struct z_erofs_pcluster *pcl, + SetPagePrivate(page); + } + +- /* no need to submit io if it is already up-to-date */ +- if (PageUptodate(page)) { +- unlock_page(page); +- page = NULL; ++ if (likely(page->private == (unsigned long)pcl)) { ++ /* don't submit cache I/Os again if already uptodate */ ++ if (PageUptodate(page)) { ++ unlock_page(page); ++ page = NULL; ++ ++ } ++ goto out; + } +- goto out; ++ /* ++ * Already linked with another pcluster, which only appears in ++ * crafted images by fuzzers for now. But handle this anyway. ++ */ ++ tocache = false; /* use temporary short-lived pages */ ++ } else { ++ DBG_BUGON(1); /* referenced managed folios can't be truncated */ ++ tocache = true; + } +- +- /* +- * the managed page has been truncated, it's unsafe to +- * reuse this one, let's allocate a new cache-managed page. +- */ +- DBG_BUGON(page->mapping); +- DBG_BUGON(!justfound); +- +- tocache = true; + unlock_page(page); + put_page(page); + out_allocpage: +@@ -1677,16 +1678,11 @@ static void z_erofs_submit_queue(struct z_erofs_decompress_frontend *f, + end = cur + pcl->pclusterpages; + + do { +- struct page *page; +- +- page = pickup_page_for_submission(pcl, i++, +- &f->pagepool, mc); +- if (!page) +- continue; ++ struct page *page = NULL; + + if (bio && (cur != last_index + 1 || + last_bdev != mdev.m_bdev)) { +-submit_bio_retry: ++drain_io: + submit_bio(bio); + if (memstall) { + psi_memstall_leave(&pflags); +@@ -1695,6 +1691,13 @@ static void z_erofs_submit_queue(struct z_erofs_decompress_frontend *f, + bio = NULL; + } + ++ if (!page) { ++ page = pickup_page_for_submission(pcl, i++, ++ &f->pagepool, mc); ++ if (!page) ++ continue; ++ } ++ + if (unlikely(PageWorkingset(page)) && !memstall) { + psi_memstall_enter(&pflags); + memstall = 1; +@@ -1715,7 +1718,7 @@ static void z_erofs_submit_queue(struct z_erofs_decompress_frontend *f, + } + + if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) +- goto submit_bio_retry; ++ goto drain_io; + + last_index = cur; + bypass = false; +@@ -1727,11 +1730,10 @@ static void z_erofs_submit_queue(struct z_erofs_decompress_frontend *f, + move_to_bypass_jobqueue(pcl, qtail, owned_head); + } while (owned_head != Z_EROFS_PCLUSTER_TAIL); + +- if (bio) { ++ if (bio) + submit_bio(bio); +- if (memstall) +- psi_memstall_leave(&pflags); +- } ++ if (memstall) ++ psi_memstall_leave(&pflags); + + /* + * although background is preferred, no one is pending for submission. +diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c +index 7a715016b96f34..f4f81e349cefe1 100644 +--- a/fs/exfat/dir.c ++++ b/fs/exfat/dir.c +@@ -125,7 +125,7 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent + type = exfat_get_entry_type(ep); + if (type == TYPE_UNUSED) { + brelse(bh); +- break; ++ goto out; + } + + if (type != TYPE_FILE && type != TYPE_DIR) { +@@ -189,6 +189,7 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent + } + } + ++out: + dir_entry->namebuf.lfn[0] = '\0'; + *cpos = EXFAT_DEN_TO_B(dentry); + return 0; +diff --git a/fs/exfat/fatent.c b/fs/exfat/fatent.c +index 56b870d9cc0def..428d862a1d2bfc 100644 +--- a/fs/exfat/fatent.c ++++ b/fs/exfat/fatent.c +@@ -216,6 +216,16 @@ static int __exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain + + if (err) + goto dec_used_clus; ++ ++ if (num_clusters >= sbi->num_clusters - EXFAT_FIRST_CLUSTER) { ++ /* ++ * The cluster chain includes a loop, scan the ++ * bitmap to get the number of used clusters. ++ */ ++ exfat_count_used_clusters(sb, &sbi->used_clusters); ++ ++ return 0; ++ } + } while (clu != EXFAT_EOF_CLUSTER); + } + +diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c +index b72fa103b9632a..aa0e7cc2489ac9 100644 +--- a/fs/f2fs/super.c ++++ b/fs/f2fs/super.c +@@ -4931,9 +4931,6 @@ static int __init init_f2fs_fs(void) + err = register_shrinker(&f2fs_shrinker_info, "f2fs-shrinker"); + if (err) + goto free_sysfs; +- err = register_filesystem(&f2fs_fs_type); +- if (err) +- goto free_shrinker; + f2fs_create_root_stats(); + err = f2fs_init_post_read_processing(); + if (err) +@@ -4956,7 +4953,12 @@ static int __init init_f2fs_fs(void) + err = f2fs_create_casefold_cache(); + if (err) + goto free_compress_cache; ++ err = register_filesystem(&f2fs_fs_type); ++ if (err) ++ goto free_casefold_cache; + return 0; ++free_casefold_cache: ++ f2fs_destroy_casefold_cache(); + free_compress_cache: + f2fs_destroy_compress_cache(); + free_compress_mempool: +@@ -4971,8 +4973,6 @@ static int __init init_f2fs_fs(void) + f2fs_destroy_post_read_processing(); + free_root_stats: + f2fs_destroy_root_stats(); +- unregister_filesystem(&f2fs_fs_type); +-free_shrinker: + unregister_shrinker(&f2fs_shrinker_info); + free_sysfs: + f2fs_exit_sysfs(); +@@ -4996,6 +4996,7 @@ static int __init init_f2fs_fs(void) + + static void __exit exit_f2fs_fs(void) + { ++ unregister_filesystem(&f2fs_fs_type); + f2fs_destroy_casefold_cache(); + f2fs_destroy_compress_cache(); + f2fs_destroy_compress_mempool(); +@@ -5004,7 +5005,6 @@ static void __exit exit_f2fs_fs(void) + f2fs_destroy_iostat_processing(); + f2fs_destroy_post_read_processing(); + f2fs_destroy_root_stats(); +- unregister_filesystem(&f2fs_fs_type); + unregister_shrinker(&f2fs_shrinker_info); + f2fs_exit_sysfs(); + f2fs_destroy_garbage_collection_cache(); +diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c +index 0cd7439470fc43..84663ff7dc5058 100644 +--- a/fs/jbd2/commit.c ++++ b/fs/jbd2/commit.c +@@ -777,9 +777,9 @@ void jbd2_journal_commit_transaction(journal_t *journal) + /* + * If the journal is not located on the file system device, + * then we must flush the file system device before we issue +- * the commit record ++ * the commit record and update the journal tail sequence. + */ +- if (commit_transaction->t_need_data_flush && ++ if ((commit_transaction->t_need_data_flush || update_tail) && + (journal->j_fs_dev != journal->j_dev) && + (journal->j_flags & JBD2_BARRIER)) + blkdev_issue_flush(journal->j_fs_dev); +diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c +index 4556e468902449..ce63d5fde9c3a8 100644 +--- a/fs/jbd2/revoke.c ++++ b/fs/jbd2/revoke.c +@@ -654,7 +654,7 @@ static void flush_descriptor(journal_t *journal, + set_buffer_jwrite(descriptor); + BUFFER_TRACE(descriptor, "write"); + set_buffer_dirty(descriptor); +- write_dirty_buffer(descriptor, REQ_SYNC); ++ write_dirty_buffer(descriptor, JBD2_JOURNAL_REQ_FLAGS); + } + #endif + +diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c +index ada3fcc9c6d501..f14c412c56097d 100644 +--- a/fs/overlayfs/copy_up.c ++++ b/fs/overlayfs/copy_up.c +@@ -371,13 +371,13 @@ int ovl_set_attr(struct ovl_fs *ofs, struct dentry *upperdentry, + return err; + } + +-struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct dentry *real, ++struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct inode *realinode, + bool is_upper) + { + struct ovl_fh *fh; + int fh_type, dwords; + int buflen = MAX_HANDLE_SZ; +- uuid_t *uuid = &real->d_sb->s_uuid; ++ uuid_t *uuid = &realinode->i_sb->s_uuid; + int err; + + /* Make sure the real fid stays 32bit aligned */ +@@ -394,7 +394,8 @@ struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct dentry *real, + * the price or reconnecting the dentry. + */ + dwords = buflen >> 2; +- fh_type = exportfs_encode_fh(real, (void *)fh->fb.fid, &dwords, 0); ++ fh_type = exportfs_encode_inode_fh(realinode, (void *)fh->fb.fid, ++ &dwords, NULL, 0); + buflen = (dwords << 2); + + err = -EIO; +@@ -426,29 +427,29 @@ struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct dentry *real, + return ERR_PTR(err); + } + +-int ovl_set_origin(struct ovl_fs *ofs, struct dentry *lower, +- struct dentry *upper) ++struct ovl_fh *ovl_get_origin_fh(struct ovl_fs *ofs, struct dentry *origin) + { +- const struct ovl_fh *fh = NULL; +- int err; +- + /* + * When lower layer doesn't support export operations store a 'null' fh, + * so we can use the overlay.origin xattr to distignuish between a copy + * up and a pure upper inode. + */ +- if (ovl_can_decode_fh(lower->d_sb)) { +- fh = ovl_encode_real_fh(ofs, lower, false); +- if (IS_ERR(fh)) +- return PTR_ERR(fh); +- } ++ if (!ovl_can_decode_fh(origin->d_sb)) ++ return NULL; ++ ++ return ovl_encode_real_fh(ofs, d_inode(origin), false); ++} ++ ++int ovl_set_origin_fh(struct ovl_fs *ofs, const struct ovl_fh *fh, ++ struct dentry *upper) ++{ ++ int err; + + /* + * Do not fail when upper doesn't support xattrs. + */ + err = ovl_check_setxattr(ofs, upper, OVL_XATTR_ORIGIN, fh->buf, + fh ? fh->fb.len : 0, 0); +- kfree(fh); + + /* Ignore -EPERM from setting "user.*" on symlink/special */ + return err == -EPERM ? 0 : err; +@@ -461,7 +462,7 @@ static int ovl_set_upper_fh(struct ovl_fs *ofs, struct dentry *upper, + const struct ovl_fh *fh; + int err; + +- fh = ovl_encode_real_fh(ofs, upper, true); ++ fh = ovl_encode_real_fh(ofs, d_inode(upper), true); + if (IS_ERR(fh)) + return PTR_ERR(fh); + +@@ -476,7 +477,7 @@ static int ovl_set_upper_fh(struct ovl_fs *ofs, struct dentry *upper, + * + * Caller must hold i_mutex on indexdir. + */ +-static int ovl_create_index(struct dentry *dentry, struct dentry *origin, ++static int ovl_create_index(struct dentry *dentry, const struct ovl_fh *fh, + struct dentry *upper) + { + struct ovl_fs *ofs = OVL_FS(dentry->d_sb); +@@ -502,7 +503,7 @@ static int ovl_create_index(struct dentry *dentry, struct dentry *origin, + if (WARN_ON(ovl_test_flag(OVL_INDEX, d_inode(dentry)))) + return -EIO; + +- err = ovl_get_index_name(ofs, origin, &name); ++ err = ovl_get_index_name_fh(fh, &name); + if (err) + return err; + +@@ -541,6 +542,7 @@ struct ovl_copy_up_ctx { + struct dentry *destdir; + struct qstr destname; + struct dentry *workdir; ++ const struct ovl_fh *origin_fh; + bool origin; + bool indexed; + bool metacopy; +@@ -637,7 +639,7 @@ static int ovl_copy_up_metadata(struct ovl_copy_up_ctx *c, struct dentry *temp) + * hard link. + */ + if (c->origin) { +- err = ovl_set_origin(ofs, c->lowerpath.dentry, temp); ++ err = ovl_set_origin_fh(ofs, c->origin_fh, temp); + if (err) + return err; + } +@@ -749,7 +751,7 @@ static int ovl_copy_up_workdir(struct ovl_copy_up_ctx *c) + goto cleanup; + + if (S_ISDIR(c->stat.mode) && c->indexed) { +- err = ovl_create_index(c->dentry, c->lowerpath.dentry, temp); ++ err = ovl_create_index(c->dentry, c->origin_fh, temp); + if (err) + goto cleanup; + } +@@ -861,6 +863,8 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c) + { + int err; + struct ovl_fs *ofs = OVL_FS(c->dentry->d_sb); ++ struct dentry *origin = c->lowerpath.dentry; ++ struct ovl_fh *fh = NULL; + bool to_index = false; + + /* +@@ -877,17 +881,25 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c) + to_index = true; + } + +- if (S_ISDIR(c->stat.mode) || c->stat.nlink == 1 || to_index) ++ if (S_ISDIR(c->stat.mode) || c->stat.nlink == 1 || to_index) { ++ fh = ovl_get_origin_fh(ofs, origin); ++ if (IS_ERR(fh)) ++ return PTR_ERR(fh); ++ ++ /* origin_fh may be NULL */ ++ c->origin_fh = fh; + c->origin = true; ++ } + + if (to_index) { + c->destdir = ovl_indexdir(c->dentry->d_sb); +- err = ovl_get_index_name(ofs, c->lowerpath.dentry, &c->destname); ++ err = ovl_get_index_name(ofs, origin, &c->destname); + if (err) +- return err; ++ goto out_free_fh; + } else if (WARN_ON(!c->parent)) { + /* Disconnected dentry must be copied up to index dir */ +- return -EIO; ++ err = -EIO; ++ goto out_free_fh; + } else { + /* + * Mark parent "impure" because it may now contain non-pure +@@ -895,7 +907,7 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c) + */ + err = ovl_set_impure(c->parent, c->destdir); + if (err) +- return err; ++ goto out_free_fh; + } + + /* Should we copyup with O_TMPFILE or with workdir? */ +@@ -927,6 +939,8 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c) + out: + if (to_index) + kfree(c->destname.name); ++out_free_fh: ++ kfree(fh); + return err; + } + +diff --git a/fs/overlayfs/export.c b/fs/overlayfs/export.c +index 611ff567a1aa6f..3a17e4366f28c0 100644 +--- a/fs/overlayfs/export.c ++++ b/fs/overlayfs/export.c +@@ -181,35 +181,37 @@ static int ovl_connect_layer(struct dentry *dentry) + * + * Return 0 for upper file handle, > 0 for lower file handle or < 0 on error. + */ +-static int ovl_check_encode_origin(struct dentry *dentry) ++static int ovl_check_encode_origin(struct inode *inode) + { +- struct ovl_fs *ofs = OVL_FS(dentry->d_sb); ++ struct ovl_fs *ofs = OVL_FS(inode->i_sb); + bool decodable = ofs->config.nfs_export; ++ struct dentry *dentry; ++ int err; + + /* No upper layer? */ + if (!ovl_upper_mnt(ofs)) + return 1; + + /* Lower file handle for non-upper non-decodable */ +- if (!ovl_dentry_upper(dentry) && !decodable) ++ if (!ovl_inode_upper(inode) && !decodable) + return 1; + + /* Upper file handle for pure upper */ +- if (!ovl_dentry_lower(dentry)) ++ if (!ovl_inode_lower(inode)) + return 0; + + /* + * Root is never indexed, so if there's an upper layer, encode upper for + * root. + */ +- if (dentry == dentry->d_sb->s_root) ++ if (inode == d_inode(inode->i_sb->s_root)) + return 0; + + /* + * Upper decodable file handle for non-indexed upper. + */ +- if (ovl_dentry_upper(dentry) && decodable && +- !ovl_test_flag(OVL_INDEX, d_inode(dentry))) ++ if (ovl_inode_upper(inode) && decodable && ++ !ovl_test_flag(OVL_INDEX, inode)) + return 0; + + /* +@@ -218,14 +220,23 @@ static int ovl_check_encode_origin(struct dentry *dentry) + * ovl_connect_layer() will try to make origin's layer "connected" by + * copying up a "connectable" ancestor. + */ +- if (d_is_dir(dentry) && decodable) +- return ovl_connect_layer(dentry); ++ if (!decodable || !S_ISDIR(inode->i_mode)) ++ return 1; ++ ++ dentry = d_find_any_alias(inode); ++ if (!dentry) ++ return -ENOENT; ++ ++ err = ovl_connect_layer(dentry); ++ dput(dentry); ++ if (err < 0) ++ return err; + + /* Lower file handle for indexed and non-upper dir/non-dir */ + return 1; + } + +-static int ovl_dentry_to_fid(struct ovl_fs *ofs, struct dentry *dentry, ++static int ovl_dentry_to_fid(struct ovl_fs *ofs, struct inode *inode, + u32 *fid, int buflen) + { + struct ovl_fh *fh = NULL; +@@ -236,13 +247,13 @@ static int ovl_dentry_to_fid(struct ovl_fs *ofs, struct dentry *dentry, + * Check if we should encode a lower or upper file handle and maybe + * copy up an ancestor to make lower file handle connectable. + */ +- err = enc_lower = ovl_check_encode_origin(dentry); ++ err = enc_lower = ovl_check_encode_origin(inode); + if (enc_lower < 0) + goto fail; + + /* Encode an upper or lower file handle */ +- fh = ovl_encode_real_fh(ofs, enc_lower ? ovl_dentry_lower(dentry) : +- ovl_dentry_upper(dentry), !enc_lower); ++ fh = ovl_encode_real_fh(ofs, enc_lower ? ovl_inode_lower(inode) : ++ ovl_inode_upper(inode), !enc_lower); + if (IS_ERR(fh)) + return PTR_ERR(fh); + +@@ -256,8 +267,8 @@ static int ovl_dentry_to_fid(struct ovl_fs *ofs, struct dentry *dentry, + return err; + + fail: +- pr_warn_ratelimited("failed to encode file handle (%pd2, err=%i)\n", +- dentry, err); ++ pr_warn_ratelimited("failed to encode file handle (ino=%lu, err=%i)\n", ++ inode->i_ino, err); + goto out; + } + +@@ -265,19 +276,13 @@ static int ovl_encode_fh(struct inode *inode, u32 *fid, int *max_len, + struct inode *parent) + { + struct ovl_fs *ofs = OVL_FS(inode->i_sb); +- struct dentry *dentry; + int bytes, buflen = *max_len << 2; + + /* TODO: encode connectable file handles */ + if (parent) + return FILEID_INVALID; + +- dentry = d_find_any_alias(inode); +- if (!dentry) +- return FILEID_INVALID; +- +- bytes = ovl_dentry_to_fid(ofs, dentry, fid, buflen); +- dput(dentry); ++ bytes = ovl_dentry_to_fid(ofs, inode, fid, buflen); + if (bytes <= 0) + return FILEID_INVALID; + +diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c +index 80391c687c2ad8..2d2ef671b36ba5 100644 +--- a/fs/overlayfs/namei.c ++++ b/fs/overlayfs/namei.c +@@ -507,6 +507,19 @@ static int ovl_verify_fh(struct ovl_fs *ofs, struct dentry *dentry, + return err; + } + ++int ovl_verify_set_fh(struct ovl_fs *ofs, struct dentry *dentry, ++ enum ovl_xattr ox, const struct ovl_fh *fh, ++ bool is_upper, bool set) ++{ ++ int err; ++ ++ err = ovl_verify_fh(ofs, dentry, ox, fh); ++ if (set && err == -ENODATA) ++ err = ovl_setxattr(ofs, dentry, ox, fh->buf, fh->fb.len); ++ ++ return err; ++} ++ + /* + * Verify that @real dentry matches the file handle stored in xattr @name. + * +@@ -515,24 +528,22 @@ static int ovl_verify_fh(struct ovl_fs *ofs, struct dentry *dentry, + * + * Return 0 on match, -ESTALE on mismatch, -ENODATA on no xattr, < 0 on error. + */ +-int ovl_verify_set_fh(struct ovl_fs *ofs, struct dentry *dentry, +- enum ovl_xattr ox, struct dentry *real, bool is_upper, +- bool set) ++int ovl_verify_origin_xattr(struct ovl_fs *ofs, struct dentry *dentry, ++ enum ovl_xattr ox, struct dentry *real, ++ bool is_upper, bool set) + { + struct inode *inode; + struct ovl_fh *fh; + int err; + +- fh = ovl_encode_real_fh(ofs, real, is_upper); ++ fh = ovl_encode_real_fh(ofs, d_inode(real), is_upper); + err = PTR_ERR(fh); + if (IS_ERR(fh)) { + fh = NULL; + goto fail; + } + +- err = ovl_verify_fh(ofs, dentry, ox, fh); +- if (set && err == -ENODATA) +- err = ovl_setxattr(ofs, dentry, ox, fh->buf, fh->fb.len); ++ err = ovl_verify_set_fh(ofs, dentry, ox, fh, is_upper, set); + if (err) + goto fail; + +@@ -548,6 +559,7 @@ int ovl_verify_set_fh(struct ovl_fs *ofs, struct dentry *dentry, + goto out; + } + ++ + /* Get upper dentry from index */ + struct dentry *ovl_index_upper(struct ovl_fs *ofs, struct dentry *index, + bool connected) +@@ -684,7 +696,7 @@ int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index) + goto out; + } + +-static int ovl_get_index_name_fh(struct ovl_fh *fh, struct qstr *name) ++int ovl_get_index_name_fh(const struct ovl_fh *fh, struct qstr *name) + { + char *n, *s; + +@@ -720,7 +732,7 @@ int ovl_get_index_name(struct ovl_fs *ofs, struct dentry *origin, + struct ovl_fh *fh; + int err; + +- fh = ovl_encode_real_fh(ofs, origin, false); ++ fh = ovl_encode_real_fh(ofs, d_inode(origin), false); + if (IS_ERR(fh)) + return PTR_ERR(fh); + +@@ -873,20 +885,27 @@ int ovl_path_next(int idx, struct dentry *dentry, struct path *path) + static int ovl_fix_origin(struct ovl_fs *ofs, struct dentry *dentry, + struct dentry *lower, struct dentry *upper) + { ++ const struct ovl_fh *fh; + int err; + + if (ovl_check_origin_xattr(ofs, upper)) + return 0; + ++ fh = ovl_get_origin_fh(ofs, lower); ++ if (IS_ERR(fh)) ++ return PTR_ERR(fh); ++ + err = ovl_want_write(dentry); + if (err) +- return err; ++ goto out; + +- err = ovl_set_origin(ofs, lower, upper); ++ err = ovl_set_origin_fh(ofs, fh, upper); + if (!err) + err = ovl_set_impure(dentry->d_parent, upper->d_parent); + + ovl_drop_write(dentry); ++out: ++ kfree(fh); + return err; + } + +diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h +index 09ca82ed0f8ced..ca63a26a6170b0 100644 +--- a/fs/overlayfs/overlayfs.h ++++ b/fs/overlayfs/overlayfs.h +@@ -632,11 +632,15 @@ struct dentry *ovl_decode_real_fh(struct ovl_fs *ofs, struct ovl_fh *fh, + int ovl_check_origin_fh(struct ovl_fs *ofs, struct ovl_fh *fh, bool connected, + struct dentry *upperdentry, struct ovl_path **stackp); + int ovl_verify_set_fh(struct ovl_fs *ofs, struct dentry *dentry, +- enum ovl_xattr ox, struct dentry *real, bool is_upper, +- bool set); ++ enum ovl_xattr ox, const struct ovl_fh *fh, ++ bool is_upper, bool set); ++int ovl_verify_origin_xattr(struct ovl_fs *ofs, struct dentry *dentry, ++ enum ovl_xattr ox, struct dentry *real, ++ bool is_upper, bool set); + struct dentry *ovl_index_upper(struct ovl_fs *ofs, struct dentry *index, + bool connected); + int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index); ++int ovl_get_index_name_fh(const struct ovl_fh *fh, struct qstr *name); + int ovl_get_index_name(struct ovl_fs *ofs, struct dentry *origin, + struct qstr *name); + struct dentry *ovl_get_index_fh(struct ovl_fs *ofs, struct ovl_fh *fh); +@@ -648,17 +652,24 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, + unsigned int flags); + bool ovl_lower_positive(struct dentry *dentry); + ++static inline int ovl_verify_origin_fh(struct ovl_fs *ofs, struct dentry *upper, ++ const struct ovl_fh *fh, bool set) ++{ ++ return ovl_verify_set_fh(ofs, upper, OVL_XATTR_ORIGIN, fh, false, set); ++} ++ + static inline int ovl_verify_origin(struct ovl_fs *ofs, struct dentry *upper, + struct dentry *origin, bool set) + { +- return ovl_verify_set_fh(ofs, upper, OVL_XATTR_ORIGIN, origin, +- false, set); ++ return ovl_verify_origin_xattr(ofs, upper, OVL_XATTR_ORIGIN, origin, ++ false, set); + } + + static inline int ovl_verify_upper(struct ovl_fs *ofs, struct dentry *index, + struct dentry *upper, bool set) + { +- return ovl_verify_set_fh(ofs, index, OVL_XATTR_UPPER, upper, true, set); ++ return ovl_verify_origin_xattr(ofs, index, OVL_XATTR_UPPER, upper, ++ true, set); + } + + /* readdir.c */ +@@ -821,10 +832,11 @@ int ovl_copy_up_with_data(struct dentry *dentry); + int ovl_maybe_copy_up(struct dentry *dentry, int flags); + int ovl_copy_xattr(struct super_block *sb, const struct path *path, struct dentry *new); + int ovl_set_attr(struct ovl_fs *ofs, struct dentry *upper, struct kstat *stat); +-struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct dentry *real, ++struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct inode *realinode, + bool is_upper); +-int ovl_set_origin(struct ovl_fs *ofs, struct dentry *lower, +- struct dentry *upper); ++struct ovl_fh *ovl_get_origin_fh(struct ovl_fs *ofs, struct dentry *origin); ++int ovl_set_origin_fh(struct ovl_fs *ofs, const struct ovl_fh *fh, ++ struct dentry *upper); + + /* export.c */ + extern const struct export_operations ovl_export_operations; +diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c +index 2c056d737c27c3..e2574034c3fa17 100644 +--- a/fs/overlayfs/super.c ++++ b/fs/overlayfs/super.c +@@ -879,15 +879,20 @@ static int ovl_get_indexdir(struct super_block *sb, struct ovl_fs *ofs, + { + struct vfsmount *mnt = ovl_upper_mnt(ofs); + struct dentry *indexdir; ++ struct dentry *origin = ovl_lowerstack(oe)->dentry; ++ const struct ovl_fh *fh; + int err; + ++ fh = ovl_get_origin_fh(ofs, origin); ++ if (IS_ERR(fh)) ++ return PTR_ERR(fh); ++ + err = mnt_want_write(mnt); + if (err) +- return err; ++ goto out_free_fh; + + /* Verify lower root is upper root origin */ +- err = ovl_verify_origin(ofs, upperpath->dentry, +- ovl_lowerstack(oe)->dentry, true); ++ err = ovl_verify_origin_fh(ofs, upperpath->dentry, fh, true); + if (err) { + pr_err("failed to verify upper root origin\n"); + goto out; +@@ -919,9 +924,10 @@ static int ovl_get_indexdir(struct super_block *sb, struct ovl_fs *ofs, + * directory entries. + */ + if (ovl_check_origin_xattr(ofs, ofs->indexdir)) { +- err = ovl_verify_set_fh(ofs, ofs->indexdir, +- OVL_XATTR_ORIGIN, +- upperpath->dentry, true, false); ++ err = ovl_verify_origin_xattr(ofs, ofs->indexdir, ++ OVL_XATTR_ORIGIN, ++ upperpath->dentry, true, ++ false); + if (err) + pr_err("failed to verify index dir 'origin' xattr\n"); + } +@@ -939,6 +945,8 @@ static int ovl_get_indexdir(struct super_block *sb, struct ovl_fs *ofs, + + out: + mnt_drop_write(mnt); ++out_free_fh: ++ kfree(fh); + return err; + } + +diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c +index 0bf3ffcd072f6a..4e6b747e0f2e25 100644 +--- a/fs/overlayfs/util.c ++++ b/fs/overlayfs/util.c +@@ -976,12 +976,18 @@ static void ovl_cleanup_index(struct dentry *dentry) + struct dentry *index = NULL; + struct inode *inode; + struct qstr name = { }; ++ bool got_write = false; + int err; + + err = ovl_get_index_name(ofs, lowerdentry, &name); + if (err) + goto fail; + ++ err = ovl_want_write(dentry); ++ if (err) ++ goto fail; ++ ++ got_write = true; + inode = d_inode(upperdentry); + if (!S_ISDIR(inode->i_mode) && inode->i_nlink != 1) { + pr_warn_ratelimited("cleanup linked index (%pd2, ino=%lu, nlink=%u)\n", +@@ -1019,6 +1025,8 @@ static void ovl_cleanup_index(struct dentry *dentry) + goto fail; + + out: ++ if (got_write) ++ ovl_drop_write(dentry); + kfree(name.name); + dput(index); + return; +@@ -1089,6 +1097,8 @@ void ovl_nlink_end(struct dentry *dentry) + { + struct inode *inode = d_inode(dentry); + ++ ovl_drop_write(dentry); ++ + if (ovl_test_flag(OVL_INDEX, inode) && inode->i_nlink == 0) { + const struct cred *old_cred; + +diff --git a/fs/smb/client/namespace.c b/fs/smb/client/namespace.c +index 4a517b280f2b79..830f2a292bb00d 100644 +--- a/fs/smb/client/namespace.c ++++ b/fs/smb/client/namespace.c +@@ -196,11 +196,28 @@ static struct vfsmount *cifs_do_automount(struct path *path) + struct smb3_fs_context tmp; + char *full_path; + struct vfsmount *mnt; ++ struct cifs_sb_info *mntpt_sb; ++ struct cifs_ses *ses; + + if (IS_ROOT(mntpt)) + return ERR_PTR(-ESTALE); + +- cur_ctx = CIFS_SB(mntpt->d_sb)->ctx; ++ mntpt_sb = CIFS_SB(mntpt->d_sb); ++ ses = cifs_sb_master_tcon(mntpt_sb)->ses; ++ cur_ctx = mntpt_sb->ctx; ++ ++ /* ++ * At this point, the root session should be in the mntpt sb. We should ++ * bring the sb context passwords in sync with the root session's ++ * passwords. This would help prevent unnecessary retries and password ++ * swaps for automounts. ++ */ ++ mutex_lock(&ses->session_mutex); ++ rc = smb3_sync_session_ctx_passwords(mntpt_sb, ses); ++ mutex_unlock(&ses->session_mutex); ++ ++ if (rc) ++ return ERR_PTR(rc); + + fc = fs_context_for_submount(path->mnt->mnt_sb->s_type, mntpt); + if (IS_ERR(fc)) +diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c +index 2884ebdc0eda02..815a9a5cfa8079 100644 +--- a/fs/smb/server/smb2pdu.c ++++ b/fs/smb/server/smb2pdu.c +@@ -695,6 +695,9 @@ void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status) + struct smb2_hdr *rsp_hdr; + struct ksmbd_work *in_work = ksmbd_alloc_work_struct(); + ++ if (!in_work) ++ return; ++ + if (allocate_interim_rsp_buf(in_work)) { + pr_err("smb_allocate_rsp_buf failed!\n"); + ksmbd_free_work_struct(in_work); +@@ -3986,6 +3989,26 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level, + posix_info->DeviceId = cpu_to_le32(ksmbd_kstat->kstat->rdev); + posix_info->HardLinks = cpu_to_le32(ksmbd_kstat->kstat->nlink); + posix_info->Mode = cpu_to_le32(ksmbd_kstat->kstat->mode & 0777); ++ switch (ksmbd_kstat->kstat->mode & S_IFMT) { ++ case S_IFDIR: ++ posix_info->Mode |= cpu_to_le32(POSIX_TYPE_DIR << POSIX_FILETYPE_SHIFT); ++ break; ++ case S_IFLNK: ++ posix_info->Mode |= cpu_to_le32(POSIX_TYPE_SYMLINK << POSIX_FILETYPE_SHIFT); ++ break; ++ case S_IFCHR: ++ posix_info->Mode |= cpu_to_le32(POSIX_TYPE_CHARDEV << POSIX_FILETYPE_SHIFT); ++ break; ++ case S_IFBLK: ++ posix_info->Mode |= cpu_to_le32(POSIX_TYPE_BLKDEV << POSIX_FILETYPE_SHIFT); ++ break; ++ case S_IFIFO: ++ posix_info->Mode |= cpu_to_le32(POSIX_TYPE_FIFO << POSIX_FILETYPE_SHIFT); ++ break; ++ case S_IFSOCK: ++ posix_info->Mode |= cpu_to_le32(POSIX_TYPE_SOCKET << POSIX_FILETYPE_SHIFT); ++ } ++ + posix_info->Inode = cpu_to_le64(ksmbd_kstat->kstat->ino); + posix_info->DosAttributes = + S_ISDIR(ksmbd_kstat->kstat->mode) ? +@@ -5174,6 +5197,26 @@ static int find_file_posix_info(struct smb2_query_info_rsp *rsp, + file_info->AllocationSize = cpu_to_le64(stat.blocks << 9); + file_info->HardLinks = cpu_to_le32(stat.nlink); + file_info->Mode = cpu_to_le32(stat.mode & 0777); ++ switch (stat.mode & S_IFMT) { ++ case S_IFDIR: ++ file_info->Mode |= cpu_to_le32(POSIX_TYPE_DIR << POSIX_FILETYPE_SHIFT); ++ break; ++ case S_IFLNK: ++ file_info->Mode |= cpu_to_le32(POSIX_TYPE_SYMLINK << POSIX_FILETYPE_SHIFT); ++ break; ++ case S_IFCHR: ++ file_info->Mode |= cpu_to_le32(POSIX_TYPE_CHARDEV << POSIX_FILETYPE_SHIFT); ++ break; ++ case S_IFBLK: ++ file_info->Mode |= cpu_to_le32(POSIX_TYPE_BLKDEV << POSIX_FILETYPE_SHIFT); ++ break; ++ case S_IFIFO: ++ file_info->Mode |= cpu_to_le32(POSIX_TYPE_FIFO << POSIX_FILETYPE_SHIFT); ++ break; ++ case S_IFSOCK: ++ file_info->Mode |= cpu_to_le32(POSIX_TYPE_SOCKET << POSIX_FILETYPE_SHIFT); ++ } ++ + file_info->DeviceId = cpu_to_le32(stat.rdev); + + /* +diff --git a/fs/smb/server/smb2pdu.h b/fs/smb/server/smb2pdu.h +index 643f5e1cfe3570..25cc81aac350f2 100644 +--- a/fs/smb/server/smb2pdu.h ++++ b/fs/smb/server/smb2pdu.h +@@ -500,4 +500,14 @@ static inline void *smb2_get_msg(void *buf) + return buf + 4; + } + ++#define POSIX_TYPE_FILE 0 ++#define POSIX_TYPE_DIR 1 ++#define POSIX_TYPE_SYMLINK 2 ++#define POSIX_TYPE_CHARDEV 3 ++#define POSIX_TYPE_BLKDEV 4 ++#define POSIX_TYPE_FIFO 5 ++#define POSIX_TYPE_SOCKET 6 ++ ++#define POSIX_FILETYPE_SHIFT 12 ++ + #endif /* _SMB2PDU_H */ +diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c +index 2c548e8efef060..d0c19ad9d0145c 100644 +--- a/fs/smb/server/vfs.c ++++ b/fs/smb/server/vfs.c +@@ -1259,6 +1259,8 @@ int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name, + filepath, + flags, + path); ++ if (!is_last) ++ next[0] = '/'; + if (err) + goto out2; + else if (is_last) +@@ -1266,7 +1268,6 @@ int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name, + path_put(parent_path); + *parent_path = *path; + +- next[0] = '/'; + remain_len -= filename_len + 1; + } + +diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h +index 0c50c4fceb95dd..0ca93c7574ad22 100644 +--- a/include/linux/hugetlb.h ++++ b/include/linux/hugetlb.h +@@ -1239,7 +1239,7 @@ static inline __init void hugetlb_cma_reserve(int order) + } + #endif + +-#ifdef CONFIG_ARCH_WANT_HUGE_PMD_SHARE ++#ifdef CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING + static inline bool hugetlb_pmd_shared(pte_t *pte) + { + return page_count(virt_to_page(pte)) > 1; +@@ -1275,8 +1275,7 @@ bool __vma_private_lock(struct vm_area_struct *vma); + static inline pte_t * + hugetlb_walk(struct vm_area_struct *vma, unsigned long addr, unsigned long sz) + { +-#if defined(CONFIG_HUGETLB_PAGE) && \ +- defined(CONFIG_ARCH_WANT_HUGE_PMD_SHARE) && defined(CONFIG_LOCKDEP) ++#if defined(CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING) && defined(CONFIG_LOCKDEP) + struct hugetlb_vma_lock *vma_lock = vma->vm_private_data; + + /* +diff --git a/include/linux/mm.h b/include/linux/mm.h +index b6a4d6471b4a72..209370f6443666 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -3031,6 +3031,7 @@ static inline bool pagetable_pmd_ctor(struct ptdesc *ptdesc) + if (!pmd_ptlock_init(ptdesc)) + return false; + __folio_set_pgtable(folio); ++ ptdesc_pmd_pts_init(ptdesc); + lruvec_stat_add_folio(folio, NR_PAGETABLE); + return true; + } +diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h +index 20c96ce98751a4..e77d4a5c0baced 100644 +--- a/include/linux/mm_types.h ++++ b/include/linux/mm_types.h +@@ -398,11 +398,12 @@ FOLIO_MATCH(compound_head, _head_2a); + * @pmd_huge_pte: Protected by ptdesc->ptl, used for THPs. + * @__page_mapping: Aliases with page->mapping. Unused for page tables. + * @pt_mm: Used for x86 pgds. +- * @pt_frag_refcount: For fragmented page table tracking. Powerpc and s390 only. ++ * @pt_frag_refcount: For fragmented page table tracking. Powerpc only. ++ * @pt_share_count: Used for HugeTLB PMD page table share count. + * @_pt_pad_2: Padding to ensure proper alignment. + * @ptl: Lock for the page table. + * @__page_type: Same as page->page_type. Unused for page tables. +- * @_refcount: Same as page refcount. Used for s390 page tables. ++ * @_refcount: Same as page refcount. + * @pt_memcg_data: Memcg data. Tracked for page tables here. + * + * This struct overlays struct page for now. Do not modify without a good +@@ -424,6 +425,9 @@ struct ptdesc { + union { + struct mm_struct *pt_mm; + atomic_t pt_frag_refcount; ++#ifdef CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING ++ atomic_t pt_share_count; ++#endif + }; + + union { +@@ -468,6 +472,32 @@ static_assert(sizeof(struct ptdesc) <= sizeof(struct page)); + const struct page *: (const struct ptdesc *)(p), \ + struct page *: (struct ptdesc *)(p))) + ++#ifdef CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING ++static inline void ptdesc_pmd_pts_init(struct ptdesc *ptdesc) ++{ ++ atomic_set(&ptdesc->pt_share_count, 0); ++} ++ ++static inline void ptdesc_pmd_pts_inc(struct ptdesc *ptdesc) ++{ ++ atomic_inc(&ptdesc->pt_share_count); ++} ++ ++static inline void ptdesc_pmd_pts_dec(struct ptdesc *ptdesc) ++{ ++ atomic_dec(&ptdesc->pt_share_count); ++} ++ ++static inline int ptdesc_pmd_pts_count(struct ptdesc *ptdesc) ++{ ++ return atomic_read(&ptdesc->pt_share_count); ++} ++#else ++static inline void ptdesc_pmd_pts_init(struct ptdesc *ptdesc) ++{ ++} ++#endif ++ + /* + * Used for sizing the vmemmap region on some architectures + */ +diff --git a/include/linux/numa.h b/include/linux/numa.h +index 1d43371fafd2fc..eb19503604fe36 100644 +--- a/include/linux/numa.h ++++ b/include/linux/numa.h +@@ -15,6 +15,11 @@ + #define NUMA_NO_NODE (-1) + #define NUMA_NO_MEMBLK (-1) + ++static inline bool numa_valid_node(int nid) ++{ ++ return nid >= 0 && nid < MAX_NUMNODES; ++} ++ + /* optionally keep NUMA memory info available post init */ + #ifdef CONFIG_NUMA_KEEP_MEMINFO + #define __initdata_or_meminfo +diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h +index fee1e565055100..e85834722b8f2b 100644 +--- a/include/net/inet_connection_sock.h ++++ b/include/net/inet_connection_sock.h +@@ -282,7 +282,7 @@ static inline int inet_csk_reqsk_queue_len(const struct sock *sk) + + static inline int inet_csk_reqsk_queue_is_full(const struct sock *sk) + { +- return inet_csk_reqsk_queue_len(sk) >= sk->sk_max_ack_backlog; ++ return inet_csk_reqsk_queue_len(sk) > READ_ONCE(sk->sk_max_ack_backlog); + } + + bool inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req); +diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h +index f66a275bf8ccdb..20d129914121d5 100644 +--- a/include/ufs/ufshcd.h ++++ b/include/ufs/ufshcd.h +@@ -324,7 +324,6 @@ struct ufs_pwr_mode_info { + * @config_scaling_param: called to configure clock scaling parameters + * @program_key: program or evict an inline encryption key + * @event_notify: called to notify important events +- * @reinit_notify: called to notify reinit of UFSHCD during max gear switch + * @mcq_config_resource: called to configure MCQ platform resources + * @get_hba_mac: called to get vendor specific mac value, mandatory for mcq mode + * @op_runtime_config: called to config Operation and runtime regs Pointers +@@ -369,7 +368,6 @@ struct ufs_hba_variant_ops { + const union ufs_crypto_cfg_entry *cfg, int slot); + void (*event_notify)(struct ufs_hba *hba, + enum ufs_event_type evt, void *data); +- void (*reinit_notify)(struct ufs_hba *); + int (*mcq_config_resource)(struct ufs_hba *hba); + int (*get_hba_mac)(struct ufs_hba *hba); + int (*op_runtime_config)(struct ufs_hba *hba); +diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c +index 0122f220ef0d2b..c7198fbcf734f7 100644 +--- a/io_uring/io_uring.c ++++ b/io_uring/io_uring.c +@@ -537,6 +537,13 @@ static __cold void io_queue_deferred(struct io_ring_ctx *ctx) + } + } + ++static void io_eventfd_free(struct rcu_head *rcu) ++{ ++ struct io_ev_fd *ev_fd = container_of(rcu, struct io_ev_fd, rcu); ++ ++ eventfd_ctx_put(ev_fd->cq_ev_fd); ++ kfree(ev_fd); ++} + + static void io_eventfd_ops(struct rcu_head *rcu) + { +@@ -550,10 +557,8 @@ static void io_eventfd_ops(struct rcu_head *rcu) + * ordering in a race but if references are 0 we know we have to free + * it regardless. + */ +- if (atomic_dec_and_test(&ev_fd->refs)) { +- eventfd_ctx_put(ev_fd->cq_ev_fd); +- kfree(ev_fd); +- } ++ if (atomic_dec_and_test(&ev_fd->refs)) ++ call_rcu(&ev_fd->rcu, io_eventfd_free); + } + + static void io_eventfd_signal(struct io_ring_ctx *ctx) +diff --git a/io_uring/timeout.c b/io_uring/timeout.c +index 4f1f710197d623..277e22d55c6171 100644 +--- a/io_uring/timeout.c ++++ b/io_uring/timeout.c +@@ -413,10 +413,12 @@ static int io_timeout_update(struct io_ring_ctx *ctx, __u64 user_data, + + timeout->off = 0; /* noseq */ + data = req->async_data; ++ data->ts = *ts; ++ + list_add_tail(&timeout->list, &ctx->timeout_list); + hrtimer_init(&data->timer, io_timeout_get_clock(data), mode); + data->timer.function = io_timeout_fn; +- hrtimer_start(&data->timer, timespec64_to_ktime(*ts), mode); ++ hrtimer_start(&data->timer, timespec64_to_ktime(data->ts), mode); + return 0; + } + +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index 7fa1c7c9151aef..59b6efb2a11c36 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -2541,6 +2541,7 @@ __acquires(&pool->lock) + struct pool_workqueue *pwq = get_work_pwq(work); + struct worker_pool *pool = worker->pool; + unsigned long work_data; ++ int lockdep_start_depth, rcu_start_depth; + #ifdef CONFIG_LOCKDEP + /* + * It is permissible to free the struct work_struct from +@@ -2603,6 +2604,8 @@ __acquires(&pool->lock) + pwq->stats[PWQ_STAT_STARTED]++; + raw_spin_unlock_irq(&pool->lock); + ++ rcu_start_depth = rcu_preempt_depth(); ++ lockdep_start_depth = lockdep_depth(current); + lock_map_acquire(&pwq->wq->lockdep_map); + lock_map_acquire(&lockdep_map); + /* +@@ -2638,10 +2641,14 @@ __acquires(&pool->lock) + lock_map_release(&lockdep_map); + lock_map_release(&pwq->wq->lockdep_map); + +- if (unlikely(in_atomic() || lockdep_depth(current) > 0)) { +- pr_err("BUG: workqueue leaked lock or atomic: %s/0x%08x/%d\n" +- " last function: %ps\n", +- current->comm, preempt_count(), task_pid_nr(current), ++ if (unlikely((worker->task && in_atomic()) || ++ lockdep_depth(current) != lockdep_start_depth || ++ rcu_preempt_depth() != rcu_start_depth)) { ++ pr_err("BUG: workqueue leaked atomic, lock or RCU: %s[%d]\n" ++ " preempt=0x%08x lock=%d->%d RCU=%d->%d workfn=%ps\n", ++ current->comm, task_pid_nr(current), preempt_count(), ++ lockdep_start_depth, lockdep_depth(current), ++ rcu_start_depth, rcu_preempt_depth(), + worker->current_func); + debug_show_held_locks(current); + dump_stack(); +@@ -2940,23 +2947,27 @@ static int rescuer_thread(void *__rescuer) + * check_flush_dependency - check for flush dependency sanity + * @target_wq: workqueue being flushed + * @target_work: work item being flushed (NULL for workqueue flushes) ++ * @from_cancel: are we called from the work cancel path + * + * %current is trying to flush the whole @target_wq or @target_work on it. +- * If @target_wq doesn't have %WQ_MEM_RECLAIM, verify that %current is not +- * reclaiming memory or running on a workqueue which doesn't have +- * %WQ_MEM_RECLAIM as that can break forward-progress guarantee leading to +- * a deadlock. ++ * If this is not the cancel path (which implies work being flushed is either ++ * already running, or will not be at all), check if @target_wq doesn't have ++ * %WQ_MEM_RECLAIM and verify that %current is not reclaiming memory or running ++ * on a workqueue which doesn't have %WQ_MEM_RECLAIM as that can break forward- ++ * progress guarantee leading to a deadlock. + */ + static void check_flush_dependency(struct workqueue_struct *target_wq, +- struct work_struct *target_work) ++ struct work_struct *target_work, ++ bool from_cancel) + { +- work_func_t target_func = target_work ? target_work->func : NULL; ++ work_func_t target_func; + struct worker *worker; + +- if (target_wq->flags & WQ_MEM_RECLAIM) ++ if (from_cancel || target_wq->flags & WQ_MEM_RECLAIM) + return; + + worker = current_wq_worker(); ++ target_func = target_work ? target_work->func : NULL; + + WARN_ONCE(current->flags & PF_MEMALLOC, + "workqueue: PF_MEMALLOC task %d(%s) is flushing !WQ_MEM_RECLAIM %s:%ps", +@@ -3122,6 +3133,19 @@ static bool flush_workqueue_prep_pwqs(struct workqueue_struct *wq, + return wait; + } + ++static void touch_wq_lockdep_map(struct workqueue_struct *wq) ++{ ++ lock_map_acquire(&wq->lockdep_map); ++ lock_map_release(&wq->lockdep_map); ++} ++ ++static void touch_work_lockdep_map(struct work_struct *work, ++ struct workqueue_struct *wq) ++{ ++ lock_map_acquire(&work->lockdep_map); ++ lock_map_release(&work->lockdep_map); ++} ++ + /** + * __flush_workqueue - ensure that any scheduled work has run to completion. + * @wq: workqueue to flush +@@ -3141,8 +3165,7 @@ void __flush_workqueue(struct workqueue_struct *wq) + if (WARN_ON(!wq_online)) + return; + +- lock_map_acquire(&wq->lockdep_map); +- lock_map_release(&wq->lockdep_map); ++ touch_wq_lockdep_map(wq); + + mutex_lock(&wq->mutex); + +@@ -3189,7 +3212,7 @@ void __flush_workqueue(struct workqueue_struct *wq) + list_add_tail(&this_flusher.list, &wq->flusher_overflow); + } + +- check_flush_dependency(wq, NULL); ++ check_flush_dependency(wq, NULL, false); + + mutex_unlock(&wq->mutex); + +@@ -3341,6 +3364,7 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr, + struct worker *worker = NULL; + struct worker_pool *pool; + struct pool_workqueue *pwq; ++ struct workqueue_struct *wq; + + might_sleep(); + +@@ -3364,11 +3388,14 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr, + pwq = worker->current_pwq; + } + +- check_flush_dependency(pwq->wq, work); ++ wq = pwq->wq; ++ check_flush_dependency(wq, work, from_cancel); + + insert_wq_barrier(pwq, barr, work, worker); + raw_spin_unlock_irq(&pool->lock); + ++ touch_work_lockdep_map(work, wq); ++ + /* + * Force a lock recursion deadlock when using flush_work() inside a + * single-threaded or rescuer equipped workqueue. +@@ -3378,11 +3405,9 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr, + * workqueues the deadlock happens when the rescuer stalls, blocking + * forward progress. + */ +- if (!from_cancel && +- (pwq->wq->saved_max_active == 1 || pwq->wq->rescuer)) { +- lock_map_acquire(&pwq->wq->lockdep_map); +- lock_map_release(&pwq->wq->lockdep_map); +- } ++ if (!from_cancel && (wq->saved_max_active == 1 || wq->rescuer)) ++ touch_wq_lockdep_map(wq); ++ + rcu_read_unlock(); + return true; + already_gone: +@@ -3401,9 +3426,6 @@ static bool __flush_work(struct work_struct *work, bool from_cancel) + if (WARN_ON(!work->func)) + return false; + +- lock_map_acquire(&work->lockdep_map); +- lock_map_release(&work->lockdep_map); +- + if (start_flush_work(work, &barr, from_cancel)) { + wait_for_completion(&barr.done); + destroy_work_on_stack(&barr.work); +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index 92b955cc5a41d3..21c12519a7ef3a 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -6907,7 +6907,7 @@ long hugetlb_unreserve_pages(struct inode *inode, long start, long end, + return 0; + } + +-#ifdef CONFIG_ARCH_WANT_HUGE_PMD_SHARE ++#ifdef CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING + static unsigned long page_table_shareable(struct vm_area_struct *svma, + struct vm_area_struct *vma, + unsigned long addr, pgoff_t idx) +@@ -7014,7 +7014,7 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma, + spte = hugetlb_walk(svma, saddr, + vma_mmu_pagesize(svma)); + if (spte) { +- get_page(virt_to_page(spte)); ++ ptdesc_pmd_pts_inc(virt_to_ptdesc(spte)); + break; + } + } +@@ -7029,7 +7029,7 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma, + (pmd_t *)((unsigned long)spte & PAGE_MASK)); + mm_inc_nr_pmds(mm); + } else { +- put_page(virt_to_page(spte)); ++ ptdesc_pmd_pts_dec(virt_to_ptdesc(spte)); + } + spin_unlock(&mm->page_table_lock); + out: +@@ -7041,10 +7041,6 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma, + /* + * unmap huge page backed by shared pte. + * +- * Hugetlb pte page is ref counted at the time of mapping. If pte is shared +- * indicated by page_count > 1, unmap is achieved by clearing pud and +- * decrementing the ref count. If count == 1, the pte page is not shared. +- * + * Called with page table lock held. + * + * returns: 1 successfully unmapped a shared pte page +@@ -7053,23 +7049,25 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma, + int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, + unsigned long addr, pte_t *ptep) + { ++ unsigned long sz = huge_page_size(hstate_vma(vma)); + pgd_t *pgd = pgd_offset(mm, addr); + p4d_t *p4d = p4d_offset(pgd, addr); + pud_t *pud = pud_offset(p4d, addr); + + i_mmap_assert_write_locked(vma->vm_file->f_mapping); + hugetlb_vma_assert_locked(vma); +- BUG_ON(page_count(virt_to_page(ptep)) == 0); +- if (page_count(virt_to_page(ptep)) == 1) ++ if (sz != PMD_SIZE) ++ return 0; ++ if (!ptdesc_pmd_pts_count(virt_to_ptdesc(ptep))) + return 0; + + pud_clear(pud); +- put_page(virt_to_page(ptep)); ++ ptdesc_pmd_pts_dec(virt_to_ptdesc(ptep)); + mm_dec_nr_pmds(mm); + return 1; + } + +-#else /* !CONFIG_ARCH_WANT_HUGE_PMD_SHARE */ ++#else /* !CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING */ + + pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma, + unsigned long addr, pud_t *pud) +@@ -7092,7 +7090,7 @@ bool want_pmd_share(struct vm_area_struct *vma, unsigned long addr) + { + return false; + } +-#endif /* CONFIG_ARCH_WANT_HUGE_PMD_SHARE */ ++#endif /* CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING */ + + #ifdef CONFIG_ARCH_WANT_GENERAL_HUGETLB + pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -7190,7 +7188,7 @@ unsigned long hugetlb_mask_last_page(struct hstate *h) + /* See description above. Architectures can provide their own version. */ + __weak unsigned long hugetlb_mask_last_page(struct hstate *h) + { +-#ifdef CONFIG_ARCH_WANT_HUGE_PMD_SHARE ++#ifdef CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING + if (huge_page_size(h) == PMD_SIZE) + return PUD_SIZE - PMD_SIZE; + #endif +diff --git a/mm/memblock.c b/mm/memblock.c +index 87a2b4340ce4ea..e8a2a1537d6a85 100644 +--- a/mm/memblock.c ++++ b/mm/memblock.c +@@ -754,7 +754,7 @@ bool __init_memblock memblock_validate_numa_coverage(unsigned long threshold_byt + + /* calculate lose page */ + for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, &nid) { +- if (nid == NUMA_NO_NODE) ++ if (!numa_valid_node(nid)) + nr_pages += end_pfn - start_pfn; + } + +@@ -1043,7 +1043,7 @@ static bool should_skip_region(struct memblock_type *type, + return false; + + /* only memory regions are associated with nodes, check it */ +- if (nid != NUMA_NO_NODE && nid != m_nid) ++ if (numa_valid_node(nid) && nid != m_nid) + return true; + + /* skip hotpluggable memory regions if needed */ +@@ -1100,10 +1100,6 @@ void __next_mem_range(u64 *idx, int nid, enum memblock_flags flags, + int idx_a = *idx & 0xffffffff; + int idx_b = *idx >> 32; + +- if (WARN_ONCE(nid == MAX_NUMNODES, +- "Usage of MAX_NUMNODES is deprecated. Use NUMA_NO_NODE instead\n")) +- nid = NUMA_NO_NODE; +- + for (; idx_a < type_a->cnt; idx_a++) { + struct memblock_region *m = &type_a->regions[idx_a]; + +@@ -1197,9 +1193,6 @@ void __init_memblock __next_mem_range_rev(u64 *idx, int nid, + int idx_a = *idx & 0xffffffff; + int idx_b = *idx >> 32; + +- if (WARN_ONCE(nid == MAX_NUMNODES, "Usage of MAX_NUMNODES is deprecated. Use NUMA_NO_NODE instead\n")) +- nid = NUMA_NO_NODE; +- + if (*idx == (u64)ULLONG_MAX) { + idx_a = type_a->cnt - 1; + if (type_b != NULL) +@@ -1285,7 +1278,7 @@ void __init_memblock __next_mem_pfn_range(int *idx, int nid, + + if (PFN_UP(r->base) >= PFN_DOWN(r->base + r->size)) + continue; +- if (nid == MAX_NUMNODES || nid == r_nid) ++ if (!numa_valid_node(nid) || nid == r_nid) + break; + } + if (*idx >= type->cnt) { +@@ -1430,9 +1423,6 @@ phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size, + enum memblock_flags flags = choose_memblock_flags(); + phys_addr_t found; + +- if (WARN_ONCE(nid == MAX_NUMNODES, "Usage of MAX_NUMNODES is deprecated. Use NUMA_NO_NODE instead\n")) +- nid = NUMA_NO_NODE; +- + if (!align) { + /* Can't use WARNs this early in boot on powerpc */ + dump_stack(); +@@ -1445,7 +1435,7 @@ phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size, + if (found && !memblock_reserve(found, size)) + goto done; + +- if (nid != NUMA_NO_NODE && !exact_nid) { ++ if (numa_valid_node(nid) && !exact_nid) { + found = memblock_find_in_range_node(size, align, start, + end, NUMA_NO_NODE, + flags); +@@ -1965,7 +1955,7 @@ static void __init_memblock memblock_dump(struct memblock_type *type) + end = base + size - 1; + flags = rgn->flags; + #ifdef CONFIG_NUMA +- if (memblock_get_region_node(rgn) != MAX_NUMNODES) ++ if (numa_valid_node(memblock_get_region_node(rgn))) + snprintf(nid_buf, sizeof(nid_buf), " on node %d", + memblock_get_region_node(rgn)); + #endif +@@ -2154,7 +2144,7 @@ static void __init memmap_init_reserved_pages(void) + start = region->base; + end = start + region->size; + +- if (nid == NUMA_NO_NODE || nid >= MAX_NUMNODES) ++ if (!numa_valid_node(nid)) + nid = early_pfn_to_nid(PFN_DOWN(start)); + + reserve_bootmem_region(start, end, nid); +@@ -2243,7 +2233,7 @@ static int memblock_debug_show(struct seq_file *m, void *private) + + seq_printf(m, "%4d: ", i); + seq_printf(m, "%pa..%pa ", ®->base, &end); +- if (nid != MAX_NUMNODES) ++ if (numa_valid_node(nid)) + seq_printf(m, "%4d ", nid); + else + seq_printf(m, "%4c ", 'x'); +diff --git a/net/802/psnap.c b/net/802/psnap.c +index 1406bfdbda13b7..dbd9647f2ef1a0 100644 +--- a/net/802/psnap.c ++++ b/net/802/psnap.c +@@ -55,11 +55,11 @@ static int snap_rcv(struct sk_buff *skb, struct net_device *dev, + goto drop; + + rcu_read_lock(); +- proto = find_snap_client(skb_transport_header(skb)); ++ proto = find_snap_client(skb->data); + if (proto) { + /* Pass the frame on. */ +- skb->transport_header += 5; + skb_pull_rcsum(skb, 5); ++ skb_reset_transport_header(skb); + rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev); + } + rcu_read_unlock(); +diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c +index d95e2b55badb47..d6f40806ee5126 100644 +--- a/net/bluetooth/hci_sync.c ++++ b/net/bluetooth/hci_sync.c +@@ -1049,9 +1049,9 @@ static bool adv_use_rpa(struct hci_dev *hdev, uint32_t flags) + + static int hci_set_random_addr_sync(struct hci_dev *hdev, bdaddr_t *rpa) + { +- /* If we're advertising or initiating an LE connection we can't +- * go ahead and change the random address at this time. This is +- * because the eventual initiator address used for the ++ /* If a random_addr has been set we're advertising or initiating an LE ++ * connection we can't go ahead and change the random address at this ++ * time. This is because the eventual initiator address used for the + * subsequently created connection will be undefined (some + * controllers use the new address and others the one we had + * when the operation started). +@@ -1059,8 +1059,9 @@ static int hci_set_random_addr_sync(struct hci_dev *hdev, bdaddr_t *rpa) + * In this kind of scenario skip the update and let the random + * address be updated at the next cycle. + */ +- if (hci_dev_test_flag(hdev, HCI_LE_ADV) || +- hci_lookup_le_connect(hdev)) { ++ if (bacmp(&hdev->random_addr, BDADDR_ANY) && ++ (hci_dev_test_flag(hdev, HCI_LE_ADV) || ++ hci_lookup_le_connect(hdev))) { + bt_dev_dbg(hdev, "Deferring random address update"); + hci_dev_set_flag(hdev, HCI_RPA_EXPIRED); + return 0; +diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c +index 1175248e4bec4b..e3440f0d7d9d97 100644 +--- a/net/bluetooth/mgmt.c ++++ b/net/bluetooth/mgmt.c +@@ -7589,6 +7589,24 @@ static void device_added(struct sock *sk, struct hci_dev *hdev, + mgmt_event(MGMT_EV_DEVICE_ADDED, hdev, &ev, sizeof(ev), sk); + } + ++static void add_device_complete(struct hci_dev *hdev, void *data, int err) ++{ ++ struct mgmt_pending_cmd *cmd = data; ++ struct mgmt_cp_add_device *cp = cmd->param; ++ ++ if (!err) { ++ device_added(cmd->sk, hdev, &cp->addr.bdaddr, cp->addr.type, ++ cp->action); ++ device_flags_changed(NULL, hdev, &cp->addr.bdaddr, ++ cp->addr.type, hdev->conn_flags, ++ PTR_UINT(cmd->user_data)); ++ } ++ ++ mgmt_cmd_complete(cmd->sk, hdev->id, MGMT_OP_ADD_DEVICE, ++ mgmt_status(err), &cp->addr, sizeof(cp->addr)); ++ mgmt_pending_free(cmd); ++} ++ + static int add_device_sync(struct hci_dev *hdev, void *data) + { + return hci_update_passive_scan_sync(hdev); +@@ -7597,6 +7615,7 @@ static int add_device_sync(struct hci_dev *hdev, void *data) + static int add_device(struct sock *sk, struct hci_dev *hdev, + void *data, u16 len) + { ++ struct mgmt_pending_cmd *cmd; + struct mgmt_cp_add_device *cp = data; + u8 auto_conn, addr_type; + struct hci_conn_params *params; +@@ -7677,9 +7696,24 @@ static int add_device(struct sock *sk, struct hci_dev *hdev, + current_flags = params->flags; + } + +- err = hci_cmd_sync_queue(hdev, add_device_sync, NULL, NULL); +- if (err < 0) ++ cmd = mgmt_pending_new(sk, MGMT_OP_ADD_DEVICE, hdev, data, len); ++ if (!cmd) { ++ err = -ENOMEM; + goto unlock; ++ } ++ ++ cmd->user_data = UINT_PTR(current_flags); ++ ++ err = hci_cmd_sync_queue(hdev, add_device_sync, cmd, ++ add_device_complete); ++ if (err < 0) { ++ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE, ++ MGMT_STATUS_FAILED, &cp->addr, ++ sizeof(cp->addr)); ++ mgmt_pending_free(cmd); ++ } ++ ++ goto unlock; + + added: + device_added(sk, hdev, &cp->addr.bdaddr, cp->addr.type, cp->action); +diff --git a/net/core/link_watch.c b/net/core/link_watch.c +index 66422c95c83c77..e2e8a341318bda 100644 +--- a/net/core/link_watch.c ++++ b/net/core/link_watch.c +@@ -42,14 +42,18 @@ static unsigned char default_operstate(const struct net_device *dev) + * first check whether lower is indeed the source of its down state. + */ + if (!netif_carrier_ok(dev)) { +- int iflink = dev_get_iflink(dev); + struct net_device *peer; ++ int iflink; + + /* If called from netdev_run_todo()/linkwatch_sync_dev(), + * dev_net(dev) can be already freed, and RTNL is not held. + */ +- if (dev->reg_state == NETREG_UNREGISTERED || +- iflink == dev->ifindex) ++ if (dev->reg_state <= NETREG_REGISTERED) ++ iflink = dev_get_iflink(dev); ++ else ++ iflink = dev->ifindex; ++ ++ if (iflink == dev->ifindex) + return IF_OPER_DOWN; + + ASSERT_RTNL(); +diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c +index df3ddf31f8e673..705320f160ac86 100644 +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -832,7 +832,7 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb) + sock_net_set(ctl_sk, net); + if (sk) { + ctl_sk->sk_mark = (sk->sk_state == TCP_TIME_WAIT) ? +- inet_twsk(sk)->tw_mark : sk->sk_mark; ++ inet_twsk(sk)->tw_mark : READ_ONCE(sk->sk_mark); + ctl_sk->sk_priority = (sk->sk_state == TCP_TIME_WAIT) ? + inet_twsk(sk)->tw_priority : sk->sk_priority; + transmit_time = tcp_transmit_time(sk); +diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c +index de75df904a0034..34ae0ef4f9f396 100644 +--- a/net/mptcp/ctrl.c ++++ b/net/mptcp/ctrl.c +@@ -87,16 +87,15 @@ static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet) + } + + #ifdef CONFIG_SYSCTL +-static int mptcp_set_scheduler(const struct net *net, const char *name) ++static int mptcp_set_scheduler(char *scheduler, const char *name) + { +- struct mptcp_pernet *pernet = mptcp_get_pernet(net); + struct mptcp_sched_ops *sched; + int ret = 0; + + rcu_read_lock(); + sched = mptcp_sched_find(name); + if (sched) +- strscpy(pernet->scheduler, name, MPTCP_SCHED_NAME_MAX); ++ strscpy(scheduler, name, MPTCP_SCHED_NAME_MAX); + else + ret = -ENOENT; + rcu_read_unlock(); +@@ -107,7 +106,7 @@ static int mptcp_set_scheduler(const struct net *net, const char *name) + static int proc_scheduler(struct ctl_table *ctl, int write, + void *buffer, size_t *lenp, loff_t *ppos) + { +- const struct net *net = current->nsproxy->net_ns; ++ char (*scheduler)[MPTCP_SCHED_NAME_MAX] = ctl->data; + char val[MPTCP_SCHED_NAME_MAX]; + struct ctl_table tbl = { + .data = val, +@@ -115,11 +114,11 @@ static int proc_scheduler(struct ctl_table *ctl, int write, + }; + int ret; + +- strscpy(val, mptcp_get_scheduler(net), MPTCP_SCHED_NAME_MAX); ++ strscpy(val, *scheduler, MPTCP_SCHED_NAME_MAX); + + ret = proc_dostring(&tbl, write, buffer, lenp, ppos); + if (write && ret == 0) +- ret = mptcp_set_scheduler(net, val); ++ ret = mptcp_set_scheduler(*scheduler, val); + + return ret; + } +diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c +index e4ae2a08da6ac3..34ad5975fbf3ba 100644 +--- a/net/netfilter/nf_conntrack_core.c ++++ b/net/netfilter/nf_conntrack_core.c +@@ -2568,12 +2568,15 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls) + struct hlist_nulls_head *hash; + unsigned int nr_slots, i; + +- if (*sizep > (UINT_MAX / sizeof(struct hlist_nulls_head))) ++ if (*sizep > (INT_MAX / sizeof(struct hlist_nulls_head))) + return NULL; + + BUILD_BUG_ON(sizeof(struct hlist_nulls_head) != sizeof(struct hlist_head)); + nr_slots = *sizep = roundup(*sizep, PAGE_SIZE / sizeof(struct hlist_nulls_head)); + ++ if (nr_slots > (INT_MAX / sizeof(struct hlist_nulls_head))) ++ return NULL; ++ + hash = kvcalloc(nr_slots, sizeof(struct hlist_nulls_head), GFP_KERNEL); + + if (hash && nulls) +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index a110aad45fe487..1d1e998acd675e 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -8375,6 +8375,7 @@ static void nft_unregister_flowtable_hook(struct net *net, + } + + static void __nft_unregister_flowtable_net_hooks(struct net *net, ++ struct nft_flowtable *flowtable, + struct list_head *hook_list, + bool release_netdev) + { +@@ -8382,6 +8383,8 @@ static void __nft_unregister_flowtable_net_hooks(struct net *net, + + list_for_each_entry_safe(hook, next, hook_list, list) { + nf_unregister_net_hook(net, &hook->ops); ++ flowtable->data.type->setup(&flowtable->data, hook->ops.dev, ++ FLOW_BLOCK_UNBIND); + if (release_netdev) { + list_del(&hook->list); + kfree_rcu(hook, rcu); +@@ -8390,9 +8393,10 @@ static void __nft_unregister_flowtable_net_hooks(struct net *net, + } + + static void nft_unregister_flowtable_net_hooks(struct net *net, ++ struct nft_flowtable *flowtable, + struct list_head *hook_list) + { +- __nft_unregister_flowtable_net_hooks(net, hook_list, false); ++ __nft_unregister_flowtable_net_hooks(net, flowtable, hook_list, false); + } + + static int nft_register_flowtable_net_hooks(struct net *net, +@@ -9028,8 +9032,6 @@ static void nf_tables_flowtable_destroy(struct nft_flowtable *flowtable) + + flowtable->data.type->free(&flowtable->data); + list_for_each_entry_safe(hook, next, &flowtable->hook_list, list) { +- flowtable->data.type->setup(&flowtable->data, hook->ops.dev, +- FLOW_BLOCK_UNBIND); + list_del_rcu(&hook->list); + kfree_rcu(hook, rcu); + } +@@ -10399,6 +10401,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) + &nft_trans_flowtable_hooks(trans), + trans->msg_type); + nft_unregister_flowtable_net_hooks(net, ++ nft_trans_flowtable(trans), + &nft_trans_flowtable_hooks(trans)); + } else { + list_del_rcu(&nft_trans_flowtable(trans)->list); +@@ -10407,6 +10410,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) + NULL, + trans->msg_type); + nft_unregister_flowtable_net_hooks(net, ++ nft_trans_flowtable(trans), + &nft_trans_flowtable(trans)->hook_list); + } + break; +@@ -10659,11 +10663,13 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) + case NFT_MSG_NEWFLOWTABLE: + if (nft_trans_flowtable_update(trans)) { + nft_unregister_flowtable_net_hooks(net, ++ nft_trans_flowtable(trans), + &nft_trans_flowtable_hooks(trans)); + } else { + nft_use_dec_restore(&trans->ctx.table->use); + list_del_rcu(&nft_trans_flowtable(trans)->list); + nft_unregister_flowtable_net_hooks(net, ++ nft_trans_flowtable(trans), + &nft_trans_flowtable(trans)->hook_list); + } + break; +@@ -11224,7 +11230,8 @@ static void __nft_release_hook(struct net *net, struct nft_table *table) + list_for_each_entry(chain, &table->chains, list) + __nf_tables_unregister_hook(net, table, chain, true); + list_for_each_entry(flowtable, &table->flowtables, list) +- __nft_unregister_flowtable_net_hooks(net, &flowtable->hook_list, ++ __nft_unregister_flowtable_net_hooks(net, flowtable, ++ &flowtable->hook_list, + true); + } + +diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c +index 6ab317b48d6c39..815216b564f323 100644 +--- a/net/sched/cls_flow.c ++++ b/net/sched/cls_flow.c +@@ -356,7 +356,8 @@ static const struct nla_policy flow_policy[TCA_FLOW_MAX + 1] = { + [TCA_FLOW_KEYS] = { .type = NLA_U32 }, + [TCA_FLOW_MODE] = { .type = NLA_U32 }, + [TCA_FLOW_BASECLASS] = { .type = NLA_U32 }, +- [TCA_FLOW_RSHIFT] = { .type = NLA_U32 }, ++ [TCA_FLOW_RSHIFT] = NLA_POLICY_MAX(NLA_U32, ++ 31 /* BITS_PER_U32 - 1 */), + [TCA_FLOW_ADDEND] = { .type = NLA_U32 }, + [TCA_FLOW_MASK] = { .type = NLA_U32 }, + [TCA_FLOW_XOR] = { .type = NLA_U32 }, +diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c +index a65fad45d55681..09242578dac5bc 100644 +--- a/net/sched/sch_cake.c ++++ b/net/sched/sch_cake.c +@@ -644,6 +644,63 @@ static bool cake_ddst(int flow_mode) + return (flow_mode & CAKE_FLOW_DUAL_DST) == CAKE_FLOW_DUAL_DST; + } + ++static void cake_dec_srchost_bulk_flow_count(struct cake_tin_data *q, ++ struct cake_flow *flow, ++ int flow_mode) ++{ ++ if (likely(cake_dsrc(flow_mode) && ++ q->hosts[flow->srchost].srchost_bulk_flow_count)) ++ q->hosts[flow->srchost].srchost_bulk_flow_count--; ++} ++ ++static void cake_inc_srchost_bulk_flow_count(struct cake_tin_data *q, ++ struct cake_flow *flow, ++ int flow_mode) ++{ ++ if (likely(cake_dsrc(flow_mode) && ++ q->hosts[flow->srchost].srchost_bulk_flow_count < CAKE_QUEUES)) ++ q->hosts[flow->srchost].srchost_bulk_flow_count++; ++} ++ ++static void cake_dec_dsthost_bulk_flow_count(struct cake_tin_data *q, ++ struct cake_flow *flow, ++ int flow_mode) ++{ ++ if (likely(cake_ddst(flow_mode) && ++ q->hosts[flow->dsthost].dsthost_bulk_flow_count)) ++ q->hosts[flow->dsthost].dsthost_bulk_flow_count--; ++} ++ ++static void cake_inc_dsthost_bulk_flow_count(struct cake_tin_data *q, ++ struct cake_flow *flow, ++ int flow_mode) ++{ ++ if (likely(cake_ddst(flow_mode) && ++ q->hosts[flow->dsthost].dsthost_bulk_flow_count < CAKE_QUEUES)) ++ q->hosts[flow->dsthost].dsthost_bulk_flow_count++; ++} ++ ++static u16 cake_get_flow_quantum(struct cake_tin_data *q, ++ struct cake_flow *flow, ++ int flow_mode) ++{ ++ u16 host_load = 1; ++ ++ if (cake_dsrc(flow_mode)) ++ host_load = max(host_load, ++ q->hosts[flow->srchost].srchost_bulk_flow_count); ++ ++ if (cake_ddst(flow_mode)) ++ host_load = max(host_load, ++ q->hosts[flow->dsthost].dsthost_bulk_flow_count); ++ ++ /* The get_random_u16() is a way to apply dithering to avoid ++ * accumulating roundoff errors ++ */ ++ return (q->flow_quantum * quantum_div[host_load] + ++ get_random_u16()) >> 16; ++} ++ + static u32 cake_hash(struct cake_tin_data *q, const struct sk_buff *skb, + int flow_mode, u16 flow_override, u16 host_override) + { +@@ -790,10 +847,8 @@ static u32 cake_hash(struct cake_tin_data *q, const struct sk_buff *skb, + allocate_dst = cake_ddst(flow_mode); + + if (q->flows[outer_hash + k].set == CAKE_SET_BULK) { +- if (allocate_src) +- q->hosts[q->flows[reduced_hash].srchost].srchost_bulk_flow_count--; +- if (allocate_dst) +- q->hosts[q->flows[reduced_hash].dsthost].dsthost_bulk_flow_count--; ++ cake_dec_srchost_bulk_flow_count(q, &q->flows[outer_hash + k], flow_mode); ++ cake_dec_dsthost_bulk_flow_count(q, &q->flows[outer_hash + k], flow_mode); + } + found: + /* reserve queue for future packets in same flow */ +@@ -818,9 +873,10 @@ static u32 cake_hash(struct cake_tin_data *q, const struct sk_buff *skb, + q->hosts[outer_hash + k].srchost_tag = srchost_hash; + found_src: + srchost_idx = outer_hash + k; +- if (q->flows[reduced_hash].set == CAKE_SET_BULK) +- q->hosts[srchost_idx].srchost_bulk_flow_count++; + q->flows[reduced_hash].srchost = srchost_idx; ++ ++ if (q->flows[reduced_hash].set == CAKE_SET_BULK) ++ cake_inc_srchost_bulk_flow_count(q, &q->flows[reduced_hash], flow_mode); + } + + if (allocate_dst) { +@@ -841,9 +897,10 @@ static u32 cake_hash(struct cake_tin_data *q, const struct sk_buff *skb, + q->hosts[outer_hash + k].dsthost_tag = dsthost_hash; + found_dst: + dsthost_idx = outer_hash + k; +- if (q->flows[reduced_hash].set == CAKE_SET_BULK) +- q->hosts[dsthost_idx].dsthost_bulk_flow_count++; + q->flows[reduced_hash].dsthost = dsthost_idx; ++ ++ if (q->flows[reduced_hash].set == CAKE_SET_BULK) ++ cake_inc_dsthost_bulk_flow_count(q, &q->flows[reduced_hash], flow_mode); + } + } + +@@ -1856,10 +1913,6 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + + /* flowchain */ + if (!flow->set || flow->set == CAKE_SET_DECAYING) { +- struct cake_host *srchost = &b->hosts[flow->srchost]; +- struct cake_host *dsthost = &b->hosts[flow->dsthost]; +- u16 host_load = 1; +- + if (!flow->set) { + list_add_tail(&flow->flowchain, &b->new_flows); + } else { +@@ -1869,18 +1922,8 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + flow->set = CAKE_SET_SPARSE; + b->sparse_flow_count++; + +- if (cake_dsrc(q->flow_mode)) +- host_load = max(host_load, srchost->srchost_bulk_flow_count); +- +- if (cake_ddst(q->flow_mode)) +- host_load = max(host_load, dsthost->dsthost_bulk_flow_count); +- +- flow->deficit = (b->flow_quantum * +- quantum_div[host_load]) >> 16; ++ flow->deficit = cake_get_flow_quantum(b, flow, q->flow_mode); + } else if (flow->set == CAKE_SET_SPARSE_WAIT) { +- struct cake_host *srchost = &b->hosts[flow->srchost]; +- struct cake_host *dsthost = &b->hosts[flow->dsthost]; +- + /* this flow was empty, accounted as a sparse flow, but actually + * in the bulk rotation. + */ +@@ -1888,12 +1931,8 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + b->sparse_flow_count--; + b->bulk_flow_count++; + +- if (cake_dsrc(q->flow_mode)) +- srchost->srchost_bulk_flow_count++; +- +- if (cake_ddst(q->flow_mode)) +- dsthost->dsthost_bulk_flow_count++; +- ++ cake_inc_srchost_bulk_flow_count(b, flow, q->flow_mode); ++ cake_inc_dsthost_bulk_flow_count(b, flow, q->flow_mode); + } + + if (q->buffer_used > q->buffer_max_used) +@@ -1950,13 +1989,11 @@ static struct sk_buff *cake_dequeue(struct Qdisc *sch) + { + struct cake_sched_data *q = qdisc_priv(sch); + struct cake_tin_data *b = &q->tins[q->cur_tin]; +- struct cake_host *srchost, *dsthost; + ktime_t now = ktime_get(); + struct cake_flow *flow; + struct list_head *head; + bool first_flow = true; + struct sk_buff *skb; +- u16 host_load; + u64 delay; + u32 len; + +@@ -2056,11 +2093,6 @@ static struct sk_buff *cake_dequeue(struct Qdisc *sch) + q->cur_flow = flow - b->flows; + first_flow = false; + +- /* triple isolation (modified DRR++) */ +- srchost = &b->hosts[flow->srchost]; +- dsthost = &b->hosts[flow->dsthost]; +- host_load = 1; +- + /* flow isolation (DRR++) */ + if (flow->deficit <= 0) { + /* Keep all flows with deficits out of the sparse and decaying +@@ -2072,11 +2104,8 @@ static struct sk_buff *cake_dequeue(struct Qdisc *sch) + b->sparse_flow_count--; + b->bulk_flow_count++; + +- if (cake_dsrc(q->flow_mode)) +- srchost->srchost_bulk_flow_count++; +- +- if (cake_ddst(q->flow_mode)) +- dsthost->dsthost_bulk_flow_count++; ++ cake_inc_srchost_bulk_flow_count(b, flow, q->flow_mode); ++ cake_inc_dsthost_bulk_flow_count(b, flow, q->flow_mode); + + flow->set = CAKE_SET_BULK; + } else { +@@ -2088,19 +2117,7 @@ static struct sk_buff *cake_dequeue(struct Qdisc *sch) + } + } + +- if (cake_dsrc(q->flow_mode)) +- host_load = max(host_load, srchost->srchost_bulk_flow_count); +- +- if (cake_ddst(q->flow_mode)) +- host_load = max(host_load, dsthost->dsthost_bulk_flow_count); +- +- WARN_ON(host_load > CAKE_QUEUES); +- +- /* The get_random_u16() is a way to apply dithering to avoid +- * accumulating roundoff errors +- */ +- flow->deficit += (b->flow_quantum * quantum_div[host_load] + +- get_random_u16()) >> 16; ++ flow->deficit += cake_get_flow_quantum(b, flow, q->flow_mode); + list_move_tail(&flow->flowchain, &b->old_flows); + + goto retry; +@@ -2124,11 +2141,8 @@ static struct sk_buff *cake_dequeue(struct Qdisc *sch) + if (flow->set == CAKE_SET_BULK) { + b->bulk_flow_count--; + +- if (cake_dsrc(q->flow_mode)) +- srchost->srchost_bulk_flow_count--; +- +- if (cake_ddst(q->flow_mode)) +- dsthost->dsthost_bulk_flow_count--; ++ cake_dec_srchost_bulk_flow_count(b, flow, q->flow_mode); ++ cake_dec_dsthost_bulk_flow_count(b, flow, q->flow_mode); + + b->decaying_flow_count++; + } else if (flow->set == CAKE_SET_SPARSE || +@@ -2146,12 +2160,8 @@ static struct sk_buff *cake_dequeue(struct Qdisc *sch) + else if (flow->set == CAKE_SET_BULK) { + b->bulk_flow_count--; + +- if (cake_dsrc(q->flow_mode)) +- srchost->srchost_bulk_flow_count--; +- +- if (cake_ddst(q->flow_mode)) +- dsthost->dsthost_bulk_flow_count--; +- ++ cake_dec_srchost_bulk_flow_count(b, flow, q->flow_mode); ++ cake_dec_dsthost_bulk_flow_count(b, flow, q->flow_mode); + } else + b->decaying_flow_count--; + +diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c +index f65d6f92afcbc2..fd73be940f4607 100644 +--- a/net/sctp/sysctl.c ++++ b/net/sctp/sysctl.c +@@ -391,7 +391,8 @@ static struct ctl_table sctp_net_table[] = { + static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, + void *buffer, size_t *lenp, loff_t *ppos) + { +- struct net *net = current->nsproxy->net_ns; ++ struct net *net = container_of(ctl->data, struct net, ++ sctp.sctp_hmac_alg); + struct ctl_table tbl; + bool changed = false; + char *none = "none"; +@@ -436,7 +437,7 @@ static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, + static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, + void *buffer, size_t *lenp, loff_t *ppos) + { +- struct net *net = current->nsproxy->net_ns; ++ struct net *net = container_of(ctl->data, struct net, sctp.rto_min); + unsigned int min = *(unsigned int *) ctl->extra1; + unsigned int max = *(unsigned int *) ctl->extra2; + struct ctl_table tbl; +@@ -464,7 +465,7 @@ static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, + static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, + void *buffer, size_t *lenp, loff_t *ppos) + { +- struct net *net = current->nsproxy->net_ns; ++ struct net *net = container_of(ctl->data, struct net, sctp.rto_max); + unsigned int min = *(unsigned int *) ctl->extra1; + unsigned int max = *(unsigned int *) ctl->extra2; + struct ctl_table tbl; +@@ -502,7 +503,7 @@ static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write, + static int proc_sctp_do_auth(struct ctl_table *ctl, int write, + void *buffer, size_t *lenp, loff_t *ppos) + { +- struct net *net = current->nsproxy->net_ns; ++ struct net *net = container_of(ctl->data, struct net, sctp.auth_enable); + struct ctl_table tbl; + int new_value, ret; + +@@ -531,7 +532,7 @@ static int proc_sctp_do_auth(struct ctl_table *ctl, int write, + static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write, + void *buffer, size_t *lenp, loff_t *ppos) + { +- struct net *net = current->nsproxy->net_ns; ++ struct net *net = container_of(ctl->data, struct net, sctp.udp_port); + unsigned int min = *(unsigned int *)ctl->extra1; + unsigned int max = *(unsigned int *)ctl->extra2; + struct ctl_table tbl; +@@ -572,7 +573,8 @@ static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write, + static int proc_sctp_do_probe_interval(struct ctl_table *ctl, int write, + void *buffer, size_t *lenp, loff_t *ppos) + { +- struct net *net = current->nsproxy->net_ns; ++ struct net *net = container_of(ctl->data, struct net, ++ sctp.probe_interval); + struct ctl_table tbl; + int ret, new_value; + +diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c +index df166f6afad823..6e30fe879d538e 100644 +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -458,7 +458,7 @@ int tls_tx_records(struct sock *sk, int flags) + + tx_err: + if (rc < 0 && rc != -EAGAIN) +- tls_err_abort(sk, -EBADMSG); ++ tls_err_abort(sk, rc); + + return rc; + } +diff --git a/sound/soc/codecs/rt722-sdca.c b/sound/soc/codecs/rt722-sdca.c +index b9b330375addab..0f9f592744ada3 100644 +--- a/sound/soc/codecs/rt722-sdca.c ++++ b/sound/soc/codecs/rt722-sdca.c +@@ -1466,13 +1466,18 @@ static void rt722_sdca_jack_preset(struct rt722_sdca_priv *rt722) + 0x008d); + /* check HP calibration FSM status */ + for (loop_check = 0; loop_check < chk_cnt; loop_check++) { ++ usleep_range(10000, 11000); + ret = rt722_sdca_index_read(rt722, RT722_VENDOR_CALI, + RT722_DAC_DC_CALI_CTL3, &calib_status); +- if (ret < 0 || loop_check == chk_cnt) ++ if (ret < 0) + dev_dbg(&rt722->slave->dev, "calibration failed!, ret=%d\n", ret); + if ((calib_status & 0x0040) == 0x0) + break; + } ++ ++ if (loop_check == chk_cnt) ++ dev_dbg(&rt722->slave->dev, "%s, calibration time-out!\n", __func__); ++ + /* Set ADC09 power entity floating control */ + rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_ADC0A_08_PDE_FLOAT_CTL, + 0x2a12); +diff --git a/sound/soc/mediatek/common/mtk-afe-platform-driver.c b/sound/soc/mediatek/common/mtk-afe-platform-driver.c +index 01501d5747a7c0..52495c930ca3bf 100644 +--- a/sound/soc/mediatek/common/mtk-afe-platform-driver.c ++++ b/sound/soc/mediatek/common/mtk-afe-platform-driver.c +@@ -120,8 +120,8 @@ int mtk_afe_pcm_new(struct snd_soc_component *component, + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); + + size = afe->mtk_afe_hardware->buffer_bytes_max; +- snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, +- afe->dev, size, size); ++ snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, afe->dev, 0, size); ++ + return 0; + } + EXPORT_SYMBOL_GPL(mtk_afe_pcm_new); +diff --git a/tools/include/linux/numa.h b/tools/include/linux/numa.h +index 110b0e5d0fb004..c8b9369335e000 100644 +--- a/tools/include/linux/numa.h ++++ b/tools/include/linux/numa.h +@@ -13,4 +13,9 @@ + + #define NUMA_NO_NODE (-1) + ++static inline bool numa_valid_node(int nid) ++{ ++ return nid >= 0 && nid < MAX_NUMNODES; ++} ++ + #endif /* _LINUX_NUMA_H */ +diff --git a/tools/testing/selftests/alsa/Makefile b/tools/testing/selftests/alsa/Makefile +index 5af9ba8a4645bc..140c7f821727d7 100644 +--- a/tools/testing/selftests/alsa/Makefile ++++ b/tools/testing/selftests/alsa/Makefile +@@ -23,5 +23,5 @@ include ../lib.mk + $(OUTPUT)/libatest.so: conf.c alsa-local.h + $(CC) $(CFLAGS) -shared -fPIC $< $(LDLIBS) -o $@ + +-$(OUTPUT)/%: %.c $(TEST_GEN_PROGS_EXTENDED) alsa-local.h ++$(OUTPUT)/%: %.c $(OUTPUT)/libatest.so alsa-local.h + $(CC) $(CFLAGS) $< $(LDLIBS) -latest -o $@ diff --git a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.72-73.patch b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.72-73.patch new file mode 100644 index 000000000000..73157e52aabc --- /dev/null +++ b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.72-73.patch @@ -0,0 +1,586 @@ +diff --git a/Makefile b/Makefile +index fb4949cac6ffbf..2ba627f545901e 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 72 ++SUBLEVEL = 73 + EXTRAVERSION = + NAME = Pinguïn Aangedreven + +diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c +index f14c412c56097d..ada3fcc9c6d501 100644 +--- a/fs/overlayfs/copy_up.c ++++ b/fs/overlayfs/copy_up.c +@@ -371,13 +371,13 @@ int ovl_set_attr(struct ovl_fs *ofs, struct dentry *upperdentry, + return err; + } + +-struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct inode *realinode, ++struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct dentry *real, + bool is_upper) + { + struct ovl_fh *fh; + int fh_type, dwords; + int buflen = MAX_HANDLE_SZ; +- uuid_t *uuid = &realinode->i_sb->s_uuid; ++ uuid_t *uuid = &real->d_sb->s_uuid; + int err; + + /* Make sure the real fid stays 32bit aligned */ +@@ -394,8 +394,7 @@ struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct inode *realinode, + * the price or reconnecting the dentry. + */ + dwords = buflen >> 2; +- fh_type = exportfs_encode_inode_fh(realinode, (void *)fh->fb.fid, +- &dwords, NULL, 0); ++ fh_type = exportfs_encode_fh(real, (void *)fh->fb.fid, &dwords, 0); + buflen = (dwords << 2); + + err = -EIO; +@@ -427,29 +426,29 @@ struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct inode *realinode, + return ERR_PTR(err); + } + +-struct ovl_fh *ovl_get_origin_fh(struct ovl_fs *ofs, struct dentry *origin) ++int ovl_set_origin(struct ovl_fs *ofs, struct dentry *lower, ++ struct dentry *upper) + { ++ const struct ovl_fh *fh = NULL; ++ int err; ++ + /* + * When lower layer doesn't support export operations store a 'null' fh, + * so we can use the overlay.origin xattr to distignuish between a copy + * up and a pure upper inode. + */ +- if (!ovl_can_decode_fh(origin->d_sb)) +- return NULL; +- +- return ovl_encode_real_fh(ofs, d_inode(origin), false); +-} +- +-int ovl_set_origin_fh(struct ovl_fs *ofs, const struct ovl_fh *fh, +- struct dentry *upper) +-{ +- int err; ++ if (ovl_can_decode_fh(lower->d_sb)) { ++ fh = ovl_encode_real_fh(ofs, lower, false); ++ if (IS_ERR(fh)) ++ return PTR_ERR(fh); ++ } + + /* + * Do not fail when upper doesn't support xattrs. + */ + err = ovl_check_setxattr(ofs, upper, OVL_XATTR_ORIGIN, fh->buf, + fh ? fh->fb.len : 0, 0); ++ kfree(fh); + + /* Ignore -EPERM from setting "user.*" on symlink/special */ + return err == -EPERM ? 0 : err; +@@ -462,7 +461,7 @@ static int ovl_set_upper_fh(struct ovl_fs *ofs, struct dentry *upper, + const struct ovl_fh *fh; + int err; + +- fh = ovl_encode_real_fh(ofs, d_inode(upper), true); ++ fh = ovl_encode_real_fh(ofs, upper, true); + if (IS_ERR(fh)) + return PTR_ERR(fh); + +@@ -477,7 +476,7 @@ static int ovl_set_upper_fh(struct ovl_fs *ofs, struct dentry *upper, + * + * Caller must hold i_mutex on indexdir. + */ +-static int ovl_create_index(struct dentry *dentry, const struct ovl_fh *fh, ++static int ovl_create_index(struct dentry *dentry, struct dentry *origin, + struct dentry *upper) + { + struct ovl_fs *ofs = OVL_FS(dentry->d_sb); +@@ -503,7 +502,7 @@ static int ovl_create_index(struct dentry *dentry, const struct ovl_fh *fh, + if (WARN_ON(ovl_test_flag(OVL_INDEX, d_inode(dentry)))) + return -EIO; + +- err = ovl_get_index_name_fh(fh, &name); ++ err = ovl_get_index_name(ofs, origin, &name); + if (err) + return err; + +@@ -542,7 +541,6 @@ struct ovl_copy_up_ctx { + struct dentry *destdir; + struct qstr destname; + struct dentry *workdir; +- const struct ovl_fh *origin_fh; + bool origin; + bool indexed; + bool metacopy; +@@ -639,7 +637,7 @@ static int ovl_copy_up_metadata(struct ovl_copy_up_ctx *c, struct dentry *temp) + * hard link. + */ + if (c->origin) { +- err = ovl_set_origin_fh(ofs, c->origin_fh, temp); ++ err = ovl_set_origin(ofs, c->lowerpath.dentry, temp); + if (err) + return err; + } +@@ -751,7 +749,7 @@ static int ovl_copy_up_workdir(struct ovl_copy_up_ctx *c) + goto cleanup; + + if (S_ISDIR(c->stat.mode) && c->indexed) { +- err = ovl_create_index(c->dentry, c->origin_fh, temp); ++ err = ovl_create_index(c->dentry, c->lowerpath.dentry, temp); + if (err) + goto cleanup; + } +@@ -863,8 +861,6 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c) + { + int err; + struct ovl_fs *ofs = OVL_FS(c->dentry->d_sb); +- struct dentry *origin = c->lowerpath.dentry; +- struct ovl_fh *fh = NULL; + bool to_index = false; + + /* +@@ -881,25 +877,17 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c) + to_index = true; + } + +- if (S_ISDIR(c->stat.mode) || c->stat.nlink == 1 || to_index) { +- fh = ovl_get_origin_fh(ofs, origin); +- if (IS_ERR(fh)) +- return PTR_ERR(fh); +- +- /* origin_fh may be NULL */ +- c->origin_fh = fh; ++ if (S_ISDIR(c->stat.mode) || c->stat.nlink == 1 || to_index) + c->origin = true; +- } + + if (to_index) { + c->destdir = ovl_indexdir(c->dentry->d_sb); +- err = ovl_get_index_name(ofs, origin, &c->destname); ++ err = ovl_get_index_name(ofs, c->lowerpath.dentry, &c->destname); + if (err) +- goto out_free_fh; ++ return err; + } else if (WARN_ON(!c->parent)) { + /* Disconnected dentry must be copied up to index dir */ +- err = -EIO; +- goto out_free_fh; ++ return -EIO; + } else { + /* + * Mark parent "impure" because it may now contain non-pure +@@ -907,7 +895,7 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c) + */ + err = ovl_set_impure(c->parent, c->destdir); + if (err) +- goto out_free_fh; ++ return err; + } + + /* Should we copyup with O_TMPFILE or with workdir? */ +@@ -939,8 +927,6 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c) + out: + if (to_index) + kfree(c->destname.name); +-out_free_fh: +- kfree(fh); + return err; + } + +diff --git a/fs/overlayfs/export.c b/fs/overlayfs/export.c +index 3a17e4366f28c0..611ff567a1aa6f 100644 +--- a/fs/overlayfs/export.c ++++ b/fs/overlayfs/export.c +@@ -181,37 +181,35 @@ static int ovl_connect_layer(struct dentry *dentry) + * + * Return 0 for upper file handle, > 0 for lower file handle or < 0 on error. + */ +-static int ovl_check_encode_origin(struct inode *inode) ++static int ovl_check_encode_origin(struct dentry *dentry) + { +- struct ovl_fs *ofs = OVL_FS(inode->i_sb); ++ struct ovl_fs *ofs = OVL_FS(dentry->d_sb); + bool decodable = ofs->config.nfs_export; +- struct dentry *dentry; +- int err; + + /* No upper layer? */ + if (!ovl_upper_mnt(ofs)) + return 1; + + /* Lower file handle for non-upper non-decodable */ +- if (!ovl_inode_upper(inode) && !decodable) ++ if (!ovl_dentry_upper(dentry) && !decodable) + return 1; + + /* Upper file handle for pure upper */ +- if (!ovl_inode_lower(inode)) ++ if (!ovl_dentry_lower(dentry)) + return 0; + + /* + * Root is never indexed, so if there's an upper layer, encode upper for + * root. + */ +- if (inode == d_inode(inode->i_sb->s_root)) ++ if (dentry == dentry->d_sb->s_root) + return 0; + + /* + * Upper decodable file handle for non-indexed upper. + */ +- if (ovl_inode_upper(inode) && decodable && +- !ovl_test_flag(OVL_INDEX, inode)) ++ if (ovl_dentry_upper(dentry) && decodable && ++ !ovl_test_flag(OVL_INDEX, d_inode(dentry))) + return 0; + + /* +@@ -220,23 +218,14 @@ static int ovl_check_encode_origin(struct inode *inode) + * ovl_connect_layer() will try to make origin's layer "connected" by + * copying up a "connectable" ancestor. + */ +- if (!decodable || !S_ISDIR(inode->i_mode)) +- return 1; +- +- dentry = d_find_any_alias(inode); +- if (!dentry) +- return -ENOENT; +- +- err = ovl_connect_layer(dentry); +- dput(dentry); +- if (err < 0) +- return err; ++ if (d_is_dir(dentry) && decodable) ++ return ovl_connect_layer(dentry); + + /* Lower file handle for indexed and non-upper dir/non-dir */ + return 1; + } + +-static int ovl_dentry_to_fid(struct ovl_fs *ofs, struct inode *inode, ++static int ovl_dentry_to_fid(struct ovl_fs *ofs, struct dentry *dentry, + u32 *fid, int buflen) + { + struct ovl_fh *fh = NULL; +@@ -247,13 +236,13 @@ static int ovl_dentry_to_fid(struct ovl_fs *ofs, struct inode *inode, + * Check if we should encode a lower or upper file handle and maybe + * copy up an ancestor to make lower file handle connectable. + */ +- err = enc_lower = ovl_check_encode_origin(inode); ++ err = enc_lower = ovl_check_encode_origin(dentry); + if (enc_lower < 0) + goto fail; + + /* Encode an upper or lower file handle */ +- fh = ovl_encode_real_fh(ofs, enc_lower ? ovl_inode_lower(inode) : +- ovl_inode_upper(inode), !enc_lower); ++ fh = ovl_encode_real_fh(ofs, enc_lower ? ovl_dentry_lower(dentry) : ++ ovl_dentry_upper(dentry), !enc_lower); + if (IS_ERR(fh)) + return PTR_ERR(fh); + +@@ -267,8 +256,8 @@ static int ovl_dentry_to_fid(struct ovl_fs *ofs, struct inode *inode, + return err; + + fail: +- pr_warn_ratelimited("failed to encode file handle (ino=%lu, err=%i)\n", +- inode->i_ino, err); ++ pr_warn_ratelimited("failed to encode file handle (%pd2, err=%i)\n", ++ dentry, err); + goto out; + } + +@@ -276,13 +265,19 @@ static int ovl_encode_fh(struct inode *inode, u32 *fid, int *max_len, + struct inode *parent) + { + struct ovl_fs *ofs = OVL_FS(inode->i_sb); ++ struct dentry *dentry; + int bytes, buflen = *max_len << 2; + + /* TODO: encode connectable file handles */ + if (parent) + return FILEID_INVALID; + +- bytes = ovl_dentry_to_fid(ofs, inode, fid, buflen); ++ dentry = d_find_any_alias(inode); ++ if (!dentry) ++ return FILEID_INVALID; ++ ++ bytes = ovl_dentry_to_fid(ofs, dentry, fid, buflen); ++ dput(dentry); + if (bytes <= 0) + return FILEID_INVALID; + +diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c +index 2d2ef671b36ba5..80391c687c2ad8 100644 +--- a/fs/overlayfs/namei.c ++++ b/fs/overlayfs/namei.c +@@ -507,19 +507,6 @@ static int ovl_verify_fh(struct ovl_fs *ofs, struct dentry *dentry, + return err; + } + +-int ovl_verify_set_fh(struct ovl_fs *ofs, struct dentry *dentry, +- enum ovl_xattr ox, const struct ovl_fh *fh, +- bool is_upper, bool set) +-{ +- int err; +- +- err = ovl_verify_fh(ofs, dentry, ox, fh); +- if (set && err == -ENODATA) +- err = ovl_setxattr(ofs, dentry, ox, fh->buf, fh->fb.len); +- +- return err; +-} +- + /* + * Verify that @real dentry matches the file handle stored in xattr @name. + * +@@ -528,22 +515,24 @@ int ovl_verify_set_fh(struct ovl_fs *ofs, struct dentry *dentry, + * + * Return 0 on match, -ESTALE on mismatch, -ENODATA on no xattr, < 0 on error. + */ +-int ovl_verify_origin_xattr(struct ovl_fs *ofs, struct dentry *dentry, +- enum ovl_xattr ox, struct dentry *real, +- bool is_upper, bool set) ++int ovl_verify_set_fh(struct ovl_fs *ofs, struct dentry *dentry, ++ enum ovl_xattr ox, struct dentry *real, bool is_upper, ++ bool set) + { + struct inode *inode; + struct ovl_fh *fh; + int err; + +- fh = ovl_encode_real_fh(ofs, d_inode(real), is_upper); ++ fh = ovl_encode_real_fh(ofs, real, is_upper); + err = PTR_ERR(fh); + if (IS_ERR(fh)) { + fh = NULL; + goto fail; + } + +- err = ovl_verify_set_fh(ofs, dentry, ox, fh, is_upper, set); ++ err = ovl_verify_fh(ofs, dentry, ox, fh); ++ if (set && err == -ENODATA) ++ err = ovl_setxattr(ofs, dentry, ox, fh->buf, fh->fb.len); + if (err) + goto fail; + +@@ -559,7 +548,6 @@ int ovl_verify_origin_xattr(struct ovl_fs *ofs, struct dentry *dentry, + goto out; + } + +- + /* Get upper dentry from index */ + struct dentry *ovl_index_upper(struct ovl_fs *ofs, struct dentry *index, + bool connected) +@@ -696,7 +684,7 @@ int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index) + goto out; + } + +-int ovl_get_index_name_fh(const struct ovl_fh *fh, struct qstr *name) ++static int ovl_get_index_name_fh(struct ovl_fh *fh, struct qstr *name) + { + char *n, *s; + +@@ -732,7 +720,7 @@ int ovl_get_index_name(struct ovl_fs *ofs, struct dentry *origin, + struct ovl_fh *fh; + int err; + +- fh = ovl_encode_real_fh(ofs, d_inode(origin), false); ++ fh = ovl_encode_real_fh(ofs, origin, false); + if (IS_ERR(fh)) + return PTR_ERR(fh); + +@@ -885,27 +873,20 @@ int ovl_path_next(int idx, struct dentry *dentry, struct path *path) + static int ovl_fix_origin(struct ovl_fs *ofs, struct dentry *dentry, + struct dentry *lower, struct dentry *upper) + { +- const struct ovl_fh *fh; + int err; + + if (ovl_check_origin_xattr(ofs, upper)) + return 0; + +- fh = ovl_get_origin_fh(ofs, lower); +- if (IS_ERR(fh)) +- return PTR_ERR(fh); +- + err = ovl_want_write(dentry); + if (err) +- goto out; ++ return err; + +- err = ovl_set_origin_fh(ofs, fh, upper); ++ err = ovl_set_origin(ofs, lower, upper); + if (!err) + err = ovl_set_impure(dentry->d_parent, upper->d_parent); + + ovl_drop_write(dentry); +-out: +- kfree(fh); + return err; + } + +diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h +index ca63a26a6170b0..09ca82ed0f8ced 100644 +--- a/fs/overlayfs/overlayfs.h ++++ b/fs/overlayfs/overlayfs.h +@@ -632,15 +632,11 @@ struct dentry *ovl_decode_real_fh(struct ovl_fs *ofs, struct ovl_fh *fh, + int ovl_check_origin_fh(struct ovl_fs *ofs, struct ovl_fh *fh, bool connected, + struct dentry *upperdentry, struct ovl_path **stackp); + int ovl_verify_set_fh(struct ovl_fs *ofs, struct dentry *dentry, +- enum ovl_xattr ox, const struct ovl_fh *fh, +- bool is_upper, bool set); +-int ovl_verify_origin_xattr(struct ovl_fs *ofs, struct dentry *dentry, +- enum ovl_xattr ox, struct dentry *real, +- bool is_upper, bool set); ++ enum ovl_xattr ox, struct dentry *real, bool is_upper, ++ bool set); + struct dentry *ovl_index_upper(struct ovl_fs *ofs, struct dentry *index, + bool connected); + int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index); +-int ovl_get_index_name_fh(const struct ovl_fh *fh, struct qstr *name); + int ovl_get_index_name(struct ovl_fs *ofs, struct dentry *origin, + struct qstr *name); + struct dentry *ovl_get_index_fh(struct ovl_fs *ofs, struct ovl_fh *fh); +@@ -652,24 +648,17 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, + unsigned int flags); + bool ovl_lower_positive(struct dentry *dentry); + +-static inline int ovl_verify_origin_fh(struct ovl_fs *ofs, struct dentry *upper, +- const struct ovl_fh *fh, bool set) +-{ +- return ovl_verify_set_fh(ofs, upper, OVL_XATTR_ORIGIN, fh, false, set); +-} +- + static inline int ovl_verify_origin(struct ovl_fs *ofs, struct dentry *upper, + struct dentry *origin, bool set) + { +- return ovl_verify_origin_xattr(ofs, upper, OVL_XATTR_ORIGIN, origin, +- false, set); ++ return ovl_verify_set_fh(ofs, upper, OVL_XATTR_ORIGIN, origin, ++ false, set); + } + + static inline int ovl_verify_upper(struct ovl_fs *ofs, struct dentry *index, + struct dentry *upper, bool set) + { +- return ovl_verify_origin_xattr(ofs, index, OVL_XATTR_UPPER, upper, +- true, set); ++ return ovl_verify_set_fh(ofs, index, OVL_XATTR_UPPER, upper, true, set); + } + + /* readdir.c */ +@@ -832,11 +821,10 @@ int ovl_copy_up_with_data(struct dentry *dentry); + int ovl_maybe_copy_up(struct dentry *dentry, int flags); + int ovl_copy_xattr(struct super_block *sb, const struct path *path, struct dentry *new); + int ovl_set_attr(struct ovl_fs *ofs, struct dentry *upper, struct kstat *stat); +-struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct inode *realinode, ++struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct dentry *real, + bool is_upper); +-struct ovl_fh *ovl_get_origin_fh(struct ovl_fs *ofs, struct dentry *origin); +-int ovl_set_origin_fh(struct ovl_fs *ofs, const struct ovl_fh *fh, +- struct dentry *upper); ++int ovl_set_origin(struct ovl_fs *ofs, struct dentry *lower, ++ struct dentry *upper); + + /* export.c */ + extern const struct export_operations ovl_export_operations; +diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c +index e2574034c3fa17..2c056d737c27c3 100644 +--- a/fs/overlayfs/super.c ++++ b/fs/overlayfs/super.c +@@ -879,20 +879,15 @@ static int ovl_get_indexdir(struct super_block *sb, struct ovl_fs *ofs, + { + struct vfsmount *mnt = ovl_upper_mnt(ofs); + struct dentry *indexdir; +- struct dentry *origin = ovl_lowerstack(oe)->dentry; +- const struct ovl_fh *fh; + int err; + +- fh = ovl_get_origin_fh(ofs, origin); +- if (IS_ERR(fh)) +- return PTR_ERR(fh); +- + err = mnt_want_write(mnt); + if (err) +- goto out_free_fh; ++ return err; + + /* Verify lower root is upper root origin */ +- err = ovl_verify_origin_fh(ofs, upperpath->dentry, fh, true); ++ err = ovl_verify_origin(ofs, upperpath->dentry, ++ ovl_lowerstack(oe)->dentry, true); + if (err) { + pr_err("failed to verify upper root origin\n"); + goto out; +@@ -924,10 +919,9 @@ static int ovl_get_indexdir(struct super_block *sb, struct ovl_fs *ofs, + * directory entries. + */ + if (ovl_check_origin_xattr(ofs, ofs->indexdir)) { +- err = ovl_verify_origin_xattr(ofs, ofs->indexdir, +- OVL_XATTR_ORIGIN, +- upperpath->dentry, true, +- false); ++ err = ovl_verify_set_fh(ofs, ofs->indexdir, ++ OVL_XATTR_ORIGIN, ++ upperpath->dentry, true, false); + if (err) + pr_err("failed to verify index dir 'origin' xattr\n"); + } +@@ -945,8 +939,6 @@ static int ovl_get_indexdir(struct super_block *sb, struct ovl_fs *ofs, + + out: + mnt_drop_write(mnt); +-out_free_fh: +- kfree(fh); + return err; + } + +diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c +index 4e6b747e0f2e25..0bf3ffcd072f6a 100644 +--- a/fs/overlayfs/util.c ++++ b/fs/overlayfs/util.c +@@ -976,18 +976,12 @@ static void ovl_cleanup_index(struct dentry *dentry) + struct dentry *index = NULL; + struct inode *inode; + struct qstr name = { }; +- bool got_write = false; + int err; + + err = ovl_get_index_name(ofs, lowerdentry, &name); + if (err) + goto fail; + +- err = ovl_want_write(dentry); +- if (err) +- goto fail; +- +- got_write = true; + inode = d_inode(upperdentry); + if (!S_ISDIR(inode->i_mode) && inode->i_nlink != 1) { + pr_warn_ratelimited("cleanup linked index (%pd2, ino=%lu, nlink=%u)\n", +@@ -1025,8 +1019,6 @@ static void ovl_cleanup_index(struct dentry *dentry) + goto fail; + + out: +- if (got_write) +- ovl_drop_write(dentry); + kfree(name.name); + dput(index); + return; +@@ -1097,8 +1089,6 @@ void ovl_nlink_end(struct dentry *dentry) + { + struct inode *inode = d_inode(dentry); + +- ovl_drop_write(dentry); +- + if (ovl_test_flag(OVL_INDEX, inode) && inode->i_nlink == 0) { + const struct cred *old_cred; + diff --git a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.73-74.patch b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.73-74.patch new file mode 100644 index 000000000000..cc7a6c852a79 --- /dev/null +++ b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.73-74.patch @@ -0,0 +1,2591 @@ +diff --git a/Makefile b/Makefile +index 2ba627f545901e..b8e5c65910862e 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 73 ++SUBLEVEL = 74 + EXTRAVERSION = + NAME = Pinguïn Aangedreven + +diff --git a/arch/x86/include/asm/special_insns.h b/arch/x86/include/asm/special_insns.h +index 48f8dd47cf6882..1c5513b04f0387 100644 +--- a/arch/x86/include/asm/special_insns.h ++++ b/arch/x86/include/asm/special_insns.h +@@ -217,7 +217,7 @@ static inline int write_user_shstk_64(u64 __user *addr, u64 val) + + #define nop() asm volatile ("nop") + +-static inline void serialize(void) ++static __always_inline void serialize(void) + { + /* Instruction opcode for SERIALIZE; supported in binutils >= 2.35. */ + asm volatile(".byte 0xf, 0x1, 0xe8" ::: "memory"); +diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S +index 901b605166834b..6231f6efb4ee13 100644 +--- a/arch/x86/xen/xen-asm.S ++++ b/arch/x86/xen/xen-asm.S +@@ -221,7 +221,7 @@ SYM_CODE_END(xen_early_idt_handler_array) + push %rax + mov $__HYPERVISOR_iret, %eax + syscall /* Do the IRET. */ +-#ifdef CONFIG_MITIGATION_SLS ++#ifdef CONFIG_SLS + int3 + #endif + .endm +diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c +index 63e4812623361d..4990a19e601334 100644 +--- a/block/blk-sysfs.c ++++ b/block/blk-sysfs.c +@@ -842,10 +842,8 @@ int blk_register_queue(struct gendisk *disk) + * faster to shut down and is made fully functional here as + * request_queues for non-existent devices never get registered. + */ +- if (!blk_queue_init_done(q)) { +- blk_queue_flag_set(QUEUE_FLAG_INIT_DONE, q); +- percpu_ref_switch_to_percpu(&q->q_usage_counter); +- } ++ blk_queue_flag_set(QUEUE_FLAG_INIT_DONE, q); ++ percpu_ref_switch_to_percpu(&q->q_usage_counter); + + return ret; + +diff --git a/block/genhd.c b/block/genhd.c +index 203c880c3e1cd2..6d704c37f26e71 100644 +--- a/block/genhd.c ++++ b/block/genhd.c +@@ -710,13 +710,10 @@ void del_gendisk(struct gendisk *disk) + * If the disk does not own the queue, allow using passthrough requests + * again. Else leave the queue frozen to fail all I/O. + */ +- if (!test_bit(GD_OWNS_QUEUE, &disk->state)) { +- blk_queue_flag_clear(QUEUE_FLAG_INIT_DONE, q); ++ if (!test_bit(GD_OWNS_QUEUE, &disk->state)) + __blk_mq_unfreeze_queue(q, true); +- } else { +- if (queue_is_mq(q)) +- blk_mq_exit_queue(q); +- } ++ else if (queue_is_mq(q)) ++ blk_mq_exit_queue(q); + } + EXPORT_SYMBOL(del_gendisk); + +diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c +index c82b255f82bc41..64d83ff3c0d90c 100644 +--- a/drivers/acpi/resource.c ++++ b/drivers/acpi/resource.c +@@ -680,11 +680,11 @@ static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity, + for (i = 0; i < ARRAY_SIZE(override_table); i++) { + const struct irq_override_cmp *entry = &override_table[i]; + +- if (dmi_check_system(entry->system) && +- entry->irq == gsi && ++ if (entry->irq == gsi && + entry->triggering == triggering && + entry->polarity == polarity && +- entry->shareable == shareable) ++ entry->shareable == shareable && ++ dmi_check_system(entry->system)) + return entry->override; + } + +diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c +index 1e257ecd624db1..b73038ad86f7f3 100644 +--- a/drivers/block/zram/zram_drv.c ++++ b/drivers/block/zram/zram_drv.c +@@ -1262,6 +1262,7 @@ static bool zram_meta_alloc(struct zram *zram, u64 disksize) + zram->mem_pool = zs_create_pool(zram->disk->disk_name); + if (!zram->mem_pool) { + vfree(zram->table); ++ zram->table = NULL; + return false; + } + +diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c +index a16945e8319e3f..956ea29578336c 100644 +--- a/drivers/gpio/gpio-xilinx.c ++++ b/drivers/gpio/gpio-xilinx.c +@@ -66,7 +66,7 @@ struct xgpio_instance { + DECLARE_BITMAP(state, 64); + DECLARE_BITMAP(last_irq_read, 64); + DECLARE_BITMAP(dir, 64); +- spinlock_t gpio_lock; /* For serializing operations */ ++ raw_spinlock_t gpio_lock; /* For serializing operations */ + int irq; + DECLARE_BITMAP(enable, 64); + DECLARE_BITMAP(rising_edge, 64); +@@ -180,14 +180,14 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) + struct xgpio_instance *chip = gpiochip_get_data(gc); + int bit = xgpio_to_bit(chip, gpio); + +- spin_lock_irqsave(&chip->gpio_lock, flags); ++ raw_spin_lock_irqsave(&chip->gpio_lock, flags); + + /* Write to GPIO signal and set its direction to output */ + __assign_bit(bit, chip->state, val); + + xgpio_write_ch(chip, XGPIO_DATA_OFFSET, bit, chip->state); + +- spin_unlock_irqrestore(&chip->gpio_lock, flags); ++ raw_spin_unlock_irqrestore(&chip->gpio_lock, flags); + } + + /** +@@ -211,7 +211,7 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask, + bitmap_remap(hw_mask, mask, chip->sw_map, chip->hw_map, 64); + bitmap_remap(hw_bits, bits, chip->sw_map, chip->hw_map, 64); + +- spin_lock_irqsave(&chip->gpio_lock, flags); ++ raw_spin_lock_irqsave(&chip->gpio_lock, flags); + + bitmap_replace(state, chip->state, hw_bits, hw_mask, 64); + +@@ -219,7 +219,7 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask, + + bitmap_copy(chip->state, state, 64); + +- spin_unlock_irqrestore(&chip->gpio_lock, flags); ++ raw_spin_unlock_irqrestore(&chip->gpio_lock, flags); + } + + /** +@@ -237,13 +237,13 @@ static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) + struct xgpio_instance *chip = gpiochip_get_data(gc); + int bit = xgpio_to_bit(chip, gpio); + +- spin_lock_irqsave(&chip->gpio_lock, flags); ++ raw_spin_lock_irqsave(&chip->gpio_lock, flags); + + /* Set the GPIO bit in shadow register and set direction as input */ + __set_bit(bit, chip->dir); + xgpio_write_ch(chip, XGPIO_TRI_OFFSET, bit, chip->dir); + +- spin_unlock_irqrestore(&chip->gpio_lock, flags); ++ raw_spin_unlock_irqrestore(&chip->gpio_lock, flags); + + return 0; + } +@@ -266,7 +266,7 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) + struct xgpio_instance *chip = gpiochip_get_data(gc); + int bit = xgpio_to_bit(chip, gpio); + +- spin_lock_irqsave(&chip->gpio_lock, flags); ++ raw_spin_lock_irqsave(&chip->gpio_lock, flags); + + /* Write state of GPIO signal */ + __assign_bit(bit, chip->state, val); +@@ -276,7 +276,7 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) + __clear_bit(bit, chip->dir); + xgpio_write_ch(chip, XGPIO_TRI_OFFSET, bit, chip->dir); + +- spin_unlock_irqrestore(&chip->gpio_lock, flags); ++ raw_spin_unlock_irqrestore(&chip->gpio_lock, flags); + + return 0; + } +@@ -404,7 +404,7 @@ static void xgpio_irq_mask(struct irq_data *irq_data) + int bit = xgpio_to_bit(chip, irq_offset); + u32 mask = BIT(bit / 32), temp; + +- spin_lock_irqsave(&chip->gpio_lock, flags); ++ raw_spin_lock_irqsave(&chip->gpio_lock, flags); + + __clear_bit(bit, chip->enable); + +@@ -414,7 +414,7 @@ static void xgpio_irq_mask(struct irq_data *irq_data) + temp &= ~mask; + xgpio_writereg(chip->regs + XGPIO_IPIER_OFFSET, temp); + } +- spin_unlock_irqrestore(&chip->gpio_lock, flags); ++ raw_spin_unlock_irqrestore(&chip->gpio_lock, flags); + + gpiochip_disable_irq(&chip->gc, irq_offset); + } +@@ -434,7 +434,7 @@ static void xgpio_irq_unmask(struct irq_data *irq_data) + + gpiochip_enable_irq(&chip->gc, irq_offset); + +- spin_lock_irqsave(&chip->gpio_lock, flags); ++ raw_spin_lock_irqsave(&chip->gpio_lock, flags); + + __set_bit(bit, chip->enable); + +@@ -453,7 +453,7 @@ static void xgpio_irq_unmask(struct irq_data *irq_data) + xgpio_writereg(chip->regs + XGPIO_IPIER_OFFSET, val); + } + +- spin_unlock_irqrestore(&chip->gpio_lock, flags); ++ raw_spin_unlock_irqrestore(&chip->gpio_lock, flags); + } + + /** +@@ -518,7 +518,7 @@ static void xgpio_irqhandler(struct irq_desc *desc) + + chained_irq_enter(irqchip, desc); + +- spin_lock(&chip->gpio_lock); ++ raw_spin_lock(&chip->gpio_lock); + + xgpio_read_ch_all(chip, XGPIO_DATA_OFFSET, all); + +@@ -535,7 +535,7 @@ static void xgpio_irqhandler(struct irq_desc *desc) + bitmap_copy(chip->last_irq_read, all, 64); + bitmap_or(all, rising, falling, 64); + +- spin_unlock(&chip->gpio_lock); ++ raw_spin_unlock(&chip->gpio_lock); + + dev_dbg(gc->parent, "IRQ rising %*pb falling %*pb\n", 64, rising, 64, falling); + +@@ -626,7 +626,7 @@ static int xgpio_probe(struct platform_device *pdev) + bitmap_set(chip->hw_map, 0, width[0]); + bitmap_set(chip->hw_map, 32, width[1]); + +- spin_lock_init(&chip->gpio_lock); ++ raw_spin_lock_init(&chip->gpio_lock); + + chip->gc.base = -1; + chip->gc.ngpio = bitmap_weight(chip->hw_map, 64); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index f4c1cc6df1c830..2e739b80cfccf1 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -3172,7 +3172,7 @@ static int amdgpu_device_ip_resume_phase1(struct amdgpu_device *adev) + * + * @adev: amdgpu_device pointer + * +- * Second resume function for hardware IPs. The list of all the hardware ++ * First resume function for hardware IPs. The list of all the hardware + * IPs that make up the asic is walked and the resume callbacks are run for + * all blocks except COMMON, GMC, and IH. resume puts the hardware into a + * functional state after a suspend and updates the software state as +@@ -3190,7 +3190,6 @@ static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev) + if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON || + adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC || + adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH || +- adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE || + adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP) + continue; + r = adev->ip_blocks[i].version->funcs->resume(adev); +@@ -3205,36 +3204,6 @@ static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev) + return 0; + } + +-/** +- * amdgpu_device_ip_resume_phase3 - run resume for hardware IPs +- * +- * @adev: amdgpu_device pointer +- * +- * Third resume function for hardware IPs. The list of all the hardware +- * IPs that make up the asic is walked and the resume callbacks are run for +- * all DCE. resume puts the hardware into a functional state after a suspend +- * and updates the software state as necessary. This function is also used +- * for restoring the GPU after a GPU reset. +- * +- * Returns 0 on success, negative error code on failure. +- */ +-static int amdgpu_device_ip_resume_phase3(struct amdgpu_device *adev) +-{ +- int i, r; +- +- for (i = 0; i < adev->num_ip_blocks; i++) { +- if (!adev->ip_blocks[i].status.valid || adev->ip_blocks[i].status.hw) +- continue; +- if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE) { +- r = adev->ip_blocks[i].version->funcs->resume(adev); +- if (r) +- return r; +- } +- } +- +- return 0; +-} +- + /** + * amdgpu_device_ip_resume - run resume for hardware IPs + * +@@ -3261,13 +3230,6 @@ static int amdgpu_device_ip_resume(struct amdgpu_device *adev) + + r = amdgpu_device_ip_resume_phase2(adev); + +- if (r) +- return r; +- +- amdgpu_fence_driver_hw_init(adev); +- +- r = amdgpu_device_ip_resume_phase3(adev); +- + return r; + } + +@@ -4267,6 +4229,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon) + dev_err(adev->dev, "amdgpu_device_ip_resume failed (%d).\n", r); + goto exit; + } ++ amdgpu_fence_driver_hw_init(adev); + + r = amdgpu_device_ip_late_init(adev); + if (r) +@@ -5036,10 +4999,6 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle, + if (r) + goto out; + +- r = amdgpu_device_ip_resume_phase3(tmp_adev); +- if (r) +- goto out; +- + if (vram_lost) + amdgpu_device_fill_reset_magic(tmp_adev); + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +index 6aa3b1d845abe1..806ec5d021995c 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +@@ -193,8 +193,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs, + need_ctx_switch = ring->current_ctx != fence_ctx; + if (ring->funcs->emit_pipeline_sync && job && + ((tmp = amdgpu_sync_get_fence(&job->explicit_sync)) || +- (amdgpu_sriov_vf(adev) && need_ctx_switch) || +- amdgpu_vm_need_pipeline_sync(ring, job))) { ++ need_ctx_switch || amdgpu_vm_need_pipeline_sync(ring, job))) { ++ + need_pipe_sync = true; + + if (tmp) +diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +index d1a25fe6c44faa..8dffa5b6426e1c 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +@@ -1315,7 +1315,7 @@ static struct link_encoder *dcn21_link_encoder_create( + kzalloc(sizeof(struct dcn21_link_encoder), GFP_KERNEL); + int link_regs_id; + +- if (!enc21) ++ if (!enc21 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) + return NULL; + + link_regs_id = +diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c +index 689b7c16d30072..22ae38bacb44a5 100644 +--- a/drivers/gpu/drm/i915/display/intel_fb.c ++++ b/drivers/gpu/drm/i915/display/intel_fb.c +@@ -1625,7 +1625,7 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer * + * arithmetic related to alignment and offset calculation. + */ + if (is_gen12_ccs_cc_plane(&fb->base, i)) { +- if (IS_ALIGNED(fb->base.offsets[i], PAGE_SIZE)) ++ if (IS_ALIGNED(fb->base.offsets[i], 64)) + continue; + else + return -EINVAL; +diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c +index 93f08f9479d89b..03eacb22648ef7 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_fence.c ++++ b/drivers/gpu/drm/nouveau/nouveau_fence.c +@@ -386,11 +386,13 @@ nouveau_fence_sync(struct nouveau_bo *nvbo, struct nouveau_channel *chan, + if (f) { + struct nouveau_channel *prev; + bool must_wait = true; ++ bool local; + + rcu_read_lock(); + prev = rcu_dereference(f->channel); +- if (prev && (prev == chan || +- fctx->sync(f, prev, chan) == 0)) ++ local = prev && prev->cli->drm == chan->cli->drm; ++ if (local && (prev == chan || ++ fctx->sync(f, prev, chan) == 0)) + must_wait = false; + rcu_read_unlock(); + if (!must_wait) +diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c +index e714d5318f3095..76806039691a2c 100644 +--- a/drivers/gpu/drm/v3d/v3d_irq.c ++++ b/drivers/gpu/drm/v3d/v3d_irq.c +@@ -103,6 +103,7 @@ v3d_irq(int irq, void *arg) + + trace_v3d_bcl_irq(&v3d->drm, fence->seqno); + dma_fence_signal(&fence->base); ++ v3d->bin_job = NULL; + status = IRQ_HANDLED; + } + +@@ -112,6 +113,7 @@ v3d_irq(int irq, void *arg) + + trace_v3d_rcl_irq(&v3d->drm, fence->seqno); + dma_fence_signal(&fence->base); ++ v3d->render_job = NULL; + status = IRQ_HANDLED; + } + +@@ -121,6 +123,7 @@ v3d_irq(int irq, void *arg) + + trace_v3d_csd_irq(&v3d->drm, fence->seqno); + dma_fence_signal(&fence->base); ++ v3d->csd_job = NULL; + status = IRQ_HANDLED; + } + +@@ -157,6 +160,7 @@ v3d_hub_irq(int irq, void *arg) + + trace_v3d_tfu_irq(&v3d->drm, fence->seqno); + dma_fence_signal(&fence->base); ++ v3d->tfu_job = NULL; + status = IRQ_HANDLED; + } + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +index fdc34283eeb97f..ec6ca264ce11ff 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +@@ -412,7 +412,8 @@ static int vmw_bo_init(struct vmw_private *dev_priv, + + if (params->pin) + ttm_bo_pin(&vmw_bo->tbo); +- ttm_bo_unreserve(&vmw_bo->tbo); ++ if (!params->keep_resv) ++ ttm_bo_unreserve(&vmw_bo->tbo); + + return 0; + } +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h +index 156ea612fc2a48..a3ac61b991bf66 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h +@@ -53,8 +53,9 @@ struct vmw_bo_params { + u32 domain; + u32 busy_domain; + enum ttm_bo_type bo_type; +- size_t size; + bool pin; ++ bool keep_resv; ++ size_t size; + struct dma_resv *resv; + struct sg_table *sg; + }; +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +index bea576434e475c..4655c266924fed 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +@@ -399,7 +399,8 @@ static int vmw_dummy_query_bo_create(struct vmw_private *dev_priv) + .busy_domain = VMW_BO_DOMAIN_SYS, + .bo_type = ttm_bo_type_kernel, + .size = PAGE_SIZE, +- .pin = true ++ .pin = true, ++ .keep_resv = true, + }; + + /* +@@ -411,10 +412,6 @@ static int vmw_dummy_query_bo_create(struct vmw_private *dev_priv) + if (unlikely(ret != 0)) + return ret; + +- ret = ttm_bo_reserve(&vbo->tbo, false, true, NULL); +- BUG_ON(ret != 0); +- vmw_bo_pin_reserved(vbo, true); +- + ret = ttm_bo_kmap(&vbo->tbo, 0, 1, &map); + if (likely(ret == 0)) { + result = ttm_kmap_obj_virtual(&map, &dummy); +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c +index d6bcaf078b1f40..0dc3dacc5beee8 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c +@@ -163,6 +163,7 @@ struct drm_gem_object *vmw_prime_import_sg_table(struct drm_device *dev, + .bo_type = ttm_bo_type_sg, + .size = attach->dmabuf->size, + .pin = false, ++ .keep_resv = true, + .resv = attach->dmabuf->resv, + .sg = table, + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c +index a01ca3226d0af8..7fb1c88bcc475f 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c +@@ -896,7 +896,8 @@ int vmw_compat_shader_add(struct vmw_private *dev_priv, + .busy_domain = VMW_BO_DOMAIN_SYS, + .bo_type = ttm_bo_type_device, + .size = size, +- .pin = true ++ .pin = true, ++ .keep_resv = true, + }; + + if (!vmw_shader_id_ok(user_key, shader_type)) +@@ -906,10 +907,6 @@ int vmw_compat_shader_add(struct vmw_private *dev_priv, + if (unlikely(ret != 0)) + goto out; + +- ret = ttm_bo_reserve(&buf->tbo, false, true, NULL); +- if (unlikely(ret != 0)) +- goto no_reserve; +- + /* Map and copy shader bytecode. */ + ret = ttm_bo_kmap(&buf->tbo, 0, PFN_UP(size), &map); + if (unlikely(ret != 0)) { +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +index fcb87d83760ef6..75cf9e76df2ed4 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +@@ -604,15 +604,14 @@ int vmw_bo_create_and_populate(struct vmw_private *dev_priv, + .busy_domain = domain, + .bo_type = ttm_bo_type_kernel, + .size = bo_size, +- .pin = true ++ .pin = true, ++ .keep_resv = true, + }; + + ret = vmw_bo_create(dev_priv, &bo_params, &vbo); + if (unlikely(ret != 0)) + return ret; + +- ret = ttm_bo_reserve(&vbo->tbo, false, true, NULL); +- BUG_ON(ret != 0); + ret = vmw_ttm_populate(vbo->tbo.bdev, vbo->tbo.ttm, &ctx); + if (likely(ret == 0)) { + struct vmw_ttm_tt *vmw_tt = +diff --git a/drivers/hwmon/tmp513.c b/drivers/hwmon/tmp513.c +index 070f93226ed696..62d31aadda4bb8 100644 +--- a/drivers/hwmon/tmp513.c ++++ b/drivers/hwmon/tmp513.c +@@ -203,7 +203,8 @@ static int tmp51x_get_value(struct tmp51x_data *data, u8 reg, u8 pos, + *val = sign_extend32(regval, + reg == TMP51X_SHUNT_CURRENT_RESULT ? + 16 - tmp51x_get_pga_shift(data) : 15); +- *val = DIV_ROUND_CLOSEST(*val * 10 * MILLI, data->shunt_uohms); ++ *val = DIV_ROUND_CLOSEST(*val * 10 * (long)MILLI, (long)data->shunt_uohms); ++ + break; + case TMP51X_BUS_VOLTAGE_RESULT: + case TMP51X_BUS_VOLTAGE_H_LIMIT: +@@ -219,7 +220,7 @@ static int tmp51x_get_value(struct tmp51x_data *data, u8 reg, u8 pos, + case TMP51X_BUS_CURRENT_RESULT: + // Current = (ShuntVoltage * CalibrationRegister) / 4096 + *val = sign_extend32(regval, 15) * (long)data->curr_lsb_ua; +- *val = DIV_ROUND_CLOSEST(*val, MILLI); ++ *val = DIV_ROUND_CLOSEST(*val, (long)MILLI); + break; + case TMP51X_LOCAL_TEMP_RESULT: + case TMP51X_REMOTE_TEMP_RESULT_1: +@@ -259,7 +260,7 @@ static int tmp51x_set_value(struct tmp51x_data *data, u8 reg, long val) + * The user enter current value and we convert it to + * voltage. 1lsb = 10uV + */ +- val = DIV_ROUND_CLOSEST(val * data->shunt_uohms, 10 * MILLI); ++ val = DIV_ROUND_CLOSEST(val * (long)data->shunt_uohms, 10 * (long)MILLI); + max_val = U16_MAX >> tmp51x_get_pga_shift(data); + regval = clamp_val(val, -max_val, max_val); + break; +diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c +index 84fdd3f5cc8445..610df67cedaadc 100644 +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -110,6 +110,8 @@ + #define ID_P_PM_BLOCKED BIT(31) + #define ID_P_MASK GENMASK(31, 28) + ++#define ID_SLAVE_NACK BIT(0) ++ + enum rcar_i2c_type { + I2C_RCAR_GEN1, + I2C_RCAR_GEN2, +@@ -143,6 +145,7 @@ struct rcar_i2c_priv { + int irq; + + struct i2c_client *host_notify_client; ++ u8 slave_flags; + }; + + #define rcar_i2c_priv_to_dev(p) ((p)->adap.dev.parent) +@@ -597,6 +600,7 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv) + { + u32 ssr_raw, ssr_filtered; + u8 value; ++ int ret; + + ssr_raw = rcar_i2c_read(priv, ICSSR) & 0xff; + ssr_filtered = ssr_raw & rcar_i2c_read(priv, ICSIER); +@@ -612,7 +616,10 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv) + rcar_i2c_write(priv, ICRXTX, value); + rcar_i2c_write(priv, ICSIER, SDE | SSR | SAR); + } else { +- i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_REQUESTED, &value); ++ ret = i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_REQUESTED, &value); ++ if (ret) ++ priv->slave_flags |= ID_SLAVE_NACK; ++ + rcar_i2c_read(priv, ICRXTX); /* dummy read */ + rcar_i2c_write(priv, ICSIER, SDR | SSR | SAR); + } +@@ -625,18 +632,21 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv) + if (ssr_filtered & SSR) { + i2c_slave_event(priv->slave, I2C_SLAVE_STOP, &value); + rcar_i2c_write(priv, ICSCR, SIE | SDBS); /* clear our NACK */ ++ priv->slave_flags &= ~ID_SLAVE_NACK; + rcar_i2c_write(priv, ICSIER, SAR); + rcar_i2c_write(priv, ICSSR, ~SSR & 0xff); + } + + /* master wants to write to us */ + if (ssr_filtered & SDR) { +- int ret; +- + value = rcar_i2c_read(priv, ICRXTX); + ret = i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_RECEIVED, &value); +- /* Send NACK in case of error */ +- rcar_i2c_write(priv, ICSCR, SIE | SDBS | (ret < 0 ? FNA : 0)); ++ if (ret) ++ priv->slave_flags |= ID_SLAVE_NACK; ++ ++ /* Send NACK in case of error, but it will come 1 byte late :( */ ++ rcar_i2c_write(priv, ICSCR, SIE | SDBS | ++ (priv->slave_flags & ID_SLAVE_NACK ? FNA : 0)); + rcar_i2c_write(priv, ICSSR, ~SDR & 0xff); + } + +diff --git a/drivers/i2c/i2c-atr.c b/drivers/i2c/i2c-atr.c +index 8ca1daadec9373..c03196da116351 100644 +--- a/drivers/i2c/i2c-atr.c ++++ b/drivers/i2c/i2c-atr.c +@@ -412,7 +412,7 @@ static int i2c_atr_bus_notifier_call(struct notifier_block *nb, + dev_name(dev), ret); + break; + +- case BUS_NOTIFY_DEL_DEVICE: ++ case BUS_NOTIFY_REMOVED_DEVICE: + i2c_atr_detach_client(client->adapter, client); + break; + +diff --git a/drivers/i2c/muxes/i2c-demux-pinctrl.c b/drivers/i2c/muxes/i2c-demux-pinctrl.c +index 9f2e4aa2815933..299abb6dd9423d 100644 +--- a/drivers/i2c/muxes/i2c-demux-pinctrl.c ++++ b/drivers/i2c/muxes/i2c-demux-pinctrl.c +@@ -261,7 +261,9 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev) + pm_runtime_no_callbacks(&pdev->dev); + + /* switch to first parent as active master */ +- i2c_demux_activate_master(priv, 0); ++ err = i2c_demux_activate_master(priv, 0); ++ if (err) ++ goto err_rollback; + + err = device_create_file(&pdev->dev, &dev_attr_available_masters); + if (err) +diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600.h b/drivers/iio/imu/inv_icm42600/inv_icm42600.h +index 0e290c807b0f91..94c0eb0bf8748a 100644 +--- a/drivers/iio/imu/inv_icm42600/inv_icm42600.h ++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600.h +@@ -362,6 +362,7 @@ struct inv_icm42600_state { + typedef int (*inv_icm42600_bus_setup)(struct inv_icm42600_state *); + + extern const struct regmap_config inv_icm42600_regmap_config; ++extern const struct regmap_config inv_icm42600_spi_regmap_config; + extern const struct dev_pm_ops inv_icm42600_pm_ops; + + const struct iio_mount_matrix * +diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +index d938bc45439729..da65aa4e27242f 100644 +--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c ++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +@@ -44,6 +44,17 @@ const struct regmap_config inv_icm42600_regmap_config = { + }; + EXPORT_SYMBOL_NS_GPL(inv_icm42600_regmap_config, IIO_ICM42600); + ++/* define specific regmap for SPI not supporting burst write */ ++const struct regmap_config inv_icm42600_spi_regmap_config = { ++ .reg_bits = 8, ++ .val_bits = 8, ++ .max_register = 0x4FFF, ++ .ranges = inv_icm42600_regmap_ranges, ++ .num_ranges = ARRAY_SIZE(inv_icm42600_regmap_ranges), ++ .use_single_write = true, ++}; ++EXPORT_SYMBOL_NS_GPL(inv_icm42600_spi_regmap_config, IIO_ICM42600); ++ + struct inv_icm42600_hw { + uint8_t whoami; + const char *name; +diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c +index 6be4ac79493794..abfa1b73cf4d35 100644 +--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c ++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c +@@ -59,7 +59,8 @@ static int inv_icm42600_probe(struct spi_device *spi) + return -EINVAL; + chip = (uintptr_t)match; + +- regmap = devm_regmap_init_spi(spi, &inv_icm42600_regmap_config); ++ /* use SPI specific regmap */ ++ regmap = devm_regmap_init_spi(spi, &inv_icm42600_spi_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + +diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +index 13c65ec5825687..08da793969ee55 100644 +--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c ++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +@@ -2220,6 +2220,7 @@ int bnxt_re_query_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr, + qp_attr->retry_cnt = qplib_qp->retry_cnt; + qp_attr->rnr_retry = qplib_qp->rnr_retry; + qp_attr->min_rnr_timer = qplib_qp->min_rnr_timer; ++ qp_attr->port_num = __to_ib_port_num(qplib_qp->port_id); + qp_attr->rq_psn = qplib_qp->rq.psn; + qp_attr->max_rd_atomic = qplib_qp->max_rd_atomic; + qp_attr->sq_psn = qplib_qp->sq.psn; +diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h +index 98baea98fc1761..ef910e6e2ccb73 100644 +--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h ++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h +@@ -245,6 +245,10 @@ void bnxt_re_dealloc_ucontext(struct ib_ucontext *context); + int bnxt_re_mmap(struct ib_ucontext *context, struct vm_area_struct *vma); + void bnxt_re_mmap_free(struct rdma_user_mmap_entry *rdma_entry); + ++static inline u32 __to_ib_port_num(u16 port_id) ++{ ++ return (u32)port_id + 1; ++} + + unsigned long bnxt_re_lock_cqs(struct bnxt_re_qp *qp); + void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp, unsigned long flags); +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c +index 871a49315c880f..c4f10498c79d87 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c +@@ -1460,6 +1460,7 @@ int bnxt_qplib_query_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) + qp->dest_qpn = le32_to_cpu(sb->dest_qp_id); + memcpy(qp->smac, sb->src_mac, 6); + qp->vlan_id = le16_to_cpu(sb->vlan_pcp_vlan_dei_vlan_id); ++ qp->port_id = le16_to_cpu(sb->port_id); + bail: + dma_free_coherent(&rcfw->pdev->dev, sbuf.size, + sbuf.sb, sbuf.dma_addr); +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h +index b5c53e864fbb39..55fd840359ef23 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h ++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h +@@ -297,6 +297,7 @@ struct bnxt_qplib_qp { + u32 dest_qpn; + u8 smac[6]; + u16 vlan_id; ++ u16 port_id; + u8 nw_type; + struct bnxt_qplib_ah ah; + +diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c +index b1e60c13c1e1e7..a1934fe4ad5ab0 100644 +--- a/drivers/irqchip/irq-gic-v3-its.c ++++ b/drivers/irqchip/irq-gic-v3-its.c +@@ -1970,7 +1970,7 @@ static int its_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info) + if (!is_v4(its_dev->its)) + return -EINVAL; + +- guard(raw_spinlock_irq)(&its_dev->event_map.vlpi_lock); ++ guard(raw_spinlock)(&its_dev->event_map.vlpi_lock); + + /* Unmap request? */ + if (!info) +diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c +index e7f000f90bb467..6c7943c516eb09 100644 +--- a/drivers/irqchip/irq-gic-v3.c ++++ b/drivers/irqchip/irq-gic-v3.c +@@ -1460,7 +1460,7 @@ static int gic_retrigger(struct irq_data *data) + static int gic_cpu_pm_notifier(struct notifier_block *self, + unsigned long cmd, void *v) + { +- if (cmd == CPU_PM_EXIT) { ++ if (cmd == CPU_PM_EXIT || cmd == CPU_PM_ENTER_FAILED) { + if (gic_dist_security_disabled()) + gic_enable_redist(true); + gic_cpu_sys_reg_init(); +diff --git a/drivers/irqchip/irqchip.c b/drivers/irqchip/irqchip.c +index 1eeb0d0156ce9e..0ee7b6b71f5fa5 100644 +--- a/drivers/irqchip/irqchip.c ++++ b/drivers/irqchip/irqchip.c +@@ -35,11 +35,10 @@ void __init irqchip_init(void) + int platform_irqchip_probe(struct platform_device *pdev) + { + struct device_node *np = pdev->dev.of_node; +- struct device_node *par_np = of_irq_find_parent(np); ++ struct device_node *par_np __free(device_node) = of_irq_find_parent(np); + of_irq_init_cb_t irq_init_cb = of_device_get_match_data(&pdev->dev); + + if (!irq_init_cb) { +- of_node_put(par_np); + return -EINVAL; + } + +@@ -55,7 +54,6 @@ int platform_irqchip_probe(struct platform_device *pdev) + * interrupt controller can check for specific domains as necessary. + */ + if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY)) { +- of_node_put(par_np); + return -EPROBE_DEFER; + } + +diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c +index 8d75a66775cb1f..1b0c6770c14e46 100644 +--- a/drivers/mtd/spi-nor/core.c ++++ b/drivers/mtd/spi-nor/core.c +@@ -89,7 +89,7 @@ void spi_nor_spimem_setup_op(const struct spi_nor *nor, + op->addr.buswidth = spi_nor_get_protocol_addr_nbits(proto); + + if (op->dummy.nbytes) +- op->dummy.buswidth = spi_nor_get_protocol_data_nbits(proto); ++ op->dummy.buswidth = spi_nor_get_protocol_addr_nbits(proto); + + if (op->data.nbytes) + op->data.buswidth = spi_nor_get_protocol_data_nbits(proto); +diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c +index 6a716337f48be1..268399dfcf22f0 100644 +--- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c ++++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c +@@ -923,7 +923,6 @@ static void xgbe_phy_free_phy_device(struct xgbe_prv_data *pdata) + + static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata) + { +- __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, }; + struct xgbe_phy_data *phy_data = pdata->phy_data; + unsigned int phy_id = phy_data->phydev->phy_id; + +@@ -945,14 +944,7 @@ static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata) + phy_write(phy_data->phydev, 0x04, 0x0d01); + phy_write(phy_data->phydev, 0x00, 0x9140); + +- linkmode_set_bit_array(phy_10_100_features_array, +- ARRAY_SIZE(phy_10_100_features_array), +- supported); +- linkmode_set_bit_array(phy_gbit_features_array, +- ARRAY_SIZE(phy_gbit_features_array), +- supported); +- +- linkmode_copy(phy_data->phydev->supported, supported); ++ linkmode_copy(phy_data->phydev->supported, PHY_GBIT_FEATURES); + + phy_support_asym_pause(phy_data->phydev); + +@@ -964,7 +956,6 @@ static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata) + + static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata) + { +- __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, }; + struct xgbe_phy_data *phy_data = pdata->phy_data; + struct xgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom; + unsigned int phy_id = phy_data->phydev->phy_id; +@@ -1028,13 +1019,7 @@ static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata) + reg = phy_read(phy_data->phydev, 0x00); + phy_write(phy_data->phydev, 0x00, reg & ~0x00800); + +- linkmode_set_bit_array(phy_10_100_features_array, +- ARRAY_SIZE(phy_10_100_features_array), +- supported); +- linkmode_set_bit_array(phy_gbit_features_array, +- ARRAY_SIZE(phy_gbit_features_array), +- supported); +- linkmode_copy(phy_data->phydev->supported, supported); ++ linkmode_copy(phy_data->phydev->supported, PHY_GBIT_FEATURES); + phy_support_asym_pause(phy_data->phydev); + + netif_dbg(pdata, drv, pdata->netdev, +diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c +index e8d9a0eba4d6b5..8f5cc1f2331884 100644 +--- a/drivers/net/ethernet/freescale/fec_main.c ++++ b/drivers/net/ethernet/freescale/fec_main.c +@@ -1572,19 +1572,22 @@ static void fec_enet_tx(struct net_device *ndev, int budget) + fec_enet_tx_queue(ndev, i, budget); + } + +-static void fec_enet_update_cbd(struct fec_enet_priv_rx_q *rxq, ++static int fec_enet_update_cbd(struct fec_enet_priv_rx_q *rxq, + struct bufdesc *bdp, int index) + { + struct page *new_page; + dma_addr_t phys_addr; + + new_page = page_pool_dev_alloc_pages(rxq->page_pool); +- WARN_ON(!new_page); +- rxq->rx_skb_info[index].page = new_page; ++ if (unlikely(!new_page)) ++ return -ENOMEM; + ++ rxq->rx_skb_info[index].page = new_page; + rxq->rx_skb_info[index].offset = FEC_ENET_XDP_HEADROOM; + phys_addr = page_pool_get_dma_addr(new_page) + FEC_ENET_XDP_HEADROOM; + bdp->cbd_bufaddr = cpu_to_fec32(phys_addr); ++ ++ return 0; + } + + static u32 +@@ -1679,6 +1682,7 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id) + int cpu = smp_processor_id(); + struct xdp_buff xdp; + struct page *page; ++ __fec32 cbd_bufaddr; + u32 sub_len = 4; + + #if !defined(CONFIG_M5272) +@@ -1743,12 +1747,17 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id) + + index = fec_enet_get_bd_index(bdp, &rxq->bd); + page = rxq->rx_skb_info[index].page; ++ cbd_bufaddr = bdp->cbd_bufaddr; ++ if (fec_enet_update_cbd(rxq, bdp, index)) { ++ ndev->stats.rx_dropped++; ++ goto rx_processing_done; ++ } ++ + dma_sync_single_for_cpu(&fep->pdev->dev, +- fec32_to_cpu(bdp->cbd_bufaddr), ++ fec32_to_cpu(cbd_bufaddr), + pkt_len, + DMA_FROM_DEVICE); + prefetch(page_address(page)); +- fec_enet_update_cbd(rxq, bdp, index); + + if (xdp_prog) { + xdp_buff_clear_frags_flag(&xdp); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +index 015faddabc8e09..463c23ae0ad1ec 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +@@ -719,6 +719,12 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x, + /* check esn */ + if (x->props.flags & XFRM_STATE_ESN) + mlx5e_ipsec_update_esn_state(sa_entry); ++ else ++ /* According to RFC4303, section "3.3.3. Sequence Number Generation", ++ * the first packet sent using a given SA will contain a sequence ++ * number of 1. ++ */ ++ sa_entry->esn_state.esn = 1; + + mlx5e_ipsec_build_accel_xfrm_attrs(sa_entry, &sa_entry->attrs); + +@@ -763,9 +769,12 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x, + MLX5_IPSEC_RESCHED); + + if (x->xso.type == XFRM_DEV_OFFLOAD_PACKET && +- x->props.mode == XFRM_MODE_TUNNEL) +- xa_set_mark(&ipsec->sadb, sa_entry->ipsec_obj_id, +- MLX5E_IPSEC_TUNNEL_SA); ++ x->props.mode == XFRM_MODE_TUNNEL) { ++ xa_lock_bh(&ipsec->sadb); ++ __xa_set_mark(&ipsec->sadb, sa_entry->ipsec_obj_id, ++ MLX5E_IPSEC_TUNNEL_SA); ++ xa_unlock_bh(&ipsec->sadb); ++ } + + out: + x->xso.offload_handle = (unsigned long)sa_entry; +@@ -792,7 +801,6 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x, + static void mlx5e_xfrm_del_state(struct xfrm_state *x) + { + struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x); +- struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs; + struct mlx5e_ipsec *ipsec = sa_entry->ipsec; + struct mlx5e_ipsec_sa_entry *old; + +@@ -801,12 +809,6 @@ static void mlx5e_xfrm_del_state(struct xfrm_state *x) + + old = xa_erase_bh(&ipsec->sadb, sa_entry->ipsec_obj_id); + WARN_ON(old != sa_entry); +- +- if (attrs->mode == XFRM_MODE_TUNNEL && +- attrs->type == XFRM_DEV_OFFLOAD_PACKET) +- /* Make sure that no ARP requests are running in parallel */ +- flush_workqueue(ipsec->wq); +- + } + + static void mlx5e_xfrm_free_state(struct xfrm_state *x) +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +index 61288066830d94..2382c712898574 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +@@ -1442,23 +1442,21 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry) + goto err_alloc; + } + +- if (attrs->family == AF_INET) +- setup_fte_addr4(spec, &attrs->saddr.a4, &attrs->daddr.a4); +- else +- setup_fte_addr6(spec, attrs->saddr.a6, attrs->daddr.a6); +- + setup_fte_no_frags(spec); + setup_fte_upper_proto_match(spec, &attrs->upspec); + + switch (attrs->type) { + case XFRM_DEV_OFFLOAD_CRYPTO: ++ if (attrs->family == AF_INET) ++ setup_fte_addr4(spec, &attrs->saddr.a4, &attrs->daddr.a4); ++ else ++ setup_fte_addr6(spec, attrs->saddr.a6, attrs->daddr.a6); + setup_fte_spi(spec, attrs->spi, false); + setup_fte_esp(spec); + setup_fte_reg_a(spec); + break; + case XFRM_DEV_OFFLOAD_PACKET: +- if (attrs->reqid) +- setup_fte_reg_c4(spec, attrs->reqid); ++ setup_fte_reg_c4(spec, attrs->reqid); + err = setup_pkt_reformat(ipsec, attrs, &flow_act); + if (err) + goto err_pkt_reformat; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c +index de83567aae7913..940e350058d10e 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c +@@ -90,8 +90,9 @@ u32 mlx5_ipsec_device_caps(struct mlx5_core_dev *mdev) + EXPORT_SYMBOL_GPL(mlx5_ipsec_device_caps); + + static void mlx5e_ipsec_packet_setup(void *obj, u32 pdn, +- struct mlx5_accel_esp_xfrm_attrs *attrs) ++ struct mlx5e_ipsec_sa_entry *sa_entry) + { ++ struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs; + void *aso_ctx; + + aso_ctx = MLX5_ADDR_OF(ipsec_obj, obj, ipsec_aso); +@@ -119,8 +120,12 @@ static void mlx5e_ipsec_packet_setup(void *obj, u32 pdn, + * active. + */ + MLX5_SET(ipsec_obj, obj, aso_return_reg, MLX5_IPSEC_ASO_REG_C_4_5); +- if (attrs->dir == XFRM_DEV_OFFLOAD_OUT) ++ if (attrs->dir == XFRM_DEV_OFFLOAD_OUT) { + MLX5_SET(ipsec_aso, aso_ctx, mode, MLX5_IPSEC_ASO_INC_SN); ++ if (!attrs->replay_esn.trigger) ++ MLX5_SET(ipsec_aso, aso_ctx, mode_parameter, ++ sa_entry->esn_state.esn); ++ } + + if (attrs->lft.hard_packet_limit != XFRM_INF) { + MLX5_SET(ipsec_aso, aso_ctx, remove_flow_pkt_cnt, +@@ -173,7 +178,7 @@ static int mlx5_create_ipsec_obj(struct mlx5e_ipsec_sa_entry *sa_entry) + + res = &mdev->mlx5e_res.hw_objs; + if (attrs->type == XFRM_DEV_OFFLOAD_PACKET) +- mlx5e_ipsec_packet_setup(obj, res->pdn, attrs); ++ mlx5e_ipsec_packet_setup(obj, res->pdn, sa_entry); + + err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out)); + if (!err) +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +index 474e63d02ba492..d2dc375f5e49cb 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +@@ -2490,6 +2490,7 @@ struct mlx5_flow_namespace *mlx5_get_flow_namespace(struct mlx5_core_dev *dev, + break; + case MLX5_FLOW_NAMESPACE_RDMA_TX: + root_ns = steering->rdma_tx_root_ns; ++ prio = RDMA_TX_BYPASS_PRIO; + break; + case MLX5_FLOW_NAMESPACE_RDMA_RX_COUNTERS: + root_ns = steering->rdma_rx_root_ns; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c +index 005661248c7e9c..9faa9ef863a1b6 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c +@@ -540,7 +540,7 @@ int mlx5_lag_port_sel_create(struct mlx5_lag *ldev, + set_tt_map(port_sel, hash_type); + err = mlx5_lag_create_definers(ldev, hash_type, ports); + if (err) +- return err; ++ goto clear_port_sel; + + if (port_sel->tunnel) { + err = mlx5_lag_create_inner_ttc_table(ldev); +@@ -559,6 +559,8 @@ int mlx5_lag_port_sel_create(struct mlx5_lag *ldev, + mlx5_destroy_ttc_table(port_sel->inner.ttc); + destroy_definers: + mlx5_lag_destroy_definers(ldev); ++clear_port_sel: ++ memset(port_sel, 0, sizeof(*port_sel)); + return err; + } + +diff --git a/drivers/net/ethernet/netronome/nfp/bpf/offload.c b/drivers/net/ethernet/netronome/nfp/bpf/offload.c +index 9d97cd281f18e4..c03558adda91eb 100644 +--- a/drivers/net/ethernet/netronome/nfp/bpf/offload.c ++++ b/drivers/net/ethernet/netronome/nfp/bpf/offload.c +@@ -458,7 +458,8 @@ int nfp_bpf_event_output(struct nfp_app_bpf *bpf, const void *data, + map_id_full = be64_to_cpu(cbe->map_ptr); + map_id = map_id_full; + +- if (len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size) ++ if (size_add(pkt_size, data_size) > INT_MAX || ++ len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size) + return -EINVAL; + if (cbe->hdr.ver != NFP_CCM_ABI_VERSION) + return -EINVAL; +diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c +index 64bf22cd860c9a..9eccc7064c2b05 100644 +--- a/drivers/net/ethernet/ti/cpsw_ale.c ++++ b/drivers/net/ethernet/ti/cpsw_ale.c +@@ -106,15 +106,15 @@ struct cpsw_ale_dev_id { + + static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits) + { +- int idx, idx2; ++ int idx, idx2, index; + u32 hi_val = 0; + + idx = start / 32; + idx2 = (start + bits - 1) / 32; + /* Check if bits to be fetched exceed a word */ + if (idx != idx2) { +- idx2 = 2 - idx2; /* flip */ +- hi_val = ale_entry[idx2] << ((idx2 * 32) - start); ++ index = 2 - idx2; /* flip */ ++ hi_val = ale_entry[index] << ((idx2 * 32) - start); + } + start -= idx * 32; + idx = 2 - idx; /* flip */ +@@ -124,16 +124,16 @@ static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits) + static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits, + u32 value) + { +- int idx, idx2; ++ int idx, idx2, index; + + value &= BITMASK(bits); + idx = start / 32; + idx2 = (start + bits - 1) / 32; + /* Check if bits to be set exceed a word */ + if (idx != idx2) { +- idx2 = 2 - idx2; /* flip */ +- ale_entry[idx2] &= ~(BITMASK(bits + start - (idx2 * 32))); +- ale_entry[idx2] |= (value >> ((idx2 * 32) - start)); ++ index = 2 - idx2; /* flip */ ++ ale_entry[index] &= ~(BITMASK(bits + start - (idx2 * 32))); ++ ale_entry[index] |= (value >> ((idx2 * 32) - start)); + } + start -= idx * 32; + idx = 2 - idx; /* flip */ +diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +index 9f779653ed6225..02e11827440b5c 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c ++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +@@ -1571,6 +1571,12 @@ axienet_ethtools_set_coalesce(struct net_device *ndev, + return -EFAULT; + } + ++ if (ecoalesce->rx_max_coalesced_frames > 255 || ++ ecoalesce->tx_max_coalesced_frames > 255) { ++ NL_SET_ERR_MSG(extack, "frames must be less than 256"); ++ return -EINVAL; ++ } ++ + if (ecoalesce->rx_max_coalesced_frames) + lp->coalesce_count_rx = ecoalesce->rx_max_coalesced_frames; + if (ecoalesce->rx_coalesce_usecs) +diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c +index 9dd8f66610ce6b..47238c3ec82e75 100644 +--- a/drivers/net/gtp.c ++++ b/drivers/net/gtp.c +@@ -1095,8 +1095,8 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev, + goto out_encap; + } + +- gn = net_generic(dev_net(dev), gtp_net_id); +- list_add_rcu(>p->list, &gn->gtp_dev_list); ++ gn = net_generic(src_net, gtp_net_id); ++ list_add(>p->list, &gn->gtp_dev_list); + dev->priv_destructor = gtp_destructor; + + netdev_dbg(dev, "registered new GTP interface\n"); +@@ -1122,7 +1122,7 @@ static void gtp_dellink(struct net_device *dev, struct list_head *head) + hlist_for_each_entry_safe(pctx, next, >p->tid_hash[i], hlist_tid) + pdp_context_delete(pctx); + +- list_del_rcu(>p->list); ++ list_del(>p->list); + unregister_netdevice_queue(dev, head); + } + +@@ -1690,16 +1690,19 @@ static int gtp_genl_dump_pdp(struct sk_buff *skb, + struct gtp_dev *last_gtp = (struct gtp_dev *)cb->args[2], *gtp; + int i, j, bucket = cb->args[0], skip = cb->args[1]; + struct net *net = sock_net(skb->sk); ++ struct net_device *dev; + struct pdp_ctx *pctx; +- struct gtp_net *gn; +- +- gn = net_generic(net, gtp_net_id); + + if (cb->args[4]) + return 0; + + rcu_read_lock(); +- list_for_each_entry_rcu(gtp, &gn->gtp_dev_list, list) { ++ for_each_netdev_rcu(net, dev) { ++ if (dev->rtnl_link_ops != >p_link_ops) ++ continue; ++ ++ gtp = netdev_priv(dev); ++ + if (last_gtp && last_gtp != gtp) + continue; + else +@@ -1884,23 +1887,28 @@ static int __net_init gtp_net_init(struct net *net) + return 0; + } + +-static void __net_exit gtp_net_exit(struct net *net) ++static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list, ++ struct list_head *dev_to_kill) + { +- struct gtp_net *gn = net_generic(net, gtp_net_id); +- struct gtp_dev *gtp; +- LIST_HEAD(list); ++ struct net *net; + +- rtnl_lock(); +- list_for_each_entry(gtp, &gn->gtp_dev_list, list) +- gtp_dellink(gtp->dev, &list); ++ list_for_each_entry(net, net_list, exit_list) { ++ struct gtp_net *gn = net_generic(net, gtp_net_id); ++ struct gtp_dev *gtp, *gtp_next; ++ struct net_device *dev; + +- unregister_netdevice_many(&list); +- rtnl_unlock(); ++ for_each_netdev(net, dev) ++ if (dev->rtnl_link_ops == >p_link_ops) ++ gtp_dellink(dev, dev_to_kill); ++ ++ list_for_each_entry_safe(gtp, gtp_next, &gn->gtp_dev_list, list) ++ gtp_dellink(gtp->dev, dev_to_kill); ++ } + } + + static struct pernet_operations gtp_net_ops = { + .init = gtp_net_init, +- .exit = gtp_net_exit, ++ .exit_batch_rtnl = gtp_net_exit_batch_rtnl, + .id = >p_net_id, + .size = sizeof(struct gtp_net), + }; +diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c +index 468833675cc949..c0b342cc93db39 100644 +--- a/drivers/nvme/target/io-cmd-bdev.c ++++ b/drivers/nvme/target/io-cmd-bdev.c +@@ -36,7 +36,7 @@ void nvmet_bdev_set_limits(struct block_device *bdev, struct nvme_id_ns *id) + */ + id->nsfeat |= 1 << 4; + /* NPWG = Namespace Preferred Write Granularity. 0's based */ +- id->npwg = lpp0b; ++ id->npwg = to0based(bdev_io_min(bdev) / bdev_logical_block_size(bdev)); + /* NPWA = Namespace Preferred Write Alignment. 0's based */ + id->npwa = id->npwg; + /* NPDG = Namespace Preferred Deallocate Granularity. 0's based */ +diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c +index e2602e38ae4526..6be3266cd7b5b2 100644 +--- a/drivers/pci/controller/pci-host-common.c ++++ b/drivers/pci/controller/pci-host-common.c +@@ -73,6 +73,10 @@ int pci_host_common_probe(struct platform_device *pdev) + if (IS_ERR(cfg)) + return PTR_ERR(cfg); + ++ /* Do not reassign resources if probe only */ ++ if (!pci_has_flag(PCI_PROBE_ONLY)) ++ pci_add_flags(PCI_REASSIGN_ALL_BUS); ++ + bridge->sysdata = cfg; + bridge->ops = (struct pci_ops *)&ops->pci_ops; + bridge->msi_domain = true; +diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c +index 7e84e472b3383c..03b519a2284038 100644 +--- a/drivers/pci/probe.c ++++ b/drivers/pci/probe.c +@@ -3096,18 +3096,20 @@ int pci_host_probe(struct pci_host_bridge *bridge) + + bus = bridge->bus; + +- /* If we must preserve the resource configuration, claim now */ +- if (bridge->preserve_config) +- pci_bus_claim_resources(bus); +- + /* +- * Assign whatever was left unassigned. If we didn't claim above, +- * this will reassign everything. ++ * We insert PCI resources into the iomem_resource and ++ * ioport_resource trees in either pci_bus_claim_resources() ++ * or pci_bus_assign_resources(). + */ +- pci_assign_unassigned_root_bus_resources(bus); ++ if (pci_has_flag(PCI_PROBE_ONLY)) { ++ pci_bus_claim_resources(bus); ++ } else { ++ pci_bus_size_bridges(bus); ++ pci_bus_assign_resources(bus); + +- list_for_each_entry(child, &bus->children, node) +- pcie_bus_configure_settings(child); ++ list_for_each_entry(child, &bus->children, node) ++ pcie_bus_configure_settings(child); ++ } + + pci_bus_add_devices(bus); + return 0; +diff --git a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c +index 31693add7d633f..faf643a4a5d06b 100644 +--- a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c ++++ b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c +@@ -767,7 +767,7 @@ static int imx8mp_blk_ctrl_remove(struct platform_device *pdev) + + of_genpd_del_provider(pdev->dev.of_node); + +- for (i = 0; bc->onecell_data.num_domains; i++) { ++ for (i = 0; i < bc->onecell_data.num_domains; i++) { + struct imx8mp_blk_ctrl_domain *domain = &bc->domains[i]; + + pm_genpd_remove(&domain->genpd); +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index 02696c7f9beff9..0ac0b6aaf9c62c 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -10483,14 +10483,17 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) + } + + /* +- * Set the default power management level for runtime and system PM. ++ * Set the default power management level for runtime and system PM if ++ * not set by the host controller drivers. + * Default power saving mode is to keep UFS link in Hibern8 state + * and UFS device in sleep state. + */ +- hba->rpm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state( ++ if (!hba->rpm_lvl) ++ hba->rpm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state( + UFS_SLEEP_PWR_MODE, + UIC_LINK_HIBERN8_STATE); +- hba->spm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state( ++ if (!hba->spm_lvl) ++ hba->spm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state( + UFS_SLEEP_PWR_MODE, + UIC_LINK_HIBERN8_STATE); + +diff --git a/fs/cachefiles/daemon.c b/fs/cachefiles/daemon.c +index 89b11336a83697..1806bff8e59bc3 100644 +--- a/fs/cachefiles/daemon.c ++++ b/fs/cachefiles/daemon.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -576,7 +577,7 @@ static int cachefiles_daemon_dir(struct cachefiles_cache *cache, char *args) + */ + static int cachefiles_daemon_secctx(struct cachefiles_cache *cache, char *args) + { +- char *secctx; ++ int err; + + _enter(",%s", args); + +@@ -585,16 +586,16 @@ static int cachefiles_daemon_secctx(struct cachefiles_cache *cache, char *args) + return -EINVAL; + } + +- if (cache->secctx) { ++ if (cache->have_secid) { + pr_err("Second security context specified\n"); + return -EINVAL; + } + +- secctx = kstrdup(args, GFP_KERNEL); +- if (!secctx) +- return -ENOMEM; ++ err = security_secctx_to_secid(args, strlen(args), &cache->secid); ++ if (err) ++ return err; + +- cache->secctx = secctx; ++ cache->have_secid = true; + return 0; + } + +@@ -820,7 +821,6 @@ static void cachefiles_daemon_unbind(struct cachefiles_cache *cache) + put_cred(cache->cache_cred); + + kfree(cache->rootdirname); +- kfree(cache->secctx); + kfree(cache->tag); + + _leave(""); +diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h +index 111ad6ecd4baf3..4421a12960a662 100644 +--- a/fs/cachefiles/internal.h ++++ b/fs/cachefiles/internal.h +@@ -122,7 +122,6 @@ struct cachefiles_cache { + #define CACHEFILES_STATE_CHANGED 3 /* T if state changed (poll trigger) */ + #define CACHEFILES_ONDEMAND_MODE 4 /* T if in on-demand read mode */ + char *rootdirname; /* name of cache root directory */ +- char *secctx; /* LSM security context */ + char *tag; /* cache binding tag */ + refcount_t unbind_pincount;/* refcount to do daemon unbind */ + struct xarray reqs; /* xarray of pending on-demand requests */ +@@ -130,6 +129,8 @@ struct cachefiles_cache { + struct xarray ondemand_ids; /* xarray for ondemand_id allocation */ + u32 ondemand_id_next; + u32 msg_id_next; ++ u32 secid; /* LSM security id */ ++ bool have_secid; /* whether "secid" was set */ + }; + + static inline bool cachefiles_in_ondemand_mode(struct cachefiles_cache *cache) +diff --git a/fs/cachefiles/security.c b/fs/cachefiles/security.c +index fe777164f1d894..fc6611886b3b5e 100644 +--- a/fs/cachefiles/security.c ++++ b/fs/cachefiles/security.c +@@ -18,7 +18,7 @@ int cachefiles_get_security_ID(struct cachefiles_cache *cache) + struct cred *new; + int ret; + +- _enter("{%s}", cache->secctx); ++ _enter("{%u}", cache->have_secid ? cache->secid : 0); + + new = prepare_kernel_cred(current); + if (!new) { +@@ -26,8 +26,8 @@ int cachefiles_get_security_ID(struct cachefiles_cache *cache) + goto error; + } + +- if (cache->secctx) { +- ret = set_security_override_from_ctx(new, cache->secctx); ++ if (cache->have_secid) { ++ ret = set_security_override(new, cache->secid); + if (ret < 0) { + put_cred(new); + pr_err("Security denies permission to nominate security context: error %d\n", +diff --git a/fs/file.c b/fs/file.c +index bd817e31d79866..a178efc8cf4b5c 100644 +--- a/fs/file.c ++++ b/fs/file.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + #include "internal.h" + +diff --git a/fs/hfs/super.c b/fs/hfs/super.c +index 6764afa98a6ff1..431bdc65f72312 100644 +--- a/fs/hfs/super.c ++++ b/fs/hfs/super.c +@@ -418,11 +418,13 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent) + goto bail_no_root; + res = hfs_cat_find_brec(sb, HFS_ROOT_CNID, &fd); + if (!res) { +- if (fd.entrylength > sizeof(rec) || fd.entrylength < 0) { ++ if (fd.entrylength != sizeof(rec.dir)) { + res = -EIO; + goto bail_hfs_find; + } + hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, fd.entrylength); ++ if (rec.type != HFS_CDR_DIR) ++ res = -EIO; + } + if (res) + goto bail_hfs_find; +diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c +index a05ee2cbb77936..e7e6701806ad26 100644 +--- a/fs/iomap/buffered-io.c ++++ b/fs/iomap/buffered-io.c +@@ -1095,7 +1095,7 @@ static int iomap_write_delalloc_scan(struct inode *inode, + } + + /* move offset to start of next folio in range */ +- start_byte = folio_next_index(folio) << PAGE_SHIFT; ++ start_byte = folio_pos(folio) + folio_size(folio); + folio_unlock(folio); + folio_put(folio); + } +diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c +index 6f2bcbfde45e69..0ff07d53931f2f 100644 +--- a/fs/nfsd/filecache.c ++++ b/fs/nfsd/filecache.c +@@ -219,6 +219,7 @@ nfsd_file_alloc(struct net *net, struct inode *inode, unsigned char need, + return NULL; + + INIT_LIST_HEAD(&nf->nf_lru); ++ INIT_LIST_HEAD(&nf->nf_gc); + nf->nf_birthtime = ktime_get(); + nf->nf_file = NULL; + nf->nf_cred = get_current_cred(); +@@ -396,8 +397,8 @@ nfsd_file_dispose_list(struct list_head *dispose) + struct nfsd_file *nf; + + while (!list_empty(dispose)) { +- nf = list_first_entry(dispose, struct nfsd_file, nf_lru); +- list_del_init(&nf->nf_lru); ++ nf = list_first_entry(dispose, struct nfsd_file, nf_gc); ++ list_del_init(&nf->nf_gc); + nfsd_file_free(nf); + } + } +@@ -414,12 +415,12 @@ nfsd_file_dispose_list_delayed(struct list_head *dispose) + { + while(!list_empty(dispose)) { + struct nfsd_file *nf = list_first_entry(dispose, +- struct nfsd_file, nf_lru); ++ struct nfsd_file, nf_gc); + struct nfsd_net *nn = net_generic(nf->nf_net, nfsd_net_id); + struct nfsd_fcache_disposal *l = nn->fcache_disposal; + + spin_lock(&l->lock); +- list_move_tail(&nf->nf_lru, &l->freeme); ++ list_move_tail(&nf->nf_gc, &l->freeme); + spin_unlock(&l->lock); + queue_work(nfsd_filecache_wq, &l->work); + } +@@ -476,7 +477,8 @@ nfsd_file_lru_cb(struct list_head *item, struct list_lru_one *lru, + + /* Refcount went to zero. Unhash it and queue it to the dispose list */ + nfsd_file_unhash(nf); +- list_lru_isolate_move(lru, &nf->nf_lru, head); ++ list_lru_isolate(lru, &nf->nf_lru); ++ list_add(&nf->nf_gc, head); + this_cpu_inc(nfsd_file_evictions); + trace_nfsd_file_gc_disposed(nf); + return LRU_REMOVED; +@@ -555,7 +557,7 @@ nfsd_file_cond_queue(struct nfsd_file *nf, struct list_head *dispose) + + /* If refcount goes to 0, then put on the dispose list */ + if (refcount_sub_and_test(decrement, &nf->nf_ref)) { +- list_add(&nf->nf_lru, dispose); ++ list_add(&nf->nf_gc, dispose); + trace_nfsd_file_closing(nf); + } + } +@@ -631,8 +633,8 @@ nfsd_file_close_inode_sync(struct inode *inode) + + nfsd_file_queue_for_close(inode, &dispose); + while (!list_empty(&dispose)) { +- nf = list_first_entry(&dispose, struct nfsd_file, nf_lru); +- list_del_init(&nf->nf_lru); ++ nf = list_first_entry(&dispose, struct nfsd_file, nf_gc); ++ list_del_init(&nf->nf_gc); + nfsd_file_free(nf); + } + flush_delayed_fput(); +diff --git a/fs/nfsd/filecache.h b/fs/nfsd/filecache.h +index e54165a3224f0b..bf7a630f1a4561 100644 +--- a/fs/nfsd/filecache.h ++++ b/fs/nfsd/filecache.h +@@ -44,6 +44,7 @@ struct nfsd_file { + + struct nfsd_file_mark *nf_mark; + struct list_head nf_lru; ++ struct list_head nf_gc; + struct rcu_head nf_rcu; + ktime_t nf_birthtime; + }; +diff --git a/fs/notify/fdinfo.c b/fs/notify/fdinfo.c +index 5c430736ec12c4..26655572975d3d 100644 +--- a/fs/notify/fdinfo.c ++++ b/fs/notify/fdinfo.c +@@ -51,10 +51,8 @@ static void show_mark_fhandle(struct seq_file *m, struct inode *inode) + size = f.handle.handle_bytes >> 2; + + ret = exportfs_encode_fid(inode, (struct fid *)f.handle.f_handle, &size); +- if ((ret == FILEID_INVALID) || (ret < 0)) { +- WARN_ONCE(1, "Can't encode file handler for inotify: %d\n", ret); ++ if ((ret == FILEID_INVALID) || (ret < 0)) + return; +- } + + f.handle.handle_type = ret; + f.handle.handle_bytes = size * sizeof(u32); +diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c +index 70a768b623cf40..f7672472fa8279 100644 +--- a/fs/ocfs2/extent_map.c ++++ b/fs/ocfs2/extent_map.c +@@ -973,7 +973,13 @@ int ocfs2_read_virt_blocks(struct inode *inode, u64 v_block, int nr, + } + + while (done < nr) { +- down_read(&OCFS2_I(inode)->ip_alloc_sem); ++ if (!down_read_trylock(&OCFS2_I(inode)->ip_alloc_sem)) { ++ rc = -EAGAIN; ++ mlog(ML_ERROR, ++ "Inode #%llu ip_alloc_sem is temporarily unavailable\n", ++ (unsigned long long)OCFS2_I(inode)->ip_blkno); ++ break; ++ } + rc = ocfs2_extent_map_get_blocks(inode, v_block + done, + &p_block, &p_count, NULL); + up_read(&OCFS2_I(inode)->ip_alloc_sem); +diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c +index ada3fcc9c6d501..18e018cb181179 100644 +--- a/fs/overlayfs/copy_up.c ++++ b/fs/overlayfs/copy_up.c +@@ -371,13 +371,13 @@ int ovl_set_attr(struct ovl_fs *ofs, struct dentry *upperdentry, + return err; + } + +-struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct dentry *real, ++struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct inode *realinode, + bool is_upper) + { + struct ovl_fh *fh; + int fh_type, dwords; + int buflen = MAX_HANDLE_SZ; +- uuid_t *uuid = &real->d_sb->s_uuid; ++ uuid_t *uuid = &realinode->i_sb->s_uuid; + int err; + + /* Make sure the real fid stays 32bit aligned */ +@@ -394,13 +394,13 @@ struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct dentry *real, + * the price or reconnecting the dentry. + */ + dwords = buflen >> 2; +- fh_type = exportfs_encode_fh(real, (void *)fh->fb.fid, &dwords, 0); ++ fh_type = exportfs_encode_inode_fh(realinode, (void *)fh->fb.fid, ++ &dwords, NULL, 0); + buflen = (dwords << 2); + + err = -EIO; +- if (WARN_ON(fh_type < 0) || +- WARN_ON(buflen > MAX_HANDLE_SZ) || +- WARN_ON(fh_type == FILEID_INVALID)) ++ if (fh_type < 0 || fh_type == FILEID_INVALID || ++ WARN_ON(buflen > MAX_HANDLE_SZ)) + goto out_err; + + fh->fb.version = OVL_FH_VERSION; +@@ -438,7 +438,7 @@ int ovl_set_origin(struct ovl_fs *ofs, struct dentry *lower, + * up and a pure upper inode. + */ + if (ovl_can_decode_fh(lower->d_sb)) { +- fh = ovl_encode_real_fh(ofs, lower, false); ++ fh = ovl_encode_real_fh(ofs, d_inode(lower), false); + if (IS_ERR(fh)) + return PTR_ERR(fh); + } +@@ -461,7 +461,7 @@ static int ovl_set_upper_fh(struct ovl_fs *ofs, struct dentry *upper, + const struct ovl_fh *fh; + int err; + +- fh = ovl_encode_real_fh(ofs, upper, true); ++ fh = ovl_encode_real_fh(ofs, d_inode(upper), true); + if (IS_ERR(fh)) + return PTR_ERR(fh); + +diff --git a/fs/overlayfs/export.c b/fs/overlayfs/export.c +index 611ff567a1aa6f..3a17e4366f28c0 100644 +--- a/fs/overlayfs/export.c ++++ b/fs/overlayfs/export.c +@@ -181,35 +181,37 @@ static int ovl_connect_layer(struct dentry *dentry) + * + * Return 0 for upper file handle, > 0 for lower file handle or < 0 on error. + */ +-static int ovl_check_encode_origin(struct dentry *dentry) ++static int ovl_check_encode_origin(struct inode *inode) + { +- struct ovl_fs *ofs = OVL_FS(dentry->d_sb); ++ struct ovl_fs *ofs = OVL_FS(inode->i_sb); + bool decodable = ofs->config.nfs_export; ++ struct dentry *dentry; ++ int err; + + /* No upper layer? */ + if (!ovl_upper_mnt(ofs)) + return 1; + + /* Lower file handle for non-upper non-decodable */ +- if (!ovl_dentry_upper(dentry) && !decodable) ++ if (!ovl_inode_upper(inode) && !decodable) + return 1; + + /* Upper file handle for pure upper */ +- if (!ovl_dentry_lower(dentry)) ++ if (!ovl_inode_lower(inode)) + return 0; + + /* + * Root is never indexed, so if there's an upper layer, encode upper for + * root. + */ +- if (dentry == dentry->d_sb->s_root) ++ if (inode == d_inode(inode->i_sb->s_root)) + return 0; + + /* + * Upper decodable file handle for non-indexed upper. + */ +- if (ovl_dentry_upper(dentry) && decodable && +- !ovl_test_flag(OVL_INDEX, d_inode(dentry))) ++ if (ovl_inode_upper(inode) && decodable && ++ !ovl_test_flag(OVL_INDEX, inode)) + return 0; + + /* +@@ -218,14 +220,23 @@ static int ovl_check_encode_origin(struct dentry *dentry) + * ovl_connect_layer() will try to make origin's layer "connected" by + * copying up a "connectable" ancestor. + */ +- if (d_is_dir(dentry) && decodable) +- return ovl_connect_layer(dentry); ++ if (!decodable || !S_ISDIR(inode->i_mode)) ++ return 1; ++ ++ dentry = d_find_any_alias(inode); ++ if (!dentry) ++ return -ENOENT; ++ ++ err = ovl_connect_layer(dentry); ++ dput(dentry); ++ if (err < 0) ++ return err; + + /* Lower file handle for indexed and non-upper dir/non-dir */ + return 1; + } + +-static int ovl_dentry_to_fid(struct ovl_fs *ofs, struct dentry *dentry, ++static int ovl_dentry_to_fid(struct ovl_fs *ofs, struct inode *inode, + u32 *fid, int buflen) + { + struct ovl_fh *fh = NULL; +@@ -236,13 +247,13 @@ static int ovl_dentry_to_fid(struct ovl_fs *ofs, struct dentry *dentry, + * Check if we should encode a lower or upper file handle and maybe + * copy up an ancestor to make lower file handle connectable. + */ +- err = enc_lower = ovl_check_encode_origin(dentry); ++ err = enc_lower = ovl_check_encode_origin(inode); + if (enc_lower < 0) + goto fail; + + /* Encode an upper or lower file handle */ +- fh = ovl_encode_real_fh(ofs, enc_lower ? ovl_dentry_lower(dentry) : +- ovl_dentry_upper(dentry), !enc_lower); ++ fh = ovl_encode_real_fh(ofs, enc_lower ? ovl_inode_lower(inode) : ++ ovl_inode_upper(inode), !enc_lower); + if (IS_ERR(fh)) + return PTR_ERR(fh); + +@@ -256,8 +267,8 @@ static int ovl_dentry_to_fid(struct ovl_fs *ofs, struct dentry *dentry, + return err; + + fail: +- pr_warn_ratelimited("failed to encode file handle (%pd2, err=%i)\n", +- dentry, err); ++ pr_warn_ratelimited("failed to encode file handle (ino=%lu, err=%i)\n", ++ inode->i_ino, err); + goto out; + } + +@@ -265,19 +276,13 @@ static int ovl_encode_fh(struct inode *inode, u32 *fid, int *max_len, + struct inode *parent) + { + struct ovl_fs *ofs = OVL_FS(inode->i_sb); +- struct dentry *dentry; + int bytes, buflen = *max_len << 2; + + /* TODO: encode connectable file handles */ + if (parent) + return FILEID_INVALID; + +- dentry = d_find_any_alias(inode); +- if (!dentry) +- return FILEID_INVALID; +- +- bytes = ovl_dentry_to_fid(ofs, dentry, fid, buflen); +- dput(dentry); ++ bytes = ovl_dentry_to_fid(ofs, inode, fid, buflen); + if (bytes <= 0) + return FILEID_INVALID; + +diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c +index 80391c687c2ad8..273a39d3e95133 100644 +--- a/fs/overlayfs/namei.c ++++ b/fs/overlayfs/namei.c +@@ -523,7 +523,7 @@ int ovl_verify_set_fh(struct ovl_fs *ofs, struct dentry *dentry, + struct ovl_fh *fh; + int err; + +- fh = ovl_encode_real_fh(ofs, real, is_upper); ++ fh = ovl_encode_real_fh(ofs, d_inode(real), is_upper); + err = PTR_ERR(fh); + if (IS_ERR(fh)) { + fh = NULL; +@@ -720,7 +720,7 @@ int ovl_get_index_name(struct ovl_fs *ofs, struct dentry *origin, + struct ovl_fh *fh; + int err; + +- fh = ovl_encode_real_fh(ofs, origin, false); ++ fh = ovl_encode_real_fh(ofs, d_inode(origin), false); + if (IS_ERR(fh)) + return PTR_ERR(fh); + +diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h +index 09ca82ed0f8ced..981967e507b3e1 100644 +--- a/fs/overlayfs/overlayfs.h ++++ b/fs/overlayfs/overlayfs.h +@@ -821,7 +821,7 @@ int ovl_copy_up_with_data(struct dentry *dentry); + int ovl_maybe_copy_up(struct dentry *dentry, int flags); + int ovl_copy_xattr(struct super_block *sb, const struct path *path, struct dentry *new); + int ovl_set_attr(struct ovl_fs *ofs, struct dentry *upper, struct kstat *stat); +-struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct dentry *real, ++struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct inode *realinode, + bool is_upper); + int ovl_set_origin(struct ovl_fs *ofs, struct dentry *lower, + struct dentry *upper); +diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c +index 8319bcbe3ee36b..3303cb04e12c36 100644 +--- a/fs/proc/vmcore.c ++++ b/fs/proc/vmcore.c +@@ -404,6 +404,8 @@ static ssize_t __read_vmcore(struct iov_iter *iter, loff_t *fpos) + if (!iov_iter_count(iter)) + return acc; + } ++ ++ cond_resched(); + } + + return acc; +diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c +index 20f303f2a5d75a..dbcaaa274abdbf 100644 +--- a/fs/smb/client/connect.c ++++ b/fs/smb/client/connect.c +@@ -1061,6 +1061,7 @@ clean_demultiplex_info(struct TCP_Server_Info *server) + /* Release netns reference for this server. */ + put_net(cifs_net_ns(server)); + kfree(server->leaf_fullpath); ++ kfree(server->hostname); + kfree(server); + + length = atomic_dec_return(&tcpSesAllocCount); +@@ -1684,8 +1685,6 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect) + kfree_sensitive(server->session_key.response); + server->session_key.response = NULL; + server->session_key.len = 0; +- kfree(server->hostname); +- server->hostname = NULL; + + task = xchg(&server->tsk, NULL); + if (task) +diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h +index 254d4a898179c0..8f77bb0f4ae0ca 100644 +--- a/include/linux/hrtimer.h ++++ b/include/linux/hrtimer.h +@@ -532,6 +532,7 @@ extern void __init hrtimers_init(void); + extern void sysrq_timer_list_show(void); + + int hrtimers_prepare_cpu(unsigned int cpu); ++int hrtimers_cpu_starting(unsigned int cpu); + #ifdef CONFIG_HOTPLUG_CPU + int hrtimers_cpu_dying(unsigned int cpu); + #else +diff --git a/include/linux/poll.h b/include/linux/poll.h +index d1ea4f3714a848..fc641b50f1298e 100644 +--- a/include/linux/poll.h ++++ b/include/linux/poll.h +@@ -41,8 +41,16 @@ typedef struct poll_table_struct { + + static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p) + { +- if (p && p->_qproc && wait_address) ++ if (p && p->_qproc && wait_address) { + p->_qproc(filp, wait_address, p); ++ /* ++ * This memory barrier is paired in the wq_has_sleeper(). ++ * See the comment above prepare_to_wait(), we need to ++ * ensure that subsequent tests in this thread can't be ++ * reordered with __add_wait_queue() in _qproc() paths. ++ */ ++ smp_mb(); ++ } + } + + /* +diff --git a/include/linux/pruss_driver.h b/include/linux/pruss_driver.h +index c9a31c567e85bf..2e18fef1a2e109 100644 +--- a/include/linux/pruss_driver.h ++++ b/include/linux/pruss_driver.h +@@ -144,32 +144,32 @@ static inline int pruss_release_mem_region(struct pruss *pruss, + static inline int pruss_cfg_get_gpmux(struct pruss *pruss, + enum pruss_pru_id pru_id, u8 *mux) + { +- return ERR_PTR(-EOPNOTSUPP); ++ return -EOPNOTSUPP; + } + + static inline int pruss_cfg_set_gpmux(struct pruss *pruss, + enum pruss_pru_id pru_id, u8 mux) + { +- return ERR_PTR(-EOPNOTSUPP); ++ return -EOPNOTSUPP; + } + + static inline int pruss_cfg_gpimode(struct pruss *pruss, + enum pruss_pru_id pru_id, + enum pruss_gpi_mode mode) + { +- return ERR_PTR(-EOPNOTSUPP); ++ return -EOPNOTSUPP; + } + + static inline int pruss_cfg_miirt_enable(struct pruss *pruss, bool enable) + { +- return ERR_PTR(-EOPNOTSUPP); ++ return -EOPNOTSUPP; + } + + static inline int pruss_cfg_xfr_enable(struct pruss *pruss, + enum pru_type pru_type, +- bool enable); ++ bool enable) + { +- return ERR_PTR(-EOPNOTSUPP); ++ return -EOPNOTSUPP; + } + + #endif /* CONFIG_TI_PRUSS */ +diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h +index 958c805df1915b..1befad79a67349 100644 +--- a/include/net/net_namespace.h ++++ b/include/net/net_namespace.h +@@ -442,6 +442,9 @@ struct pernet_operations { + void (*pre_exit)(struct net *net); + void (*exit)(struct net *net); + void (*exit_batch)(struct list_head *net_exit_list); ++ /* Following method is called with RTNL held. */ ++ void (*exit_batch_rtnl)(struct list_head *net_exit_list, ++ struct list_head *dev_kill_list); + unsigned int *id; + size_t size; + }; +diff --git a/kernel/cpu.c b/kernel/cpu.c +index 0c72b94ed076a3..7ab11b45976842 100644 +--- a/kernel/cpu.c ++++ b/kernel/cpu.c +@@ -2206,7 +2206,7 @@ static struct cpuhp_step cpuhp_hp_states[] = { + }, + [CPUHP_AP_HRTIMERS_DYING] = { + .name = "hrtimers:dying", +- .startup.single = NULL, ++ .startup.single = hrtimers_cpu_starting, + .teardown.single = hrtimers_cpu_dying, + }, + +diff --git a/kernel/gen_kheaders.sh b/kernel/gen_kheaders.sh +index 383fd43ac61222..7e1340da5acae6 100755 +--- a/kernel/gen_kheaders.sh ++++ b/kernel/gen_kheaders.sh +@@ -89,6 +89,7 @@ find $cpio_dir -type f -print0 | + + # Create archive and try to normalize metadata for reproducibility. + tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \ ++ --exclude=".__afs*" --exclude=".nfs*" \ + --owner=0 --group=0 --sort=name --numeric-owner --mode=u=rw,go=r,a+X \ + -I $XZ -cf $tarfile -C $cpio_dir/ . > /dev/null + +diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c +index 57e5cb36f1bc93..e99b1305e1a5f4 100644 +--- a/kernel/time/hrtimer.c ++++ b/kernel/time/hrtimer.c +@@ -2180,6 +2180,15 @@ int hrtimers_prepare_cpu(unsigned int cpu) + } + + cpu_base->cpu = cpu; ++ hrtimer_cpu_base_init_expiry_lock(cpu_base); ++ return 0; ++} ++ ++int hrtimers_cpu_starting(unsigned int cpu) ++{ ++ struct hrtimer_cpu_base *cpu_base = this_cpu_ptr(&hrtimer_bases); ++ ++ /* Clear out any left over state from a CPU down operation */ + cpu_base->active_bases = 0; + cpu_base->hres_active = 0; + cpu_base->hang_detected = 0; +@@ -2188,7 +2197,6 @@ int hrtimers_prepare_cpu(unsigned int cpu) + cpu_base->expires_next = KTIME_MAX; + cpu_base->softirq_expires_next = KTIME_MAX; + cpu_base->online = 1; +- hrtimer_cpu_base_init_expiry_lock(cpu_base); + return 0; + } + +@@ -2266,6 +2274,7 @@ int hrtimers_cpu_dying(unsigned int dying_cpu) + void __init hrtimers_init(void) + { + hrtimers_prepare_cpu(smp_processor_id()); ++ hrtimers_cpu_starting(smp_processor_id()); + open_softirq(HRTIMER_SOFTIRQ, hrtimer_run_softirq); + } + +diff --git a/mm/filemap.c b/mm/filemap.c +index 2c308413387ffb..6a3d62de1cca7b 100644 +--- a/mm/filemap.c ++++ b/mm/filemap.c +@@ -3037,7 +3037,7 @@ static inline loff_t folio_seek_hole_data(struct xa_state *xas, + if (ops->is_partially_uptodate(folio, offset, bsz) == + seek_data) + break; +- start = (start + bsz) & ~(bsz - 1); ++ start = (start + bsz) & ~((u64)bsz - 1); + offset += bsz; + } while (offset < folio_size(folio)); + unlock: +diff --git a/net/core/filter.c b/net/core/filter.c +index 34320ce70096ac..5881944f1681c9 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -11190,6 +11190,7 @@ BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern, + bool is_sockarray = map->map_type == BPF_MAP_TYPE_REUSEPORT_SOCKARRAY; + struct sock_reuseport *reuse; + struct sock *selected_sk; ++ int err; + + selected_sk = map->ops->map_lookup_elem(map, key); + if (!selected_sk) +@@ -11197,10 +11198,6 @@ BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern, + + reuse = rcu_dereference(selected_sk->sk_reuseport_cb); + if (!reuse) { +- /* Lookup in sock_map can return TCP ESTABLISHED sockets. */ +- if (sk_is_refcounted(selected_sk)) +- sock_put(selected_sk); +- + /* reuseport_array has only sk with non NULL sk_reuseport_cb. + * The only (!reuse) case here is - the sk has already been + * unhashed (e.g. by close()), so treat it as -ENOENT. +@@ -11208,24 +11205,33 @@ BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern, + * Other maps (e.g. sock_map) do not provide this guarantee and + * the sk may never be in the reuseport group to begin with. + */ +- return is_sockarray ? -ENOENT : -EINVAL; ++ err = is_sockarray ? -ENOENT : -EINVAL; ++ goto error; + } + + if (unlikely(reuse->reuseport_id != reuse_kern->reuseport_id)) { + struct sock *sk = reuse_kern->sk; + +- if (sk->sk_protocol != selected_sk->sk_protocol) +- return -EPROTOTYPE; +- else if (sk->sk_family != selected_sk->sk_family) +- return -EAFNOSUPPORT; +- +- /* Catch all. Likely bound to a different sockaddr. */ +- return -EBADFD; ++ if (sk->sk_protocol != selected_sk->sk_protocol) { ++ err = -EPROTOTYPE; ++ } else if (sk->sk_family != selected_sk->sk_family) { ++ err = -EAFNOSUPPORT; ++ } else { ++ /* Catch all. Likely bound to a different sockaddr. */ ++ err = -EBADFD; ++ } ++ goto error; + } + + reuse_kern->selected_sk = selected_sk; + + return 0; ++error: ++ /* Lookup in sock_map can return TCP ESTABLISHED sockets. */ ++ if (sk_is_refcounted(selected_sk)) ++ sock_put(selected_sk); ++ ++ return err; + } + + static const struct bpf_func_proto sk_select_reuseport_proto = { +diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c +index 92b7fea4d495cf..70ac9d9bc87708 100644 +--- a/net/core/net_namespace.c ++++ b/net/core/net_namespace.c +@@ -321,8 +321,9 @@ static __net_init int setup_net(struct net *net, struct user_namespace *user_ns) + { + /* Must be called with pernet_ops_rwsem held */ + const struct pernet_operations *ops, *saved_ops; +- int error = 0; + LIST_HEAD(net_exit_list); ++ LIST_HEAD(dev_kill_list); ++ int error = 0; + + refcount_set(&net->ns.count, 1); + ref_tracker_dir_init(&net->refcnt_tracker, 128, "net refcnt"); +@@ -360,6 +361,15 @@ static __net_init int setup_net(struct net *net, struct user_namespace *user_ns) + + synchronize_rcu(); + ++ ops = saved_ops; ++ rtnl_lock(); ++ list_for_each_entry_continue_reverse(ops, &pernet_list, list) { ++ if (ops->exit_batch_rtnl) ++ ops->exit_batch_rtnl(&net_exit_list, &dev_kill_list); ++ } ++ unregister_netdevice_many(&dev_kill_list); ++ rtnl_unlock(); ++ + ops = saved_ops; + list_for_each_entry_continue_reverse(ops, &pernet_list, list) + ops_exit_list(ops, &net_exit_list); +@@ -588,6 +598,7 @@ static void cleanup_net(struct work_struct *work) + struct net *net, *tmp, *last; + struct llist_node *net_kill_list; + LIST_HEAD(net_exit_list); ++ LIST_HEAD(dev_kill_list); + + /* Atomically snapshot the list of namespaces to cleanup */ + net_kill_list = llist_del_all(&cleanup_list); +@@ -628,6 +639,14 @@ static void cleanup_net(struct work_struct *work) + */ + synchronize_rcu(); + ++ rtnl_lock(); ++ list_for_each_entry_reverse(ops, &pernet_list, list) { ++ if (ops->exit_batch_rtnl) ++ ops->exit_batch_rtnl(&net_exit_list, &dev_kill_list); ++ } ++ unregister_netdevice_many(&dev_kill_list); ++ rtnl_unlock(); ++ + /* Run all of the network namespace exit methods */ + list_for_each_entry_reverse(ops, &pernet_list, list) + ops_exit_list(ops, &net_exit_list); +@@ -1170,7 +1189,17 @@ static void free_exit_list(struct pernet_operations *ops, struct list_head *net_ + { + ops_pre_exit_list(ops, net_exit_list); + synchronize_rcu(); ++ ++ if (ops->exit_batch_rtnl) { ++ LIST_HEAD(dev_kill_list); ++ ++ rtnl_lock(); ++ ops->exit_batch_rtnl(net_exit_list, &dev_kill_list); ++ unregister_netdevice_many(&dev_kill_list); ++ rtnl_unlock(); ++ } + ops_exit_list(ops, net_exit_list); ++ + ops_free_list(ops, net_exit_list); + } + +diff --git a/net/core/pktgen.c b/net/core/pktgen.c +index 0e472f6fab8538..359e24c3f22cab 100644 +--- a/net/core/pktgen.c ++++ b/net/core/pktgen.c +@@ -850,6 +850,9 @@ static ssize_t get_imix_entries(const char __user *buffer, + unsigned long weight; + unsigned long size; + ++ if (pkt_dev->n_imix_entries >= MAX_IMIX_ENTRIES) ++ return -E2BIG; ++ + len = num_arg(&buffer[i], max_digits, &size); + if (len < 0) + return len; +@@ -879,9 +882,6 @@ static ssize_t get_imix_entries(const char __user *buffer, + + i++; + pkt_dev->n_imix_entries++; +- +- if (pkt_dev->n_imix_entries > MAX_IMIX_ENTRIES) +- return -E2BIG; + } while (c == ' '); + + return i; +diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c +index d25e962b18a53e..2839ca8053ba6d 100644 +--- a/net/dccp/ipv6.c ++++ b/net/dccp/ipv6.c +@@ -616,7 +616,7 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) + by tcp. Feel free to propose better solution. + --ANK (980728) + */ +- if (np->rxopt.all) ++ if (np->rxopt.all && sk->sk_state != DCCP_LISTEN) + opt_skb = skb_clone_and_charge_r(skb, sk); + + if (sk->sk_state == DCCP_OPEN) { /* Fast path */ +diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c +index 64bdb6d978eed4..f285e52b8b8579 100644 +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -1456,7 +1456,7 @@ int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) + by tcp. Feel free to propose better solution. + --ANK (980728) + */ +- if (np->rxopt.all) ++ if (np->rxopt.all && sk->sk_state != TCP_LISTEN) + opt_skb = skb_clone_and_charge_r(skb, sk); + + reason = SKB_DROP_REASON_NOT_SPECIFIED; +@@ -1495,8 +1495,6 @@ int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) + if (nsk != sk) { + if (tcp_child_process(sk, nsk, skb)) + goto reset; +- if (opt_skb) +- __kfree_skb(opt_skb); + return 0; + } + } else +diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c +index c0e2da5072bea2..9e4631fade90c9 100644 +--- a/net/mac802154/iface.c ++++ b/net/mac802154/iface.c +@@ -684,6 +684,10 @@ void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata) + ASSERT_RTNL(); + + mutex_lock(&sdata->local->iflist_mtx); ++ if (list_empty(&sdata->local->interfaces)) { ++ mutex_unlock(&sdata->local->iflist_mtx); ++ return; ++ } + list_del_rcu(&sdata->list); + mutex_unlock(&sdata->local->iflist_mtx); + +diff --git a/net/mptcp/options.c b/net/mptcp/options.c +index 2e1539027e6d33..8e6a6dc6e0a409 100644 +--- a/net/mptcp/options.c ++++ b/net/mptcp/options.c +@@ -607,7 +607,6 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb, + } + opts->ext_copy.use_ack = 1; + opts->suboptions = OPTION_MPTCP_DSS; +- WRITE_ONCE(msk->old_wspace, __mptcp_space((struct sock *)msk)); + + /* Add kind/length/subtype/flag overhead if mapping is not populated */ + if (dss_size == 0) +@@ -1287,7 +1286,7 @@ static void mptcp_set_rwin(struct tcp_sock *tp, struct tcphdr *th) + } + MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_RCVWNDCONFLICT); + } +- return; ++ goto update_wspace; + } + + if (rcv_wnd_new != rcv_wnd_old) { +@@ -1312,6 +1311,9 @@ static void mptcp_set_rwin(struct tcp_sock *tp, struct tcphdr *th) + th->window = htons(new_win); + MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_RCVWNDSHARED); + } ++ ++update_wspace: ++ WRITE_ONCE(msk->old_wspace, tp->rcv_wnd); + } + + __sum16 __mptcp_make_csum(u64 data_seq, u32 subflow_seq, u16 data_len, __wsum sum) +diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h +index 89d1c299ff2b9f..88c762de772875 100644 +--- a/net/mptcp/protocol.h ++++ b/net/mptcp/protocol.h +@@ -685,10 +685,15 @@ static inline u64 mptcp_data_avail(const struct mptcp_sock *msk) + + static inline bool mptcp_epollin_ready(const struct sock *sk) + { ++ u64 data_avail = mptcp_data_avail(mptcp_sk(sk)); ++ ++ if (!data_avail) ++ return false; ++ + /* mptcp doesn't have to deal with small skbs in the receive queue, +- * at it can always coalesce them ++ * as it can always coalesce them + */ +- return (mptcp_data_avail(mptcp_sk(sk)) >= sk->sk_rcvlowat) || ++ return (data_avail >= sk->sk_rcvlowat) || + (mem_cgroup_sockets_enabled && sk->sk_memcg && + mem_cgroup_under_socket_pressure(sk->sk_memcg)) || + READ_ONCE(tcp_memory_pressure); +diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c +index 4f5cbcaa38386f..9445ca97163b40 100644 +--- a/net/openvswitch/actions.c ++++ b/net/openvswitch/actions.c +@@ -918,7 +918,9 @@ static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port, + { + struct vport *vport = ovs_vport_rcu(dp, out_port); + +- if (likely(vport && netif_carrier_ok(vport->dev))) { ++ if (likely(vport && ++ netif_running(vport->dev) && ++ netif_carrier_ok(vport->dev))) { + u16 mru = OVS_CB(skb)->mru; + u32 cutlen = OVS_CB(skb)->cutlen; + +diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c +index 6e1cd71d33a599..2050d888df2ae1 100644 +--- a/net/vmw_vsock/af_vsock.c ++++ b/net/vmw_vsock/af_vsock.c +@@ -490,6 +490,15 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk) + */ + vsk->transport->release(vsk); + vsock_deassign_transport(vsk); ++ ++ /* transport's release() and destruct() can touch some socket ++ * state, since we are reassigning the socket to a new transport ++ * during vsock_connect(), let's reset these fields to have a ++ * clean state. ++ */ ++ sock_reset_flag(sk, SOCK_DONE); ++ sk->sk_state = TCP_CLOSE; ++ vsk->peer_shutdown = 0; + } + + /* We increase the module refcnt to prevent the transport unloading +@@ -866,6 +875,9 @@ EXPORT_SYMBOL_GPL(vsock_create_connected); + + s64 vsock_stream_has_data(struct vsock_sock *vsk) + { ++ if (WARN_ON(!vsk->transport)) ++ return 0; ++ + return vsk->transport->stream_has_data(vsk); + } + EXPORT_SYMBOL_GPL(vsock_stream_has_data); +@@ -874,6 +886,9 @@ s64 vsock_connectible_has_data(struct vsock_sock *vsk) + { + struct sock *sk = sk_vsock(vsk); + ++ if (WARN_ON(!vsk->transport)) ++ return 0; ++ + if (sk->sk_type == SOCK_SEQPACKET) + return vsk->transport->seqpacket_has_data(vsk); + else +@@ -883,6 +898,9 @@ EXPORT_SYMBOL_GPL(vsock_connectible_has_data); + + s64 vsock_stream_has_space(struct vsock_sock *vsk) + { ++ if (WARN_ON(!vsk->transport)) ++ return 0; ++ + return vsk->transport->stream_has_space(vsk); + } + EXPORT_SYMBOL_GPL(vsock_stream_has_space); +diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c +index 43495820b64fb1..c57fe7ddcf73bf 100644 +--- a/net/vmw_vsock/virtio_transport_common.c ++++ b/net/vmw_vsock/virtio_transport_common.c +@@ -26,6 +26,9 @@ + /* Threshold for detecting small packets to copy */ + #define GOOD_COPY_LEN 128 + ++static void virtio_transport_cancel_close_work(struct vsock_sock *vsk, ++ bool cancel_timeout); ++ + static const struct virtio_transport * + virtio_transport_get_ops(struct vsock_sock *vsk) + { +@@ -922,6 +925,8 @@ void virtio_transport_destruct(struct vsock_sock *vsk) + { + struct virtio_vsock_sock *vvs = vsk->trans; + ++ virtio_transport_cancel_close_work(vsk, true); ++ + kfree(vvs); + vsk->trans = NULL; + } +@@ -1004,17 +1009,11 @@ static void virtio_transport_wait_close(struct sock *sk, long timeout) + } + } + +-static void virtio_transport_do_close(struct vsock_sock *vsk, +- bool cancel_timeout) ++static void virtio_transport_cancel_close_work(struct vsock_sock *vsk, ++ bool cancel_timeout) + { + struct sock *sk = sk_vsock(vsk); + +- sock_set_flag(sk, SOCK_DONE); +- vsk->peer_shutdown = SHUTDOWN_MASK; +- if (vsock_stream_has_data(vsk) <= 0) +- sk->sk_state = TCP_CLOSING; +- sk->sk_state_change(sk); +- + if (vsk->close_work_scheduled && + (!cancel_timeout || cancel_delayed_work(&vsk->close_work))) { + vsk->close_work_scheduled = false; +@@ -1026,6 +1025,20 @@ static void virtio_transport_do_close(struct vsock_sock *vsk, + } + } + ++static void virtio_transport_do_close(struct vsock_sock *vsk, ++ bool cancel_timeout) ++{ ++ struct sock *sk = sk_vsock(vsk); ++ ++ sock_set_flag(sk, SOCK_DONE); ++ vsk->peer_shutdown = SHUTDOWN_MASK; ++ if (vsock_stream_has_data(vsk) <= 0) ++ sk->sk_state = TCP_CLOSING; ++ sk->sk_state_change(sk); ++ ++ virtio_transport_cancel_close_work(vsk, cancel_timeout); ++} ++ + static void virtio_transport_close_timeout(struct work_struct *work) + { + struct vsock_sock *vsk = +@@ -1428,8 +1441,11 @@ void virtio_transport_recv_pkt(struct virtio_transport *t, + + lock_sock(sk); + +- /* Check if sk has been closed before lock_sock */ +- if (sock_flag(sk, SOCK_DONE)) { ++ /* Check if sk has been closed or assigned to another transport before ++ * lock_sock (note: listener sockets are not assigned to any transport) ++ */ ++ if (sock_flag(sk, SOCK_DONE) || ++ (sk->sk_state != TCP_LISTEN && vsk->transport != &t->transport)) { + (void)virtio_transport_reset_no_sock(t, skb); + release_sock(sk); + sock_put(sk); +diff --git a/net/vmw_vsock/vsock_bpf.c b/net/vmw_vsock/vsock_bpf.c +index 4aa6e74ec2957b..f201d9eca1df2f 100644 +--- a/net/vmw_vsock/vsock_bpf.c ++++ b/net/vmw_vsock/vsock_bpf.c +@@ -77,6 +77,7 @@ static int vsock_bpf_recvmsg(struct sock *sk, struct msghdr *msg, + size_t len, int flags, int *addr_len) + { + struct sk_psock *psock; ++ struct vsock_sock *vsk; + int copied; + + psock = sk_psock_get(sk); +@@ -84,6 +85,13 @@ static int vsock_bpf_recvmsg(struct sock *sk, struct msghdr *msg, + return __vsock_recvmsg(sk, msg, len, flags); + + lock_sock(sk); ++ vsk = vsock_sk(sk); ++ ++ if (!vsk->transport) { ++ copied = -ENODEV; ++ goto out; ++ } ++ + if (vsock_has_data(sk, psock) && sk_psock_queue_empty(psock)) { + release_sock(sk); + sk_psock_put(sk, psock); +@@ -108,6 +116,7 @@ static int vsock_bpf_recvmsg(struct sock *sk, struct msghdr *msg, + copied = sk_msg_recvmsg(sk, psock, msg, len, flags); + } + ++out: + release_sock(sk); + sk_psock_put(sk, psock); + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index fc93af80f0bffe..739f8fd1792bd5 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -10430,6 +10430,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC), + SND_PCI_QUIRK(0x1d72, 0x1945, "Redmi G", ALC256_FIXUP_ASUS_HEADSET_MIC), + SND_PCI_QUIRK(0x1d72, 0x1947, "RedmiBook Air", ALC255_FIXUP_XIAOMI_HEADSET_MIC), ++ SND_PCI_QUIRK(0x1f66, 0x0105, "Ayaneo Portable Game Player", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x2782, 0x0214, "VAIO VJFE-CL", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), + SND_PCI_QUIRK(0x2782, 0x0228, "Infinix ZERO BOOK 13", ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13), + SND_PCI_QUIRK(0x2782, 0x0232, "CHUWI CoreBook XPro", ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO), +diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/testing/selftests/net/mptcp/mptcp_connect.c +index 4209b95690394b..414addef9a4514 100644 +--- a/tools/testing/selftests/net/mptcp/mptcp_connect.c ++++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c +@@ -25,6 +25,8 @@ + #include + #include + ++#include ++ + #include + #include + +@@ -1211,23 +1213,42 @@ static void parse_setsock_options(const char *name) + exit(1); + } + +-void xdisconnect(int fd, int addrlen) ++void xdisconnect(int fd) + { +- struct sockaddr_storage empty; ++ socklen_t addrlen = sizeof(struct sockaddr_storage); ++ struct sockaddr_storage addr, empty; + int msec_sleep = 10; +- int queued = 1; +- int i; ++ void *raw_addr; ++ int i, cmdlen; ++ char cmd[128]; ++ ++ /* get the local address and convert it to string */ ++ if (getsockname(fd, (struct sockaddr *)&addr, &addrlen) < 0) ++ xerror("getsockname"); ++ ++ if (addr.ss_family == AF_INET) ++ raw_addr = &(((struct sockaddr_in *)&addr)->sin_addr); ++ else if (addr.ss_family == AF_INET6) ++ raw_addr = &(((struct sockaddr_in6 *)&addr)->sin6_addr); ++ else ++ xerror("bad family"); ++ ++ strcpy(cmd, "ss -M | grep -q "); ++ cmdlen = strlen(cmd); ++ if (!inet_ntop(addr.ss_family, raw_addr, &cmd[cmdlen], ++ sizeof(cmd) - cmdlen)) ++ xerror("inet_ntop"); + + shutdown(fd, SHUT_WR); + +- /* while until the pending data is completely flushed, the later ++ /* ++ * wait until the pending data is completely flushed and all ++ * the MPTCP sockets reached the closed status. + * disconnect will bypass/ignore/drop any pending data. + */ + for (i = 0; ; i += msec_sleep) { +- if (ioctl(fd, SIOCOUTQ, &queued) < 0) +- xerror("can't query out socket queue: %d", errno); +- +- if (!queued) ++ /* closed socket are not listed by 'ss' */ ++ if (system(cmd) != 0) + break; + + if (i > poll_timeout) +@@ -1281,9 +1302,9 @@ int main_loop(void) + return ret; + + if (cfg_truncate > 0) { +- xdisconnect(fd, peer->ai_addrlen); ++ xdisconnect(fd); + } else if (--cfg_repeat > 0) { +- xdisconnect(fd, peer->ai_addrlen); ++ xdisconnect(fd); + + /* the socket could be unblocking at this point, we need the + * connect to be blocking +diff --git a/tools/testing/selftests/tc-testing/tc-tests/filters/flow.json b/tools/testing/selftests/tc-testing/tc-tests/filters/flow.json +index 58189327f6444a..383fbda07245c8 100644 +--- a/tools/testing/selftests/tc-testing/tc-tests/filters/flow.json ++++ b/tools/testing/selftests/tc-testing/tc-tests/filters/flow.json +@@ -78,10 +78,10 @@ + "setup": [ + "$TC qdisc add dev $DEV1 ingress" + ], +- "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 protocol ip flow map key dst rshift 0xff", ++ "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 protocol ip flow map key dst rshift 0x1f", + "expExitCode": "0", + "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 protocol ip prio 1 flow", +- "matchPattern": "filter parent ffff: protocol ip pref 1 flow chain [0-9]+ handle 0x1 map keys dst rshift 255 baseclass", ++ "matchPattern": "filter parent ffff: protocol ip pref 1 flow chain [0-9]+ handle 0x1 map keys dst rshift 31 baseclass", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 ingress" diff --git a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.74-75.patch b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.74-75.patch new file mode 100644 index 000000000000..38dace8c9faf --- /dev/null +++ b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.74-75.patch @@ -0,0 +1,1630 @@ +diff --git a/Makefile b/Makefile +index b8e5c65910862e..b8041104f248d3 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 6 +-SUBLEVEL = 74 ++SUBLEVEL = 75 + EXTRAVERSION = + NAME = Pinguïn Aangedreven + +diff --git a/block/ioctl.c b/block/ioctl.c +index 3786033342848d..231537f79a8cb4 100644 +--- a/block/ioctl.c ++++ b/block/ioctl.c +@@ -115,7 +115,7 @@ static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode, + return -EINVAL; + + filemap_invalidate_lock(inode->i_mapping); +- err = truncate_bdev_range(bdev, mode, start, start + len - 1); ++ err = truncate_bdev_range(bdev, mode, start, end - 1); + if (err) + goto fail; + err = blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL); +@@ -127,7 +127,7 @@ static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode, + static int blk_ioctl_secure_erase(struct block_device *bdev, blk_mode_t mode, + void __user *argp) + { +- uint64_t start, len; ++ uint64_t start, len, end; + uint64_t range[2]; + int err; + +@@ -142,11 +142,12 @@ static int blk_ioctl_secure_erase(struct block_device *bdev, blk_mode_t mode, + len = range[1]; + if ((start & 511) || (len & 511)) + return -EINVAL; +- if (start + len > bdev_nr_bytes(bdev)) ++ if (check_add_overflow(start, len, &end) || ++ end > bdev_nr_bytes(bdev)) + return -EINVAL; + + filemap_invalidate_lock(bdev->bd_inode->i_mapping); +- err = truncate_bdev_range(bdev, mode, start, start + len - 1); ++ err = truncate_bdev_range(bdev, mode, start, end - 1); + if (!err) + err = blkdev_issue_secure_erase(bdev, start >> 9, len >> 9, + GFP_KERNEL); +diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c +index f1263364fa97fa..86fa5dc7dd99a8 100644 +--- a/drivers/ata/libahci.c ++++ b/drivers/ata/libahci.c +@@ -2082,13 +2082,6 @@ static void ahci_qc_fill_rtf(struct ata_queued_cmd *qc) + struct ahci_port_priv *pp = qc->ap->private_data; + u8 *rx_fis = pp->rx_fis; + +- /* +- * rtf may already be filled (e.g. for successful NCQ commands). +- * If that is the case, we have nothing to do. +- */ +- if (qc->flags & ATA_QCFLAG_RTF_FILLED) +- return; +- + if (pp->fbs_enabled) + rx_fis += qc->dev->link->pmp * AHCI_RX_FIS_SZ; + +@@ -2102,7 +2095,6 @@ static void ahci_qc_fill_rtf(struct ata_queued_cmd *qc) + !(qc->flags & ATA_QCFLAG_EH)) { + ata_tf_from_fis(rx_fis + RX_FIS_PIO_SETUP, &qc->result_tf); + qc->result_tf.status = (rx_fis + RX_FIS_PIO_SETUP)[15]; +- qc->flags |= ATA_QCFLAG_RTF_FILLED; + return; + } + +@@ -2125,12 +2117,10 @@ static void ahci_qc_fill_rtf(struct ata_queued_cmd *qc) + */ + qc->result_tf.status = fis[2]; + qc->result_tf.error = fis[3]; +- qc->flags |= ATA_QCFLAG_RTF_FILLED; + return; + } + + ata_tf_from_fis(rx_fis + RX_FIS_D2H_REG, &qc->result_tf); +- qc->flags |= ATA_QCFLAG_RTF_FILLED; + } + + static void ahci_qc_ncq_fill_rtf(struct ata_port *ap, u64 done_mask) +@@ -2165,6 +2155,7 @@ static void ahci_qc_ncq_fill_rtf(struct ata_port *ap, u64 done_mask) + if (qc && ata_is_ncq(qc->tf.protocol)) { + qc->result_tf.status = status; + qc->result_tf.error = error; ++ qc->result_tf.flags = qc->tf.flags; + qc->flags |= ATA_QCFLAG_RTF_FILLED; + } + done_mask &= ~(1ULL << tag); +@@ -2189,6 +2180,7 @@ static void ahci_qc_ncq_fill_rtf(struct ata_port *ap, u64 done_mask) + fis += RX_FIS_SDB; + qc->result_tf.status = fis[2]; + qc->result_tf.error = fis[3]; ++ qc->result_tf.flags = qc->tf.flags; + qc->flags |= ATA_QCFLAG_RTF_FILLED; + } + done_mask &= ~(1ULL << tag); +diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c +index 4ed90d46a017a8..f627753519b978 100644 +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -4792,8 +4792,16 @@ static void fill_result_tf(struct ata_queued_cmd *qc) + { + struct ata_port *ap = qc->ap; + ++ /* ++ * rtf may already be filled (e.g. for successful NCQ commands). ++ * If that is the case, we have nothing to do. ++ */ ++ if (qc->flags & ATA_QCFLAG_RTF_FILLED) ++ return; ++ + qc->result_tf.flags = qc->tf.flags; + ap->ops->qc_fill_rtf(qc); ++ qc->flags |= ATA_QCFLAG_RTF_FILLED; + } + + static void ata_verify_xfer(struct ata_queued_cmd *qc) +diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c +index cdead37d0823ad..a64baa97e3583d 100644 +--- a/drivers/cpufreq/amd-pstate.c ++++ b/drivers/cpufreq/amd-pstate.c +@@ -579,8 +579,13 @@ static void amd_pstate_adjust_perf(unsigned int cpu, + unsigned long max_perf, min_perf, des_perf, + cap_perf, lowest_nonlinear_perf, max_freq; + struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); +- struct amd_cpudata *cpudata = policy->driver_data; + unsigned int target_freq; ++ struct amd_cpudata *cpudata; ++ ++ if (!policy) ++ return; ++ ++ cpudata = policy->driver_data; + + if (policy->min != cpudata->min_limit_freq || policy->max != cpudata->max_limit_freq) + amd_pstate_update_min_max_limit(policy); +diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c +index 2aa0e01a6891b0..f11b071a896f59 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c ++++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c +@@ -63,7 +63,8 @@ void dmub_hw_lock_mgr_inbox0_cmd(struct dc_dmub_srv *dmub_srv, + + bool should_use_dmub_lock(struct dc_link *link) + { +- if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) ++ if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1 || ++ link->psr_settings.psr_version == DC_PSR_VERSION_1) + return true; + return false; + } +diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c +index 76806039691a2c..b2d59a16869728 100644 +--- a/drivers/gpu/drm/v3d/v3d_irq.c ++++ b/drivers/gpu/drm/v3d/v3d_irq.c +@@ -102,8 +102,10 @@ v3d_irq(int irq, void *arg) + to_v3d_fence(v3d->bin_job->base.irq_fence); + + trace_v3d_bcl_irq(&v3d->drm, fence->seqno); +- dma_fence_signal(&fence->base); ++ + v3d->bin_job = NULL; ++ dma_fence_signal(&fence->base); ++ + status = IRQ_HANDLED; + } + +@@ -112,8 +114,10 @@ v3d_irq(int irq, void *arg) + to_v3d_fence(v3d->render_job->base.irq_fence); + + trace_v3d_rcl_irq(&v3d->drm, fence->seqno); +- dma_fence_signal(&fence->base); ++ + v3d->render_job = NULL; ++ dma_fence_signal(&fence->base); ++ + status = IRQ_HANDLED; + } + +@@ -122,8 +126,10 @@ v3d_irq(int irq, void *arg) + to_v3d_fence(v3d->csd_job->base.irq_fence); + + trace_v3d_csd_irq(&v3d->drm, fence->seqno); +- dma_fence_signal(&fence->base); ++ + v3d->csd_job = NULL; ++ dma_fence_signal(&fence->base); ++ + status = IRQ_HANDLED; + } + +@@ -159,8 +165,10 @@ v3d_hub_irq(int irq, void *arg) + to_v3d_fence(v3d->tfu_job->base.irq_fence); + + trace_v3d_tfu_irq(&v3d->drm, fence->seqno); +- dma_fence_signal(&fence->base); ++ + v3d->tfu_job = NULL; ++ dma_fence_signal(&fence->base); ++ + status = IRQ_HANDLED; + } + +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index f16940f3d93d46..1174626904cb02 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -506,7 +506,6 @@ + #define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_E100 0xe100 + + #define I2C_VENDOR_ID_GOODIX 0x27c6 +-#define I2C_DEVICE_ID_GOODIX_01E0 0x01e0 + #define I2C_DEVICE_ID_GOODIX_01E8 0x01e8 + #define I2C_DEVICE_ID_GOODIX_01E9 0x01e9 + #define I2C_DEVICE_ID_GOODIX_01F0 0x01f0 +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index bf9cad71125923..e62104e1a6038b 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -1447,8 +1447,7 @@ static __u8 *mt_report_fixup(struct hid_device *hdev, __u8 *rdesc, + { + if (hdev->vendor == I2C_VENDOR_ID_GOODIX && + (hdev->product == I2C_DEVICE_ID_GOODIX_01E8 || +- hdev->product == I2C_DEVICE_ID_GOODIX_01E9 || +- hdev->product == I2C_DEVICE_ID_GOODIX_01E0)) { ++ hdev->product == I2C_DEVICE_ID_GOODIX_01E9)) { + if (rdesc[607] == 0x15) { + rdesc[607] = 0x25; + dev_info( +@@ -2073,10 +2072,7 @@ static const struct hid_device_id mt_devices[] = { + I2C_DEVICE_ID_GOODIX_01E8) }, + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU, + HID_DEVICE(BUS_I2C, HID_GROUP_ANY, I2C_VENDOR_ID_GOODIX, +- I2C_DEVICE_ID_GOODIX_01E9) }, +- { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU, +- HID_DEVICE(BUS_I2C, HID_GROUP_ANY, I2C_VENDOR_ID_GOODIX, +- I2C_DEVICE_ID_GOODIX_01E0) }, ++ I2C_DEVICE_ID_GOODIX_01E8) }, + + /* GoodTouch panels */ + { .driver_data = MT_CLS_NSMU, +diff --git a/drivers/hwmon/drivetemp.c b/drivers/hwmon/drivetemp.c +index 2a4ec55ddb47ed..291d91f6864676 100644 +--- a/drivers/hwmon/drivetemp.c ++++ b/drivers/hwmon/drivetemp.c +@@ -194,7 +194,7 @@ static int drivetemp_scsi_command(struct drivetemp_data *st, + scsi_cmd[14] = ata_command; + + err = scsi_execute_cmd(st->sdev, scsi_cmd, op, st->smartdata, +- ATA_SECT_SIZE, HZ, 5, NULL); ++ ATA_SECT_SIZE, 10 * HZ, 5, NULL); + if (err > 0) + err = -EIO; + return err; +diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c +index c7e51cc2ea2687..082a383c4913ec 100644 +--- a/drivers/infiniband/hw/bnxt_re/main.c ++++ b/drivers/infiniband/hw/bnxt_re/main.c +@@ -485,6 +485,8 @@ static void bnxt_re_set_default_pacing_data(struct bnxt_re_dev *rdev) + static void __wait_for_fifo_occupancy_below_th(struct bnxt_re_dev *rdev) + { + u32 read_val, fifo_occup; ++ struct bnxt_qplib_db_pacing_data *pacing_data = rdev->qplib_res.pacing_data; ++ u32 retry_fifo_check = 1000; + + /* loop shouldn't run infintely as the occupancy usually goes + * below pacing algo threshold as soon as pacing kicks in. +@@ -500,6 +502,14 @@ static void __wait_for_fifo_occupancy_below_th(struct bnxt_re_dev *rdev) + + if (fifo_occup < rdev->qplib_res.pacing_data->pacing_th) + break; ++ if (!retry_fifo_check--) { ++ dev_info_once(rdev_to_dev(rdev), ++ "%s: fifo_occup = 0x%xfifo_max_depth = 0x%x pacing_th = 0x%x\n", ++ __func__, fifo_occup, pacing_data->fifo_max_depth, ++ pacing_data->pacing_th); ++ break; ++ } ++ + } + } + +diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c +index 0cfcad8348a6da..198a44c87e8411 100644 +--- a/drivers/input/joystick/xpad.c ++++ b/drivers/input/joystick/xpad.c +@@ -150,6 +150,7 @@ static const struct xpad_device { + { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 }, + { 0x045e, 0x028f, "Microsoft X-Box 360 pad v2", 0, XTYPE_XBOX360 }, + { 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, ++ { 0x045e, 0x02a9, "Xbox 360 Wireless Receiver (Unofficial)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, + { 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE }, + { 0x045e, 0x02dd, "Microsoft X-Box One pad (Firmware 2015)", 0, XTYPE_XBOXONE }, + { 0x045e, 0x02e3, "Microsoft X-Box One Elite pad", MAP_PADDLES, XTYPE_XBOXONE }, +@@ -305,6 +306,7 @@ static const struct xpad_device { + { 0x1689, 0xfe00, "Razer Sabertooth", 0, XTYPE_XBOX360 }, + { 0x17ef, 0x6182, "Lenovo Legion Controller for Windows", 0, XTYPE_XBOX360 }, + { 0x1949, 0x041a, "Amazon Game Controller", 0, XTYPE_XBOX360 }, ++ { 0x1a86, 0xe310, "QH Electronics Controller", 0, XTYPE_XBOX360 }, + { 0x1bad, 0x0002, "Harmonix Rock Band Guitar", 0, XTYPE_XBOX360 }, + { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, + { 0x1bad, 0x0130, "Ion Drum Rocker", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, +@@ -372,16 +374,19 @@ static const struct xpad_device { + { 0x294b, 0x3303, "Snakebyte GAMEPAD BASE X", 0, XTYPE_XBOXONE }, + { 0x294b, 0x3404, "Snakebyte GAMEPAD RGB X", 0, XTYPE_XBOXONE }, + { 0x2dc8, 0x2000, "8BitDo Pro 2 Wired Controller fox Xbox", 0, XTYPE_XBOXONE }, +- { 0x2dc8, 0x3106, "8BitDo Pro 2 Wired Controller", 0, XTYPE_XBOX360 }, ++ { 0x2dc8, 0x3106, "8BitDo Ultimate Wireless / Pro 2 Wired Controller", 0, XTYPE_XBOX360 }, + { 0x2dc8, 0x310a, "8BitDo Ultimate 2C Wireless Controller", 0, XTYPE_XBOX360 }, + { 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE }, + { 0x31e3, 0x1100, "Wooting One", 0, XTYPE_XBOX360 }, + { 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 }, + { 0x31e3, 0x1210, "Wooting Lekker", 0, XTYPE_XBOX360 }, + { 0x31e3, 0x1220, "Wooting Two HE", 0, XTYPE_XBOX360 }, ++ { 0x31e3, 0x1230, "Wooting Two HE (ARM)", 0, XTYPE_XBOX360 }, + { 0x31e3, 0x1300, "Wooting 60HE (AVR)", 0, XTYPE_XBOX360 }, + { 0x31e3, 0x1310, "Wooting 60HE (ARM)", 0, XTYPE_XBOX360 }, + { 0x3285, 0x0607, "Nacon GC-100", 0, XTYPE_XBOX360 }, ++ { 0x3285, 0x0646, "Nacon Pro Compact", 0, XTYPE_XBOXONE }, ++ { 0x3285, 0x0663, "Nacon Evol-X", 0, XTYPE_XBOXONE }, + { 0x3537, 0x1004, "GameSir T4 Kaleid", 0, XTYPE_XBOX360 }, + { 0x3767, 0x0101, "Fanatec Speedster 3 Forceshock Wheel", 0, XTYPE_XBOX }, + { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX }, +@@ -513,6 +518,7 @@ static const struct usb_device_id xpad_table[] = { + XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */ + XPAD_XBOX360_VENDOR(0x17ef), /* Lenovo */ + XPAD_XBOX360_VENDOR(0x1949), /* Amazon controllers */ ++ XPAD_XBOX360_VENDOR(0x1a86), /* QH Electronics */ + XPAD_XBOX360_VENDOR(0x1bad), /* Harmonix Rock Band guitar and drums */ + XPAD_XBOX360_VENDOR(0x20d6), /* PowerA controllers */ + XPAD_XBOXONE_VENDOR(0x20d6), /* PowerA controllers */ +@@ -528,6 +534,7 @@ static const struct usb_device_id xpad_table[] = { + XPAD_XBOX360_VENDOR(0x2f24), /* GameSir controllers */ + XPAD_XBOX360_VENDOR(0x31e3), /* Wooting Keyboards */ + XPAD_XBOX360_VENDOR(0x3285), /* Nacon GC-100 */ ++ XPAD_XBOXONE_VENDOR(0x3285), /* Nacon Evol-X */ + XPAD_XBOX360_VENDOR(0x3537), /* GameSir Controllers */ + XPAD_XBOXONE_VENDOR(0x3537), /* GameSir Controllers */ + { } +diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c +index c229bd6b3f7f2f..aad2d75c036781 100644 +--- a/drivers/input/keyboard/atkbd.c ++++ b/drivers/input/keyboard/atkbd.c +@@ -89,7 +89,7 @@ static const unsigned short atkbd_set2_keycode[ATKBD_KEYMAP_SIZE] = { + 0, 46, 45, 32, 18, 5, 4, 95, 0, 57, 47, 33, 20, 19, 6,183, + 0, 49, 48, 35, 34, 21, 7,184, 0, 0, 50, 36, 22, 8, 9,185, + 0, 51, 37, 23, 24, 11, 10, 0, 0, 52, 53, 38, 39, 25, 12, 0, +- 0, 89, 40, 0, 26, 13, 0, 0, 58, 54, 28, 27, 0, 43, 0, 85, ++ 0, 89, 40, 0, 26, 13, 0,193, 58, 54, 28, 27, 0, 43, 0, 85, + 0, 86, 91, 90, 92, 0, 14, 94, 0, 79,124, 75, 71,121, 0, 0, + 82, 83, 80, 76, 77, 72, 1, 69, 87, 78, 81, 74, 55, 73, 70, 99, + +diff --git a/drivers/irqchip/irq-sunxi-nmi.c b/drivers/irqchip/irq-sunxi-nmi.c +index e760b1278143dd..262b625c30c102 100644 +--- a/drivers/irqchip/irq-sunxi-nmi.c ++++ b/drivers/irqchip/irq-sunxi-nmi.c +@@ -186,7 +186,8 @@ static int __init sunxi_sc_nmi_irq_init(struct device_node *node, + gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; + gc->chip_types[0].chip.irq_eoi = irq_gc_ack_set_bit; + gc->chip_types[0].chip.irq_set_type = sunxi_sc_nmi_set_type; +- gc->chip_types[0].chip.flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED; ++ gc->chip_types[0].chip.flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED | ++ IRQCHIP_SKIP_SET_WAKE; + gc->chip_types[0].regs.ack = reg_offs->pend; + gc->chip_types[0].regs.mask = reg_offs->enable; + gc->chip_types[0].regs.type = reg_offs->ctrl; +diff --git a/drivers/of/unittest-data/tests-platform.dtsi b/drivers/of/unittest-data/tests-platform.dtsi +index fa39611071b32f..cd310b26b50c81 100644 +--- a/drivers/of/unittest-data/tests-platform.dtsi ++++ b/drivers/of/unittest-data/tests-platform.dtsi +@@ -34,5 +34,18 @@ dev@100 { + }; + }; + }; ++ ++ platform-tests-2 { ++ // No #address-cells or #size-cells ++ node { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ test-device@100 { ++ compatible = "test-sub-device"; ++ reg = <0x100 1>; ++ }; ++ }; ++ }; + }; + }; +diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c +index 7986113adc7d31..3b22c36bfb0b7c 100644 +--- a/drivers/of/unittest.c ++++ b/drivers/of/unittest.c +@@ -1186,6 +1186,7 @@ static void __init of_unittest_bus_3cell_ranges(void) + static void __init of_unittest_reg(void) + { + struct device_node *np; ++ struct resource res; + int ret; + u64 addr, size; + +@@ -1202,6 +1203,19 @@ static void __init of_unittest_reg(void) + np, addr); + + of_node_put(np); ++ ++ np = of_find_node_by_path("/testcase-data/platform-tests-2/node/test-device@100"); ++ if (!np) { ++ pr_err("missing testcase data\n"); ++ return; ++ } ++ ++ ret = of_address_to_resource(np, 0, &res); ++ unittest(ret == -EINVAL, "of_address_to_resource(%pOF) expected error on untranslatable address\n", ++ np); ++ ++ of_node_put(np); ++ + } + + static void __init of_unittest_parse_interrupts(void) +diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c +index 3075b2ddf7a697..deeb657981a690 100644 +--- a/drivers/scsi/scsi_transport_iscsi.c ++++ b/drivers/scsi/scsi_transport_iscsi.c +@@ -4103,7 +4103,7 @@ iscsi_if_rx(struct sk_buff *skb) + } + do { + /* +- * special case for GET_STATS: ++ * special case for GET_STATS, GET_CHAP and GET_HOST_STATS: + * on success - sending reply and stats from + * inside of if_recv_msg(), + * on error - fall through. +@@ -4112,6 +4112,8 @@ iscsi_if_rx(struct sk_buff *skb) + break; + if (ev->type == ISCSI_UEVENT_GET_CHAP && !err) + break; ++ if (ev->type == ISCSI_UEVENT_GET_HOST_STATS && !err) ++ break; + err = iscsi_if_send_reply(portid, nlh->nlmsg_type, + ev, sizeof(*ev)); + if (err == -EAGAIN && --retries < 0) { +diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c +index d0b55c1fa908a5..b3c588b102d900 100644 +--- a/drivers/scsi/storvsc_drv.c ++++ b/drivers/scsi/storvsc_drv.c +@@ -171,6 +171,12 @@ do { \ + dev_warn(&(dev)->device, fmt, ##__VA_ARGS__); \ + } while (0) + ++#define storvsc_log_ratelimited(dev, level, fmt, ...) \ ++do { \ ++ if (do_logging(level)) \ ++ dev_warn_ratelimited(&(dev)->device, fmt, ##__VA_ARGS__); \ ++} while (0) ++ + struct vmscsi_request { + u16 length; + u8 srb_status; +@@ -1177,7 +1183,7 @@ static void storvsc_on_io_completion(struct storvsc_device *stor_device, + int loglevel = (stor_pkt->vm_srb.cdb[0] == TEST_UNIT_READY) ? + STORVSC_LOGGING_WARN : STORVSC_LOGGING_ERROR; + +- storvsc_log(device, loglevel, ++ storvsc_log_ratelimited(device, loglevel, + "tag#%d cmd 0x%x status: scsi 0x%x srb 0x%x hv 0x%x\n", + scsi_cmd_to_rq(request->cmd)->tag, + stor_pkt->vm_srb.cdb[0], +diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c +index fe2737e55f8e89..729b0472bab098 100644 +--- a/drivers/usb/gadget/function/u_serial.c ++++ b/drivers/usb/gadget/function/u_serial.c +@@ -1398,10 +1398,6 @@ void gserial_disconnect(struct gserial *gser) + /* REVISIT as above: how best to track this? */ + port->port_line_coding = gser->port_line_coding; + +- /* disable endpoints, aborting down any active I/O */ +- usb_ep_disable(gser->out); +- usb_ep_disable(gser->in); +- + port->port_usb = NULL; + gser->ioport = NULL; + if (port->port.count > 0) { +@@ -1413,6 +1409,10 @@ void gserial_disconnect(struct gserial *gser) + spin_unlock(&port->port_lock); + spin_unlock_irqrestore(&serial_port_lock, flags); + ++ /* disable endpoints, aborting down any active I/O */ ++ usb_ep_disable(gser->out); ++ usb_ep_disable(gser->in); ++ + /* finally, free any unused/unusable I/O buffers */ + spin_lock_irqsave(&port->port_lock, flags); + if (port->port.count == 0) +diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c +index 821f25e52ec24c..4cde2bd3885f13 100644 +--- a/drivers/usb/serial/quatech2.c ++++ b/drivers/usb/serial/quatech2.c +@@ -503,7 +503,7 @@ static void qt2_process_read_urb(struct urb *urb) + + newport = *(ch + 3); + +- if (newport > serial->num_ports) { ++ if (newport >= serial->num_ports) { + dev_err(&port->dev, + "%s - port change to invalid port: %i\n", + __func__, newport); +diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c +index e53757d1d0958a..3bf1043cd7957c 100644 +--- a/drivers/vfio/platform/vfio_platform_common.c ++++ b/drivers/vfio/platform/vfio_platform_common.c +@@ -388,6 +388,11 @@ static ssize_t vfio_platform_read_mmio(struct vfio_platform_region *reg, + { + unsigned int done = 0; + ++ if (off >= reg->size) ++ return -EINVAL; ++ ++ count = min_t(size_t, count, reg->size - off); ++ + if (!reg->ioaddr) { + reg->ioaddr = + ioremap(reg->addr, reg->size); +@@ -467,6 +472,11 @@ static ssize_t vfio_platform_write_mmio(struct vfio_platform_region *reg, + { + unsigned int done = 0; + ++ if (off >= reg->size) ++ return -EINVAL; ++ ++ count = min_t(size_t, count, reg->size - off); ++ + if (!reg->ioaddr) { + reg->ioaddr = + ioremap(reg->addr, reg->size); +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 71ced0ada9a2e5..f019ce64eba48e 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -5366,6 +5366,8 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb) + INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */ + mutex_init(&sbi->s_orphan_lock); + ++ spin_lock_init(&sbi->s_bdev_wb_lock); ++ + ext4_fast_commit_init(sb); + + sb->s_root = NULL; +@@ -5586,7 +5588,6 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb) + * Save the original bdev mapping's wb_err value which could be + * used to detect the metadata async write error. + */ +- spin_lock_init(&sbi->s_bdev_wb_lock); + errseq_check_and_advance(&sb->s_bdev->bd_inode->i_mapping->wb_err, + &sbi->s_bdev_wb_err); + EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS; +diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c +index 9296e0e282bcd8..2adaffa58e88b4 100644 +--- a/fs/gfs2/file.c ++++ b/fs/gfs2/file.c +@@ -251,6 +251,7 @@ static int do_gfs2_set_flags(struct inode *inode, u32 reqflags, u32 mask) + error = filemap_fdatawait(inode->i_mapping); + if (error) + goto out; ++ truncate_inode_pages(inode->i_mapping, 0); + if (new_flags & GFS2_DIF_JDATA) + gfs2_ordered_del_inode(ip); + } +diff --git a/fs/libfs.c b/fs/libfs.c +index dc0f7519045f11..f5566964aa7d13 100644 +--- a/fs/libfs.c ++++ b/fs/libfs.c +@@ -239,6 +239,18 @@ const struct inode_operations simple_dir_inode_operations = { + }; + EXPORT_SYMBOL(simple_dir_inode_operations); + ++/* simple_offset_add() never assigns these to a dentry */ ++enum { ++ DIR_OFFSET_FIRST = 2, /* Find first real entry */ ++ DIR_OFFSET_EOD = S32_MAX, ++}; ++ ++/* simple_offset_add() allocation range */ ++enum { ++ DIR_OFFSET_MIN = DIR_OFFSET_FIRST + 1, ++ DIR_OFFSET_MAX = DIR_OFFSET_EOD - 1, ++}; ++ + static void offset_set(struct dentry *dentry, u32 offset) + { + dentry->d_fsdata = (void *)((uintptr_t)(offset)); +@@ -260,9 +272,7 @@ void simple_offset_init(struct offset_ctx *octx) + { + xa_init_flags(&octx->xa, XA_FLAGS_ALLOC1); + lockdep_set_class(&octx->xa.xa_lock, &simple_offset_xa_lock); +- +- /* 0 is '.', 1 is '..', so always start with offset 2 */ +- octx->next_offset = 2; ++ octx->next_offset = DIR_OFFSET_MIN; + } + + /** +@@ -275,7 +285,8 @@ void simple_offset_init(struct offset_ctx *octx) + */ + int simple_offset_add(struct offset_ctx *octx, struct dentry *dentry) + { +- static const struct xa_limit limit = XA_LIMIT(2, U32_MAX); ++ static const struct xa_limit limit = XA_LIMIT(DIR_OFFSET_MIN, ++ DIR_OFFSET_MAX); + u32 offset; + int ret; + +@@ -284,9 +295,21 @@ int simple_offset_add(struct offset_ctx *octx, struct dentry *dentry) + + ret = xa_alloc_cyclic(&octx->xa, &offset, dentry, limit, + &octx->next_offset, GFP_KERNEL); +- if (ret < 0) +- return ret; ++ if (unlikely(ret < 0)) ++ return ret == -EBUSY ? -ENOSPC : ret; ++ ++ offset_set(dentry, offset); ++ return 0; ++} + ++static int simple_offset_replace(struct offset_ctx *octx, struct dentry *dentry, ++ long offset) ++{ ++ void *ret; ++ ++ ret = xa_store(&octx->xa, offset, dentry, GFP_KERNEL); ++ if (xa_is_err(ret)) ++ return xa_err(ret); + offset_set(dentry, offset); + return 0; + } +@@ -309,6 +332,36 @@ void simple_offset_remove(struct offset_ctx *octx, struct dentry *dentry) + offset_set(dentry, 0); + } + ++/** ++ * simple_offset_rename - handle directory offsets for rename ++ * @old_dir: parent directory of source entry ++ * @old_dentry: dentry of source entry ++ * @new_dir: parent_directory of destination entry ++ * @new_dentry: dentry of destination ++ * ++ * Caller provides appropriate serialization. ++ * ++ * User space expects the directory offset value of the replaced ++ * (new) directory entry to be unchanged after a rename. ++ * ++ * Returns zero on success, a negative errno value on failure. ++ */ ++int simple_offset_rename(struct inode *old_dir, struct dentry *old_dentry, ++ struct inode *new_dir, struct dentry *new_dentry) ++{ ++ struct offset_ctx *old_ctx = old_dir->i_op->get_offset_ctx(old_dir); ++ struct offset_ctx *new_ctx = new_dir->i_op->get_offset_ctx(new_dir); ++ long new_offset = dentry2offset(new_dentry); ++ ++ simple_offset_remove(old_ctx, old_dentry); ++ ++ if (new_offset) { ++ offset_set(new_dentry, 0); ++ return simple_offset_replace(new_ctx, old_dentry, new_offset); ++ } ++ return simple_offset_add(new_ctx, old_dentry); ++} ++ + /** + * simple_offset_rename_exchange - exchange rename with directory offsets + * @old_dir: parent of dentry being moved +@@ -316,6 +369,9 @@ void simple_offset_remove(struct offset_ctx *octx, struct dentry *dentry) + * @new_dir: destination parent + * @new_dentry: destination dentry + * ++ * This API preserves the directory offset values. Caller provides ++ * appropriate serialization. ++ * + * Returns zero on success. Otherwise a negative errno is returned and the + * rename is rolled back. + */ +@@ -333,11 +389,11 @@ int simple_offset_rename_exchange(struct inode *old_dir, + simple_offset_remove(old_ctx, old_dentry); + simple_offset_remove(new_ctx, new_dentry); + +- ret = simple_offset_add(new_ctx, old_dentry); ++ ret = simple_offset_replace(new_ctx, old_dentry, new_index); + if (ret) + goto out_restore; + +- ret = simple_offset_add(old_ctx, new_dentry); ++ ret = simple_offset_replace(old_ctx, new_dentry, old_index); + if (ret) { + simple_offset_remove(new_ctx, old_dentry); + goto out_restore; +@@ -352,10 +408,8 @@ int simple_offset_rename_exchange(struct inode *old_dir, + return 0; + + out_restore: +- offset_set(old_dentry, old_index); +- xa_store(&old_ctx->xa, old_index, old_dentry, GFP_KERNEL); +- offset_set(new_dentry, new_index); +- xa_store(&new_ctx->xa, new_index, new_dentry, GFP_KERNEL); ++ (void)simple_offset_replace(old_ctx, old_dentry, old_index); ++ (void)simple_offset_replace(new_ctx, new_dentry, new_index); + return ret; + } + +@@ -396,57 +450,91 @@ static loff_t offset_dir_llseek(struct file *file, loff_t offset, int whence) + return -EINVAL; + } + +- /* In this case, ->private_data is protected by f_pos_lock */ +- file->private_data = NULL; + return vfs_setpos(file, offset, U32_MAX); + } + +-static struct dentry *offset_find_next(struct xa_state *xas) ++static struct dentry *find_positive_dentry(struct dentry *parent, ++ struct dentry *dentry, ++ bool next) + { ++ struct dentry *found = NULL; ++ ++ spin_lock(&parent->d_lock); ++ if (next) ++ dentry = list_next_entry(dentry, d_child); ++ else if (!dentry) ++ dentry = list_first_entry_or_null(&parent->d_subdirs, ++ struct dentry, d_child); ++ for (; dentry && !list_entry_is_head(dentry, &parent->d_subdirs, d_child); ++ dentry = list_next_entry(dentry, d_child)) { ++ if (!simple_positive(dentry)) ++ continue; ++ spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); ++ if (simple_positive(dentry)) ++ found = dget_dlock(dentry); ++ spin_unlock(&dentry->d_lock); ++ if (likely(found)) ++ break; ++ } ++ spin_unlock(&parent->d_lock); ++ return found; ++} ++ ++static noinline_for_stack struct dentry * ++offset_dir_lookup(struct dentry *parent, loff_t offset) ++{ ++ struct inode *inode = d_inode(parent); ++ struct offset_ctx *octx = inode->i_op->get_offset_ctx(inode); + struct dentry *child, *found = NULL; + +- rcu_read_lock(); +- child = xas_next_entry(xas, U32_MAX); +- if (!child) +- goto out; +- spin_lock(&child->d_lock); +- if (simple_positive(child)) +- found = dget_dlock(child); +- spin_unlock(&child->d_lock); +-out: +- rcu_read_unlock(); ++ XA_STATE(xas, &octx->xa, offset); ++ ++ if (offset == DIR_OFFSET_FIRST) ++ found = find_positive_dentry(parent, NULL, false); ++ else { ++ rcu_read_lock(); ++ child = xas_next_entry(&xas, DIR_OFFSET_MAX); ++ found = find_positive_dentry(parent, child, false); ++ rcu_read_unlock(); ++ } + return found; + } + + static bool offset_dir_emit(struct dir_context *ctx, struct dentry *dentry) + { +- u32 offset = dentry2offset(dentry); + struct inode *inode = d_inode(dentry); + +- return ctx->actor(ctx, dentry->d_name.name, dentry->d_name.len, offset, +- inode->i_ino, fs_umode_to_dtype(inode->i_mode)); ++ return dir_emit(ctx, dentry->d_name.name, dentry->d_name.len, ++ inode->i_ino, fs_umode_to_dtype(inode->i_mode)); + } + +-static void *offset_iterate_dir(struct inode *inode, struct dir_context *ctx) ++static void offset_iterate_dir(struct file *file, struct dir_context *ctx) + { +- struct offset_ctx *so_ctx = inode->i_op->get_offset_ctx(inode); +- XA_STATE(xas, &so_ctx->xa, ctx->pos); ++ struct dentry *dir = file->f_path.dentry; + struct dentry *dentry; + ++ dentry = offset_dir_lookup(dir, ctx->pos); ++ if (!dentry) ++ goto out_eod; + while (true) { +- dentry = offset_find_next(&xas); +- if (!dentry) +- return ERR_PTR(-ENOENT); ++ struct dentry *next; + +- if (!offset_dir_emit(ctx, dentry)) { +- dput(dentry); ++ ctx->pos = dentry2offset(dentry); ++ if (!offset_dir_emit(ctx, dentry)) + break; +- } + ++ next = find_positive_dentry(dir, dentry, true); + dput(dentry); +- ctx->pos = xas.xa_index + 1; ++ ++ if (!next) ++ goto out_eod; ++ dentry = next; + } +- return NULL; ++ dput(dentry); ++ return; ++ ++out_eod: ++ ctx->pos = DIR_OFFSET_EOD; + } + + /** +@@ -466,6 +554,8 @@ static void *offset_iterate_dir(struct inode *inode, struct dir_context *ctx) + * + * On return, @ctx->pos contains an offset that will read the next entry + * in this directory when offset_readdir() is called again with @ctx. ++ * Caller places this value in the d_off field of the last entry in the ++ * user's buffer. + * + * Return values: + * %0 - Complete +@@ -478,13 +568,8 @@ static int offset_readdir(struct file *file, struct dir_context *ctx) + + if (!dir_emit_dots(file, ctx)) + return 0; +- +- /* In this case, ->private_data is protected by f_pos_lock */ +- if (ctx->pos == 2) +- file->private_data = NULL; +- else if (file->private_data == ERR_PTR(-ENOENT)) +- return 0; +- file->private_data = offset_iterate_dir(d_inode(dir), ctx); ++ if (ctx->pos != DIR_OFFSET_EOD) ++ offset_iterate_dir(file, ctx); + return 0; + } + +diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c +index e695df1dbb23b2..9ebd7a5ee23c21 100644 +--- a/fs/smb/client/smb2inode.c ++++ b/fs/smb/client/smb2inode.c +@@ -176,27 +176,27 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + struct kvec *out_iov, int *out_buftype, struct dentry *dentry) + { + +- struct reparse_data_buffer *rbuf; ++ struct smb2_query_info_rsp *qi_rsp = NULL; + struct smb2_compound_vars *vars = NULL; +- struct kvec *rsp_iov, *iov; +- struct smb_rqst *rqst; +- int rc; +- __le16 *utf16_path = NULL; + __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; +- struct cifs_fid fid; ++ struct cifs_open_info_data *idata; + struct cifs_ses *ses = tcon->ses; ++ struct reparse_data_buffer *rbuf; + struct TCP_Server_Info *server; +- int num_rqst = 0, i; + int resp_buftype[MAX_COMPOUND]; +- struct smb2_query_info_rsp *qi_rsp = NULL; +- struct cifs_open_info_data *idata; ++ int retries = 0, cur_sleep = 1; ++ __u8 delete_pending[8] = {1,}; ++ struct kvec *rsp_iov, *iov; + struct inode *inode = NULL; +- int flags = 0; +- __u8 delete_pending[8] = {1, 0, 0, 0, 0, 0, 0, 0}; ++ __le16 *utf16_path = NULL; ++ struct smb_rqst *rqst; + unsigned int size[2]; +- void *data[2]; ++ struct cifs_fid fid; ++ int num_rqst = 0, i; + unsigned int len; +- int retries = 0, cur_sleep = 1; ++ int tmp_rc, rc; ++ int flags = 0; ++ void *data[2]; + + replay_again: + /* reinitialize for possible replay */ +@@ -637,7 +637,14 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + tcon->need_reconnect = true; + } + ++ tmp_rc = rc; + for (i = 0; i < num_cmds; i++) { ++ char *buf = rsp_iov[i + i].iov_base; ++ ++ if (buf && resp_buftype[i + 1] != CIFS_NO_BUFFER) ++ rc = server->ops->map_error(buf, false); ++ else ++ rc = tmp_rc; + switch (cmds[i]) { + case SMB2_OP_QUERY_INFO: + idata = in_iov[i].iov_base; +@@ -803,6 +810,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + } + } + SMB2_close_free(&rqst[num_rqst]); ++ rc = tmp_rc; + + num_cmds += 2; + if (out_iov && out_buftype) { +@@ -858,22 +866,52 @@ static int parse_create_response(struct cifs_open_info_data *data, + return rc; + } + ++/* Check only if SMB2_OP_QUERY_WSL_EA command failed in the compound chain */ ++static bool ea_unsupported(int *cmds, int num_cmds, ++ struct kvec *out_iov, int *out_buftype) ++{ ++ int i; ++ ++ if (cmds[num_cmds - 1] != SMB2_OP_QUERY_WSL_EA) ++ return false; ++ ++ for (i = 1; i < num_cmds - 1; i++) { ++ struct smb2_hdr *hdr = out_iov[i].iov_base; ++ ++ if (out_buftype[i] == CIFS_NO_BUFFER || !hdr || ++ hdr->Status != STATUS_SUCCESS) ++ return false; ++ } ++ return true; ++} ++ ++static inline void free_rsp_iov(struct kvec *iovs, int *buftype, int count) ++{ ++ int i; ++ ++ for (i = 0; i < count; i++) { ++ free_rsp_buf(buftype[i], iovs[i].iov_base); ++ memset(&iovs[i], 0, sizeof(*iovs)); ++ buftype[i] = CIFS_NO_BUFFER; ++ } ++} ++ + int smb2_query_path_info(const unsigned int xid, + struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, + const char *full_path, + struct cifs_open_info_data *data) + { ++ struct kvec in_iov[3], out_iov[5] = {}; ++ struct cached_fid *cfid = NULL; + struct cifs_open_parms oparms; +- __u32 create_options = 0; + struct cifsFileInfo *cfile; +- struct cached_fid *cfid = NULL; ++ __u32 create_options = 0; ++ int out_buftype[5] = {}; + struct smb2_hdr *hdr; +- struct kvec in_iov[3], out_iov[3] = {}; +- int out_buftype[3] = {}; ++ int num_cmds = 0; + int cmds[3]; + bool islink; +- int i, num_cmds = 0; + int rc, rc2; + + data->adjust_tz = false; +@@ -943,14 +981,14 @@ int smb2_query_path_info(const unsigned int xid, + if (rc || !data->reparse_point) + goto out; + +- if (!tcon->posix_extensions) +- cmds[num_cmds++] = SMB2_OP_QUERY_WSL_EA; + /* + * Skip SMB2_OP_GET_REPARSE if symlink already parsed in create + * response. + */ + if (data->reparse.tag != IO_REPARSE_TAG_SYMLINK) + cmds[num_cmds++] = SMB2_OP_GET_REPARSE; ++ if (!tcon->posix_extensions) ++ cmds[num_cmds++] = SMB2_OP_QUERY_WSL_EA; + + oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, + FILE_READ_ATTRIBUTES | +@@ -958,9 +996,18 @@ int smb2_query_path_info(const unsigned int xid, + FILE_OPEN, create_options | + OPEN_REPARSE_POINT, ACL_NO_MODE); + cifs_get_readable_path(tcon, full_path, &cfile); ++ free_rsp_iov(out_iov, out_buftype, ARRAY_SIZE(out_iov)); + rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, + &oparms, in_iov, cmds, num_cmds, +- cfile, NULL, NULL, NULL); ++ cfile, out_iov, out_buftype, NULL); ++ if (rc && ea_unsupported(cmds, num_cmds, ++ out_iov, out_buftype)) { ++ if (data->reparse.tag != IO_REPARSE_TAG_LX_BLK && ++ data->reparse.tag != IO_REPARSE_TAG_LX_CHR) ++ rc = 0; ++ else ++ rc = -EOPNOTSUPP; ++ } + break; + case -EREMOTE: + break; +@@ -978,8 +1025,7 @@ int smb2_query_path_info(const unsigned int xid, + } + + out: +- for (i = 0; i < ARRAY_SIZE(out_buftype); i++) +- free_rsp_buf(out_buftype[i], out_iov[i].iov_base); ++ free_rsp_iov(out_iov, out_buftype, ARRAY_SIZE(out_iov)); + return rc; + } + +diff --git a/include/linux/fs.h b/include/linux/fs.h +index 6c3d86532e3f91..e47596d354ff75 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -3197,6 +3197,8 @@ struct offset_ctx { + void simple_offset_init(struct offset_ctx *octx); + int simple_offset_add(struct offset_ctx *octx, struct dentry *dentry); + void simple_offset_remove(struct offset_ctx *octx, struct dentry *dentry); ++int simple_offset_rename(struct inode *old_dir, struct dentry *old_dentry, ++ struct inode *new_dir, struct dentry *new_dentry); + int simple_offset_rename_exchange(struct inode *old_dir, + struct dentry *old_dentry, + struct inode *new_dir, +diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h +index 175079552f68da..8cf31bb8871988 100644 +--- a/include/linux/seccomp.h ++++ b/include/linux/seccomp.h +@@ -70,10 +70,10 @@ struct seccomp_data; + + #ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER + static inline int secure_computing(void) { return 0; } +-static inline int __secure_computing(const struct seccomp_data *sd) { return 0; } + #else + static inline void secure_computing_strict(int this_syscall) { return; } + #endif ++static inline int __secure_computing(const struct seccomp_data *sd) { return 0; } + + static inline long prctl_get_seccomp(void) + { +diff --git a/mm/filemap.c b/mm/filemap.c +index 6a3d62de1cca7b..056422e6a0be8f 100644 +--- a/mm/filemap.c ++++ b/mm/filemap.c +@@ -4270,6 +4270,20 @@ static void filemap_cachestat(struct address_space *mapping, + rcu_read_unlock(); + } + ++/* ++ * See mincore: reveal pagecache information only for files ++ * that the calling process has write access to, or could (if ++ * tried) open for writing. ++ */ ++static inline bool can_do_cachestat(struct file *f) ++{ ++ if (f->f_mode & FMODE_WRITE) ++ return true; ++ if (inode_owner_or_capable(file_mnt_idmap(f), file_inode(f))) ++ return true; ++ return file_permission(f, MAY_WRITE) == 0; ++} ++ + /* + * The cachestat(2) system call. + * +@@ -4329,6 +4343,11 @@ SYSCALL_DEFINE4(cachestat, unsigned int, fd, + return -EOPNOTSUPP; + } + ++ if (!can_do_cachestat(f.file)) { ++ fdput(f); ++ return -EPERM; ++ } ++ + if (flags != 0) { + fdput(f); + return -EINVAL; +diff --git a/mm/shmem.c b/mm/shmem.c +index db7dd45c918158..283fb62084d454 100644 +--- a/mm/shmem.c ++++ b/mm/shmem.c +@@ -3434,8 +3434,7 @@ static int shmem_rename2(struct mnt_idmap *idmap, + return error; + } + +- simple_offset_remove(shmem_get_offset_ctx(old_dir), old_dentry); +- error = simple_offset_add(shmem_get_offset_ctx(new_dir), old_dentry); ++ error = simple_offset_rename(old_dir, old_dentry, new_dir, new_dentry); + if (error) + return error; + +diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c +index dd1803bf9c5c63..b5d64cd3ab0a23 100644 +--- a/net/ipv4/ip_tunnel.c ++++ b/net/ipv4/ip_tunnel.c +@@ -218,7 +218,7 @@ static struct ip_tunnel *ip_tunnel_find(struct ip_tunnel_net *itn, + struct ip_tunnel *t = NULL; + struct hlist_head *head = ip_bucket(itn, parms); + +- hlist_for_each_entry_rcu(t, head, hash_node) { ++ hlist_for_each_entry_rcu(t, head, hash_node, lockdep_rtnl_is_held()) { + if (local == t->parms.iph.saddr && + remote == t->parms.iph.daddr && + link == READ_ONCE(t->parms.link) && +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index afa9073567dc40..023ac39041a214 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -1179,8 +1179,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt, + while (sibling) { + if (sibling->fib6_metric == rt->fib6_metric && + rt6_qualify_for_ecmp(sibling)) { +- list_add_tail(&rt->fib6_siblings, +- &sibling->fib6_siblings); ++ list_add_tail_rcu(&rt->fib6_siblings, ++ &sibling->fib6_siblings); + break; + } + sibling = rcu_dereference_protected(sibling->fib6_next, +@@ -1241,7 +1241,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt, + fib6_siblings) + sibling->fib6_nsiblings--; + rt->fib6_nsiblings = 0; +- list_del_init(&rt->fib6_siblings); ++ list_del_rcu(&rt->fib6_siblings); + rt6_multipath_rebalance(next_sibling); + return err; + } +@@ -1954,7 +1954,7 @@ static void fib6_del_route(struct fib6_table *table, struct fib6_node *fn, + &rt->fib6_siblings, fib6_siblings) + sibling->fib6_nsiblings--; + rt->fib6_nsiblings = 0; +- list_del_init(&rt->fib6_siblings); ++ list_del_rcu(&rt->fib6_siblings); + rt6_multipath_rebalance(next_sibling); + } + +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index fc5c5346202530..c5cee40a658b46 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -418,8 +418,8 @@ void fib6_select_path(const struct net *net, struct fib6_result *res, + struct flowi6 *fl6, int oif, bool have_oif_match, + const struct sk_buff *skb, int strict) + { +- struct fib6_info *sibling, *next_sibling; + struct fib6_info *match = res->f6i; ++ struct fib6_info *sibling; + + if (!match->nh && (!match->fib6_nsiblings || have_oif_match)) + goto out; +@@ -445,8 +445,8 @@ void fib6_select_path(const struct net *net, struct fib6_result *res, + if (fl6->mp_hash <= atomic_read(&match->fib6_nh->fib_nh_upper_bound)) + goto out; + +- list_for_each_entry_safe(sibling, next_sibling, &match->fib6_siblings, +- fib6_siblings) { ++ list_for_each_entry_rcu(sibling, &match->fib6_siblings, ++ fib6_siblings) { + const struct fib6_nh *nh = sibling->fib6_nh; + int nh_upper_bound; + +@@ -5186,14 +5186,18 @@ static void ip6_route_mpath_notify(struct fib6_info *rt, + * nexthop. Since sibling routes are always added at the end of + * the list, find the first sibling of the last route appended + */ ++ rcu_read_lock(); ++ + if ((nlflags & NLM_F_APPEND) && rt_last && rt_last->fib6_nsiblings) { +- rt = list_first_entry(&rt_last->fib6_siblings, +- struct fib6_info, +- fib6_siblings); ++ rt = list_first_or_null_rcu(&rt_last->fib6_siblings, ++ struct fib6_info, ++ fib6_siblings); + } + + if (rt) + inet6_rt_notify(RTM_NEWROUTE, rt, info, nlflags); ++ ++ rcu_read_unlock(); + } + + static bool ip6_route_mpath_should_notify(const struct fib6_info *rt) +@@ -5538,17 +5542,21 @@ static size_t rt6_nlmsg_size(struct fib6_info *f6i) + nexthop_for_each_fib6_nh(f6i->nh, rt6_nh_nlmsg_size, + &nexthop_len); + } else { +- struct fib6_info *sibling, *next_sibling; + struct fib6_nh *nh = f6i->fib6_nh; ++ struct fib6_info *sibling; + + nexthop_len = 0; + if (f6i->fib6_nsiblings) { + rt6_nh_nlmsg_size(nh, &nexthop_len); + +- list_for_each_entry_safe(sibling, next_sibling, +- &f6i->fib6_siblings, fib6_siblings) { ++ rcu_read_lock(); ++ ++ list_for_each_entry_rcu(sibling, &f6i->fib6_siblings, ++ fib6_siblings) { + rt6_nh_nlmsg_size(sibling->fib6_nh, &nexthop_len); + } ++ ++ rcu_read_unlock(); + } + nexthop_len += lwtunnel_get_encap_size(nh->fib_nh_lws); + } +@@ -5712,7 +5720,7 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb, + lwtunnel_fill_encap(skb, dst->lwtstate, RTA_ENCAP, RTA_ENCAP_TYPE) < 0) + goto nla_put_failure; + } else if (rt->fib6_nsiblings) { +- struct fib6_info *sibling, *next_sibling; ++ struct fib6_info *sibling; + struct nlattr *mp; + + mp = nla_nest_start_noflag(skb, RTA_MULTIPATH); +@@ -5724,14 +5732,21 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb, + 0) < 0) + goto nla_put_failure; + +- list_for_each_entry_safe(sibling, next_sibling, +- &rt->fib6_siblings, fib6_siblings) { ++ rcu_read_lock(); ++ ++ list_for_each_entry_rcu(sibling, &rt->fib6_siblings, ++ fib6_siblings) { + if (fib_add_nexthop(skb, &sibling->fib6_nh->nh_common, + sibling->fib6_nh->fib_nh_weight, +- AF_INET6, 0) < 0) ++ AF_INET6, 0) < 0) { ++ rcu_read_unlock(); ++ + goto nla_put_failure; ++ } + } + ++ rcu_read_unlock(); ++ + nla_nest_end(skb, mp); + } else if (rt->nh) { + if (nla_put_u32(skb, RTA_NH_ID, rt->nh->id)) +@@ -6168,7 +6183,7 @@ void inet6_rt_notify(int event, struct fib6_info *rt, struct nl_info *info, + err = -ENOBUFS; + seq = info->nlh ? info->nlh->nlmsg_seq : 0; + +- skb = nlmsg_new(rt6_nlmsg_size(rt), gfp_any()); ++ skb = nlmsg_new(rt6_nlmsg_size(rt), GFP_ATOMIC); + if (!skb) + goto errout; + +@@ -6181,7 +6196,7 @@ void inet6_rt_notify(int event, struct fib6_info *rt, struct nl_info *info, + goto errout; + } + rtnl_notify(skb, net, info->portid, RTNLGRP_IPV6_ROUTE, +- info->nlh, gfp_any()); ++ info->nlh, GFP_ATOMIC); + return; + errout: + if (err < 0) +diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c +index b10efeaf0629d2..9fd70462b41d5a 100644 +--- a/net/sched/sch_ets.c ++++ b/net/sched/sch_ets.c +@@ -91,6 +91,8 @@ ets_class_from_arg(struct Qdisc *sch, unsigned long arg) + { + struct ets_sched *q = qdisc_priv(sch); + ++ if (arg == 0 || arg > q->nbands) ++ return NULL; + return &q->classes[arg - 1]; + } + +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index f1e1dbc509f6e4..6d105a23c8284c 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -2209,6 +2209,7 @@ config SND_SOC_WM8993 + + config SND_SOC_WM8994 + tristate ++ depends on MFD_WM8994 + + config SND_SOC_WM8995 + tristate +diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig +index 93c2b1b08d0a6f..e8716501685bce 100644 +--- a/sound/soc/samsung/Kconfig ++++ b/sound/soc/samsung/Kconfig +@@ -127,8 +127,9 @@ config SND_SOC_SAMSUNG_TM2_WM5110 + + config SND_SOC_SAMSUNG_ARIES_WM8994 + tristate "SoC I2S Audio support for WM8994 on Aries" +- depends on SND_SOC_SAMSUNG && MFD_WM8994 && IIO && EXTCON ++ depends on SND_SOC_SAMSUNG && I2C && IIO && EXTCON + select SND_SOC_BT_SCO ++ select MFD_WM8994 + select SND_SOC_WM8994 + select SND_SAMSUNG_I2S + help +@@ -140,8 +141,9 @@ config SND_SOC_SAMSUNG_ARIES_WM8994 + + config SND_SOC_SAMSUNG_MIDAS_WM1811 + tristate "SoC I2S Audio support for Midas boards" +- depends on SND_SOC_SAMSUNG ++ depends on SND_SOC_SAMSUNG && I2C + select SND_SAMSUNG_I2S ++ select MFD_WM8994 + select SND_SOC_WM8994 + help + Say Y if you want to add support for SoC audio on the Midas boards. +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index ec81b47c41c9ea..9cdd6cfd8219a7 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -2139,6 +2139,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_CTL_MSG_DELAY_1M), + DEVICE_FLG(0x0c45, 0x6340, /* Sonix HD USB Camera */ + QUIRK_FLAG_GET_SAMPLE_RATE), ++ DEVICE_FLG(0x0d8c, 0x0014, /* USB Audio Device */ ++ QUIRK_FLAG_CTL_MSG_DELAY_1M), + DEVICE_FLG(0x0ecb, 0x205c, /* JBL Quantum610 Wireless */ + QUIRK_FLAG_FIXED_RATE), + DEVICE_FLG(0x0ecb, 0x2069, /* JBL Quantum810 Wireless */ +diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile +index 91a48efb140bef..efaf0e0bc4592b 100644 +--- a/tools/testing/selftests/net/Makefile ++++ b/tools/testing/selftests/net/Makefile +@@ -91,6 +91,7 @@ TEST_PROGS += test_vxlan_mdb.sh + TEST_PROGS += test_bridge_neigh_suppress.sh + TEST_PROGS += test_vxlan_nolocalbypass.sh + TEST_PROGS += test_bridge_backup_port.sh ++TEST_PROGS += ipv6_route_update_soft_lockup.sh + + TEST_FILES := settings + TEST_FILES += in_netns.sh lib.sh net_helper.sh setup_loopback.sh setup_veth.sh +diff --git a/tools/testing/selftests/net/ipv6_route_update_soft_lockup.sh b/tools/testing/selftests/net/ipv6_route_update_soft_lockup.sh +new file mode 100644 +index 00000000000000..a6b2b1f9c641c9 +--- /dev/null ++++ b/tools/testing/selftests/net/ipv6_route_update_soft_lockup.sh +@@ -0,0 +1,262 @@ ++#!/bin/bash ++# SPDX-License-Identifier: GPL-2.0 ++# ++# Testing for potential kernel soft lockup during IPv6 routing table ++# refresh under heavy outgoing IPv6 traffic. If a kernel soft lockup ++# occurs, a kernel panic will be triggered to prevent associated issues. ++# ++# ++# Test Environment Layout ++# ++# ┌----------------┐ ┌----------------┐ ++# | SOURCE_NS | | SINK_NS | ++# | NAMESPACE | | NAMESPACE | ++# |(iperf3 clients)| |(iperf3 servers)| ++# | | | | ++# | | | | ++# | ┌-----------| nexthops |---------┐ | ++# | |veth_source|<--------------------------------------->|veth_sink|<┐ | ++# | └-----------|2001:0DB8:1::0:1/96 2001:0DB8:1::1:1/96 |---------┘ | | ++# | | ^ 2001:0DB8:1::1:2/96 | | | ++# | | . . | fwd | | ++# | ┌---------┐ | . . | | | ++# | | IPv6 | | . . | V | ++# | | routing | | . 2001:0DB8:1::1:80/96| ┌-----┐ | ++# | | table | | . | | lo | | ++# | | nexthop | | . └--------┴-----┴-┘ ++# | | update | | ............................> 2001:0DB8:2::1:1/128 ++# | └-------- ┘ | ++# └----------------┘ ++# ++# The test script sets up two network namespaces, source_ns and sink_ns, ++# connected via a veth link. Within source_ns, it continuously updates the ++# IPv6 routing table by flushing and inserting IPV6_NEXTHOP_ADDR_COUNT nexthop ++# IPs destined for SINK_LOOPBACK_IP_ADDR in sink_ns. This refresh occurs at a ++# rate of 1/ROUTING_TABLE_REFRESH_PERIOD per second for TEST_DURATION seconds. ++# ++# Simultaneously, multiple iperf3 clients within source_ns generate heavy ++# outgoing IPv6 traffic. Each client is assigned a unique port number starting ++# at 5000 and incrementing sequentially. Each client targets a unique iperf3 ++# server running in sink_ns, connected to the SINK_LOOPBACK_IFACE interface ++# using the same port number. ++# ++# The number of iperf3 servers and clients is set to half of the total ++# available cores on each machine. ++# ++# NOTE: We have tested this script on machines with various CPU specifications, ++# ranging from lower to higher performance as listed below. The test script ++# effectively triggered a kernel soft lockup on machines running an unpatched ++# kernel in under a minute: ++# ++# - 1x Intel Xeon E-2278G 8-Core Processor @ 3.40GHz ++# - 1x Intel Xeon E-2378G Processor 8-Core @ 2.80GHz ++# - 1x AMD EPYC 7401P 24-Core Processor @ 2.00GHz ++# - 1x AMD EPYC 7402P 24-Core Processor @ 2.80GHz ++# - 2x Intel Xeon Gold 5120 14-Core Processor @ 2.20GHz ++# - 1x Ampere Altra Q80-30 80-Core Processor @ 3.00GHz ++# - 2x Intel Xeon Gold 5120 14-Core Processor @ 2.20GHz ++# - 2x Intel Xeon Silver 4214 24-Core Processor @ 2.20GHz ++# - 1x AMD EPYC 7502P 32-Core @ 2.50GHz ++# - 1x Intel Xeon Gold 6314U 32-Core Processor @ 2.30GHz ++# - 2x Intel Xeon Gold 6338 32-Core Processor @ 2.00GHz ++# ++# On less performant machines, you may need to increase the TEST_DURATION ++# parameter to enhance the likelihood of encountering a race condition leading ++# to a kernel soft lockup and avoid a false negative result. ++# ++# NOTE: The test may not produce the expected result in virtualized ++# environments (e.g., qemu) due to differences in timing and CPU handling, ++# which can affect the conditions needed to trigger a soft lockup. ++ ++source lib.sh ++source net_helper.sh ++ ++TEST_DURATION=300 ++ROUTING_TABLE_REFRESH_PERIOD=0.01 ++ ++IPERF3_BITRATE="300m" ++ ++ ++IPV6_NEXTHOP_ADDR_COUNT="128" ++IPV6_NEXTHOP_ADDR_MASK="96" ++IPV6_NEXTHOP_PREFIX="2001:0DB8:1" ++ ++ ++SOURCE_TEST_IFACE="veth_source" ++SOURCE_TEST_IP_ADDR="2001:0DB8:1::0:1/96" ++ ++SINK_TEST_IFACE="veth_sink" ++# ${SINK_TEST_IFACE} is populated with the following range of IPv6 addresses: ++# 2001:0DB8:1::1:1 to 2001:0DB8:1::1:${IPV6_NEXTHOP_ADDR_COUNT} ++SINK_LOOPBACK_IFACE="lo" ++SINK_LOOPBACK_IP_MASK="128" ++SINK_LOOPBACK_IP_ADDR="2001:0DB8:2::1:1" ++ ++nexthop_ip_list="" ++termination_signal="" ++kernel_softlokup_panic_prev_val="" ++ ++terminate_ns_processes_by_pattern() { ++ local ns=$1 ++ local pattern=$2 ++ ++ for pid in $(ip netns pids ${ns}); do ++ [ -e /proc/$pid/cmdline ] && grep -qe "${pattern}" /proc/$pid/cmdline && kill -9 $pid ++ done ++} ++ ++cleanup() { ++ echo "info: cleaning up namespaces and terminating all processes within them..." ++ ++ ++ # Terminate iperf3 instances running in the source_ns. To avoid race ++ # conditions, first iterate over the PIDs and terminate those ++ # associated with the bash shells running the ++ # `while true; do iperf3 -c ...; done` loops. In a second iteration, ++ # terminate the individual `iperf3 -c ...` instances. ++ terminate_ns_processes_by_pattern ${source_ns} while ++ terminate_ns_processes_by_pattern ${source_ns} iperf3 ++ ++ # Repeat the same process for sink_ns ++ terminate_ns_processes_by_pattern ${sink_ns} while ++ terminate_ns_processes_by_pattern ${sink_ns} iperf3 ++ ++ # Check if any iperf3 instances are still running. This could happen ++ # if a core has entered an infinite loop and the timeout for detecting ++ # the soft lockup has not expired, but either the test interval has ++ # already elapsed or the test was terminated manually (e.g., with ^C) ++ for pid in $(ip netns pids ${source_ns}); do ++ if [ -e /proc/$pid/cmdline ] && grep -qe 'iperf3' /proc/$pid/cmdline; then ++ echo "FAIL: unable to terminate some iperf3 instances. Soft lockup is underway. A kernel panic is on the way!" ++ exit ${ksft_fail} ++ fi ++ done ++ ++ if [ "$termination_signal" == "SIGINT" ]; then ++ echo "SKIP: Termination due to ^C (SIGINT)" ++ elif [ "$termination_signal" == "SIGALRM" ]; then ++ echo "PASS: No kernel soft lockup occurred during this ${TEST_DURATION} second test" ++ fi ++ ++ cleanup_ns ${source_ns} ${sink_ns} ++ ++ sysctl -qw kernel.softlockup_panic=${kernel_softlokup_panic_prev_val} ++} ++ ++setup_prepare() { ++ setup_ns source_ns sink_ns ++ ++ ip -n ${source_ns} link add name ${SOURCE_TEST_IFACE} type veth peer name ${SINK_TEST_IFACE} netns ${sink_ns} ++ ++ # Setting up the Source namespace ++ ip -n ${source_ns} addr add ${SOURCE_TEST_IP_ADDR} dev ${SOURCE_TEST_IFACE} ++ ip -n ${source_ns} link set dev ${SOURCE_TEST_IFACE} qlen 10000 ++ ip -n ${source_ns} link set dev ${SOURCE_TEST_IFACE} up ++ ip netns exec ${source_ns} sysctl -qw net.ipv6.fib_multipath_hash_policy=1 ++ ++ # Setting up the Sink namespace ++ ip -n ${sink_ns} addr add ${SINK_LOOPBACK_IP_ADDR}/${SINK_LOOPBACK_IP_MASK} dev ${SINK_LOOPBACK_IFACE} ++ ip -n ${sink_ns} link set dev ${SINK_LOOPBACK_IFACE} up ++ ip netns exec ${sink_ns} sysctl -qw net.ipv6.conf.${SINK_LOOPBACK_IFACE}.forwarding=1 ++ ++ ip -n ${sink_ns} link set ${SINK_TEST_IFACE} up ++ ip netns exec ${sink_ns} sysctl -qw net.ipv6.conf.${SINK_TEST_IFACE}.forwarding=1 ++ ++ ++ # Populate nexthop IPv6 addresses on the test interface in the sink_ns ++ echo "info: populating ${IPV6_NEXTHOP_ADDR_COUNT} IPv6 addresses on the ${SINK_TEST_IFACE} interface ..." ++ for IP in $(seq 1 ${IPV6_NEXTHOP_ADDR_COUNT}); do ++ ip -n ${sink_ns} addr add ${IPV6_NEXTHOP_PREFIX}::$(printf "1:%x" "${IP}")/${IPV6_NEXTHOP_ADDR_MASK} dev ${SINK_TEST_IFACE}; ++ done ++ ++ # Preparing list of nexthops ++ for IP in $(seq 1 ${IPV6_NEXTHOP_ADDR_COUNT}); do ++ nexthop_ip_list=$nexthop_ip_list" nexthop via ${IPV6_NEXTHOP_PREFIX}::$(printf "1:%x" $IP) dev ${SOURCE_TEST_IFACE} weight 1" ++ done ++} ++ ++ ++test_soft_lockup_during_routing_table_refresh() { ++ # Start num_of_iperf_servers iperf3 servers in the sink_ns namespace, ++ # each listening on ports starting at 5001 and incrementing ++ # sequentially. Since iperf3 instances may terminate unexpectedly, a ++ # while loop is used to automatically restart them in such cases. ++ echo "info: starting ${num_of_iperf_servers} iperf3 servers in the sink_ns namespace ..." ++ for i in $(seq 1 ${num_of_iperf_servers}); do ++ cmd="iperf3 --bind ${SINK_LOOPBACK_IP_ADDR} -s -p $(printf '5%03d' ${i}) --rcv-timeout 200 &>/dev/null" ++ ip netns exec ${sink_ns} bash -c "while true; do ${cmd}; done &" &>/dev/null ++ done ++ ++ # Wait for the iperf3 servers to be ready ++ for i in $(seq ${num_of_iperf_servers}); do ++ port=$(printf '5%03d' ${i}); ++ wait_local_port_listen ${sink_ns} ${port} tcp ++ done ++ ++ # Continuously refresh the routing table in the background within ++ # the source_ns namespace ++ ip netns exec ${source_ns} bash -c " ++ while \$(ip netns list | grep -q ${source_ns}); do ++ ip -6 route add ${SINK_LOOPBACK_IP_ADDR}/${SINK_LOOPBACK_IP_MASK} ${nexthop_ip_list}; ++ sleep ${ROUTING_TABLE_REFRESH_PERIOD}; ++ ip -6 route delete ${SINK_LOOPBACK_IP_ADDR}/${SINK_LOOPBACK_IP_MASK}; ++ done &" ++ ++ # Start num_of_iperf_servers iperf3 clients in the source_ns namespace, ++ # each sending TCP traffic on sequential ports starting at 5001. ++ # Since iperf3 instances may terminate unexpectedly (e.g., if the route ++ # to the server is deleted in the background during a route refresh), a ++ # while loop is used to automatically restart them in such cases. ++ echo "info: starting ${num_of_iperf_servers} iperf3 clients in the source_ns namespace ..." ++ for i in $(seq 1 ${num_of_iperf_servers}); do ++ cmd="iperf3 -c ${SINK_LOOPBACK_IP_ADDR} -p $(printf '5%03d' ${i}) --length 64 --bitrate ${IPERF3_BITRATE} -t 0 --connect-timeout 150 &>/dev/null" ++ ip netns exec ${source_ns} bash -c "while true; do ${cmd}; done &" &>/dev/null ++ done ++ ++ echo "info: IPv6 routing table is being updated at the rate of $(echo "1/${ROUTING_TABLE_REFRESH_PERIOD}" | bc)/s for ${TEST_DURATION} seconds ..." ++ echo "info: A kernel soft lockup, if detected, results in a kernel panic!" ++ ++ wait ++} ++ ++# Make sure 'iperf3' is installed, skip the test otherwise ++if [ ! -x "$(command -v "iperf3")" ]; then ++ echo "SKIP: 'iperf3' is not installed. Skipping the test." ++ exit ${ksft_skip} ++fi ++ ++# Determine the number of cores on the machine ++num_of_iperf_servers=$(( $(nproc)/2 )) ++ ++# Check if we are running on a multi-core machine, skip the test otherwise ++if [ "${num_of_iperf_servers}" -eq 0 ]; then ++ echo "SKIP: This test is not valid on a single core machine!" ++ exit ${ksft_skip} ++fi ++ ++# Since the kernel soft lockup we're testing causes at least one core to enter ++# an infinite loop, destabilizing the host and likely affecting subsequent ++# tests, we trigger a kernel panic instead of reporting a failure and ++# continuing ++kernel_softlokup_panic_prev_val=$(sysctl -n kernel.softlockup_panic) ++sysctl -qw kernel.softlockup_panic=1 ++ ++handle_sigint() { ++ termination_signal="SIGINT" ++ cleanup ++ exit ${ksft_skip} ++} ++ ++handle_sigalrm() { ++ termination_signal="SIGALRM" ++ cleanup ++ exit ${ksft_pass} ++} ++ ++trap handle_sigint SIGINT ++trap handle_sigalrm SIGALRM ++ ++(sleep ${TEST_DURATION} && kill -s SIGALRM $$)& ++ ++setup_prepare ++test_soft_lockup_during_routing_table_refresh From 2bf71e2fda9de36ad00dba8fd50bb02c60b778fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20W=C3=B3jt?= Date: Thu, 31 Oct 2024 14:55:39 +0100 Subject: [PATCH 04/33] Add MXQ target. Copy HDMI fix from odroid-c1. --- config/boards/aml-s805-mxq.tvb | 18 ++++ config/bootscripts/boot-aml-s805-mxq.cmd | 30 ++++++ .../0067-meson8b-mxq-add-HDMI-support.patch | 92 +++++++++++++++++++ 3 files changed, 140 insertions(+) create mode 100644 config/boards/aml-s805-mxq.tvb create mode 100644 config/bootscripts/boot-aml-s805-mxq.cmd create mode 100644 patch/kernel/archive/meson-6.10/0067-meson8b-mxq-add-HDMI-support.patch diff --git a/config/boards/aml-s805-mxq.tvb b/config/boards/aml-s805-mxq.tvb new file mode 100644 index 000000000000..6a1557968be0 --- /dev/null +++ b/config/boards/aml-s805-mxq.tvb @@ -0,0 +1,18 @@ +# MXQ TV box based on Amlogic S805 quad core 1GB RAM SoC GBE +BOARD_NAME="MXQ" +BOARDFAMILY="meson8b" +BOARD_MAINTAINER="" +KERNEL_TARGET="current,edge" +KERNEL_TEST_TARGET="current" +BOOTCONFIG="none" +BOOTSCRIPT="boot-aml-s805-mxq.cmd:boot.cmd" +# The preinstalled U-BOOT looks for this script +BOOTSCRIPT_OUTPUT="s805_autoscript" + +BOOTSIZE="200" +BOOTFS_TYPE="fat" +BOOT_LOGO=desktop + +family_tweaks() { + cp $SRC/packages/blobs/splash/armbian-u-boot-24.bmp $SDCARD/boot/boot.bmp +} diff --git a/config/bootscripts/boot-aml-s805-mxq.cmd b/config/bootscripts/boot-aml-s805-mxq.cmd new file mode 100644 index 000000000000..da48b5d5f318 --- /dev/null +++ b/config/bootscripts/boot-aml-s805-mxq.cmd @@ -0,0 +1,30 @@ +# TODO: extract dtb file name to config script +# TODO: support for boot from usb + +setenv rootdev "LABEL=armbi_root" +setenv rootfstype "ext4" + +# Default Console Device Setting +setenv console "both" +setenv verbosity "1" + +# Enable/Disable USB autosuspend (seems broken on current (6.x) kernels) +# 0 = disabled +# 1 = enabled +setenv usb_autosuspend "0" + +########################################### +if test "${console}" = "display" || test "${console}" = "both"; then setenv consoleargs "console=tty1"; fi +if test "${console}" = "serial" || test "${console}" = "both"; then setenv consoleargs "console=ttyAML0,115200n8 ${consoleargs}"; fi +setenv consoleargs "${consoleargs} no_console_suspend consoleblank=0" +if test "${usb_autosuspend}" = "0"; then setenv extraargs "usbcore.autosuspend=-1"; fi + +# Boot Arguments +setenv bootargs "root=${rootdev} rootwait rw ${consoleargs} rootfstype=${rootfstype} loglevel=${verbosity} ${extraargs}" + +# Booting +fatload mmc 0:1 0x20800000 uImage +fatload mmc 0:1 0x22000000 uInitrd +fatload mmc 0:1 0x21800000 dtb/meson8b-mxq.dtb + +bootm 0x20800000 0x22000000 0x21800000 diff --git a/patch/kernel/archive/meson-6.10/0067-meson8b-mxq-add-HDMI-support.patch b/patch/kernel/archive/meson-6.10/0067-meson8b-mxq-add-HDMI-support.patch new file mode 100644 index 000000000000..eeda43e6ddd1 --- /dev/null +++ b/patch/kernel/archive/meson-6.10/0067-meson8b-mxq-add-HDMI-support.patch @@ -0,0 +1,92 @@ +From 0a16d190127f66d1955482d7f896f2f8fc637218 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dominik=20W=C3=B3jt?= +Date: Tue, 29 Oct 2024 19:31:00 +0100 +Subject: meson8b-mxq: add HDMI support + +Copied from 0066-ARM-dts-meson8b-odroid-c1-enable-HDMI-for-the-Odroid.patch + +--- + arch/arm/boot/dts/amlogic/meson8b-mxq.dts | 60 +++++++++++++++++++++++ + 1 file changed, 60 insertions(+) + +diff --git a/arch/arm/boot/dts/amlogic/meson8b-mxq.dts b/arch/arm/boot/dts/amlogic/meson8b-mxq.dts +index 7adedd3258c3..43e9ea14da2f 100644 +--- a/arch/arm/boot/dts/amlogic/meson8b-mxq.dts ++++ b/arch/arm/boot/dts/amlogic/meson8b-mxq.dts +@@ -27,6 +27,50 @@ memory { + reg = <0x40000000 0x40000000>; + }; + ++ hdmi-connector { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_connector_in: endpoint { ++ remote-endpoint = <&hdmi_tx_tmds_out>; ++ }; ++ }; ++ }; ++ ++ ++ sound { ++ compatible = "amlogic,gx-sound-card"; ++ model = "ODROID-C1"; ++ ++ assigned-clocks = <&clkc CLKID_MPLL0>, ++ <&clkc CLKID_MPLL1>; ++ assigned-clock-rates = <294912000>, ++ <270950400>; ++ ++ dai-link-0 { ++ sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>; ++ }; ++ ++ dai-link-1 { ++ sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>; ++ dai-format = "i2s"; ++ mclk-fs = <256>; ++ ++ codec-0 { ++ sound-dai = <&aiu AIU_HDMI CTRL_I2S>; ++ }; ++ }; ++ ++ dai-link-2 { ++ sound-dai = <&aiu AIU_HDMI CTRL_OUT>; ++ ++ codec-0 { ++ sound-dai = <&hdmi_tx 0>; ++ }; ++ }; ++ }; ++ + vcck: regulator-vcck { + compatible = "pwm-regulator"; + +@@ -91,6 +135,22 @@ vddee: regulator-vddee { + }; + }; + ++&aiu { ++ status = "okay"; ++}; ++ ++&hdmi_tx { ++ status = "okay"; ++ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; ++ pinctrl-names = "default"; ++}; ++ ++&hdmi_tx_tmds_port { ++ hdmi_tx_tmds_out: endpoint { ++ remote-endpoint = <&hdmi_connector_in>; ++ }; ++}; ++ + &cpu0 { + cpu-supply = <&vcck>; + }; +-- +2.39.5 + From a6fc0ab3280e27432258ca7f8f8300edb742b396 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20W=C3=B3jt?= Date: Mon, 11 Nov 2024 16:30:30 +0100 Subject: [PATCH 05/33] meson8, MXQ: add boot from usb support, configurable dtb --- config/boards/aml-s805-mxq.tvb | 1 + config/bootenv/aml-s805-mxq.txt | 3 +++ config/bootscripts/boot-aml-s805-mxq.cmd | 25 +++++++++++++++++++----- 3 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 config/bootenv/aml-s805-mxq.txt diff --git a/config/boards/aml-s805-mxq.tvb b/config/boards/aml-s805-mxq.tvb index 6a1557968be0..5ff0ed54cd1c 100644 --- a/config/boards/aml-s805-mxq.tvb +++ b/config/boards/aml-s805-mxq.tvb @@ -8,6 +8,7 @@ BOOTCONFIG="none" BOOTSCRIPT="boot-aml-s805-mxq.cmd:boot.cmd" # The preinstalled U-BOOT looks for this script BOOTSCRIPT_OUTPUT="s805_autoscript" +BOOTENV_FILE="aml-s805-mxq.txt" BOOTSIZE="200" BOOTFS_TYPE="fat" diff --git a/config/bootenv/aml-s805-mxq.txt b/config/bootenv/aml-s805-mxq.txt new file mode 100644 index 000000000000..b7edee36c491 --- /dev/null +++ b/config/bootenv/aml-s805-mxq.txt @@ -0,0 +1,3 @@ +dtb_file=/dtb/meson8b-mxq.dtb + +# The following contents are auto-generated. diff --git a/config/bootscripts/boot-aml-s805-mxq.cmd b/config/bootscripts/boot-aml-s805-mxq.cmd index da48b5d5f318..2ad46d2e4321 100644 --- a/config/bootscripts/boot-aml-s805-mxq.cmd +++ b/config/bootscripts/boot-aml-s805-mxq.cmd @@ -1,5 +1,7 @@ -# TODO: extract dtb file name to config script -# TODO: support for boot from usb +# DO NOT EDIT THIS FILE +# +# Please edit /boot/armbianEnv.txt to set supported parameters +# setenv rootdev "LABEL=armbi_root" setenv rootfstype "ext4" @@ -13,6 +15,19 @@ setenv verbosity "1" # 1 = enabled setenv usb_autosuspend "0" +# Find the bootdev +# Same order is followed as in factory U-BOOT, when searching for this script, +# so same device should be found. +# We can't use `test -z` due to the bug: https://lists.denx.de/pipermail/u-boot/2005-August/011447.html +env set bootdev "" +if test -n "${bootdev}"; test $? != 0; then if fatload usb 0 11000000 s805_autoscript; then env set bootdev "usb 0"; fi; fi; +if test -n "${bootdev}"; test $? != 0; then if fatload usb 1 11000000 s805_autoscript; then env set bootdev "usb 1"; fi; fi; +if test -n "${bootdev}"; test $? != 0; then if fatload usb 2 11000000 s805_autoscript; then env set bootdev "usb 2"; fi; fi; +if test -n "${bootdev}"; test $? != 0; then if fatload usb 3 11000000 s805_autoscript; then env set bootdev "usb 3"; fi; fi; +if test -n "${bootdev}"; test $? != 0; then if fatload mmc 0 11000000 s805_autoscript; then env set bootdev "mmc 0"; fi; fi; + +fatload ${bootdev} 0x20800000 /armbianEnv.txt && env import -t 0x20800000 ${filesize} + ########################################### if test "${console}" = "display" || test "${console}" = "both"; then setenv consoleargs "console=tty1"; fi if test "${console}" = "serial" || test "${console}" = "both"; then setenv consoleargs "console=ttyAML0,115200n8 ${consoleargs}"; fi @@ -23,8 +38,8 @@ if test "${usb_autosuspend}" = "0"; then setenv extraargs "usbcore.autosuspend=- setenv bootargs "root=${rootdev} rootwait rw ${consoleargs} rootfstype=${rootfstype} loglevel=${verbosity} ${extraargs}" # Booting -fatload mmc 0:1 0x20800000 uImage -fatload mmc 0:1 0x22000000 uInitrd -fatload mmc 0:1 0x21800000 dtb/meson8b-mxq.dtb +fatload "${bootdev}" 0x20800000 /uImage +fatload "${bootdev}" 0x22000000 /uInitrd +fatload "${bootdev}" 0x21800000 "${dtb_file}" bootm 0x20800000 0x22000000 0x21800000 From 880c8a9a224ad104935d28b4672820b0654015f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20W=C3=B3jt?= Date: Tue, 4 Feb 2025 16:01:00 +0100 Subject: [PATCH 06/33] MXQ: remove boot logo Built-in U-BOOT is used, so the logo will not be displayed anyway. --- config/boards/aml-s805-mxq.tvb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/config/boards/aml-s805-mxq.tvb b/config/boards/aml-s805-mxq.tvb index 5ff0ed54cd1c..54b9244fa3bb 100644 --- a/config/boards/aml-s805-mxq.tvb +++ b/config/boards/aml-s805-mxq.tvb @@ -12,8 +12,3 @@ BOOTENV_FILE="aml-s805-mxq.txt" BOOTSIZE="200" BOOTFS_TYPE="fat" -BOOT_LOGO=desktop - -family_tweaks() { - cp $SRC/packages/blobs/splash/armbian-u-boot-24.bmp $SDCARD/boot/boot.bmp -} From 5b29f4dd4b673cf9ec97e649cf376a69299dcde0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20W=C3=B3jt?= Date: Sat, 8 Feb 2025 23:08:34 +0100 Subject: [PATCH 07/33] meson: kernel update: legacy -> 6.6, current -> 6.12 (#7801) * Add MXQ target. Copy HDMI fix from odroid-c1. * meson8, MXQ: add boot from usb support, configurable dtb * MXQ: remove boot logo Built-in U-BOOT is used, so the logo will not be displayed anyway. * meson: kernel update: legacy -> 6.6, current -> 6.12 * Change Odroid C1 and Onecloud to community supported as build now passes --------- Co-authored-by: Igor Pecovnik --- config/boards/aml-s805-mxq.tvb | 2 +- config/boards/{odroidc1.eos => odroidc1.csc} | 2 +- config/boards/{onecloud.eos => onecloud.csc} | 2 +- config/kernel/linux-meson-current.config | 70 +- ...-edge.config => linux-meson-legacy.config} | 70 +- .../sources/families/include/meson_common.inc | 8 +- ...eneric-0001-m8-m8b-m8m2-Support-HDMI.patch | 4406 ----------------- ...m2-drm-forcefully-enable-XRGB-format.patch | 22 - ...-clock-speed-before-sending-HS-CMD13.patch | 74 - ...-modify-and-simplify-calculation-in-.patch | 35 - .../meson-6.1/odroidc1-dts-Enable-HDMI.patch | 107 - .../meson-6.1/onecloud-0001-add-dts.patch | 443 -- ...meson8b-usb2-Add-support-for-reading.patch | 0 ...n8b-usb2-Add-support-for-reading-the.patch | 0 ...onn-gpio-Fall-back-to-polling-the-GP.patch | 0 ...register-child-USB-connector-devices.patch | 2 +- ...d-GPIO-controller-capabilities-to-th.patch | 0 ...odroidc1-Enable-the-Micro-USB-OTG-co.patch | 0 ...Add-bindings-for-the-Amlogic-Meson-C.patch | 0 ...a-new-driver-for-the-CVBS-DAC-CVBS-P.patch | 0 ...lay-meson-vpu-Add-the-CVBS-DAC-prope.patch | 0 ...pport-for-using-a-PHY-for-the-CVBS-D.patch | 2 +- ...k-meson8b-Add-the-RMII-reference-clo.patch | 0 ...k-meson8b-Add-the-Meson8-Ethernet-RM.patch | 0 ...b-Add-the-Ethernet-RMII-clock-tree-o.patch | 0 ...dwmac-meson-Add-the-Ethernet-clock-i.patch | 0 ...mac-meson-Rename-the-SPEED_100-macro.patch | 0 ...wmac-meson-Manage-the-ethernet-clock.patch | 0 ...-meson-Initialize-all-known-PREG_ETH.patch | 0 ...son8-Add-the-clock-input-to-the-Ethe.patch | 0 ...k-meson8b-add-the-rtc_32k-oscillator.patch | 0 ...son8b-Add-the-mpeg_rtc_osc_sel-clock.patch | 0 ...d-address-cells-size-cells-and-range.patch | 0 ...ware-Document-the-Amlogic-Meson6-8-8.patch | 0 ...cpus-Document-Meson8-TrustZone-firmw.patch | 2 +- ...d-support-for-the-TrustZone-firmware.patch | 0 ...p-Add-support-for-SoCs-running-on-Tr.patch | 0 ...n-mx-socinfo-Add-support-for-the-Tru.patch | 0 ...fuse-Add-support-for-the-TrustZone-f.patch | 0 ...on8-Add-the-PWM_C-DV9-and-PWM_D-pins.patch | 0 ...lay-meson-vpu-add-support-for-Meson8.patch | 0 ...son8-Meson8b-Meson8m2-specific-vpu_c.patch | 0 ...-bits-per-pixel-for-the-framebuffer-.patch | 0 ...separate-list-of-supported-formats-f.patch | 0 ...IU_OSD1_CTRL_STAT2-alpha-replace-val.patch | 0 ...-the-RGB-to-YUV-converter-on-Meson8-.patch | 0 ...-meson_vpu_init-to-work-with-Meson8-.patch | 0 ...be-the-HDMI-PHY-frequency-limits-of-.patch | 0 ...e-the-HDMI-encoder-for-Meson8-8b-8m2.patch | 0 ...set-ycbcr_420_allowed-on-64-bit-SoCs.patch | 0 ...-Make-the-HHI-registers-optional-WIP.patch | 0 ...pport-for-the-Meson8-8b-8m2-TranSwit.patch | 2 +- ...on-Meson8-Meson8b-Meson8m2-VCLK-HACK.patch | 0 ...-support-for-Meson8-Meson8b-Meson8m2.patch | 0 .../0059-ARM-dts-meson-add-the-VPU-WiP.patch | 0 ...s-meson8-add-the-HDMI-controller-WiP.patch | 0 ...8-Add-the-shared-CMA-dma-memory-pool.patch | 0 ...meson8-add-the-AO-CEC-controller-WiP.patch | 0 ...-meson8b-add-the-HDMI-controller-WiP.patch | 0 ...eson8b-add-the-AO-CEC-controller-WiP.patch | 0 ...odroid-c1-enable-HDMI-for-the-Odroid.patch | 0 .../0067-meson8b-mxq-add-HDMI-support.patch} | 51 +- ...-clock-speed-before-sending-HS-CMD13.patch | 8 +- ...-modify-and-simplify-calculation-in-.patch | 0 .../onecloud-0001-add-dts.patch | 0 .../onecloud-0002-dts-Support-HDMI.patch | 0 66 files changed, 106 insertions(+), 5202 deletions(-) rename config/boards/{odroidc1.eos => odroidc1.csc} (96%) rename config/boards/{onecloud.eos => onecloud.csc} (93%) rename config/kernel/{linux-meson-edge.config => linux-meson-legacy.config} (97%) delete mode 100644 patch/kernel/archive/meson-6.1/generic-0001-m8-m8b-m8m2-Support-HDMI.patch delete mode 100644 patch/kernel/archive/meson-6.1/generic-0002-m8-m8b-m8m2-drm-forcefully-enable-XRGB-format.patch delete mode 100644 patch/kernel/archive/meson-6.1/generic-Revert-mmc-core-Set-HS-clock-speed-before-sending-HS-CMD13.patch delete mode 100644 patch/kernel/archive/meson-6.1/generic-Revert-pwm-meson-modify-and-simplify-calculation-in-.patch delete mode 100644 patch/kernel/archive/meson-6.1/odroidc1-dts-Enable-HDMI.patch delete mode 100644 patch/kernel/archive/meson-6.1/onecloud-0001-add-dts.patch rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0007-dt-bindings-phy-meson8b-usb2-Add-support-for-reading.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0008-phy-amlogic-meson8b-usb2-Add-support-for-reading-the.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0009-usb-common-usb-conn-gpio-Fall-back-to-polling-the-GP.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0010-usb-dwc2-register-child-USB-connector-devices.patch (95%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0011-ARM-dts-meson-Add-GPIO-controller-capabilities-to-th.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0012-ARM-dts-meson8b-odroidc1-Enable-the-Micro-USB-OTG-co.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0013-dt-bindings-phy-Add-bindings-for-the-Amlogic-Meson-C.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0014-phy-amlogic-Add-a-new-driver-for-the-CVBS-DAC-CVBS-P.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0015-dt-bindings-display-meson-vpu-Add-the-CVBS-DAC-prope.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0016-drm-meson-Add-support-for-using-a-PHY-for-the-CVBS-D.patch (99%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0018-dt-bindings-clock-meson8b-Add-the-RMII-reference-clo.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0019-dt-bindings-clock-meson8b-Add-the-Meson8-Ethernet-RM.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0020-clk-meson-meson8b-Add-the-Ethernet-RMII-clock-tree-o.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0021-dt-bindings-net-dwmac-meson-Add-the-Ethernet-clock-i.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0022-net-stmmac-dwmac-meson-Rename-the-SPEED_100-macro.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0023-net-stmmac-dwmac-meson-Manage-the-ethernet-clock.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0024-net-stmmac-dwmac-meson-Initialize-all-known-PREG_ETH.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0025-ARM-dts-meson-meson8-Add-the-clock-input-to-the-Ethe.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0026-dt-bindings-clock-meson8b-add-the-rtc_32k-oscillator.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0027-clk-meson-meson8b-Add-the-mpeg_rtc_osc_sel-clock.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0028-ARM-dts-meson-Add-address-cells-size-cells-and-range.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0029-dt-bindings-firmware-Document-the-Amlogic-Meson6-8-8.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0030-dt-bindings-arm-cpus-Document-Meson8-TrustZone-firmw.patch (97%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0031-ARM-meson-Add-support-for-the-TrustZone-firmware.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0032-ARM-meson-platsmp-Add-support-for-SoCs-running-on-Tr.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0033-soc-amlogic-meson-mx-socinfo-Add-support-for-the-Tru.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0034-nvmem-meson-mx-efuse-Add-support-for-the-TrustZone-f.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0036-ARM-dts-meson8-Add-the-PWM_C-DV9-and-PWM_D-pins.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0045-dt-bindings-display-meson-vpu-add-support-for-Meson8.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0046-drm-meson-add-Meson8-Meson8b-Meson8m2-specific-vpu_c.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0047-drm-meson-Use-24-bits-per-pixel-for-the-framebuffer-.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0048-drm-meson-Use-a-separate-list-of-supported-formats-f.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0049-drm-meson-Skip-VIU_OSD1_CTRL_STAT2-alpha-replace-val.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0050-drm-meson-Enable-the-RGB-to-YUV-converter-on-Meson8-.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0051-drm-meson-Update-meson_vpu_init-to-work-with-Meson8-.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0052-drm-meson-Describe-the-HDMI-PHY-frequency-limits-of-.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0053-drm-meson-Update-the-HDMI-encoder-for-Meson8-8b-8m2.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0054-drm-meson-Only-set-ycbcr_420_allowed-on-64-bit-SoCs.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0055-drm-meson-Make-the-HHI-registers-optional-WIP.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0056-drm-meson-Add-support-for-the-Meson8-8b-8m2-TranSwit.patch (99%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0057-drm-meson-Meson8-Meson8b-Meson8m2-VCLK-HACK.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0058-drm-meson-Enable-support-for-Meson8-Meson8b-Meson8m2.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0059-ARM-dts-meson-add-the-VPU-WiP.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0060-ARM-dts-meson8-add-the-HDMI-controller-WiP.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0061-ARM-dts-meson8-Add-the-shared-CMA-dma-memory-pool.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0062-ARM-dts-meson8-add-the-AO-CEC-controller-WiP.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0063-ARM-dts-meson8b-add-the-HDMI-controller-WiP.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0064-ARM-dts-meson8b-add-the-AO-CEC-controller-WiP.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/0066-ARM-dts-meson8b-odroid-c1-enable-HDMI-for-the-Odroid.patch (100%) rename patch/kernel/archive/{meson-6.1/onecloud-0002-dts-Support-HDMI.patch => meson-6.12/0067-meson8b-mxq-add-HDMI-support.patch} (53%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/generic-Revert-mmc-core-Set-HS-clock-speed-before-sending-HS-CMD13.patch (89%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/generic-Revert-pwm-meson-modify-and-simplify-calculation-in-.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/onecloud-0001-add-dts.patch (100%) rename patch/kernel/archive/{meson-6.10 => meson-6.12}/onecloud-0002-dts-Support-HDMI.patch (100%) diff --git a/config/boards/aml-s805-mxq.tvb b/config/boards/aml-s805-mxq.tvb index 54b9244fa3bb..2426958b9503 100644 --- a/config/boards/aml-s805-mxq.tvb +++ b/config/boards/aml-s805-mxq.tvb @@ -2,7 +2,7 @@ BOARD_NAME="MXQ" BOARDFAMILY="meson8b" BOARD_MAINTAINER="" -KERNEL_TARGET="current,edge" +KERNEL_TARGET="legacy,current" KERNEL_TEST_TARGET="current" BOOTCONFIG="none" BOOTSCRIPT="boot-aml-s805-mxq.cmd:boot.cmd" diff --git a/config/boards/odroidc1.eos b/config/boards/odroidc1.csc similarity index 96% rename from config/boards/odroidc1.eos rename to config/boards/odroidc1.csc index 786428d5ece0..f31fd4fd50de 100644 --- a/config/boards/odroidc1.eos +++ b/config/boards/odroidc1.csc @@ -2,7 +2,7 @@ BOARD_NAME="Odroid C1" BOARDFAMILY="meson8b" BOARD_MAINTAINER="juanlufont" -KERNEL_TARGET="current,edge" +KERNEL_TARGET="legacy,current" KERNEL_TEST_TARGET="current" BOOTDIR='u-boot-odroidc1' diff --git a/config/boards/onecloud.eos b/config/boards/onecloud.csc similarity index 93% rename from config/boards/onecloud.eos rename to config/boards/onecloud.csc index a7e5abeb4c99..881be89a5d8f 100644 --- a/config/boards/onecloud.eos +++ b/config/boards/onecloud.csc @@ -2,7 +2,7 @@ BOARD_NAME="OneCloud" BOARDFAMILY="meson8b" BOARD_MAINTAINER="hzyitc" -KERNEL_TARGET="current,edge" +KERNEL_TARGET="legacy,current" KERNEL_TEST_TARGET="current" BOOTCONFIG="none" BOOTSCRIPT="boot-onecloud.cmd:boot.cmd" diff --git a/config/kernel/linux-meson-current.config b/config/kernel/linux-meson-current.config index 028a28dc6373..ad51160f11e9 100644 --- a/config/kernel/linux-meson-current.config +++ b/config/kernel/linux-meson-current.config @@ -34,13 +34,13 @@ CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_PERF=y CONFIG_CGROUP_BPF=y CONFIG_CGROUP_MISC=y -CONFIG_CGROUP_DEBUG=y CONFIG_NAMESPACES=y CONFIG_USER_NS=y CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y CONFIG_PERF_EVENTS=y CONFIG_KEXEC=y +# CONFIG_CRASH_DUMP is not set CONFIG_ARCH_MESON=y CONFIG_ARM_THUMBEE=y CONFIG_PL310_ERRATA_588369=y @@ -82,6 +82,7 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_CMDLINE_PARTITION=y CONFIG_BINFMT_MISC=m CONFIG_CMA=y +CONFIG_CMA_AREAS=7 CONFIG_NET=y CONFIG_PACKET=y CONFIG_PACKET_DIAG=m @@ -342,7 +343,6 @@ CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_TTL=m CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NFT_DUP_IPV6=m @@ -392,7 +392,6 @@ CONFIG_BRIDGE_EBT_REDIRECT=m CONFIG_BRIDGE_EBT_SNAT=m CONFIG_BRIDGE_EBT_LOG=m CONFIG_BRIDGE_EBT_NFLOG=m -CONFIG_BPFILTER=y CONFIG_IP_DCCP=m CONFIG_RDS=m CONFIG_RDS_TCP=m @@ -417,9 +416,6 @@ CONFIG_VLAN_8021Q_GVRP=y CONFIG_VLAN_8021Q_MVRP=y CONFIG_LLC2=m CONFIG_ATALK=m -CONFIG_DEV_APPLETALK=m -CONFIG_IPDDP=m -CONFIG_IPDDP_ENCAP=y CONFIG_X25=m CONFIG_LAPB=m CONFIG_PHONET=m @@ -491,7 +487,6 @@ CONFIG_NET_ACT_GACT=m CONFIG_GACT_PROB=y CONFIG_NET_ACT_MIRRED=m CONFIG_NET_ACT_SAMPLE=m -CONFIG_NET_ACT_IPT=m CONFIG_NET_ACT_NAT=m CONFIG_NET_ACT_PEDIT=m CONFIG_NET_ACT_SIMP=m @@ -567,8 +562,10 @@ CONFIG_BT_ATH3K=m CONFIG_BT_MTKSDIO=m CONFIG_BT_MTKUART=m CONFIG_BT_VIRTIO=m +CONFIG_BT_NXPUART=m CONFIG_AF_RXRPC_IPV6=y CONFIG_AF_RXRPC_INJECT_LOSS=y +CONFIG_AF_RXRPC_INJECT_RX_DELAY=y CONFIG_AF_RXRPC_DEBUG=y CONFIG_RXKAD=y CONFIG_CFG80211=m @@ -580,10 +577,9 @@ CONFIG_MAC80211_DEBUGFS=y CONFIG_RFKILL=m CONFIG_RFKILL_INPUT=y CONFIG_RFKILL_GPIO=m +CONFIG_PAGE_POOL_STATS=y CONFIG_PCI=y -# CONFIG_PCIEASPM is not set CONFIG_PCI_MSI=y -# CONFIG_VGA_ARB is not set CONFIG_PCI_HOST_GENERIC=y # CONFIG_PCI_MESON is not set CONFIG_UEVENT_HELPER=y @@ -601,6 +597,7 @@ CONFIG_OF_OVERLAY=y CONFIG_ZRAM=m CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y +CONFIG_ZRAM_MULTI_COMP=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_DRBD=m CONFIG_DRBD_FAULT_INJECTION=y @@ -630,9 +627,6 @@ CONFIG_SATA_AHCI=y CONFIG_SATA_AHCI_PLATFORM=y CONFIG_SATA_MV=y CONFIG_MD=y -CONFIG_MD_LINEAR=m -CONFIG_MD_MULTIPATH=m -CONFIG_MD_FAULTY=m CONFIG_BCACHE=m CONFIG_BCACHE_ASYNC_REGISTRATION=y CONFIG_BLK_DEV_DM=m @@ -746,6 +740,7 @@ CONFIG_DWMAC_DWC_QOS_ETH=y # CONFIG_NET_VENDOR_XILINX is not set CONFIG_REALTEK_PHY=y # CONFIG_MDIO_BUS_MUX_MESON_G12A is not set +# CONFIG_MDIO_BUS_MUX_MESON_GXL is not set CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m CONFIG_PPP_DEFLATE=m @@ -769,6 +764,7 @@ CONFIG_USB_PEGASUS=m CONFIG_USB_RTL8150=m CONFIG_USB_RTL8152=m CONFIG_USB_LAN78XX=m +CONFIG_USB_USBNET=m CONFIG_USB_NET_CDC_EEM=m CONFIG_USB_NET_HUAWEI_CDC_NCM=m CONFIG_USB_NET_CDC_MBIM=m @@ -780,6 +776,7 @@ CONFIG_USB_NET_SMSC95XX=m CONFIG_USB_NET_GL620A=m CONFIG_USB_NET_PLUSB=m CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_RNDIS_HOST=m CONFIG_USB_ALI_M5632=y CONFIG_USB_AN2720=y CONFIG_USB_EPSON2888=y @@ -847,6 +844,14 @@ CONFIG_RTL8192CU=m CONFIG_RTL8XXXU=m CONFIG_RTL8XXXU_UNTESTED=y CONFIG_RTW88=m +CONFIG_RTW88_8822BS=m +CONFIG_RTW88_8822BU=m +CONFIG_RTW88_8822CS=m +CONFIG_RTW88_8822CU=m +CONFIG_RTW88_8723DS=m +CONFIG_RTW88_8723DU=m +CONFIG_RTW88_8821CS=m +CONFIG_RTW88_8821CU=m CONFIG_RTW89=m CONFIG_RSI_91X=m # CONFIG_RSI_DEBUGFS is not set @@ -861,7 +866,6 @@ CONFIG_WL12XX=m CONFIG_WL18XX=m CONFIG_WLCORE_SPI=m CONFIG_WLCORE_SDIO=m -CONFIG_RTL8723DU=m CONFIG_RTL8723DS=m CONFIG_RTL8822BU=m CONFIG_RTL8821CU=m @@ -869,9 +873,7 @@ CONFIG_88XXAU=m CONFIG_RTL8192EU=m CONFIG_RTL8189FS=m CONFIG_RTL8189ES=m -CONFIG_USB_ZD1201=m CONFIG_ZD1211RW=m -CONFIG_USB_NET_RNDIS_WLAN=m CONFIG_VIRT_WIFI=m CONFIG_NETDEVSIM=m CONFIG_NET_FAILOVER=y @@ -888,7 +890,6 @@ CONFIG_MOUSE_SYNAPTICS_USB=m CONFIG_SERIAL_MESON=y CONFIG_SERIAL_MESON_CONSOLE=y CONFIG_SERIAL_DEV_BUS=y -CONFIG_TTY_PRINTK=y CONFIG_VIRTIO_CONSOLE=y CONFIG_HW_RANDOM=y # CONFIG_HW_RANDOM_ARM_SMCCC_TRNG is not set @@ -1109,11 +1110,13 @@ CONFIG_VIDEO_VICODEC=m CONFIG_VIDEO_VIMC=m CONFIG_VIDEO_VIVID=m CONFIG_VIDEO_VIVID_CEC=y -CONFIG_DVB_MB86A16=m +CONFIG_VIDEO_VISL=m +CONFIG_VISL_DEBUGFS=y CONFIG_DRM=y CONFIG_DRM_MALI_DISPLAY=y # CONFIG_DRM_DW_HDMI_I2S_AUDIO is not set CONFIG_DRM_MESON=y +# CONFIG_DRM_MESON_DW_MIPI_DSI is not set CONFIG_DRM_LIMA=y CONFIG_FB=y CONFIG_FB_SIMPLE=y @@ -1121,10 +1124,10 @@ CONFIG_FB_MODE_HELPERS=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_SOUND=m CONFIG_SND=m -CONFIG_SND_DYNAMIC_MINORS=y # CONFIG_SND_PCI is not set # CONFIG_SND_SPI is not set CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_AUDIO_MIDI_V2=y CONFIG_SND_USB_UA101=m CONFIG_SND_USB_CAIAQ=m CONFIG_SND_USB_CAIAQ_INPUT=y @@ -1136,10 +1139,11 @@ CONFIG_SND_USB_PODHD=m CONFIG_SND_USB_TONEPORT=m CONFIG_SND_USB_VARIAX=m CONFIG_SND_SOC=m -CONFIG_SND_MESON_AIU=m +CONFIG_SND_MESON_GX_SOUND_CARD=m # CONFIG_SND_SOC_MESON_T9015 is not set CONFIG_SND_SIMPLE_CARD=m CONFIG_SND_AUDIO_GRAPH_CARD=m +# CONFIG_I2C_HID is not set CONFIG_USB_LED_TRIG=y CONFIG_USB_ULPI_BUS=y CONFIG_USB_CONN_GPIO=y @@ -1246,6 +1250,7 @@ CONFIG_USB_LD=m CONFIG_USB_TRANCEVIBRATOR=m CONFIG_USB_ISIGHTFW=m CONFIG_USB_YUREX=m +CONFIG_USB_ONBOARD_DEV=y CONFIG_USB_ULPI=y CONFIG_USB_GADGET=y CONFIG_U_SERIAL_CONSOLE=y @@ -1265,6 +1270,7 @@ CONFIG_USB_CONFIGFS_F_UAC1=y CONFIG_USB_CONFIGFS_F_UAC1_LEGACY=y CONFIG_USB_CONFIGFS_F_UAC2=y CONFIG_USB_CONFIGFS_F_MIDI=y +CONFIG_USB_CONFIGFS_F_MIDI2=y CONFIG_USB_CONFIGFS_F_HID=y CONFIG_USB_CONFIGFS_F_UVC=y CONFIG_USB_CONFIGFS_F_PRINTER=y @@ -1314,7 +1320,6 @@ CONFIG_LEDS_TRIGGER_CAMERA=y CONFIG_LEDS_TRIGGER_PANIC=y CONFIG_LEDS_TRIGGER_NETDEV=y CONFIG_LEDS_TRIGGER_PATTERN=y -CONFIG_LEDS_TRIGGER_AUDIO=y CONFIG_LEDS_TRIGGER_TTY=y CONFIG_EDAC=y CONFIG_RTC_CLASS=y @@ -1394,6 +1399,7 @@ CONFIG_XFS_POSIX_ACL=y CONFIG_XFS_RT=y CONFIG_XFS_ONLINE_SCRUB=y CONFIG_XFS_ONLINE_REPAIR=y +CONFIG_XFS_DEBUG=y CONFIG_GFS2_FS=y CONFIG_OCFS2_FS=y CONFIG_OCFS2_DEBUG_FS=y @@ -1419,7 +1425,7 @@ CONFIG_VIRTIO_FS=y CONFIG_OVERLAY_FS=y CONFIG_FSCACHE=y CONFIG_FSCACHE_STATS=y -CONFIG_CACHEFILES=y +CONFIG_CACHEFILES=m CONFIG_ISO9660_FS=y CONFIG_JOLIET=y CONFIG_ZISOFS=y @@ -1428,14 +1434,13 @@ CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_FAT_DEFAULT_UTF8=y CONFIG_EXFAT_FS=y -CONFIG_NTFS_FS=y -CONFIG_NTFS_RW=y -CONFIG_NTFS3_FS=y CONFIG_NTFS3_LZX_XPRESS=y CONFIG_NTFS3_FS_POSIX_ACL=y +CONFIG_NTFS_FS=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_QUOTA=y CONFIG_ORANGEFS_FS=m CONFIG_ADFS_FS=m CONFIG_AFFS_FS=m @@ -1448,6 +1453,7 @@ CONFIG_BFS_FS=m CONFIG_EFS_FS=m CONFIG_CRAMFS=m CONFIG_SQUASHFS=m +CONFIG_SQUASHFS_CHOICE_DECOMP_BY_MOUNT=y CONFIG_SQUASHFS_XATTR=y CONFIG_SQUASHFS_LZ4=y CONFIG_SQUASHFS_LZO=y @@ -1471,7 +1477,11 @@ CONFIG_SYSV_FS=m CONFIG_UFS_FS=m CONFIG_EROFS_FS=m CONFIG_EROFS_FS_ZIP_LZMA=y +CONFIG_EROFS_FS_ZIP_DEFLATE=y +CONFIG_EROFS_FS_PCPU_KTHREAD=y +# CONFIG_EROFS_FS_PCPU_KTHREAD_HIPRI is not set CONFIG_NFS_FS=y +CONFIG_NFS_V2=y CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y CONFIG_NFS_SWAP=y @@ -1479,15 +1489,19 @@ CONFIG_NFS_V4_1=y CONFIG_NFS_V4_2=y CONFIG_NFS_V4_1_MIGRATION=y CONFIG_ROOT_NFS=y -CONFIG_NFS_FSCACHE=y CONFIG_NFSD=m +CONFIG_NFSD_V2=y +CONFIG_NFSD_V2_ACL=y CONFIG_NFSD_V3_ACL=y CONFIG_NFSD_V4=y CONFIG_NFSD_BLOCKLAYOUT=y CONFIG_NFSD_SCSILAYOUT=y CONFIG_NFSD_FLEXFILELAYOUT=y CONFIG_NFSD_V4_2_INTER_SSC=y +# CONFIG_NFSD_LEGACY_CLIENT_TRACKING is not set CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_CAMELLIA=y +CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA2=y CONFIG_SUNRPC_DEBUG=y CONFIG_CEPH_FS=m CONFIG_CEPH_FSCACHE=y @@ -1585,13 +1599,10 @@ CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_ADIANTUM=m CONFIG_CRYPTO_ARC4=m CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_CFB=m CONFIG_CRYPTO_CTS=m -CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_HCTR2=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_OFB=m CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_AEGIS128=m CONFIG_CRYPTO_CHACHA20POLY1305=m @@ -1616,7 +1627,6 @@ CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m CONFIG_CRYPTO_USER_API_RNG=m CONFIG_CRYPTO_USER_API_AEAD=m -CONFIG_CRYPTO_STATS=y CONFIG_CRYPTO_GHASH_ARM_CE=m CONFIG_CRYPTO_NHPOLY1305_NEON=m CONFIG_CRYPTO_BLAKE2B_NEON=m @@ -1638,11 +1648,11 @@ CONFIG_SYSTEM_BLACKLIST_KEYRING=y CONFIG_PACKING=y CONFIG_PRIME_NUMBERS=m CONFIG_CRC4=m -CONFIG_CRC8=m CONFIG_DMA_CMA=y CONFIG_CMA_SIZE_MBYTES=64 CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO_DWARF5=y CONFIG_DEBUG_INFO_BTF=y CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_MEMORY_INIT=y CONFIG_FTRACE_SYSCALLS=y diff --git a/config/kernel/linux-meson-edge.config b/config/kernel/linux-meson-legacy.config similarity index 97% rename from config/kernel/linux-meson-edge.config rename to config/kernel/linux-meson-legacy.config index ad51160f11e9..028a28dc6373 100644 --- a/config/kernel/linux-meson-edge.config +++ b/config/kernel/linux-meson-legacy.config @@ -34,13 +34,13 @@ CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_PERF=y CONFIG_CGROUP_BPF=y CONFIG_CGROUP_MISC=y +CONFIG_CGROUP_DEBUG=y CONFIG_NAMESPACES=y CONFIG_USER_NS=y CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y CONFIG_PERF_EVENTS=y CONFIG_KEXEC=y -# CONFIG_CRASH_DUMP is not set CONFIG_ARCH_MESON=y CONFIG_ARM_THUMBEE=y CONFIG_PL310_ERRATA_588369=y @@ -82,7 +82,6 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_CMDLINE_PARTITION=y CONFIG_BINFMT_MISC=m CONFIG_CMA=y -CONFIG_CMA_AREAS=7 CONFIG_NET=y CONFIG_PACKET=y CONFIG_PACKET_DIAG=m @@ -343,6 +342,7 @@ CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_TTL=m CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NFT_DUP_IPV6=m @@ -392,6 +392,7 @@ CONFIG_BRIDGE_EBT_REDIRECT=m CONFIG_BRIDGE_EBT_SNAT=m CONFIG_BRIDGE_EBT_LOG=m CONFIG_BRIDGE_EBT_NFLOG=m +CONFIG_BPFILTER=y CONFIG_IP_DCCP=m CONFIG_RDS=m CONFIG_RDS_TCP=m @@ -416,6 +417,9 @@ CONFIG_VLAN_8021Q_GVRP=y CONFIG_VLAN_8021Q_MVRP=y CONFIG_LLC2=m CONFIG_ATALK=m +CONFIG_DEV_APPLETALK=m +CONFIG_IPDDP=m +CONFIG_IPDDP_ENCAP=y CONFIG_X25=m CONFIG_LAPB=m CONFIG_PHONET=m @@ -487,6 +491,7 @@ CONFIG_NET_ACT_GACT=m CONFIG_GACT_PROB=y CONFIG_NET_ACT_MIRRED=m CONFIG_NET_ACT_SAMPLE=m +CONFIG_NET_ACT_IPT=m CONFIG_NET_ACT_NAT=m CONFIG_NET_ACT_PEDIT=m CONFIG_NET_ACT_SIMP=m @@ -562,10 +567,8 @@ CONFIG_BT_ATH3K=m CONFIG_BT_MTKSDIO=m CONFIG_BT_MTKUART=m CONFIG_BT_VIRTIO=m -CONFIG_BT_NXPUART=m CONFIG_AF_RXRPC_IPV6=y CONFIG_AF_RXRPC_INJECT_LOSS=y -CONFIG_AF_RXRPC_INJECT_RX_DELAY=y CONFIG_AF_RXRPC_DEBUG=y CONFIG_RXKAD=y CONFIG_CFG80211=m @@ -577,9 +580,10 @@ CONFIG_MAC80211_DEBUGFS=y CONFIG_RFKILL=m CONFIG_RFKILL_INPUT=y CONFIG_RFKILL_GPIO=m -CONFIG_PAGE_POOL_STATS=y CONFIG_PCI=y +# CONFIG_PCIEASPM is not set CONFIG_PCI_MSI=y +# CONFIG_VGA_ARB is not set CONFIG_PCI_HOST_GENERIC=y # CONFIG_PCI_MESON is not set CONFIG_UEVENT_HELPER=y @@ -597,7 +601,6 @@ CONFIG_OF_OVERLAY=y CONFIG_ZRAM=m CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y -CONFIG_ZRAM_MULTI_COMP=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_DRBD=m CONFIG_DRBD_FAULT_INJECTION=y @@ -627,6 +630,9 @@ CONFIG_SATA_AHCI=y CONFIG_SATA_AHCI_PLATFORM=y CONFIG_SATA_MV=y CONFIG_MD=y +CONFIG_MD_LINEAR=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m CONFIG_BCACHE=m CONFIG_BCACHE_ASYNC_REGISTRATION=y CONFIG_BLK_DEV_DM=m @@ -740,7 +746,6 @@ CONFIG_DWMAC_DWC_QOS_ETH=y # CONFIG_NET_VENDOR_XILINX is not set CONFIG_REALTEK_PHY=y # CONFIG_MDIO_BUS_MUX_MESON_G12A is not set -# CONFIG_MDIO_BUS_MUX_MESON_GXL is not set CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m CONFIG_PPP_DEFLATE=m @@ -764,7 +769,6 @@ CONFIG_USB_PEGASUS=m CONFIG_USB_RTL8150=m CONFIG_USB_RTL8152=m CONFIG_USB_LAN78XX=m -CONFIG_USB_USBNET=m CONFIG_USB_NET_CDC_EEM=m CONFIG_USB_NET_HUAWEI_CDC_NCM=m CONFIG_USB_NET_CDC_MBIM=m @@ -776,7 +780,6 @@ CONFIG_USB_NET_SMSC95XX=m CONFIG_USB_NET_GL620A=m CONFIG_USB_NET_PLUSB=m CONFIG_USB_NET_MCS7830=m -CONFIG_USB_NET_RNDIS_HOST=m CONFIG_USB_ALI_M5632=y CONFIG_USB_AN2720=y CONFIG_USB_EPSON2888=y @@ -844,14 +847,6 @@ CONFIG_RTL8192CU=m CONFIG_RTL8XXXU=m CONFIG_RTL8XXXU_UNTESTED=y CONFIG_RTW88=m -CONFIG_RTW88_8822BS=m -CONFIG_RTW88_8822BU=m -CONFIG_RTW88_8822CS=m -CONFIG_RTW88_8822CU=m -CONFIG_RTW88_8723DS=m -CONFIG_RTW88_8723DU=m -CONFIG_RTW88_8821CS=m -CONFIG_RTW88_8821CU=m CONFIG_RTW89=m CONFIG_RSI_91X=m # CONFIG_RSI_DEBUGFS is not set @@ -866,6 +861,7 @@ CONFIG_WL12XX=m CONFIG_WL18XX=m CONFIG_WLCORE_SPI=m CONFIG_WLCORE_SDIO=m +CONFIG_RTL8723DU=m CONFIG_RTL8723DS=m CONFIG_RTL8822BU=m CONFIG_RTL8821CU=m @@ -873,7 +869,9 @@ CONFIG_88XXAU=m CONFIG_RTL8192EU=m CONFIG_RTL8189FS=m CONFIG_RTL8189ES=m +CONFIG_USB_ZD1201=m CONFIG_ZD1211RW=m +CONFIG_USB_NET_RNDIS_WLAN=m CONFIG_VIRT_WIFI=m CONFIG_NETDEVSIM=m CONFIG_NET_FAILOVER=y @@ -890,6 +888,7 @@ CONFIG_MOUSE_SYNAPTICS_USB=m CONFIG_SERIAL_MESON=y CONFIG_SERIAL_MESON_CONSOLE=y CONFIG_SERIAL_DEV_BUS=y +CONFIG_TTY_PRINTK=y CONFIG_VIRTIO_CONSOLE=y CONFIG_HW_RANDOM=y # CONFIG_HW_RANDOM_ARM_SMCCC_TRNG is not set @@ -1110,13 +1109,11 @@ CONFIG_VIDEO_VICODEC=m CONFIG_VIDEO_VIMC=m CONFIG_VIDEO_VIVID=m CONFIG_VIDEO_VIVID_CEC=y -CONFIG_VIDEO_VISL=m -CONFIG_VISL_DEBUGFS=y +CONFIG_DVB_MB86A16=m CONFIG_DRM=y CONFIG_DRM_MALI_DISPLAY=y # CONFIG_DRM_DW_HDMI_I2S_AUDIO is not set CONFIG_DRM_MESON=y -# CONFIG_DRM_MESON_DW_MIPI_DSI is not set CONFIG_DRM_LIMA=y CONFIG_FB=y CONFIG_FB_SIMPLE=y @@ -1124,10 +1121,10 @@ CONFIG_FB_MODE_HELPERS=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_SOUND=m CONFIG_SND=m +CONFIG_SND_DYNAMIC_MINORS=y # CONFIG_SND_PCI is not set # CONFIG_SND_SPI is not set CONFIG_SND_USB_AUDIO=m -CONFIG_SND_USB_AUDIO_MIDI_V2=y CONFIG_SND_USB_UA101=m CONFIG_SND_USB_CAIAQ=m CONFIG_SND_USB_CAIAQ_INPUT=y @@ -1139,11 +1136,10 @@ CONFIG_SND_USB_PODHD=m CONFIG_SND_USB_TONEPORT=m CONFIG_SND_USB_VARIAX=m CONFIG_SND_SOC=m -CONFIG_SND_MESON_GX_SOUND_CARD=m +CONFIG_SND_MESON_AIU=m # CONFIG_SND_SOC_MESON_T9015 is not set CONFIG_SND_SIMPLE_CARD=m CONFIG_SND_AUDIO_GRAPH_CARD=m -# CONFIG_I2C_HID is not set CONFIG_USB_LED_TRIG=y CONFIG_USB_ULPI_BUS=y CONFIG_USB_CONN_GPIO=y @@ -1250,7 +1246,6 @@ CONFIG_USB_LD=m CONFIG_USB_TRANCEVIBRATOR=m CONFIG_USB_ISIGHTFW=m CONFIG_USB_YUREX=m -CONFIG_USB_ONBOARD_DEV=y CONFIG_USB_ULPI=y CONFIG_USB_GADGET=y CONFIG_U_SERIAL_CONSOLE=y @@ -1270,7 +1265,6 @@ CONFIG_USB_CONFIGFS_F_UAC1=y CONFIG_USB_CONFIGFS_F_UAC1_LEGACY=y CONFIG_USB_CONFIGFS_F_UAC2=y CONFIG_USB_CONFIGFS_F_MIDI=y -CONFIG_USB_CONFIGFS_F_MIDI2=y CONFIG_USB_CONFIGFS_F_HID=y CONFIG_USB_CONFIGFS_F_UVC=y CONFIG_USB_CONFIGFS_F_PRINTER=y @@ -1320,6 +1314,7 @@ CONFIG_LEDS_TRIGGER_CAMERA=y CONFIG_LEDS_TRIGGER_PANIC=y CONFIG_LEDS_TRIGGER_NETDEV=y CONFIG_LEDS_TRIGGER_PATTERN=y +CONFIG_LEDS_TRIGGER_AUDIO=y CONFIG_LEDS_TRIGGER_TTY=y CONFIG_EDAC=y CONFIG_RTC_CLASS=y @@ -1399,7 +1394,6 @@ CONFIG_XFS_POSIX_ACL=y CONFIG_XFS_RT=y CONFIG_XFS_ONLINE_SCRUB=y CONFIG_XFS_ONLINE_REPAIR=y -CONFIG_XFS_DEBUG=y CONFIG_GFS2_FS=y CONFIG_OCFS2_FS=y CONFIG_OCFS2_DEBUG_FS=y @@ -1425,7 +1419,7 @@ CONFIG_VIRTIO_FS=y CONFIG_OVERLAY_FS=y CONFIG_FSCACHE=y CONFIG_FSCACHE_STATS=y -CONFIG_CACHEFILES=m +CONFIG_CACHEFILES=y CONFIG_ISO9660_FS=y CONFIG_JOLIET=y CONFIG_ZISOFS=y @@ -1434,13 +1428,14 @@ CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_FAT_DEFAULT_UTF8=y CONFIG_EXFAT_FS=y +CONFIG_NTFS_FS=y +CONFIG_NTFS_RW=y +CONFIG_NTFS3_FS=y CONFIG_NTFS3_LZX_XPRESS=y CONFIG_NTFS3_FS_POSIX_ACL=y -CONFIG_NTFS_FS=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y -CONFIG_TMPFS_QUOTA=y CONFIG_ORANGEFS_FS=m CONFIG_ADFS_FS=m CONFIG_AFFS_FS=m @@ -1453,7 +1448,6 @@ CONFIG_BFS_FS=m CONFIG_EFS_FS=m CONFIG_CRAMFS=m CONFIG_SQUASHFS=m -CONFIG_SQUASHFS_CHOICE_DECOMP_BY_MOUNT=y CONFIG_SQUASHFS_XATTR=y CONFIG_SQUASHFS_LZ4=y CONFIG_SQUASHFS_LZO=y @@ -1477,11 +1471,7 @@ CONFIG_SYSV_FS=m CONFIG_UFS_FS=m CONFIG_EROFS_FS=m CONFIG_EROFS_FS_ZIP_LZMA=y -CONFIG_EROFS_FS_ZIP_DEFLATE=y -CONFIG_EROFS_FS_PCPU_KTHREAD=y -# CONFIG_EROFS_FS_PCPU_KTHREAD_HIPRI is not set CONFIG_NFS_FS=y -CONFIG_NFS_V2=y CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y CONFIG_NFS_SWAP=y @@ -1489,19 +1479,15 @@ CONFIG_NFS_V4_1=y CONFIG_NFS_V4_2=y CONFIG_NFS_V4_1_MIGRATION=y CONFIG_ROOT_NFS=y +CONFIG_NFS_FSCACHE=y CONFIG_NFSD=m -CONFIG_NFSD_V2=y -CONFIG_NFSD_V2_ACL=y CONFIG_NFSD_V3_ACL=y CONFIG_NFSD_V4=y CONFIG_NFSD_BLOCKLAYOUT=y CONFIG_NFSD_SCSILAYOUT=y CONFIG_NFSD_FLEXFILELAYOUT=y CONFIG_NFSD_V4_2_INTER_SSC=y -# CONFIG_NFSD_LEGACY_CLIENT_TRACKING is not set CONFIG_RPCSEC_GSS_KRB5=m -CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_CAMELLIA=y -CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA2=y CONFIG_SUNRPC_DEBUG=y CONFIG_CEPH_FS=m CONFIG_CEPH_FSCACHE=y @@ -1599,10 +1585,13 @@ CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_ADIANTUM=m CONFIG_CRYPTO_ARC4=m CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CFB=m CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_HCTR2=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_OFB=m CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_AEGIS128=m CONFIG_CRYPTO_CHACHA20POLY1305=m @@ -1627,6 +1616,7 @@ CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m CONFIG_CRYPTO_USER_API_RNG=m CONFIG_CRYPTO_USER_API_AEAD=m +CONFIG_CRYPTO_STATS=y CONFIG_CRYPTO_GHASH_ARM_CE=m CONFIG_CRYPTO_NHPOLY1305_NEON=m CONFIG_CRYPTO_BLAKE2B_NEON=m @@ -1648,11 +1638,11 @@ CONFIG_SYSTEM_BLACKLIST_KEYRING=y CONFIG_PACKING=y CONFIG_PRIME_NUMBERS=m CONFIG_CRC4=m +CONFIG_CRC8=m CONFIG_DMA_CMA=y CONFIG_CMA_SIZE_MBYTES=64 CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO_DWARF5=y CONFIG_DEBUG_INFO_BTF=y CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_MEMORY_INIT=y CONFIG_FTRACE_SYSCALLS=y diff --git a/config/sources/families/include/meson_common.inc b/config/sources/families/include/meson_common.inc index cef6e2c6f5d4..436b83e09361 100644 --- a/config/sources/families/include/meson_common.inc +++ b/config/sources/families/include/meson_common.inc @@ -24,15 +24,11 @@ SKIP_BOOTSPLASH="yes" case $BRANCH in legacy) - declare -g KERNEL_MAJOR_MINOR="6.1" - ;; - - current) declare -g KERNEL_MAJOR_MINOR="6.6" ;; - edge) - declare -g KERNEL_MAJOR_MINOR="6.10" + current) + declare -g KERNEL_MAJOR_MINOR="6.12" ;; esac diff --git a/patch/kernel/archive/meson-6.1/generic-0001-m8-m8b-m8m2-Support-HDMI.patch b/patch/kernel/archive/meson-6.1/generic-0001-m8-m8b-m8m2-Support-HDMI.patch deleted file mode 100644 index d4a74968ffa4..000000000000 --- a/patch/kernel/archive/meson-6.1/generic-0001-m8-m8b-m8m2-Support-HDMI.patch +++ /dev/null @@ -1,4406 +0,0 @@ -meson8/meson8b/meson8m2: Support HDMI - -The following codes are come from https://github.com/xdarklight/linux/commits/meson-mx-integration-5.18-20220516. - -Special thank to Martin Blumenstingl. - ---- - .../bindings/display/amlogic,meson-vpu.yaml | 16 + - .../phy/amlogic,meson-cvbs-dac-phy.yaml | 81 + - arch/arm/boot/dts/meson.dtsi | 13 + - arch/arm/boot/dts/meson8.dtsi | 168 +- - arch/arm/boot/dts/meson8b.dtsi | 171 +- - arch/arm/boot/dts/meson8m2.dtsi | 4 + - drivers/gpu/drm/meson/Kconfig | 9 + - drivers/gpu/drm/meson/Makefile | 1 + - drivers/gpu/drm/meson/meson_drv.c | 315 +++- - drivers/gpu/drm/meson/meson_drv.h | 49 +- - drivers/gpu/drm/meson/meson_encoder_cvbs.c | 61 +- - drivers/gpu/drm/meson/meson_encoder_hdmi.c | 69 +- - drivers/gpu/drm/meson/meson_plane.c | 37 +- - drivers/gpu/drm/meson/meson_transwitch_hdmi.c | 1579 +++++++++++++++++ - drivers/gpu/drm/meson/meson_transwitch_hdmi.h | 536 ++++++ - drivers/gpu/drm/meson/meson_vclk.c | 146 ++ - drivers/gpu/drm/meson/meson_venc.c | 44 +- - drivers/gpu/drm/meson/meson_viu.c | 18 +- - drivers/phy/amlogic/Kconfig | 10 + - drivers/phy/amlogic/Makefile | 1 + - drivers/phy/amlogic/phy-meson-cvbs-dac.c | 375 ++++ - 21 files changed, 3577 insertions(+), 126 deletions(-) - create mode 100644 Documentation/devicetree/bindings/phy/amlogic,meson-cvbs-dac-phy.yaml - create mode 100644 drivers/gpu/drm/meson/meson_transwitch_hdmi.c - create mode 100644 drivers/gpu/drm/meson/meson_transwitch_hdmi.h - create mode 100644 drivers/phy/amlogic/phy-meson-cvbs-dac.c - -diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml -index 6655a93b187..bbc58c8bdfc 100644 ---- a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml -+++ b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml -@@ -66,8 +66,12 @@ properties: - - const: amlogic,meson-gx-vpu - - enum: - - amlogic,meson-g12a-vpu # G12A (S905X2, S905Y2, S905D2) -+ - amlogic,meson8-vpu -+ - amlogic,meson8b-vpu -+ - amlogic,meson8m2-vpu - - reg: -+ minItems: 1 - maxItems: 2 - - reg-names: -@@ -82,6 +86,15 @@ properties: - description: should point to a canvas provider node - $ref: /schemas/types.yaml#/definitions/phandle - -+ phys: -+ maxItems: 1 -+ description: -+ PHY specifier for the CVBS DAC -+ -+ phy-names: -+ items: -+ - const: cvbs-dac -+ - power-domains: - maxItems: 1 - description: phandle to the associated power domain -@@ -125,6 +138,9 @@ examples: - #size-cells = <0>; - amlogic,canvas = <&canvas>; - -+ phys = <&cvbs_dac_phy>; -+ phy-names = "cvbs-dac"; -+ - /* CVBS VDAC output port */ - port@0 { - reg = <0>; -diff --git a/Documentation/devicetree/bindings/phy/amlogic,meson-cvbs-dac-phy.yaml b/Documentation/devicetree/bindings/phy/amlogic,meson-cvbs-dac-phy.yaml -new file mode 100644 -index 00000000000..d73cb12c0d9 ---- /dev/null -+++ b/Documentation/devicetree/bindings/phy/amlogic,meson-cvbs-dac-phy.yaml -@@ -0,0 +1,81 @@ -+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: "http://devicetree.org/schemas/phy/amlogic,meson-cvbs-dac-phy.yaml#" -+$schema: "http://devicetree.org/meta-schemas/core.yaml#" -+ -+title: Amlogic Meson Composite Video Baseband Signal DAC -+ -+maintainers: -+ - Martin Blumenstingl -+ -+description: |+ -+ The CVBS DAC node should be the child of a syscon node with the -+ required property: -+ -+ compatible = "amlogic,meson-hhi-sysctrl", "simple-mfd", "syscon" -+ -+ Refer to the bindings described in -+ Documentation/devicetree/bindings/mfd/syscon.yaml -+ -+properties: -+ $nodename: -+ pattern: "^video-dac@[0-9a-f]+$" -+ -+ compatible: -+ oneOf: -+ - items: -+ - enum: -+ - amlogic,meson8-cvbs-dac -+ - amlogic,meson-gxbb-cvbs-dac -+ - amlogic,meson-gxl-cvbs-dac -+ - amlogic,meson-g12a-cvbs-dac -+ - const: amlogic,meson-cvbs-dac -+ - const: amlogic,meson-cvbs-dac -+ -+ reg: -+ maxItems: 1 -+ -+ clocks: -+ minItems: 1 -+ -+ nvmem-cells: -+ minItems: 1 -+ -+ nvmem-cell-names: -+ items: -+ - const: cvbs_trimming -+ -+ "#phy-cells": -+ const: 0 -+ -+required: -+ - compatible -+ - reg -+ - clocks -+ - "#phy-cells" -+ -+additionalProperties: false -+ -+examples: -+ - | -+ video-dac@2f4 { -+ compatible = "amlogic,meson8-cvbs-dac", "amlogic,meson-cvbs-dac"; -+ reg = <0x2f4 0x8>; -+ -+ #phy-cells = <0>; -+ -+ clocks = <&vdac_clock>; -+ -+ nvmem-cells = <&cvbs_trimming>; -+ nvmem-cell-names = "cvbs_trimming"; -+ }; -+ - | -+ video-dac@2ec { -+ compatible = "amlogic,meson-g12a-cvbs-dac", "amlogic,meson-cvbs-dac"; -+ reg = <0x2ec 0x8>; -+ -+ #phy-cells = <0>; -+ -+ clocks = <&vdac_clock>; -+ }; -diff --git a/arch/arm/boot/dts/meson.dtsi b/arch/arm/boot/dts/meson.dtsi -index 8e3860d5d91..9a56cdf776a 100644 ---- a/arch/arm/boot/dts/meson.dtsi -+++ b/arch/arm/boot/dts/meson.dtsi -@@ -35,6 +35,19 @@ hhi: system-controller@4000 { - "simple-mfd", - "syscon"; - reg = <0x4000 0x400>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0x0 0x4000 0x400>; -+ -+ -+ cvbs_dac: video-dac@2f4 { -+ compatible = "amlogic,meson-cvbs-dac"; -+ reg = <0x2f4 0x8>; -+ -+ #phy-cells = <0>; -+ -+ status = "disabled"; -+ }; - }; - - aiu: audio-controller@5400 { -diff --git a/arch/arm/boot/dts/meson8.dtsi b/arch/arm/boot/dts/meson8.dtsi -index 0f8bac8bac8..646bb8b102b 100644 ---- a/arch/arm/boot/dts/meson8.dtsi -+++ b/arch/arm/boot/dts/meson8.dtsi -@@ -314,6 +314,113 @@ mali: gpu@c0000 { - operating-points-v2 = <&gpu_opp_table>; - #cooling-cells = <2>; /* min followed by max */ - }; -+ -+ hdmi_tx: hdmi-tx@42000 { -+ compatible = "amlogic,meson8-hdmi-tx"; -+ reg = <0x42000 0xc>; -+ interrupts = ; -+ phys = <&hdmi_tx_phy>; -+ phy-names = "hdmi"; -+ clocks = <&clkc CLKID_HDMI_PCLK>, -+ <&clkc CLKID_HDMI_SYS>; -+ clock-names = "pclk", "sys"; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ #sound-dai-cells = <1>; -+ sound-name-prefix = "HDMITX"; -+ -+ status = "disabled"; -+ -+ /* VPU VENC Input */ -+ hdmi_tx_venc_port: port@0 { -+ reg = <0>; -+ -+ hdmi_tx_in: endpoint { -+ remote-endpoint = <&hdmi_tx_out>; -+ }; -+ }; -+ -+ /* TMDS Output */ -+ hdmi_tx_tmds_port: port@1 { -+ reg = <1>; -+ }; -+ }; -+ -+ vpu: vpu@100000 { -+ compatible = "amlogic,meson8-vpu"; -+ -+ reg = <0x100000 0x10000>; -+ reg-names = "vpu"; -+ -+ interrupts = ; -+ -+ amlogic,canvas = <&canvas>; -+ -+ /* -+ * The VCLK{,2}_IN path always needs to derived from -+ * the CLKID_VID_PLL_FINAL_DIV so other clocks like -+ * MPLL1 are not used (MPLL1 is reserved for audio -+ * purposes). -+ */ -+ assigned-clocks = <&clkc CLKID_VCLK_IN_SEL>, -+ <&clkc CLKID_VCLK2_IN_SEL>; -+ assigned-clock-parents = <&clkc CLKID_VID_PLL_FINAL_DIV>, -+ <&clkc CLKID_VID_PLL_FINAL_DIV>; -+ -+ clocks = <&clkc CLKID_VPU_INTR>, -+ <&clkc CLKID_HDMI_INTR_SYNC>, -+ <&clkc CLKID_GCLK_VENCI_INT>, -+ <&clkc CLKID_HDMI_PLL_HDMI_OUT>, -+ <&clkc CLKID_HDMI_TX_PIXEL>, -+ <&clkc CLKID_CTS_ENCP>, -+ <&clkc CLKID_CTS_ENCI>, -+ <&clkc CLKID_CTS_ENCT>, -+ <&clkc CLKID_CTS_ENCL>, -+ <&clkc CLKID_CTS_VDAC0>; -+ clock-names = "vpu_intr", -+ "hdmi_intr_sync", -+ "venci_int", -+ "tmds", -+ "hdmi_tx_pixel", -+ "cts_encp", -+ "cts_enci", -+ "cts_enct", -+ "cts_encl", -+ "cts_vdac0"; -+ -+ resets = <&clkc CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_PRE>, -+ <&clkc CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_POST>, -+ <&clkc CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_PRE>, -+ <&clkc CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_POST>; -+ reset-names = "vid_pll_pre", -+ "vid_pll_post", -+ "vid_pll_soft_pre", -+ "vid_pll_soft_post"; -+ -+ phys = <&cvbs_dac>; -+ phy-names = "cvbs-dac"; -+ -+ power-domains = <&pwrc PWRC_MESON8_VPU_ID>; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ /* CVBS VDAC output port */ -+ cvbs_vdac_port: port@0 { -+ reg = <0>; -+ }; -+ -+ /* HDMI-TX output port */ -+ hdmi_tx_port: port@1 { -+ reg = <1>; -+ -+ hdmi_tx_out: endpoint { -+ remote-endpoint = <&hdmi_tx_in>; -+ }; -+ }; -+ }; - }; - }; /* end of / */ - -@@ -363,6 +470,14 @@ gpio_ao: ao-bank@14 { - gpio-ranges = <&pinctrl_aobus 0 0 16>; - }; - -+ hdmi_cec_ao_pins: hdmi-cec-ao { -+ mux { -+ groups = "hdmi_cec_ao"; -+ function = "hdmi_cec_ao"; -+ bias-pull-up; -+ }; -+ }; -+ - i2s_am_clk_pins: i2s-am-clk-out { - mux { - groups = "i2s_am_clk_out_ao"; -@@ -427,6 +542,15 @@ mux { - }; - }; - }; -+ -+ cec_AO: cec@100 { -+ compatible = "amlogic,meson-gx-ao-cec"; // FIXME -+ reg = <0x100 0x14>; -+ interrupts = ; -+ // TODO: 32768HZ clock -+ hdmi-phandle = <&hdmi_tx>; -+ status = "disabled"; -+ }; - }; - - &ao_arc_rproc { -@@ -479,6 +603,22 @@ gpio: banks@80b0 { - gpio-ranges = <&pinctrl_cbus 0 0 120>; - }; - -+ hdmi_hpd_pins: hdmi-hpd { -+ mux { -+ groups = "hdmi_hpd"; -+ function = "hdmi"; -+ bias-disable; -+ }; -+ }; -+ -+ hdmi_i2c_pins: hdmi-i2c { -+ mux { -+ groups = "hdmi_sda", "hdmi_scl"; -+ function = "hdmi"; -+ bias-disable; -+ }; -+ }; -+ - sd_a_pins: sd-a { - mux { - groups = "sd_d0_a", "sd_d1_a", "sd_d2_a", -@@ -584,6 +724,17 @@ smp-sram@1ff80 { - }; - }; - -+&cvbs_dac { -+ compatible = "amlogic,meson8-cvbs-dac", "amlogic,meson-cvbs-dac"; -+ -+ clocks = <&clkc CLKID_CTS_VDAC0>; -+ -+ nvmem-cells = <&cvbs_trimming>; -+ nvmem-cell-names = "cvbs_trimming"; -+ -+ status = "okay"; -+}; -+ - &efuse { - compatible = "amlogic,meson8-efuse"; - clocks = <&clkc CLKID_EFUSE>; -@@ -593,6 +744,10 @@ temperature_calib: calib@1f4 { - /* only the upper two bytes are relevant */ - reg = <0x1f4 0x4>; - }; -+ -+ cvbs_trimming: calib@1f8 { -+ reg = <0x1f8 0x2>; -+ }; - }; - - ðmac { -@@ -608,16 +763,18 @@ &gpio_intc { - }; - - &hhi { -- clkc: clock-controller { -+ clkc: clock-controller@0 { - compatible = "amlogic,meson8-clkc"; -+ reg = <0x0 0x39c>; - clocks = <&xtal>, <&ddr_clkc DDR_CLKID_DDR_PLL>; - clock-names = "xtal", "ddr_pll"; - #clock-cells = <1>; - #reset-cells = <1>; - }; - -- pwrc: power-controller { -+ pwrc: power-controller@100 { - compatible = "amlogic,meson8-pwrc"; -+ reg = <0x100 0x10>; - #power-domain-cells = <1>; - amlogic,ao-sysctrl = <&pmu>; - clocks = <&clkc CLKID_VPU>; -@@ -625,6 +782,13 @@ pwrc: power-controller { - assigned-clocks = <&clkc CLKID_VPU>; - assigned-clock-rates = <364285714>; - }; -+ -+ hdmi_tx_phy: hdmi-phy@3a0 { -+ compatible = "amlogic,meson8-hdmi-tx-phy"; -+ clocks = <&clkc CLKID_HDMI_PLL_HDMI_OUT>; -+ reg = <0x3a0 0xc>; -+ #phy-cells = <0>; -+ }; - }; - - &hwrng { -diff --git a/arch/arm/boot/dts/meson8b.dtsi b/arch/arm/boot/dts/meson8b.dtsi -index cf9c04a61ba..20acfc607f0 100644 ---- a/arch/arm/boot/dts/meson8b.dtsi -+++ b/arch/arm/boot/dts/meson8b.dtsi -@@ -276,6 +276,116 @@ mali: gpu@c0000 { - operating-points-v2 = <&gpu_opp_table>; - #cooling-cells = <2>; /* min followed by max */ - }; -+ -+ hdmi_tx: hdmi-tx@42000 { -+ compatible = "amlogic,meson8b-hdmi-tx"; -+ reg = <0x42000 0xc>; -+ interrupts = ; -+ phys = <&hdmi_tx_phy>; -+ phy-names = "hdmi"; -+ clocks = <&clkc CLKID_HDMI_PCLK>, -+ <&clkc CLKID_HDMI_SYS>; -+ clock-names = "pclk", "sys"; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ #sound-dai-cells = <1>; -+ sound-name-prefix = "HDMITX"; -+ -+ status = "disabled"; -+ -+ /* VPU VENC Input */ -+ hdmi_tx_venc_port: port@0 { -+ reg = <0>; -+ -+ hdmi_tx_in: endpoint { -+ remote-endpoint = <&hdmi_tx_out>; -+ }; -+ }; -+ -+ /* TMDS Output */ -+ hdmi_tx_tmds_port: port@1 { -+ reg = <1>; -+ }; -+ }; -+ -+ vpu: vpu@100000 { -+ compatible = "amlogic,meson8b-vpu"; -+ -+ reg = <0x100000 0x10000>; -+ reg-names = "vpu"; -+ -+ interrupts = ; -+ -+ amlogic,canvas = <&canvas>; -+ -+ /* -+ * The VCLK{,2}_IN path always needs to derived from -+ * the CLKID_VID_PLL_FINAL_DIV so other clocks like -+ * MPLL1 are not used (MPLL1 is reserved for audio -+ * purposes). -+ */ -+ assigned-clocks = <&clkc CLKID_VCLK_IN_SEL>, -+ <&clkc CLKID_VCLK2_IN_SEL>; -+ assigned-clock-parents = <&clkc CLKID_VID_PLL_FINAL_DIV>, -+ <&clkc CLKID_VID_PLL_FINAL_DIV>; -+ -+ clocks = <&clkc CLKID_VPU_INTR>, -+ <&clkc CLKID_HDMI_INTR_SYNC>, -+ <&clkc CLKID_GCLK_VENCI_INT>, -+ <&clkc CLKID_HDMI_PLL_HDMI_OUT>, -+ <&clkc CLKID_HDMI_TX_PIXEL>, -+ <&clkc CLKID_CTS_ENCP>, -+ <&clkc CLKID_CTS_ENCI>, -+ <&clkc CLKID_CTS_ENCT>, -+ <&clkc CLKID_CTS_ENCL>, -+ <&clkc CLKID_CTS_VDAC0>; -+ clock-names = "vpu_intr", -+ "hdmi_intr_sync", -+ "venci_int", -+ "tmds", -+ "hdmi_tx_pixel", -+ "cts_encp", -+ "cts_enci", -+ "cts_enct", -+ "cts_encl", -+ "cts_vdac0"; -+ -+ resets = <&clkc CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_PRE>, -+ <&clkc CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_POST>, -+ <&clkc CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_PRE>, -+ <&clkc CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_POST>; -+ reset-names = "vid_pll_pre", -+ "vid_pll_post", -+ "vid_pll_soft_pre", -+ "vid_pll_soft_post"; -+ -+ phys = <&cvbs_dac>; -+ phy-names = "cvbs-dac"; -+ -+ power-domains = <&pwrc PWRC_MESON8_VPU_ID>; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ #sound-dai-cells = <0>; -+ sound-name-prefix = "HDMITX"; -+ -+ /* CVBS VDAC output port */ -+ cvbs_vdac_port: port@0 { -+ reg = <0>; -+ }; -+ -+ /* HDMI-TX output port */ -+ hdmi_tx_port: port@1 { -+ reg = <1>; -+ -+ hdmi_tx_out: endpoint { -+ remote-endpoint = <&hdmi_tx_in>; -+ }; -+ }; -+ }; - }; - }; /* end of / */ - -@@ -325,6 +435,14 @@ gpio_ao: ao-bank@14 { - gpio-ranges = <&pinctrl_aobus 0 0 16>; - }; - -+ hdmi_cec_ao_pins: hdmi-cec-ao { -+ mux { -+ groups = "hdmi_cec_1"; -+ function = "hdmi_cec"; -+ bias-pull-up; -+ }; -+ }; -+ - i2s_am_clk_pins: i2s-am-clk-out { - mux { - groups = "i2s_am_clk_out"; -@@ -381,6 +499,15 @@ mux { - }; - }; - }; -+ -+ cec_AO: cec@100 { -+ compatible = "amlogic,meson-gx-ao-cec"; // FIXME -+ reg = <0x100 0x14>; -+ interrupts = ; -+ // TODO: 32768HZ clock -+ hdmi-phandle = <&hdmi_tx>; -+ status = "disabled"; -+ }; - }; - - &ao_arc_rproc { -@@ -471,6 +598,22 @@ mux { - }; - }; - -+ hdmi_hpd_pins: hdmi-hpd { -+ mux { -+ groups = "hdmi_hpd"; -+ function = "hdmi"; -+ bias-disable; -+ }; -+ }; -+ -+ hdmi_i2c_pins: hdmi-i2c { -+ mux { -+ groups = "hdmi_sda", "hdmi_scl"; -+ function = "hdmi"; -+ bias-disable; -+ }; -+ }; -+ - i2c_a_pins: i2c-a { - mux { - groups = "i2c_sda_a", "i2c_sck_a"; -@@ -547,6 +690,16 @@ smp-sram@1ff80 { - }; - }; - -+&cvbs_dac { -+ compatible = "amlogic,meson8-cvbs-dac", "amlogic,meson-cvbs-dac"; -+ -+ clocks = <&clkc CLKID_CTS_VDAC0>; -+ -+ nvmem-cells = <&cvbs_trimming>; -+ nvmem-cell-names = "cvbs_trimming"; -+ -+ status = "okay"; -+}; - - &efuse { - compatible = "amlogic,meson8b-efuse"; -@@ -557,6 +710,10 @@ temperature_calib: calib@1f4 { - /* only the upper two bytes are relevant */ - reg = <0x1f4 0x4>; - }; -+ -+ cvbs_trimming: calib@1f8 { -+ reg = <0x1f8 0x2>; -+ }; - }; - - ðmac { -@@ -586,16 +743,18 @@ &gpio_intc { - }; - - &hhi { -- clkc: clock-controller { -+ clkc: clock-controller@0 { - compatible = "amlogic,meson8b-clkc"; -+ reg = <0x0 0x39c>; - clocks = <&xtal>, <&ddr_clkc DDR_CLKID_DDR_PLL>; - clock-names = "xtal", "ddr_pll"; - #clock-cells = <1>; - #reset-cells = <1>; - }; - -- pwrc: power-controller { -+ pwrc: power-controller@100 { - compatible = "amlogic,meson8b-pwrc"; -+ reg = <0x100 0x10>; - #power-domain-cells = <1>; - amlogic,ao-sysctrl = <&pmu>; - resets = <&reset RESET_DBLK>, -@@ -617,6 +776,14 @@ pwrc: power-controller { - assigned-clocks = <&clkc CLKID_VPU>; - assigned-clock-rates = <182142857>; - }; -+ -+ hdmi_tx_phy: hdmi-phy@3a0 { -+ compatible = "amlogic,meson8b-hdmi-tx-phy", -+ "amlogic,meson8-hdmi-tx-phy"; -+ clocks = <&clkc CLKID_HDMI_PLL_HDMI_OUT>; -+ reg = <0x3a0 0xc>; -+ #phy-cells = <0>; -+ }; - }; - - &hwrng { -diff --git a/arch/arm/boot/dts/meson8m2.dtsi b/arch/arm/boot/dts/meson8m2.dtsi -index 6725dd9fd82..fcb2ad97609 100644 ---- a/arch/arm/boot/dts/meson8m2.dtsi -+++ b/arch/arm/boot/dts/meson8m2.dtsi -@@ -96,6 +96,10 @@ &usb1_phy { - compatible = "amlogic,meson8m2-usb2-phy", "amlogic,meson-mx-usb2-phy"; - }; - -+&vpu { -+ compatible = "amlogic,meson8m2-vpu"; -+}; -+ - &wdt { - compatible = "amlogic,meson8m2-wdt", "amlogic,meson8b-wdt"; - }; -diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig -index 823909da87d..ba9f1bc8408 100644 ---- a/drivers/gpu/drm/meson/Kconfig -+++ b/drivers/gpu/drm/meson/Kconfig -@@ -10,6 +10,7 @@ config DRM_MESON - select REGMAP_MMIO - select MESON_CANVAS - select CEC_CORE if CEC_NOTIFIER -+ imply PHY_MESON_CVBS_DAC - - config DRM_MESON_DW_HDMI - tristate "HDMI Synopsys Controller support for Amlogic Meson Display" -@@ -17,3 +18,11 @@ config DRM_MESON_DW_HDMI - default y if DRM_MESON - select DRM_DW_HDMI - imply DRM_DW_HDMI_I2S_AUDIO -+ -+config DRM_MESON_TRANSWITCH_HDMI -+ tristate "Amlogic Meson8/8b/8m2 TranSwitch HDMI 1.4 Controller support" -+ depends on ARM || COMPILE_TEST -+ depends on DRM_MESON -+ default y if DRM_MESON -+ select REGMAP_MMIO -+ select SND_SOC_HDMI_CODEC if SND_SOC -diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile -index 3afa31bdc95..817a5270aee 100644 ---- a/drivers/gpu/drm/meson/Makefile -+++ b/drivers/gpu/drm/meson/Makefile -@@ -6,3 +6,4 @@ meson-drm-y += meson_encoder_hdmi.o - - obj-$(CONFIG_DRM_MESON) += meson-drm.o - obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o -+obj-$(CONFIG_DRM_MESON_TRANSWITCH_HDMI) += meson_transwitch_hdmi.o -diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c -index 3b24a924b7b..091c670ab0e 100644 ---- a/drivers/gpu/drm/meson/meson_drv.c -+++ b/drivers/gpu/drm/meson/meson_drv.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -132,30 +133,147 @@ static struct regmap_config meson_regmap_config = { - .max_register = 0x1000, - }; - -+static int meson_cvbs_dac_phy_init(struct meson_drm *priv) -+{ -+ struct platform_device *pdev; -+ const char *platform_id_name; -+ -+ priv->cvbs_dac = devm_phy_optional_get(priv->dev, "cvbs-dac"); -+ if (IS_ERR(priv->cvbs_dac)) -+ return dev_err_probe(priv->dev, PTR_ERR(priv->cvbs_dac), -+ "Failed to get the 'cvbs-dac' PHY\n"); -+ else if (priv->cvbs_dac) -+ return 0; -+ -+ switch (priv->compat) { -+ case VPU_COMPATIBLE_GXBB: -+ platform_id_name = "meson-gxbb-cvbs-dac"; -+ break; -+ case VPU_COMPATIBLE_GXL: -+ case VPU_COMPATIBLE_GXM: -+ platform_id_name = "meson-gxl-cvbs-dac"; -+ break; -+ case VPU_COMPATIBLE_G12A: -+ platform_id_name = "meson-g12a-cvbs-dac"; -+ break; -+ default: -+ return dev_err_probe(priv->dev, -EINVAL, -+ "No CVBS DAC platform ID found\n"); -+ } -+ -+ pdev = platform_device_register_data(priv->dev, platform_id_name, -+ PLATFORM_DEVID_AUTO, NULL, 0); -+ if (IS_ERR(pdev)) -+ return dev_err_probe(priv->dev, PTR_ERR(pdev), -+ "Failed to register fallback CVBS DAC PHY platform device\n"); -+ -+ priv->cvbs_dac = platform_get_drvdata(pdev); -+ if (IS_ERR(priv->cvbs_dac)) { -+ platform_device_unregister(pdev); -+ return dev_err_probe(priv->dev, PTR_ERR(priv->cvbs_dac), -+ "Failed to get the 'cvbs-dac' PHY from it's platform device\n"); -+ } -+ -+ dev_warn(priv->dev, "Using fallback for old .dtbs without CVBS DAC\n"); -+ -+ priv->cvbs_dac_pdev = pdev; -+ -+ return 0; -+} -+ -+static void meson_cvbs_dac_phy_exit(struct meson_drm *priv) -+{ -+ platform_device_unregister(priv->cvbs_dac_pdev); -+} -+ - static void meson_vpu_init(struct meson_drm *priv) - { -- u32 value; -+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) { -+ writel(0x0, priv->io_base + _REG(VPU_MEM_PD_REG0)); -+ writel(0x0, priv->io_base + _REG(VPU_MEM_PD_REG1)); -+ } else { -+ u32 value; -+ -+ /* -+ * Slave dc0 and dc5 connected to master port 1. -+ * By default other slaves are connected to master port 0. -+ */ -+ value = VPU_RDARB_SLAVE_TO_MASTER_PORT(0, 1) | -+ VPU_RDARB_SLAVE_TO_MASTER_PORT(5, 1); -+ writel_relaxed(value, -+ priv->io_base + _REG(VPU_RDARB_MODE_L1C1)); -+ -+ /* Slave dc0 connected to master port 1 */ -+ value = VPU_RDARB_SLAVE_TO_MASTER_PORT(0, 1); -+ writel_relaxed(value, -+ priv->io_base + _REG(VPU_RDARB_MODE_L1C2)); -+ -+ /* Slave dc4 and dc7 connected to master port 1 */ -+ value = VPU_RDARB_SLAVE_TO_MASTER_PORT(4, 1) | -+ VPU_RDARB_SLAVE_TO_MASTER_PORT(7, 1); -+ writel_relaxed(value, -+ priv->io_base + _REG(VPU_RDARB_MODE_L2C1)); -+ -+ /* Slave dc1 connected to master port 1 */ -+ value = VPU_RDARB_SLAVE_TO_MASTER_PORT(1, 1); -+ writel_relaxed(value, -+ priv->io_base + _REG(VPU_WRARB_MODE_L2C1)); -+ } -+} -+ -+static int meson_video_clock_init(struct meson_drm *priv) -+{ -+ int ret; -+ -+ ret = clk_bulk_prepare(VPU_VID_CLK_NUM, priv->vid_clks); -+ if (ret) -+ return dev_err_probe(priv->dev, ret, -+ "Failed to prepare the video clocks\n"); -+ -+ ret = clk_bulk_prepare(priv->num_intr_clks, priv->intr_clks); -+ if (ret) -+ return dev_err_probe(priv->dev, ret, -+ "Failed to prepare the interrupt clocks\n"); -+ -+ return 0; -+} -+ -+static void meson_video_clock_exit(struct meson_drm *priv) -+{ -+ if (priv->clk_dac_enabled) -+ clk_disable(priv->clk_dac); -+ -+ if (priv->clk_venc_enabled) -+ clk_disable(priv->clk_venc); -+ -+ clk_bulk_unprepare(priv->num_intr_clks, priv->intr_clks); -+ clk_bulk_unprepare(VPU_VID_CLK_NUM, priv->vid_clks); -+} -+ -+static void meson_fbdev_setup(struct meson_drm *priv) -+{ -+ unsigned int preferred_bpp; - - /* -- * Slave dc0 and dc5 connected to master port 1. -- * By default other slaves are connected to master port 0. -+ * All SoC generations before GXBB don't have a way to configure the -+ * alpha value for DRM_FORMAT_XRGB8888 and DRM_FORMAT_XBGR8888. These -+ * formats have an X component instead of an alpha component. On -+ * Meson8/8b/8m2 there is no way to configure the alpha value to use -+ * instead of the X component. This results in the fact that the -+ * formats with X component are only supported on GXBB and newer. Use -+ * 24 bits per pixel and therefore DRM_FORMAT_RGB888 to get a -+ * working framebuffer console. - */ -- value = VPU_RDARB_SLAVE_TO_MASTER_PORT(0, 1) | -- VPU_RDARB_SLAVE_TO_MASTER_PORT(5, 1); -- writel_relaxed(value, priv->io_base + _REG(VPU_RDARB_MODE_L1C1)); -- -- /* Slave dc0 connected to master port 1 */ -- value = VPU_RDARB_SLAVE_TO_MASTER_PORT(0, 1); -- writel_relaxed(value, priv->io_base + _REG(VPU_RDARB_MODE_L1C2)); -- -- /* Slave dc4 and dc7 connected to master port 1 */ -- value = VPU_RDARB_SLAVE_TO_MASTER_PORT(4, 1) | -- VPU_RDARB_SLAVE_TO_MASTER_PORT(7, 1); -- writel_relaxed(value, priv->io_base + _REG(VPU_RDARB_MODE_L2C1)); -- -- /* Slave dc1 connected to master port 1 */ -- value = VPU_RDARB_SLAVE_TO_MASTER_PORT(1, 1); -- writel_relaxed(value, priv->io_base + _REG(VPU_WRARB_MODE_L2C1)); -+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) -+ preferred_bpp = 24; -+ else -+ preferred_bpp = 32; -+ -+ drm_fbdev_generic_setup(priv->drm, preferred_bpp); - } - - struct meson_drm_soc_attr { -@@ -164,13 +282,29 @@ struct meson_drm_soc_attr { - }; - - static const struct meson_drm_soc_attr meson_drm_soc_attrs[] = { -- /* S805X/S805Y HDMI PLL won't lock for HDMI PHY freq > 1,65GHz */ -+ /* The maximum frequency of HDMI PHY on Meson8 and Meson8m2 is ~3GHz */ -+ { -+ .limits = { -+ .max_hdmi_phy_freq = 2976000, -+ }, -+ .attrs = (const struct soc_device_attribute []) { -+ { .soc_id = "Meson8 (S802)", }, -+ { .soc_id = "Meson8m2 (S812)", }, -+ { /* sentinel */ }, -+ } -+ }, -+ /* -+ * GXL S805X/S805Y HDMI PLL won't lock for HDMI PHY freq > 1,65GHz. -+ * Meson8b (S805) only supports "1200p@60 max resolution" according to -+ * the public datasheet. -+ */ - { - .limits = { - .max_hdmi_phy_freq = 1650000, - }, - .attrs = (const struct soc_device_attribute []) { - { .soc_id = "GXL (S805*)", }, -+ { .soc_id = "Meson8b (S805)", }, - { /* sentinel */ } - } - }, -@@ -211,67 +345,123 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) - priv->compat = match->compat; - priv->afbcd.ops = match->afbcd_ops; - -+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) { -+ priv->vid_pll_resets[VPU_RESET_VID_PLL_PRE].id = "vid_pll_pre"; -+ priv->vid_pll_resets[VPU_RESET_VID_PLL_POST].id = "vid_pll_post"; -+ priv->vid_pll_resets[VPU_RESET_VID_PLL_SOFT_PRE].id = "vid_pll_soft_pre"; -+ priv->vid_pll_resets[VPU_RESET_VID_PLL_SOFT_POST].id = "vid_pll_soft_post"; -+ -+ ret = devm_reset_control_bulk_get_exclusive(dev, -+ VPU_RESET_VID_PLL_NUM, -+ priv->vid_pll_resets); -+ if (ret) -+ goto free_drm; -+ -+ priv->intr_clks[0].id = "vpu_intr"; -+ priv->intr_clks[1].id = "hdmi_intr_sync"; -+ priv->intr_clks[2].id = "venci_int"; -+ priv->num_intr_clks = 3; -+ -+ ret = devm_clk_bulk_get(dev, priv->num_intr_clks, -+ priv->intr_clks); -+ if (ret) -+ goto free_drm; -+ -+ priv->vid_clks[VPU_VID_CLK_TMDS].id = "tmds"; -+ priv->vid_clks[VPU_VID_CLK_HDMI_TX_PIXEL].id = "hdmi_tx_pixel"; -+ priv->vid_clks[VPU_VID_CLK_CTS_ENCP].id = "cts_encp"; -+ priv->vid_clks[VPU_VID_CLK_CTS_ENCI].id = "cts_enci"; -+ priv->vid_clks[VPU_VID_CLK_CTS_ENCT].id = "cts_enct"; -+ priv->vid_clks[VPU_VID_CLK_CTS_ENCL].id = "cts_encl"; -+ priv->vid_clks[VPU_VID_CLK_CTS_VDAC0].id = "cts_vdac0"; -+ -+ ret = devm_clk_bulk_get(dev, VPU_VID_CLK_NUM, priv->vid_clks); -+ if (ret) -+ goto free_drm; -+ } else { -+ priv->intr_clks[0].id = "vpu_intr"; -+ priv->num_intr_clks = 1; -+ -+ ret = devm_clk_bulk_get_optional(dev, priv->num_intr_clks, -+ priv->intr_clks); -+ if (ret) -+ goto free_drm; -+ } -+ -+ ret = meson_video_clock_init(priv); -+ if (ret) -+ goto free_drm; -+ - regs = devm_platform_ioremap_resource_byname(pdev, "vpu"); - if (IS_ERR(regs)) { - ret = PTR_ERR(regs); -- goto free_drm; -+ goto video_clock_exit; - } - - priv->io_base = regs; - -+ /* -+ * The HHI resource is optional because it contains the clocks and CVBS -+ * encoder registers. These are managed by separate drivers though. -+ */ - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hhi"); -- if (!res) { -- ret = -EINVAL; -- goto free_drm; -- } -- /* Simply ioremap since it may be a shared register zone */ -- regs = devm_ioremap(dev, res->start, resource_size(res)); -- if (!regs) { -- ret = -EADDRNOTAVAIL; -- goto free_drm; -- } -+ if (res) { -+ /* Simply ioremap since it may be a shared register zone */ -+ regs = devm_ioremap(dev, res->start, resource_size(res)); -+ if (!regs) { -+ ret = -EADDRNOTAVAIL; -+ goto video_clock_exit; -+ } - -- priv->hhi = devm_regmap_init_mmio(dev, regs, -- &meson_regmap_config); -- if (IS_ERR(priv->hhi)) { -- dev_err(&pdev->dev, "Couldn't create the HHI regmap\n"); -- ret = PTR_ERR(priv->hhi); -- goto free_drm; -+ priv->hhi = devm_regmap_init_mmio(dev, regs, -+ &meson_regmap_config); -+ if (IS_ERR(priv->hhi)) { -+ dev_err(&pdev->dev, -+ "Couldn't create the HHI regmap\n"); -+ ret = PTR_ERR(priv->hhi); -+ goto video_clock_exit; -+ } - } - - priv->canvas = meson_canvas_get(dev); - if (IS_ERR(priv->canvas)) { - ret = PTR_ERR(priv->canvas); -- goto free_drm; -+ goto video_clock_exit; - } - - ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_osd1); - if (ret) -- goto free_drm; -+ goto video_clock_exit; - ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_0); - if (ret) { - meson_canvas_free(priv->canvas, priv->canvas_id_osd1); -- goto free_drm; -+ goto video_clock_exit; - } - ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_1); - if (ret) { - meson_canvas_free(priv->canvas, priv->canvas_id_osd1); - meson_canvas_free(priv->canvas, priv->canvas_id_vd1_0); -- goto free_drm; -+ goto video_clock_exit; - } - ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_2); - if (ret) { - meson_canvas_free(priv->canvas, priv->canvas_id_osd1); - meson_canvas_free(priv->canvas, priv->canvas_id_vd1_0); - meson_canvas_free(priv->canvas, priv->canvas_id_vd1_1); -- goto free_drm; -+ goto video_clock_exit; - } - -+ ret = meson_cvbs_dac_phy_init(priv); -+ if (ret) -+ goto free_drm; -+ - priv->vsync_irq = platform_get_irq(pdev, 0); - - ret = drm_vblank_init(drm, 1); - if (ret) -- goto free_drm; -+ goto exit_cvbs_dac_phy; - - /* Assign limits per soc revision/package */ - for (i = 0 ; i < ARRAY_SIZE(meson_drm_soc_attrs) ; ++i) { -@@ -287,11 +477,11 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) - */ - ret = drm_aperture_remove_framebuffers(false, &meson_driver); - if (ret) -- goto free_drm; -+ goto exit_cvbs_dac_phy; - - ret = drmm_mode_config_init(drm); - if (ret) -- goto free_drm; -+ goto exit_cvbs_dac_phy; - drm->mode_config.max_width = 3840; - drm->mode_config.max_height = 2160; - drm->mode_config.funcs = &meson_mode_config_funcs; -@@ -306,7 +496,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) - if (priv->afbcd.ops) { - ret = priv->afbcd.ops->init(priv); - if (ret) -- goto free_drm; -+ goto exit_cvbs_dac_phy; - } - - /* Encoder Initialization */ -@@ -319,7 +509,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) - ret = component_bind_all(drm->dev, drm); - if (ret) { - dev_err(drm->dev, "Couldn't bind all components\n"); -- goto exit_afbcd; -+ goto exit_cvbs_dac_phy; - } - } - -@@ -353,7 +543,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) - if (ret) - goto uninstall_irq; - -- drm_fbdev_generic_setup(drm, 32); -+ meson_fbdev_setup(priv); - - return 0; - -@@ -362,6 +552,10 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) - exit_afbcd: - if (priv->afbcd.ops) - priv->afbcd.ops->exit(priv); -+exit_cvbs_dac_phy: -+ meson_cvbs_dac_phy_exit(priv); -+video_clock_exit: -+ meson_video_clock_exit(priv); - free_drm: - drm_dev_put(drm); - -@@ -398,6 +592,10 @@ static void meson_drv_unbind(struct device *dev) - - if (priv->afbcd.ops) - priv->afbcd.ops->exit(priv); -+ -+ meson_cvbs_dac_phy_exit(priv); -+ -+ meson_video_clock_exit(priv); - } - - static const struct component_master_ops meson_drv_master_ops = { -@@ -412,6 +610,8 @@ static int __maybe_unused meson_drv_pm_suspend(struct device *dev) - if (!priv) - return 0; - -+ // TODO: video clock suspend -+ - return drm_mode_config_helper_suspend(priv->drm); - } - -@@ -422,6 +622,7 @@ static int __maybe_unused meson_drv_pm_resume(struct device *dev) - if (!priv) - return 0; - -+ meson_video_clock_init(priv); - meson_vpu_init(priv); - meson_venc_init(priv); - meson_vpp_init(priv); -@@ -504,6 +705,18 @@ static int meson_drv_remove(struct platform_device *pdev) - return 0; - } - -+static struct meson_drm_match_data meson_drm_m8_data = { -+ .compat = VPU_COMPATIBLE_M8, -+}; -+ -+static struct meson_drm_match_data meson_drm_m8b_data = { -+ .compat = VPU_COMPATIBLE_M8B, -+}; -+ -+static struct meson_drm_match_data meson_drm_m8m2_data = { -+ .compat = VPU_COMPATIBLE_M8M2, -+}; -+ - static struct meson_drm_match_data meson_drm_gxbb_data = { - .compat = VPU_COMPATIBLE_GXBB, - }; -@@ -523,6 +736,12 @@ static struct meson_drm_match_data meson_drm_g12a_data = { - }; - - static const struct of_device_id dt_match[] = { -+ { .compatible = "amlogic,meson8-vpu", -+ .data = (void *)&meson_drm_m8_data }, -+ { .compatible = "amlogic,meson8b-vpu", -+ .data = (void *)&meson_drm_m8b_data }, -+ { .compatible = "amlogic,meson8m2-vpu", -+ .data = (void *)&meson_drm_m8m2_data }, - { .compatible = "amlogic,meson-gxbb-vpu", - .data = (void *)&meson_drm_gxbb_data }, - { .compatible = "amlogic,meson-gxl-vpu", -diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h -index c62ee358456..fe0a8f8762f 100644 ---- a/drivers/gpu/drm/meson/meson_drv.h -+++ b/drivers/gpu/drm/meson/meson_drv.h -@@ -7,22 +7,29 @@ - #ifndef __MESON_DRV_H - #define __MESON_DRV_H - -+#include - #include - #include - #include - #include -+#include - - struct drm_crtc; - struct drm_device; - struct drm_plane; - struct meson_drm; - struct meson_afbcd_ops; -+struct phy; -+struct platform_device; - - enum vpu_compatible { -- VPU_COMPATIBLE_GXBB = 0, -- VPU_COMPATIBLE_GXL = 1, -- VPU_COMPATIBLE_GXM = 2, -- VPU_COMPATIBLE_G12A = 3, -+ VPU_COMPATIBLE_M8 = 0, -+ VPU_COMPATIBLE_M8B = 1, -+ VPU_COMPATIBLE_M8M2 = 2, -+ VPU_COMPATIBLE_GXBB = 3, -+ VPU_COMPATIBLE_GXL = 4, -+ VPU_COMPATIBLE_GXM = 5, -+ VPU_COMPATIBLE_G12A = 6, - }; - - enum { -@@ -40,6 +47,25 @@ struct meson_drm_soc_limits { - unsigned int max_hdmi_phy_freq; - }; - -+enum vpu_bulk_clk_id { -+ VPU_VID_CLK_TMDS = 0, -+ VPU_VID_CLK_HDMI_TX_PIXEL, -+ VPU_VID_CLK_CTS_ENCP, -+ VPU_VID_CLK_CTS_ENCI, -+ VPU_VID_CLK_CTS_ENCT, -+ VPU_VID_CLK_CTS_ENCL, -+ VPU_VID_CLK_CTS_VDAC0, -+ VPU_VID_CLK_NUM -+}; -+ -+enum vpu_bulk_vid_pll_reset_id { -+ VPU_RESET_VID_PLL_PRE = 0, -+ VPU_RESET_VID_PLL_POST, -+ VPU_RESET_VID_PLL_SOFT_PRE, -+ VPU_RESET_VID_PLL_SOFT_POST, -+ VPU_RESET_VID_PLL_NUM -+}; -+ - struct meson_drm { - struct device *dev; - enum vpu_compatible compat; -@@ -61,6 +87,21 @@ struct meson_drm { - - const struct meson_drm_soc_limits *limits; - -+ struct phy *cvbs_dac; -+ bool cvbs_dac_enabled; -+ struct platform_device *cvbs_dac_pdev; -+ -+ struct clk_bulk_data intr_clks[3]; -+ unsigned int num_intr_clks; -+ bool intr_clks_enabled; -+ struct clk_bulk_data vid_clks[VPU_VID_CLK_NUM]; -+ bool vid_clk_rate_exclusive[VPU_VID_CLK_NUM]; -+ struct clk *clk_venc; -+ bool clk_venc_enabled; -+ struct clk *clk_dac; -+ bool clk_dac_enabled; -+ struct reset_control_bulk_data vid_pll_resets[VPU_RESET_VID_PLL_NUM]; -+ - /* Components Data */ - struct { - bool osd1_enabled; -diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c -index 3f73b211fa8..833f701fe27 100644 ---- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c -+++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c -@@ -11,6 +11,7 @@ - - #include - #include -+#include - - #include - #include -@@ -24,12 +25,6 @@ - #include "meson_vclk.h" - #include "meson_encoder_cvbs.h" - --/* HHI VDAC Registers */ --#define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */ --#define HHI_VDAC_CNTL0_G12A 0x2EC /* 0xbd offset in data sheet */ --#define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */ --#define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbe offset in data sheet */ -- - struct meson_encoder_cvbs { - struct drm_encoder encoder; - struct drm_bridge bridge; -@@ -87,11 +82,28 @@ static int meson_encoder_cvbs_attach(struct drm_bridge *bridge, - { - struct meson_encoder_cvbs *meson_encoder_cvbs = - bridge_to_meson_encoder_cvbs(bridge); -+ int ret; -+ -+ ret = phy_init(meson_encoder_cvbs->priv->cvbs_dac); -+ if (ret) -+ return ret; - - return drm_bridge_attach(bridge->encoder, meson_encoder_cvbs->next_bridge, - &meson_encoder_cvbs->bridge, flags); - } - -+static void meson_encoder_cvbs_detach(struct drm_bridge *bridge) -+{ -+ struct meson_encoder_cvbs *meson_encoder_cvbs = -+ bridge_to_meson_encoder_cvbs(bridge); -+ int ret; -+ -+ ret = phy_exit(meson_encoder_cvbs->priv->cvbs_dac); -+ if (ret) -+ dev_err(meson_encoder_cvbs->priv->dev, -+ "Failed to exit the CVBS DAC\n"); -+} -+ - static int meson_encoder_cvbs_get_modes(struct drm_bridge *bridge, - struct drm_connector *connector) - { -@@ -148,6 +160,7 @@ static void meson_encoder_cvbs_atomic_enable(struct drm_bridge *bridge, - struct drm_connector_state *conn_state; - struct drm_crtc_state *crtc_state; - struct drm_connector *connector; -+ int ret; - - connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); - if (WARN_ON(!connector)) -@@ -177,16 +190,13 @@ static void meson_encoder_cvbs_atomic_enable(struct drm_bridge *bridge, - writel_bits_relaxed(VENC_VDAC_SEL_ATV_DMD, 0, - priv->io_base + _REG(VENC_VDAC_DACSEL0)); - -- if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) { -- regmap_write(priv->hhi, HHI_VDAC_CNTL0, 1); -- regmap_write(priv->hhi, HHI_VDAC_CNTL1, 0); -- } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) || -- meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) { -- regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0xf0001); -- regmap_write(priv->hhi, HHI_VDAC_CNTL1, 0); -- } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { -- regmap_write(priv->hhi, HHI_VDAC_CNTL0_G12A, 0x906001); -- regmap_write(priv->hhi, HHI_VDAC_CNTL1_G12A, 0); -+ if (!priv->cvbs_dac_enabled) { -+ ret = phy_power_on(priv->cvbs_dac); -+ if (ret) -+ dev_err(priv->dev, -+ "Failed to power on the CVBS DAC\n"); -+ else -+ priv->cvbs_dac_enabled = true; - } - } - -@@ -196,19 +206,22 @@ static void meson_encoder_cvbs_atomic_disable(struct drm_bridge *bridge, - struct meson_encoder_cvbs *meson_encoder_cvbs = - bridge_to_meson_encoder_cvbs(bridge); - struct meson_drm *priv = meson_encoder_cvbs->priv; -+ int ret; - -- /* Disable CVBS VDAC */ -- if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { -- regmap_write(priv->hhi, HHI_VDAC_CNTL0_G12A, 0); -- regmap_write(priv->hhi, HHI_VDAC_CNTL1_G12A, 0); -- } else { -- regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0); -- regmap_write(priv->hhi, HHI_VDAC_CNTL1, 8); -- } -+ if (!priv->cvbs_dac_enabled) -+ return; -+ -+ ret = phy_power_off(priv->cvbs_dac); -+ if (ret) -+ dev_err(priv->dev, -+ "Failed to power off the CVBS DAC\n"); -+ else -+ priv->cvbs_dac_enabled = false; - } - - static const struct drm_bridge_funcs meson_encoder_cvbs_bridge_funcs = { - .attach = meson_encoder_cvbs_attach, -+ .detach = meson_encoder_cvbs_detach, - .mode_valid = meson_encoder_cvbs_mode_valid, - .get_modes = meson_encoder_cvbs_get_modes, - .atomic_enable = meson_encoder_cvbs_atomic_enable, -diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c -index 53231bfdf7e..f950c557d5f 100644 ---- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c -+++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c -@@ -188,13 +188,13 @@ static void meson_encoder_hdmi_atomic_enable(struct drm_bridge *bridge, - { - struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge); - struct drm_atomic_state *state = bridge_state->base.state; -- unsigned int ycrcb_map = VPU_HDMI_OUTPUT_CBYCR; - struct meson_drm *priv = encoder_hdmi->priv; - struct drm_connector_state *conn_state; - const struct drm_display_mode *mode; - struct drm_crtc_state *crtc_state; - struct drm_connector *connector; - bool yuv420_mode = false; -+ unsigned int ycrcb_map; - int vic; - - connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); -@@ -215,7 +215,14 @@ static void meson_encoder_hdmi_atomic_enable(struct drm_bridge *bridge, - - dev_dbg(priv->dev, "\"%s\" vic %d\n", mode->name, vic); - -- if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) { -+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) { -+ if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_RGB888_1X24) -+ ycrcb_map = VPU_HDMI_OUTPUT_YCBCR; -+ else -+ ycrcb_map = VPU_HDMI_OUTPUT_CRYCB; -+ } else if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) { - ycrcb_map = VPU_HDMI_OUTPUT_CRYCB; - yuv420_mode = true; - } else if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYVY8_1X16) -@@ -227,17 +234,22 @@ static void meson_encoder_hdmi_atomic_enable(struct drm_bridge *bridge, - /* VCLK Set clock */ - meson_encoder_hdmi_set_vclk(encoder_hdmi, mode); - -- if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) -- /* Setup YUV420 to HDMI-TX, no 10bit diphering */ -- writel_relaxed(2 | (2 << 2), -- priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); -- else if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYVY8_1X16) -- /* Setup YUV422 to HDMI-TX, no 10bit diphering */ -- writel_relaxed(1 | (2 << 2), -- priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); -- else -- /* Setup YUV444 to HDMI-TX, no 10bit diphering */ -- writel_relaxed(0, priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); -+ if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) && -+ !meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) && -+ !meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) { -+ if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) -+ /* Setup YUV420 to HDMI-TX, no 10bit diphering */ -+ writel_relaxed(2 | (2 << 2), -+ priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); -+ else if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYVY8_1X16) -+ /* Setup YUV422 to HDMI-TX, no 10bit diphering */ -+ writel_relaxed(1 | (2 << 2), -+ priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); -+ else -+ /* Setup YUV444 to HDMI-TX, no 10bit diphering */ -+ writel_relaxed(0, -+ priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); -+ } - - dev_dbg(priv->dev, "%s\n", priv->venc.hdmi_use_enci ? "VENCI" : "VENCP"); - -@@ -260,7 +272,11 @@ static void meson_encoder_hdmi_atomic_disable(struct drm_bridge *bridge, - writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN)); - } - --static const u32 meson_encoder_hdmi_out_bus_fmts[] = { -+static const u32 meson8_encoder_hdmi_out_bus_fmts[] = { -+ MEDIA_BUS_FMT_YUV8_1X24, -+}; -+ -+static const u32 meson_gx_encoder_hdmi_out_bus_fmts[] = { - MEDIA_BUS_FMT_YUV8_1X24, - MEDIA_BUS_FMT_UYVY8_1X16, - MEDIA_BUS_FMT_UYYVYY8_0_5X24, -@@ -274,13 +290,27 @@ meson_encoder_hdmi_get_inp_bus_fmts(struct drm_bridge *bridge, - u32 output_fmt, - unsigned int *num_input_fmts) - { -+ struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge); -+ struct meson_drm *priv = encoder_hdmi->priv; -+ unsigned int num_out_bus_fmts; -+ const u32 *out_bus_fmts; - u32 *input_fmts = NULL; - int i; - -+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) { -+ num_out_bus_fmts = ARRAY_SIZE(meson8_encoder_hdmi_out_bus_fmts); -+ out_bus_fmts = meson8_encoder_hdmi_out_bus_fmts; -+ } else { -+ num_out_bus_fmts = ARRAY_SIZE(meson_gx_encoder_hdmi_out_bus_fmts); -+ out_bus_fmts = meson_gx_encoder_hdmi_out_bus_fmts; -+ } -+ - *num_input_fmts = 0; - -- for (i = 0 ; i < ARRAY_SIZE(meson_encoder_hdmi_out_bus_fmts) ; ++i) { -- if (output_fmt == meson_encoder_hdmi_out_bus_fmts[i]) { -+ for (i = 0 ; i < num_out_bus_fmts ; ++i) { -+ if (output_fmt == out_bus_fmts[i]) { - *num_input_fmts = 1; - input_fmts = kcalloc(*num_input_fmts, - sizeof(*input_fmts), -@@ -432,8 +462,11 @@ int meson_encoder_hdmi_init(struct meson_drm *priv) - - drm_connector_attach_max_bpc_property(meson_encoder_hdmi->connector, 8, 8); - -- /* Handle this here until handled by drm_bridge_connector_init() */ -- meson_encoder_hdmi->connector->ycbcr_420_allowed = true; -+ if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) && -+ !meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) && -+ !meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) -+ /* Handle this here until handled by drm_bridge_connector_init() */ -+ meson_encoder_hdmi->connector->ycbcr_420_allowed = true; - - pdev = of_find_device_by_node(remote); - of_node_put(remote); -diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c -index 815dfe30492..27e39577218 100644 ---- a/drivers/gpu/drm/meson/meson_plane.c -+++ b/drivers/gpu/drm/meson/meson_plane.c -@@ -200,8 +200,11 @@ static void meson_plane_atomic_update(struct drm_plane *plane, - priv->viu.osd1_ctrl_stat2 &= ~OSD_DPATH_MALI_AFBCD; - } - -- /* On GXBB, Use the old non-HDR RGB2YUV converter */ -- if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) -+ /* On GXBB and earlier, Use the old non-HDR RGB2YUV converter */ -+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) - priv->viu.osd1_blk0_cfg[0] |= OSD_OUTPUT_COLOR_RGB; - - if (priv->viu.osd1_afbcd && -@@ -471,7 +474,20 @@ static const struct drm_plane_funcs meson_plane_funcs = { - .format_mod_supported = meson_plane_format_mod_supported, - }; - --static const uint32_t supported_drm_formats[] = { -+/* -+ * X components (for example in DRM_FORMAT_XRGB8888 and DRM_FORMAT_XBGR8888) -+ * are not supported because these older SoC's are lacking the OSD_REPLACE_EN -+ * bit to replace the X alpha component with a static value, leaving the alpha -+ * component in an undefined state. -+ */ -+static const uint32_t supported_drm_formats_m8[] = { -+ DRM_FORMAT_ARGB8888, -+ DRM_FORMAT_ABGR8888, -+ DRM_FORMAT_RGB888, -+ DRM_FORMAT_RGB565, -+}; -+ -+static const uint32_t supported_drm_formats_gx[] = { - DRM_FORMAT_ARGB8888, - DRM_FORMAT_ABGR8888, - DRM_FORMAT_XRGB8888, -@@ -533,6 +549,8 @@ int meson_plane_create(struct meson_drm *priv) - { - struct meson_plane *meson_plane; - struct drm_plane *plane; -+ unsigned int num_drm_formats; -+ const uint32_t *drm_formats; - const uint64_t *format_modifiers = format_modifiers_default; - - meson_plane = devm_kzalloc(priv->drm->dev, sizeof(*meson_plane), -@@ -548,10 +566,19 @@ int meson_plane_create(struct meson_drm *priv) - else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) - format_modifiers = format_modifiers_afbc_g12a; - -+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) { -+ drm_formats = supported_drm_formats_m8; -+ num_drm_formats = ARRAY_SIZE(supported_drm_formats_m8); -+ } else { -+ drm_formats = supported_drm_formats_gx; -+ num_drm_formats = ARRAY_SIZE(supported_drm_formats_gx); -+ } -+ - drm_universal_plane_init(priv->drm, plane, 0xFF, - &meson_plane_funcs, -- supported_drm_formats, -- ARRAY_SIZE(supported_drm_formats), -+ drm_formats, num_drm_formats, - format_modifiers, - DRM_PLANE_TYPE_PRIMARY, "meson_primary_plane"); - -diff --git a/drivers/gpu/drm/meson/meson_transwitch_hdmi.c b/drivers/gpu/drm/meson/meson_transwitch_hdmi.c -new file mode 100644 -index 00000000000..e88bdba7c16 ---- /dev/null -+++ b/drivers/gpu/drm/meson/meson_transwitch_hdmi.c -@@ -0,0 +1,1579 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2021 Martin Blumenstingl -+ * -+ * All registers and magic values are taken from Amlogic's GPL kernel sources: -+ * Copyright (C) 2010 Amlogic, Inc. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+ -+#include "meson_transwitch_hdmi.h" -+ -+#define HDMI_ADDR_PORT 0x0 -+#define HDMI_DATA_PORT 0x4 -+#define HDMI_CTRL_PORT 0x8 -+ #define HDMI_CTRL_PORT_APB3_ERR_EN BIT(15) -+ -+struct meson_txc_hdmi { -+ struct device *dev; -+ -+ struct regmap *regmap; -+ -+ struct clk *pclk; -+ struct clk *sys_clk; -+ -+ struct phy *phy; -+ bool phy_is_on; -+ -+ struct mutex codec_mutex; -+ enum drm_connector_status last_connector_status; -+ hdmi_codec_plugged_cb codec_plugged_cb; -+ struct device *codec_dev; -+ -+ struct platform_device *hdmi_codec_pdev; -+ -+ struct drm_connector *current_connector; -+ -+ struct drm_bridge bridge; -+ struct drm_bridge *next_bridge; -+ -+ bool sink_is_hdmi; -+}; -+ -+#define bridge_to_meson_txc_hdmi(x) container_of(x, struct meson_txc_hdmi, bridge) -+ -+static const struct regmap_range meson_txc_hdmi_regmap_ranges[] = { -+ regmap_reg_range(0x0000, 0x07ff), -+ regmap_reg_range(0x8000, 0x800c), -+}; -+ -+static const struct regmap_access_table meson_txc_hdmi_regmap_access = { -+ .yes_ranges = meson_txc_hdmi_regmap_ranges, -+ .n_yes_ranges = ARRAY_SIZE(meson_txc_hdmi_regmap_ranges), -+}; -+ -+static int meson_txc_hdmi_reg_read(void *context, unsigned int addr, -+ unsigned int *data) -+{ -+ void __iomem *base = context; -+ -+ writel(addr, base + HDMI_ADDR_PORT); -+ writel(addr, base + HDMI_ADDR_PORT); -+ -+ *data = readl(base + HDMI_DATA_PORT); -+ -+ return 0; -+} -+ -+static int meson_txc_hdmi_reg_write(void *context, unsigned int addr, -+ unsigned int data) -+{ -+ void __iomem *base = context; -+ -+ writel(addr, base + HDMI_ADDR_PORT); -+ writel(addr, base + HDMI_ADDR_PORT); -+ -+ writel(data, base + HDMI_DATA_PORT); -+ -+ return 0; -+} -+ -+static const struct regmap_config meson_txc_hdmi_regmap_config = { -+ .reg_bits = 16, -+ .val_bits = 16, -+ .reg_stride = 1, -+ .reg_read = meson_txc_hdmi_reg_read, -+ .reg_write = meson_txc_hdmi_reg_write, -+ .rd_table = &meson_txc_hdmi_regmap_access, -+ .wr_table = &meson_txc_hdmi_regmap_access, -+ .max_register = HDMI_OTHER_RX_PACKET_INTR_CLR, -+ .fast_io = true, -+}; -+ -+static void meson_txc_hdmi_write_infoframe(struct regmap *regmap, -+ unsigned int tx_pkt_reg, u8 *buf, -+ unsigned int len, bool enable) -+{ -+ unsigned int i; -+ -+ /* Write the data bytes by starting at register offset 1 */ -+ for (i = HDMI_INFOFRAME_HEADER_SIZE; i < len; i++) -+ regmap_write(regmap, -+ tx_pkt_reg + i - HDMI_INFOFRAME_HEADER_SIZE + 1, -+ buf[i]); -+ -+ /* Zero all remaining data bytes */ -+ for (; i < 0x1c; i++) -+ regmap_write(regmap, tx_pkt_reg + i, 0x00); -+ -+ /* Write the header (which we skipped above) */ -+ regmap_write(regmap, tx_pkt_reg + 0x00, buf[3]); -+ regmap_write(regmap, tx_pkt_reg + 0x1c, buf[0]); -+ regmap_write(regmap, tx_pkt_reg + 0x1d, buf[1]); -+ regmap_write(regmap, tx_pkt_reg + 0x1e, buf[2]); -+ -+ regmap_write(regmap, tx_pkt_reg + 0x1f, enable ? 0xff : 0x00); -+} -+ -+static void meson_txc_hdmi_disable_infoframe(struct meson_txc_hdmi *priv, -+ unsigned int tx_pkt_reg) -+{ -+ u8 buf[HDMI_INFOFRAME_HEADER_SIZE] = { 0 }; -+ -+ meson_txc_hdmi_write_infoframe(priv->regmap, tx_pkt_reg, buf, -+ HDMI_INFOFRAME_HEADER_SIZE, false); -+} -+ -+static void meson_txc_hdmi_sys5_reset_assert(struct meson_txc_hdmi *priv) -+{ -+ /* A comment in the vendor driver says: bit5,6 is converted */ -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_2, -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH3_RST_IN | -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH0_RST_IN); -+ usleep_range(10, 20); -+ -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_2, -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH2_RST_IN | -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH1_RST_IN); -+ usleep_range(10, 20); -+ -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_1, -+ TX_SYS5_TX_SOFT_RESET_1_TX_PIXEL_RSTN | -+ TX_SYS5_TX_SOFT_RESET_1_TX_TMDS_RSTN | -+ TX_SYS5_TX_SOFT_RESET_1_TX_AUDIO_MASTER_RSTN | -+ TX_SYS5_TX_SOFT_RESET_1_TX_AUDIO_RESAMPLE_RSTN | -+ TX_SYS5_TX_SOFT_RESET_1_TX_I2S_RESET_RSTN | -+ TX_SYS5_TX_SOFT_RESET_1_TX_DIG_RESET_N_CH2 | -+ TX_SYS5_TX_SOFT_RESET_1_TX_DIG_RESET_N_CH1 | -+ TX_SYS5_TX_SOFT_RESET_1_TX_DIG_RESET_N_CH0); -+ usleep_range(10, 20); -+} -+ -+static void meson_txc_hdmi_sys5_reset_deassert(struct meson_txc_hdmi *priv) -+{ -+ /* Release the resets except tmds_clk */ -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_1, -+ TX_SYS5_TX_SOFT_RESET_1_TX_TMDS_RSTN); -+ usleep_range(10, 20); -+ -+ /* Release the tmds_clk reset as well */ -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_1, 0x0); -+ usleep_range(10, 20); -+ -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_2, -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH2_RST_IN | -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH1_RST_IN | -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_SR_RST); -+ usleep_range(10, 20); -+ -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_2, -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH2_RST_IN | -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH1_RST_IN); -+ usleep_range(10, 20); -+} -+ -+static void meson_txc_hdmi_config_hdcp_registers(struct meson_txc_hdmi *priv) -+{ -+ regmap_write(priv->regmap, TX_HDCP_CONFIG0, -+ FIELD_PREP(TX_HDCP_CONFIG0_ROM_ENCRYPT_OFF, 0x3)); -+ regmap_write(priv->regmap, TX_HDCP_MEM_CONFIG, 0x0); -+ regmap_write(priv->regmap, TX_HDCP_ENCRYPT_BYTE, 0x0); -+ -+ regmap_write(priv->regmap, TX_HDCP_MODE, TX_HDCP_MODE_CLEAR_AVMUTE); -+ -+ regmap_write(priv->regmap, TX_HDCP_MODE, TX_HDCP_MODE_ESS_CONFIG); -+} -+ -+static u8 meson_txc_hdmi_bus_fmt_to_color_depth(unsigned int bus_format) -+{ -+ switch (bus_format) { -+ case MEDIA_BUS_FMT_RGB888_1X24: -+ case MEDIA_BUS_FMT_YUV8_1X24: -+ case MEDIA_BUS_FMT_UYVY8_1X16: -+ /* 8 bit */ -+ return 0x0; -+ -+ case MEDIA_BUS_FMT_RGB101010_1X30: -+ case MEDIA_BUS_FMT_YUV10_1X30: -+ case MEDIA_BUS_FMT_UYVY10_1X20: -+ /* 10 bit */ -+ return 0x1; -+ -+ case MEDIA_BUS_FMT_RGB121212_1X36: -+ case MEDIA_BUS_FMT_YUV12_1X36: -+ case MEDIA_BUS_FMT_UYVY12_1X24: -+ /* 12 bit */ -+ return 0x2; -+ -+ case MEDIA_BUS_FMT_RGB161616_1X48: -+ case MEDIA_BUS_FMT_YUV16_1X48: -+ /* 16 bit */ -+ return 0x3; -+ -+ default: -+ /* unknown, default to 8 bit */ -+ return 0x0; -+ } -+} -+ -+static u8 meson_txc_hdmi_bus_fmt_to_color_format(unsigned int bus_format) -+{ -+ switch (bus_format) { -+ case MEDIA_BUS_FMT_YUV8_1X24: -+ case MEDIA_BUS_FMT_YUV10_1X30: -+ case MEDIA_BUS_FMT_YUV12_1X36: -+ case MEDIA_BUS_FMT_YUV16_1X48: -+ /* Documented as YCbCr444 */ -+ return 0x1; -+ -+ case MEDIA_BUS_FMT_UYVY8_1X16: -+ case MEDIA_BUS_FMT_UYVY10_1X20: -+ case MEDIA_BUS_FMT_UYVY12_1X24: -+ /* Documented as YCbCr422 */ -+ return 0x3; -+ -+ case MEDIA_BUS_FMT_RGB888_1X24: -+ case MEDIA_BUS_FMT_RGB101010_1X30: -+ case MEDIA_BUS_FMT_RGB121212_1X36: -+ case MEDIA_BUS_FMT_RGB161616_1X48: -+ default: -+ /* Documented as RGB444 */ -+ return 0x0; -+ } -+} -+ -+static void meson_txc_hdmi_config_color_space(struct meson_txc_hdmi *priv, -+ unsigned int input_bus_format, -+ unsigned int output_bus_format, -+ enum hdmi_quantization_range quant_range, -+ enum hdmi_colorimetry colorimetry) -+{ -+ unsigned int regval; -+ -+ regmap_write(priv->regmap, TX_VIDEO_DTV_MODE, -+ FIELD_PREP(TX_VIDEO_DTV_MODE_COLOR_DEPTH, -+ meson_txc_hdmi_bus_fmt_to_color_depth(output_bus_format))); -+ -+ regmap_write(priv->regmap, TX_VIDEO_DTV_OPTION_L, -+ FIELD_PREP(TX_VIDEO_DTV_OPTION_L_OUTPUT_COLOR_FORMAT, -+ meson_txc_hdmi_bus_fmt_to_color_format(output_bus_format)) | -+ FIELD_PREP(TX_VIDEO_DTV_OPTION_L_INPUT_COLOR_FORMAT, -+ meson_txc_hdmi_bus_fmt_to_color_format(input_bus_format)) | -+ FIELD_PREP(TX_VIDEO_DTV_OPTION_L_OUTPUT_COLOR_DEPTH, -+ meson_txc_hdmi_bus_fmt_to_color_depth(output_bus_format)) | -+ FIELD_PREP(TX_VIDEO_DTV_OPTION_L_INPUT_COLOR_DEPTH, -+ meson_txc_hdmi_bus_fmt_to_color_depth(input_bus_format))); -+ -+ if (quant_range == HDMI_QUANTIZATION_RANGE_LIMITED) -+ regval = FIELD_PREP(TX_VIDEO_DTV_OPTION_H_OUTPUT_COLOR_RANGE, -+ TX_VIDEO_DTV_OPTION_H_COLOR_RANGE_16_235) | -+ FIELD_PREP(TX_VIDEO_DTV_OPTION_H_INPUT_COLOR_RANGE, -+ TX_VIDEO_DTV_OPTION_H_COLOR_RANGE_16_235); -+ else -+ regval = FIELD_PREP(TX_VIDEO_DTV_OPTION_H_OUTPUT_COLOR_RANGE, -+ TX_VIDEO_DTV_OPTION_H_COLOR_RANGE_0_255) | -+ FIELD_PREP(TX_VIDEO_DTV_OPTION_H_INPUT_COLOR_RANGE, -+ TX_VIDEO_DTV_OPTION_H_COLOR_RANGE_0_255); -+ -+ regmap_write(priv->regmap, TX_VIDEO_DTV_OPTION_H, regval); -+ -+ if (colorimetry == HDMI_COLORIMETRY_ITU_601) { -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_B0, 0x2f); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_B1, 0x1d); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_R0, 0x8b); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_R1, 0x4c); -+ -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_CB0, 0x18); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_CB1, 0x58); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_CR0, 0xd0); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_CR1, 0xb6); -+ } else { -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_B0, 0x7b); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_B1, 0x12); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_R0, 0x6c); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_R1, 0x36); -+ -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_CB0, 0xf2); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_CB1, 0x2f); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_CR0, 0xd4); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_CR1, 0x77); -+ } -+} -+ -+static void meson_txc_hdmi_config_serializer_clock(struct meson_txc_hdmi *priv, -+ enum hdmi_colorimetry colorimetry) -+{ -+ /* Serializer Internal clock setting */ -+ if (colorimetry == HDMI_COLORIMETRY_ITU_601) -+ regmap_write(priv->regmap, TX_SYS1_PLL, 0x24); -+ else -+ regmap_write(priv->regmap, TX_SYS1_PLL, 0x22); -+ -+#if 0 -+ // TODO: not ported yet -+ if ((param->VIC==HDMI_1080p60)&&(param->color_depth==COLOR_30BIT)&&(hdmi_rd_reg(0x018)==0x22)) { -+ regmap_write(priv->regmap, TX_SYS1_PLL, 0x12); -+ } -+#endif -+} -+ -+static void meson_txc_hdmi_reconfig_packet_setting(struct meson_txc_hdmi *priv, -+ u8 cea_mode) -+{ -+ u8 alloc_active2, alloc_eof1, alloc_sof1, alloc_sof2; -+ -+ regmap_write(priv->regmap, TX_PACKET_CONTROL_1, -+ FIELD_PREP(TX_PACKET_CONTROL_1_PACKET_START_LATENCY, 58)); -+ regmap_write(priv->regmap, TX_PACKET_CONTROL_2, -+ TX_PACKET_CONTROL_2_HORIZONTAL_GC_PACKET_TRANSPORT_EN); -+ -+ switch (cea_mode) { -+ case 31: -+ /* 1920x1080p50 */ -+ alloc_active2 = 0x12; -+ alloc_eof1 = 0x10; -+ alloc_sof1 = 0xb6; -+ alloc_sof2 = 0x11; -+ break; -+ case 93: -+ /* 3840x2160p24 */ -+ alloc_active2 = 0x12; -+ alloc_eof1 = 0x47; -+ alloc_sof1 = 0xf8; -+ alloc_sof2 = 0x52; -+ break; -+ case 94: -+ /* 3840x2160p25 */ -+ alloc_active2 = 0x12; -+ alloc_eof1 = 0x44; -+ alloc_sof1 = 0xda; -+ alloc_sof2 = 0x52; -+ break; -+ case 95: -+ /* 3840x2160p30 */ -+ alloc_active2 = 0x0f; -+ alloc_eof1 = 0x3a; -+ alloc_sof1 = 0x60; -+ alloc_sof2 = 0x52; -+ break; -+ case 98: -+ /* 4096x2160p24 */ -+ alloc_active2 = 0x12; -+ alloc_eof1 = 0x47; -+ alloc_sof1 = 0xf8; -+ alloc_sof2 = 0x52; -+ break; -+ default: -+ /* Disable the special packet settings only */ -+ regmap_write(priv->regmap, TX_PACKET_ALLOC_ACTIVE_1, 0x00); -+ return; -+ } -+ -+ /* -+ * The vendor driver says: manually configure these register to get -+ * stable video timings. -+ */ -+ regmap_write(priv->regmap, TX_PACKET_ALLOC_ACTIVE_1, 0x01); -+ regmap_write(priv->regmap, TX_PACKET_ALLOC_ACTIVE_2, alloc_active2); -+ regmap_write(priv->regmap, TX_PACKET_ALLOC_EOF_1, alloc_eof1); -+ regmap_write(priv->regmap, TX_PACKET_ALLOC_EOF_2, 0x12); -+ regmap_write(priv->regmap, TX_CORE_ALLOC_VSYNC_0, 0x01); -+ regmap_write(priv->regmap, TX_CORE_ALLOC_VSYNC_1, 0x00); -+ regmap_write(priv->regmap, TX_CORE_ALLOC_VSYNC_2, 0x0a); -+ regmap_write(priv->regmap, TX_PACKET_ALLOC_SOF_1, alloc_sof1); -+ regmap_write(priv->regmap, TX_PACKET_ALLOC_SOF_2, alloc_sof2); -+ regmap_update_bits(priv->regmap, TX_PACKET_CONTROL_1, -+ TX_PACKET_CONTROL_1_FORCE_PACKET_TIMING, -+ TX_PACKET_CONTROL_1_FORCE_PACKET_TIMING); -+} -+ -+static void meson_txc_hdmi_set_avi_infoframe(struct meson_txc_hdmi *priv, -+ struct drm_connector *conn, -+ const struct drm_display_mode *mode, -+ const struct drm_connector_state *conn_state, -+ unsigned int output_bus_format, -+ enum hdmi_quantization_range quant_range, -+ enum hdmi_colorimetry colorimetry) -+{ -+ u8 buf[HDMI_INFOFRAME_SIZE(AVI)], *video_code; -+ struct hdmi_avi_infoframe frame; -+ int ret; -+ -+ ret = drm_hdmi_avi_infoframe_from_display_mode(&frame, conn, mode); -+ if (ret < 0) { -+ drm_err(priv->bridge.dev, -+ "Failed to setup AVI infoframe: %d\n", ret); -+ return; -+ } -+ -+ switch (output_bus_format) { -+ case MEDIA_BUS_FMT_YUV8_1X24: -+ case MEDIA_BUS_FMT_YUV10_1X30: -+ case MEDIA_BUS_FMT_YUV12_1X36: -+ case MEDIA_BUS_FMT_YUV16_1X48: -+ frame.colorspace = HDMI_COLORSPACE_YUV444; -+ break; -+ -+ case MEDIA_BUS_FMT_UYVY8_1X16: -+ case MEDIA_BUS_FMT_UYVY10_1X20: -+ case MEDIA_BUS_FMT_UYVY12_1X24: -+ frame.colorspace = HDMI_COLORSPACE_YUV422; -+ break; -+ -+ case MEDIA_BUS_FMT_RGB888_1X24: -+ case MEDIA_BUS_FMT_RGB101010_1X30: -+ case MEDIA_BUS_FMT_RGB121212_1X36: -+ case MEDIA_BUS_FMT_RGB161616_1X48: -+ default: -+ frame.colorspace = HDMI_COLORSPACE_RGB; -+ break; -+ } -+ -+ drm_hdmi_avi_infoframe_colorimetry(&frame, conn_state); -+ drm_hdmi_avi_infoframe_quant_range(&frame, conn, mode, quant_range); -+ drm_hdmi_avi_infoframe_bars(&frame, conn_state); -+ -+ ret = hdmi_avi_infoframe_pack(&frame, buf, sizeof(buf)); -+ if (ret < 0) { -+ drm_err(priv->bridge.dev, -+ "Failed to pack AVI infoframe: %d\n", ret); -+ return; -+ } -+ -+ video_code = &buf[HDMI_INFOFRAME_HEADER_SIZE + 3]; -+ if (*video_code > 108) { -+ regmap_write(priv->regmap, TX_PKT_REG_EXCEPT0_BASE_ADDR, -+ *video_code); -+ *video_code = 0x00; -+ } else { -+ regmap_write(priv->regmap, TX_PKT_REG_EXCEPT0_BASE_ADDR, -+ 0x00); -+ } -+ -+ meson_txc_hdmi_write_infoframe(priv->regmap, -+ TX_PKT_REG_AVI_INFO_BASE_ADDR, buf, -+ sizeof(buf), true); -+} -+ -+static void meson_txc_hdmi_set_vendor_infoframe(struct meson_txc_hdmi *priv, -+ struct drm_connector *conn, -+ const struct drm_display_mode *mode) -+{ -+ u8 buf[HDMI_INFOFRAME_HEADER_SIZE + 6]; -+ struct hdmi_vendor_infoframe frame; -+ int ret; -+ -+ ret = drm_hdmi_vendor_infoframe_from_display_mode(&frame, conn, mode); -+ if (ret) { -+ drm_dbg(priv->bridge.dev, -+ "Failed to setup vendor infoframe: %d\n", ret); -+ return; -+ } -+ -+ ret = hdmi_vendor_infoframe_pack(&frame, buf, sizeof(buf)); -+ if (ret < 0) { -+ drm_err(priv->bridge.dev, -+ "Failed to pack vendor infoframe: %d\n", ret); -+ return; -+ } -+ -+ meson_txc_hdmi_write_infoframe(priv->regmap, -+ TX_PKT_REG_VEND_INFO_BASE_ADDR, buf, -+ sizeof(buf), true); -+} -+ -+static void meson_txc_hdmi_set_spd_infoframe(struct meson_txc_hdmi *priv) -+{ -+ u8 buf[HDMI_INFOFRAME_SIZE(SPD)]; -+ struct hdmi_spd_infoframe frame; -+ int ret; -+ -+ ret = hdmi_spd_infoframe_init(&frame, "Amlogic", "Meson TXC HDMI"); -+ if (ret < 0) { -+ drm_err(priv->bridge.dev, -+ "Failed to setup SPD infoframe: %d\n", ret); -+ return; -+ } -+ -+ ret = hdmi_spd_infoframe_pack(&frame, buf, sizeof(buf)); -+ if (ret < 0) { -+ drm_err(priv->bridge.dev, -+ "Failed to pack SDP infoframe: %d\n", ret); -+ return; -+ } -+ -+ meson_txc_hdmi_write_infoframe(priv->regmap, -+ TX_PKT_REG_SPD_INFO_BASE_ADDR, buf, -+ sizeof(buf), true); -+} -+ -+static void meson_txc_hdmi_handle_plugged_change(struct meson_txc_hdmi *priv) -+{ -+ bool plugged; -+ -+ plugged = priv->last_connector_status == connector_status_connected; -+ -+ if (priv->codec_dev && priv->codec_plugged_cb) -+ priv->codec_plugged_cb(priv->codec_dev, plugged); -+} -+ -+static int meson_txc_hdmi_bridge_attach(struct drm_bridge *bridge, -+ enum drm_bridge_attach_flags flags) -+{ -+ struct meson_txc_hdmi *priv = bridge->driver_private; -+ -+ if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) { -+ drm_err(bridge->dev, -+ "DRM_BRIDGE_ATTACH_NO_CONNECTOR flag is not set but needed\n"); -+ return -EINVAL; -+ } -+ -+ return drm_bridge_attach(bridge->encoder, priv->next_bridge, bridge, -+ flags); -+} -+ -+/* Can return a maximum of 11 possible output formats for a mode/connector */ -+#define MAX_OUTPUT_SEL_FORMATS 11 -+ -+static u32 * -+meson_txc_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, -+ struct drm_bridge_state *bridge_state, -+ struct drm_crtc_state *crtc_state, -+ struct drm_connector_state *conn_state, -+ unsigned int *num_output_fmts) -+{ -+ struct drm_connector *conn = conn_state->connector; -+ struct drm_display_info *info = &conn->display_info; -+ u8 max_bpc = conn_state->max_requested_bpc; -+ unsigned int i = 0; -+ u32 *output_fmts; -+ -+ *num_output_fmts = 0; -+ -+ output_fmts = kcalloc(MAX_OUTPUT_SEL_FORMATS, sizeof(*output_fmts), -+ GFP_KERNEL); -+ if (!output_fmts) -+ return NULL; -+ -+ /* If we are the only bridge, avoid negotiating with ourselves */ -+ if (list_is_singular(&bridge->encoder->bridge_chain)) { -+ *num_output_fmts = 1; -+ output_fmts[0] = MEDIA_BUS_FMT_FIXED; -+ -+ return output_fmts; -+ } -+ -+ /* -+ * Order bus formats from 16bit to 8bit and from YUV422 to RGB -+ * if supported. In any case the default RGB888 format is added -+ */ -+ -+ if (max_bpc >= 16 && info->bpc == 16) { -+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR444) -+ output_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48; -+ -+ output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48; -+ } -+ -+ if (max_bpc >= 12 && info->bpc >= 12) { -+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR422) -+ output_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24; -+ -+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR444) -+ output_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36; -+ -+ output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36; -+ } -+ -+ if (max_bpc >= 10 && info->bpc >= 10) { -+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR422) -+ output_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20; -+ -+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR444) -+ output_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30; -+ -+ output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; -+ } -+ -+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR422) -+ output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16; -+ -+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR444) -+ output_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; -+ -+ /* Default 8bit RGB fallback */ -+ output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; -+ -+ *num_output_fmts = i; -+ -+ return output_fmts; -+} -+ -+/* Can return a maximum of 3 possible input formats for an output format */ -+#define MAX_INPUT_SEL_FORMATS 3 -+ -+static u32 * -+meson_txc_hdmi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, -+ struct drm_bridge_state *bridge_state, -+ struct drm_crtc_state *crtc_state, -+ struct drm_connector_state *conn_state, -+ u32 output_fmt, -+ unsigned int *num_input_fmts) -+{ -+ u32 *input_fmts; -+ unsigned int i = 0; -+ -+ *num_input_fmts = 0; -+ -+ input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts), -+ GFP_KERNEL); -+ if (!input_fmts) -+ return NULL; -+ -+ switch (output_fmt) { -+ /* If MEDIA_BUS_FMT_FIXED is tested, return default bus format */ -+ case MEDIA_BUS_FMT_FIXED: -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; -+ break; -+ -+ /* 8bit */ -+ case MEDIA_BUS_FMT_RGB888_1X24: -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; -+ input_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; -+ input_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16; -+ break; -+ case MEDIA_BUS_FMT_YUV8_1X24: -+ input_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; -+ input_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16; -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; -+ break; -+ case MEDIA_BUS_FMT_UYVY8_1X16: -+ input_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16; -+ input_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; -+ break; -+ -+ /* 10bit */ -+ case MEDIA_BUS_FMT_RGB101010_1X30: -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; -+ input_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30; -+ input_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20; -+ break; -+ case MEDIA_BUS_FMT_YUV10_1X30: -+ input_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30; -+ input_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20; -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; -+ break; -+ case MEDIA_BUS_FMT_UYVY10_1X20: -+ input_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20; -+ input_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30; -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; -+ break; -+ -+ /* 12bit */ -+ case MEDIA_BUS_FMT_RGB121212_1X36: -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36; -+ input_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36; -+ input_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24; -+ break; -+ case MEDIA_BUS_FMT_YUV12_1X36: -+ input_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36; -+ input_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24; -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36; -+ break; -+ case MEDIA_BUS_FMT_UYVY12_1X24: -+ input_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24; -+ input_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36; -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36; -+ break; -+ -+ /* 16bit */ -+ case MEDIA_BUS_FMT_RGB161616_1X48: -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48; -+ input_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48; -+ break; -+ case MEDIA_BUS_FMT_YUV16_1X48: -+ input_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48; -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48; -+ break; -+ } -+ -+ *num_input_fmts = i; -+ -+ if (*num_input_fmts == 0) { -+ kfree(input_fmts); -+ input_fmts = NULL; -+ } -+ -+ return input_fmts; -+} -+ -+static void meson_txc_hdmi_bridge_atomic_enable(struct drm_bridge *bridge, -+ struct drm_bridge_state *old_bridge_state) -+{ -+ struct meson_txc_hdmi *priv = bridge_to_meson_txc_hdmi(bridge); -+ struct drm_atomic_state *state = old_bridge_state->base.state; -+ enum hdmi_quantization_range quant_range; -+ struct drm_connector_state *conn_state; -+ struct drm_bridge_state *bridge_state; -+ const struct drm_display_mode *mode; -+ enum hdmi_colorimetry colorimetry; -+ struct drm_crtc_state *crtc_state; -+ struct drm_connector *connector; -+ unsigned int i; -+ u8 cea_mode; -+ -+ bridge_state = drm_atomic_get_new_bridge_state(state, bridge); -+ -+ connector = drm_atomic_get_new_connector_for_encoder(state, -+ bridge->encoder); -+ if (WARN_ON(!connector)) -+ return; -+ -+ conn_state = drm_atomic_get_new_connector_state(state, connector); -+ if (WARN_ON(!conn_state)) -+ return; -+ -+ crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); -+ if (WARN_ON(!crtc_state)) -+ return; -+ -+ priv->current_connector = connector; -+ -+ mode = &crtc_state->adjusted_mode; -+ -+ cea_mode = drm_match_cea_mode(mode); -+ -+ if (priv->sink_is_hdmi) { -+ quant_range = drm_default_rgb_quant_range(mode); -+ -+ switch (cea_mode) { -+ case 2 ... 3: -+ case 6 ... 7: -+ case 17 ... 18: -+ case 21 ... 22: -+ colorimetry = HDMI_COLORIMETRY_ITU_601; -+ break; -+ -+ default: -+ colorimetry = HDMI_COLORIMETRY_ITU_709; -+ break; -+ } -+ -+ meson_txc_hdmi_set_avi_infoframe(priv, connector, mode, -+ conn_state, -+ bridge_state->output_bus_cfg.format, -+ quant_range, colorimetry); -+ meson_txc_hdmi_set_vendor_infoframe(priv, connector, mode); -+ meson_txc_hdmi_set_spd_infoframe(priv); -+ } else { -+ quant_range = HDMI_QUANTIZATION_RANGE_FULL; -+ colorimetry = HDMI_COLORIMETRY_NONE; -+ } -+ -+ meson_txc_hdmi_sys5_reset_assert(priv); -+ -+ meson_txc_hdmi_config_hdcp_registers(priv); -+ -+ if (cea_mode == 39) -+ regmap_write(priv->regmap, TX_VIDEO_DTV_TIMING, 0x0); -+ else -+ regmap_write(priv->regmap, TX_VIDEO_DTV_TIMING, -+ TX_VIDEO_DTV_TIMING_DISABLE_VIC39_CORRECTION); -+ -+ regmap_write(priv->regmap, TX_CORE_DATA_CAPTURE_2, -+ TX_CORE_DATA_CAPTURE_2_INTERNAL_PACKET_ENABLE); -+ regmap_write(priv->regmap, TX_CORE_DATA_MONITOR_1, -+ TX_CORE_DATA_MONITOR_1_LANE0 | -+ FIELD_PREP(TX_CORE_DATA_MONITOR_1_SELECT_LANE0, 0x7)); -+ regmap_write(priv->regmap, TX_CORE_DATA_MONITOR_2, -+ FIELD_PREP(TX_CORE_DATA_MONITOR_2_MONITOR_SELECT, 0x2)); -+ -+ if (priv->sink_is_hdmi) -+ regmap_write(priv->regmap, TX_TMDS_MODE, -+ TX_TMDS_MODE_FORCED_HDMI | -+ TX_TMDS_MODE_HDMI_CONFIG); -+ else -+ regmap_write(priv->regmap, TX_TMDS_MODE, -+ TX_TMDS_MODE_FORCED_HDMI); -+ -+ regmap_write(priv->regmap, TX_SYS4_CONNECT_SEL_1, 0x0); -+ -+ /* -+ * Set tmds_clk pattern to be "0000011111" before being sent to AFE -+ * clock channel. -+ */ -+ regmap_write(priv->regmap, TX_SYS4_CK_INV_VIDEO, -+ TX_SYS4_CK_INV_VIDEO_TMDS_CLK_PATTERN); -+ -+ regmap_write(priv->regmap, TX_SYS5_FIFO_CONFIG, -+ TX_SYS5_FIFO_CONFIG_CLK_CHANNEL3_OUTPUT_ENABLE | -+ TX_SYS5_FIFO_CONFIG_AFE_FIFO_CHANNEL2_ENABLE | -+ TX_SYS5_FIFO_CONFIG_AFE_FIFO_CHANNEL1_ENABLE | -+ TX_SYS5_FIFO_CONFIG_AFE_FIFO_CHANNEL0_ENABLE); -+ -+ meson_txc_hdmi_config_color_space(priv, -+ bridge_state->input_bus_cfg.format, -+ bridge_state->output_bus_cfg.format, -+ quant_range, colorimetry); -+ -+ meson_txc_hdmi_sys5_reset_deassert(priv); -+ -+ meson_txc_hdmi_config_serializer_clock(priv, colorimetry); -+ meson_txc_hdmi_reconfig_packet_setting(priv, cea_mode); -+ -+ /* all resets need to be applied twice */ -+ for (i = 0; i < 2; i++) { -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_1, -+ TX_SYS5_TX_SOFT_RESET_1_TX_PIXEL_RSTN | -+ TX_SYS5_TX_SOFT_RESET_1_TX_TMDS_RSTN | -+ TX_SYS5_TX_SOFT_RESET_1_TX_AUDIO_MASTER_RSTN | -+ TX_SYS5_TX_SOFT_RESET_1_TX_AUDIO_RESAMPLE_RSTN | -+ TX_SYS5_TX_SOFT_RESET_1_TX_I2S_RESET_RSTN | -+ TX_SYS5_TX_SOFT_RESET_1_TX_DIG_RESET_N_CH2 | -+ TX_SYS5_TX_SOFT_RESET_1_TX_DIG_RESET_N_CH1 | -+ TX_SYS5_TX_SOFT_RESET_1_TX_DIG_RESET_N_CH0); -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_2, -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH3_RST_IN | -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH2_RST_IN | -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH1_RST_IN | -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH0_RST_IN | -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_SR_RST | -+ TX_SYS5_TX_SOFT_RESET_2_TX_DDC_HDCP_RSTN | -+ TX_SYS5_TX_SOFT_RESET_2_TX_DDC_EDID_RSTN | -+ TX_SYS5_TX_SOFT_RESET_2_TX_DIG_RESET_N_CH3); -+ usleep_range(5000, 10000); -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_1, 0x00); -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_2, 0x00); -+ usleep_range(5000, 10000); -+ } -+ -+ if (!priv->phy_is_on) { -+ int ret; -+ -+ ret = phy_power_on(priv->phy); -+ if (ret) -+ drm_err(bridge->dev, "Failed to turn on PHY\n"); -+ else -+ priv->phy_is_on = true; -+ } -+} -+ -+static void meson_txc_hdmi_bridge_atomic_disable(struct drm_bridge *bridge, -+ struct drm_bridge_state *old_bridge_state) -+{ -+ struct meson_txc_hdmi *priv = bridge_to_meson_txc_hdmi(bridge); -+ -+ priv->current_connector = NULL; -+ -+ if (priv->phy_is_on) { -+ int ret; -+ -+ ret = phy_power_off(priv->phy); -+ if (ret) -+ drm_err(bridge->dev, "Failed to turn off PHY\n"); -+ else -+ priv->phy_is_on = false; -+ } -+ -+ meson_txc_hdmi_disable_infoframe(priv, TX_PKT_REG_AUDIO_INFO_BASE_ADDR); -+ meson_txc_hdmi_disable_infoframe(priv, TX_PKT_REG_AVI_INFO_BASE_ADDR); -+ meson_txc_hdmi_disable_infoframe(priv, TX_PKT_REG_EXCEPT0_BASE_ADDR); -+ meson_txc_hdmi_disable_infoframe(priv, TX_PKT_REG_VEND_INFO_BASE_ADDR); -+} -+ -+static enum drm_mode_status -+meson_txc_hdmi_bridge_mode_valid(struct drm_bridge *bridge, -+ const struct drm_display_info *info, -+ const struct drm_display_mode *mode) -+{ -+ return MODE_OK; -+} -+ -+static enum drm_connector_status meson_txc_hdmi_bridge_detect(struct drm_bridge *bridge) -+{ -+ struct meson_txc_hdmi *priv = bridge_to_meson_txc_hdmi(bridge); -+ enum drm_connector_status status; -+ unsigned int val; -+ -+ regmap_read(priv->regmap, TX_HDCP_ST_EDID_STATUS, &val); -+ if (val & TX_HDCP_ST_EDID_STATUS_HPD_STATUS) -+ status = connector_status_connected; -+ else -+ status = connector_status_disconnected; -+ -+ mutex_lock(&priv->codec_mutex); -+ if (priv->last_connector_status != status) { -+ priv->last_connector_status = status; -+ meson_txc_hdmi_handle_plugged_change(priv); -+ } -+ mutex_unlock(&priv->codec_mutex); -+ -+ return status; -+} -+ -+static int meson_txc_hdmi_get_edid_block(void *data, u8 *buf, unsigned int block, -+ size_t len) -+{ -+ unsigned int i, regval, start = block * EDID_LENGTH; -+ struct meson_txc_hdmi *priv = data; -+ int ret; -+ -+ /* Start the DDC transaction */ -+ regmap_update_bits(priv->regmap, TX_HDCP_EDID_CONFIG, -+ TX_HDCP_EDID_CONFIG_SYS_TRIGGER_CONFIG, 0); -+ regmap_update_bits(priv->regmap, TX_HDCP_EDID_CONFIG, -+ TX_HDCP_EDID_CONFIG_SYS_TRIGGER_CONFIG, -+ TX_HDCP_EDID_CONFIG_SYS_TRIGGER_CONFIG); -+ -+ ret = regmap_read_poll_timeout(priv->regmap, -+ TX_HDCP_ST_EDID_STATUS, -+ regval, -+ (regval & TX_HDCP_ST_EDID_STATUS_EDID_DATA_READY), -+ 1000, 200000); -+ -+ regmap_update_bits(priv->regmap, TX_HDCP_EDID_CONFIG, -+ TX_HDCP_EDID_CONFIG_SYS_TRIGGER_CONFIG, 0); -+ -+ if (ret) -+ return ret; -+ -+ for (i = 0; i < len; i++) { -+ regmap_read(priv->regmap, TX_RX_EDID_OFFSET + start + i, -+ ®val); -+ buf[i] = regval; -+ } -+ -+ return 0; -+} -+ -+static struct edid *meson_txc_hdmi_bridge_get_edid(struct drm_bridge *bridge, -+ struct drm_connector *connector) -+{ -+ struct meson_txc_hdmi *priv = bridge_to_meson_txc_hdmi(bridge); -+ struct edid *edid; -+ -+ edid = drm_do_get_edid(connector, meson_txc_hdmi_get_edid_block, priv); -+ if (!edid) { -+ drm_dbg(priv->bridge.dev, "Failed to get EDID\n"); -+ return NULL; -+ } -+ -+ priv->sink_is_hdmi = drm_detect_hdmi_monitor(edid); -+ -+ return edid; -+} -+ -+static const struct drm_bridge_funcs meson_txc_hdmi_bridge_funcs = { -+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, -+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, -+ .atomic_reset = drm_atomic_helper_bridge_reset, -+ .attach = meson_txc_hdmi_bridge_attach, -+ .atomic_get_output_bus_fmts = meson_txc_hdmi_bridge_atomic_get_output_bus_fmts, -+ .atomic_get_input_bus_fmts = meson_txc_hdmi_bridge_atomic_get_input_bus_fmts, -+ .atomic_enable = meson_txc_hdmi_bridge_atomic_enable, -+ .atomic_disable = meson_txc_hdmi_bridge_atomic_disable, -+ .mode_valid = meson_txc_hdmi_bridge_mode_valid, -+ .detect = meson_txc_hdmi_bridge_detect, -+ .get_edid = meson_txc_hdmi_bridge_get_edid, -+}; -+ -+static int meson_txc_hdmi_parse_dt(struct meson_txc_hdmi *priv) -+{ -+ struct device_node *endpoint, *remote; -+ -+ endpoint = of_graph_get_endpoint_by_regs(priv->dev->of_node, 1, -1); -+ if (!endpoint) { -+ dev_err(priv->dev, "Missing endpoint in port@1\n"); -+ return -ENODEV; -+ } -+ -+ remote = of_graph_get_remote_port_parent(endpoint); -+ of_node_put(endpoint); -+ if (!remote) { -+ dev_err(priv->dev, "Endpoint in port@1 unconnected\n"); -+ return -ENODEV; -+ } -+ -+ if (!of_device_is_available(remote)) { -+ dev_err(priv->dev, "port@1 remote device is disabled\n"); -+ of_node_put(remote); -+ return -ENODEV; -+ } -+ -+ priv->next_bridge = of_drm_find_bridge(remote); -+ of_node_put(remote); -+ if (!priv->next_bridge) -+ return -EPROBE_DEFER; -+ -+ return 0; -+} -+ -+static int meson_txc_hdmi_hw_init(struct meson_txc_hdmi *priv) -+{ -+ unsigned long ddc_i2c_bus_clk_hz = 500 * 1000; -+ unsigned long sys_clk_hz = 24 * 1000 * 1000; -+ int ret; -+ -+ ret = phy_init(priv->phy); -+ if (ret) { -+ dev_err(priv->dev, "Failed to initialize the PHY: %d\n", ret); -+ return ret; -+ } -+ -+ ret = clk_set_rate(priv->sys_clk, sys_clk_hz); -+ if (ret) { -+ dev_err(priv->dev, "Failed to set HDMI system clock to 24MHz\n"); -+ goto err_phy_exit; -+ } -+ -+ ret = clk_prepare_enable(priv->sys_clk); -+ if (ret) { -+ dev_err(priv->dev, "Failed to enable the sys clk\n"); -+ goto err_phy_exit; -+ } -+ -+ regmap_update_bits(priv->regmap, HDMI_OTHER_CTRL1, -+ HDMI_OTHER_CTRL1_POWER_ON, -+ HDMI_OTHER_CTRL1_POWER_ON); -+ -+ regmap_write(priv->regmap, TX_HDMI_PHY_CONFIG0, -+ TX_HDMI_PHY_CONFIG0_HDMI_COMMON_B7_B0); -+ -+ regmap_write(priv->regmap, TX_HDCP_MODE, 0x40); -+ -+ /* -+ * The vendor driver comments that this is a setting for "Band-gap and -+ * main-bias". 0x1d = power-up, 0x00 = power-down. -+ */ -+ regmap_write(priv->regmap, TX_SYS1_AFE_TEST, 0x1d); -+ -+ meson_txc_hdmi_config_serializer_clock(priv, HDMI_COLORIMETRY_NONE); -+ -+ /* -+ * The vendor driver has a comment with the following information for -+ * the magic value: -+ * bit[2:0]=011: CK channel output TMDS CLOCK -+ * bit[2:0]=101, ck channel output PHYCLCK -+ */ -+ regmap_write(priv->regmap, TX_SYS1_AFE_CONNECT, 0xfb); -+ -+ /* Termination resistor calib value */ -+ regmap_write(priv->regmap, TX_CORE_CALIB_VALUE, 0x0f); -+ -+ /* HPD glitch filter */ -+ regmap_write(priv->regmap, TX_HDCP_HPD_FILTER_L, 0xa0); -+ regmap_write(priv->regmap, TX_HDCP_HPD_FILTER_H, 0xa0); -+ -+ /* Disable MEM power-down */ -+ regmap_write(priv->regmap, TX_MEM_PD_REG0, 0x0); -+ -+ regmap_write(priv->regmap, TX_HDCP_CONFIG3, -+ FIELD_PREP(TX_HDCP_CONFIG3_DDC_I2C_BUS_CLOCK_TIME_DIVIDER, -+ (sys_clk_hz / ddc_i2c_bus_clk_hz) - 1)); -+ -+ /* Enable software controlled DDC transaction */ -+ regmap_write(priv->regmap, TX_HDCP_EDID_CONFIG, -+ TX_HDCP_EDID_CONFIG_FORCED_MEM_COPY_DONE | -+ TX_HDCP_EDID_CONFIG_MEM_COPY_DONE_CONFIG); -+ regmap_write(priv->regmap, TX_CORE_EDID_CONFIG_MORE, -+ TX_CORE_EDID_CONFIG_MORE_SYS_TRIGGER_CONFIG_SEMI_MANU); -+ -+ /* mask (= disable) all interrupts */ -+ regmap_write(priv->regmap, HDMI_OTHER_INTR_MASKN, 0x0); -+ -+ /* clear any pending interrupt */ -+ regmap_write(priv->regmap, HDMI_OTHER_INTR_STAT_CLR, -+ HDMI_OTHER_INTR_STAT_CLR_EDID_RISING | -+ HDMI_OTHER_INTR_STAT_CLR_HPD_FALLING | -+ HDMI_OTHER_INTR_STAT_CLR_HPD_RISING); -+ -+ return 0; -+ -+err_phy_exit: -+ phy_exit(priv->phy); -+ return 0; -+} -+ -+static void meson_txc_hdmi_hw_exit(struct meson_txc_hdmi *priv) -+{ -+ int ret; -+ -+ /* mask (= disable) all interrupts */ -+ regmap_write(priv->regmap, HDMI_OTHER_INTR_MASKN, -+ HDMI_OTHER_INTR_MASKN_TX_EDID_INT_RISE | -+ HDMI_OTHER_INTR_MASKN_TX_HPD_INT_FALL | -+ HDMI_OTHER_INTR_MASKN_TX_HPD_INT_RISE); -+ -+ regmap_update_bits(priv->regmap, HDMI_OTHER_CTRL1, -+ HDMI_OTHER_CTRL1_POWER_ON, 0); -+ -+ clk_disable_unprepare(priv->sys_clk); -+ -+ ret = phy_exit(priv->phy); -+ if (ret) -+ dev_err(priv->dev, "Failed to exit the PHY: %d\n", ret); -+} -+ -+static u32 meson_txc_hdmi_hdmi_codec_calc_audio_n(struct hdmi_codec_params *hparms) -+{ -+ u32 audio_n; -+ -+ if ((hparms->sample_rate % 44100) == 0) -+ audio_n = (128 * hparms->sample_rate) / 900; -+ else -+ audio_n = (128 * hparms->sample_rate) / 1000; -+ -+ if (hparms->cea.coding_type == HDMI_AUDIO_CODING_TYPE_EAC3 || -+ hparms->cea.coding_type == HDMI_AUDIO_CODING_TYPE_DTS_HD) -+ audio_n *= 4; -+ -+ return audio_n; -+} -+ -+static u8 meson_txc_hdmi_hdmi_codec_coding_type(struct hdmi_codec_params *hparms) -+{ -+ switch (hparms->cea.coding_type) { -+ case HDMI_AUDIO_CODING_TYPE_MLP: -+ return TX_AUDIO_CONTROL_AUDIO_PACKET_TYPE_HBR_AUDIO_PACKET; -+ case HDMI_AUDIO_CODING_TYPE_DSD: -+ return TX_AUDIO_CONTROL_AUDIO_PACKET_TYPE_ONE_BIT_AUDIO; -+ case HDMI_AUDIO_CODING_TYPE_DST: -+ return TX_AUDIO_CONTROL_AUDIO_PACKET_TYPE_DST_AUDIO_PACKET; -+ default: -+ return TX_AUDIO_CONTROL_AUDIO_PACKET_TYPE_AUDIO_SAMPLE_PACKET; -+ } -+} -+ -+static int meson_txc_hdmi_hdmi_codec_hw_params(struct device *dev, void *data, -+ struct hdmi_codec_daifmt *fmt, -+ struct hdmi_codec_params *hparms) -+{ -+ u8 buf[HDMI_INFOFRAME_SIZE(AUDIO)]; -+ struct meson_txc_hdmi *priv = data; -+ u16 audio_tx_format; -+ u32 audio_n; -+ int len, i; -+ -+ if (hparms->cea.coding_type == HDMI_AUDIO_CODING_TYPE_MLP) { -+ /* -+ * TODO: fixed CTS is not supported yet, it needs special -+ * TX_SYS1_ACR_N_* settings -+ */ -+ return -EINVAL; -+ } -+ -+ switch (hparms->sample_width) { -+ case 16: -+ audio_tx_format = FIELD_PREP(TX_AUDIO_FORMAT_BIT_WIDTH_MASK, -+ TX_AUDIO_FORMAT_BIT_WIDTH_16); -+ break; -+ -+ case 20: -+ audio_tx_format = FIELD_PREP(TX_AUDIO_FORMAT_BIT_WIDTH_MASK, -+ TX_AUDIO_FORMAT_BIT_WIDTH_20); -+ break; -+ -+ case 24: -+ audio_tx_format = FIELD_PREP(TX_AUDIO_FORMAT_BIT_WIDTH_MASK, -+ TX_AUDIO_FORMAT_BIT_WIDTH_24); -+ break; -+ -+ default: -+ return -EINVAL; -+ } -+ -+ switch (fmt->fmt) { -+ case HDMI_I2S: -+ regmap_update_bits(priv->regmap, HDMI_OTHER_CTRL1, -+ HDMI_OTHER_CTRL1_HDMI_AUDIO_CLOCK_ON, -+ HDMI_OTHER_CTRL1_HDMI_AUDIO_CLOCK_ON); -+ -+ audio_tx_format |= TX_AUDIO_FORMAT_SPDIF_OR_I2S | -+ TX_AUDIO_FORMAT_I2S_ONE_BIT_OR_I2S | -+ FIELD_PREP(TX_AUDIO_FORMAT_I2S_FORMAT, 0x2); -+ -+ if (hparms->channels > 2) -+ audio_tx_format |= TX_AUDIO_FORMAT_I2S_2_OR_8_CH; -+ -+ regmap_write(priv->regmap, TX_AUDIO_FORMAT, -+ audio_tx_format); -+ -+ regmap_write(priv->regmap, TX_AUDIO_I2S, TX_AUDIO_I2S_ENABLE); -+ regmap_write(priv->regmap, TX_AUDIO_SPDIF, 0x0); -+ break; -+ -+ case HDMI_SPDIF: -+ regmap_update_bits(priv->regmap, HDMI_OTHER_CTRL1, -+ HDMI_OTHER_CTRL1_HDMI_AUDIO_CLOCK_ON, 0x0); -+ -+ if (hparms->cea.coding_type == HDMI_AUDIO_CODING_TYPE_STREAM) -+ audio_tx_format |= TX_AUDIO_FORMAT_SPDIF_CHANNEL_STATUS_FROM_DATA_OR_REG; -+ -+ regmap_write(priv->regmap, TX_AUDIO_FORMAT, -+ audio_tx_format); -+ -+ regmap_write(priv->regmap, TX_AUDIO_I2S, 0x0); -+ regmap_write(priv->regmap, TX_AUDIO_SPDIF, TX_AUDIO_SPDIF_ENABLE); -+ break; -+ -+ default: -+ return -EINVAL; -+ } -+ -+ if (hparms->channels > 2) -+ regmap_write(priv->regmap, TX_AUDIO_HEADER, -+ TX_AUDIO_HEADER_AUDIO_SAMPLE_PACKET_HEADER_LAYOUT1); -+ else -+ regmap_write(priv->regmap, TX_AUDIO_HEADER, 0x0); -+ -+ regmap_write(priv->regmap, TX_AUDIO_SAMPLE, -+ FIELD_PREP(TX_AUDIO_SAMPLE_CHANNEL_VALID, -+ BIT(hparms->channels) - 1)); -+ -+ audio_n = meson_txc_hdmi_hdmi_codec_calc_audio_n(hparms); -+ -+ regmap_write(priv->regmap, TX_SYS1_ACR_N_0, -+ FIELD_PREP(TX_SYS1_ACR_N_0_N_BYTE0, -+ (audio_n >> 0) & 0xff)); -+ regmap_write(priv->regmap, TX_SYS1_ACR_N_1, -+ FIELD_PREP(TX_SYS1_ACR_N_1_N_BYTE1, -+ (audio_n >> 8) & 0xff)); -+ regmap_update_bits(priv->regmap, TX_SYS1_ACR_N_2, -+ TX_SYS1_ACR_N_2_N_UPPER_NIBBLE, -+ FIELD_PREP(TX_SYS1_ACR_N_2_N_UPPER_NIBBLE, -+ (audio_n >> 16) & 0xf)); -+ -+ regmap_write(priv->regmap, TX_SYS0_ACR_CTS_0, 0x0); -+ regmap_write(priv->regmap, TX_SYS0_ACR_CTS_1, 0x0); -+ regmap_write(priv->regmap, TX_SYS0_ACR_CTS_2, -+ TX_SYS0_ACR_CTS_2_FORCE_ARC_STABLE); -+ -+ regmap_write(priv->regmap, TX_AUDIO_CONTROL, -+ TX_AUDIO_CONTROL_AUTO_AUDIO_FIFO_CLEAR | -+ FIELD_PREP(TX_AUDIO_CONTROL_AUDIO_PACKET_TYPE_MASK, -+ meson_txc_hdmi_hdmi_codec_coding_type(hparms)) | -+ TX_AUDIO_CONTROL_AUDIO_SAMPLE_PACKET_FLAT); -+ -+ len = hdmi_audio_infoframe_pack(&hparms->cea, buf, sizeof(buf)); -+ if (len < 0) -+ return len; -+ -+ meson_txc_hdmi_write_infoframe(priv->regmap, -+ TX_PKT_REG_AUDIO_INFO_BASE_ADDR, -+ buf, len, true); -+ -+ for (i = 0; i < ARRAY_SIZE(hparms->iec.status); i++) { -+ unsigned char sub1, sub2; -+ -+ sub1 = sub2 = hparms->iec.status[i]; -+ -+ if (i == 2) { -+ sub1 |= FIELD_PREP(IEC958_AES2_CON_CHANNEL, 1); -+ sub2 |= FIELD_PREP(IEC958_AES2_CON_CHANNEL, 2); -+ } -+ -+ regmap_write(priv->regmap, TX_IEC60958_SUB1_OFFSET + i, sub1); -+ regmap_write(priv->regmap, TX_IEC60958_SUB2_OFFSET + i, sub2); -+ } -+ -+ return 0; -+} -+ -+static int meson_txc_hdmi_hdmi_codec_audio_startup(struct device *dev, -+ void *data) -+{ -+ struct meson_txc_hdmi *priv = data; -+ -+ regmap_update_bits(priv->regmap, TX_PACKET_CONTROL_2, -+ TX_PACKET_CONTROL_2_AUDIO_REQUEST_DISABLE, 0x0); -+ -+ /* reset audio master and sample */ -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_1, -+ TX_SYS5_TX_SOFT_RESET_1_TX_AUDIO_RESAMPLE_RSTN | -+ TX_SYS5_TX_SOFT_RESET_1_TX_AUDIO_MASTER_RSTN); -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_1, 0x0); -+ -+ regmap_write(priv->regmap, TX_AUDIO_CONTROL_MORE, -+ TX_AUDIO_CONTROL_MORE_ENABLE); -+ -+ regmap_write(priv->regmap, TX_AUDIO_FIFO, -+ FIELD_PREP(TX_AUDIO_FIFO_FIFO_DEPTH_MASK, -+ TX_AUDIO_FIFO_FIFO_DEPTH_512) | -+ FIELD_PREP(TX_AUDIO_FIFO_CRITICAL_THRESHOLD_MASK, -+ TX_AUDIO_FIFO_CRITICAL_THRESHOLD_DEPTH_DIV16) | -+ FIELD_PREP(TX_AUDIO_FIFO_NORMAL_THRESHOLD_MASK, -+ TX_AUDIO_FIFO_NORMAL_THRESHOLD_DEPTH_DIV8)); -+ -+ regmap_write(priv->regmap, TX_AUDIO_LIPSYNC, 0x0); -+ -+ regmap_write(priv->regmap, TX_SYS1_ACR_N_2, -+ FIELD_PREP(TX_SYS1_ACR_N_2_N_MEAS_TOLERANCE, 0x3)); -+ -+ return 0; -+} -+ -+static void meson_txc_hdmi_hdmi_codec_audio_shutdown(struct device *dev, -+ void *data) -+{ -+ struct meson_txc_hdmi *priv = data; -+ -+ meson_txc_hdmi_disable_infoframe(priv, TX_PKT_REG_AUDIO_INFO_BASE_ADDR); -+ -+ regmap_write(priv->regmap, TX_AUDIO_CONTROL_MORE, 0x0); -+ regmap_update_bits(priv->regmap, HDMI_OTHER_CTRL1, -+ HDMI_OTHER_CTRL1_HDMI_AUDIO_CLOCK_ON, 0x0); -+ -+ regmap_update_bits(priv->regmap, TX_PACKET_CONTROL_2, -+ TX_PACKET_CONTROL_2_AUDIO_REQUEST_DISABLE, -+ TX_PACKET_CONTROL_2_AUDIO_REQUEST_DISABLE); -+} -+ -+static int meson_txc_hdmi_hdmi_codec_mute_stream(struct device *dev, -+ void *data, -+ bool enable, int direction) -+{ -+ struct meson_txc_hdmi *priv = data; -+ -+ regmap_write(priv->regmap, TX_AUDIO_PACK, -+ enable ? 0 : TX_AUDIO_PACK_AUDIO_SAMPLE_PACKETS_ENABLE); -+ -+ return 0; -+} -+ -+static int meson_txc_hdmi_hdmi_codec_get_eld(struct device *dev, void *data, -+ uint8_t *buf, size_t len) -+{ -+ struct meson_txc_hdmi *priv = data; -+ -+ if (priv->current_connector) -+ memcpy(buf, priv->current_connector->eld, -+ min_t(size_t, MAX_ELD_BYTES, len)); -+ else -+ memset(buf, 0, len); -+ -+ return 0; -+} -+ -+static int meson_txc_hdmi_hdmi_codec_get_dai_id(struct snd_soc_component *component, -+ struct device_node *endpoint) -+{ -+ struct of_endpoint of_ep; -+ int ret; -+ -+ ret = of_graph_parse_endpoint(endpoint, &of_ep); -+ if (ret < 0) -+ return ret; -+ -+ /* -+ * HDMI sound should be located as reg = <2> -+ * Then, it is sound port 0 -+ */ -+ if (of_ep.port == 2) -+ return 0; -+ -+ return -EINVAL; -+} -+ -+static int meson_txc_hdmi_hdmi_codec_hook_plugged_cb(struct device *dev, -+ void *data, -+ hdmi_codec_plugged_cb fn, -+ struct device *codec_dev) -+{ -+ struct meson_txc_hdmi *priv = data; -+ -+ mutex_lock(&priv->codec_mutex); -+ priv->codec_plugged_cb = fn; -+ priv->codec_dev = codec_dev; -+ meson_txc_hdmi_handle_plugged_change(priv); -+ mutex_unlock(&priv->codec_mutex); -+ -+ return 0; -+} -+ -+static struct hdmi_codec_ops meson_txc_hdmi_hdmi_codec_ops = { -+ .hw_params = meson_txc_hdmi_hdmi_codec_hw_params, -+ .audio_startup = meson_txc_hdmi_hdmi_codec_audio_startup, -+ .audio_shutdown = meson_txc_hdmi_hdmi_codec_audio_shutdown, -+ .mute_stream = meson_txc_hdmi_hdmi_codec_mute_stream, -+ .get_eld = meson_txc_hdmi_hdmi_codec_get_eld, -+ .get_dai_id = meson_txc_hdmi_hdmi_codec_get_dai_id, -+ .hook_plugged_cb = meson_txc_hdmi_hdmi_codec_hook_plugged_cb, -+}; -+ -+static int meson_txc_hdmi_hdmi_codec_init(struct meson_txc_hdmi *priv) -+{ -+ struct hdmi_codec_pdata pdata = { -+ .ops = &meson_txc_hdmi_hdmi_codec_ops, -+ .i2s = 1, -+ .spdif = 1, -+ .max_i2s_channels = 8, -+ .data = priv, -+ }; -+ -+ priv->hdmi_codec_pdev = platform_device_register_data(priv->dev, -+ HDMI_CODEC_DRV_NAME, -+ PLATFORM_DEVID_AUTO, -+ &pdata, sizeof(pdata)); -+ return PTR_ERR_OR_ZERO(priv->hdmi_codec_pdev); -+} -+ -+static int meson_txc_hdmi_bind(struct device *dev, struct device *master, -+ void *data) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct meson_txc_hdmi *priv; -+ void __iomem *base; -+ u32 regval; -+ int ret; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->dev = dev; -+ -+ mutex_init(&priv->codec_mutex); -+ -+ dev_set_drvdata(dev, priv); -+ -+ base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); -+ -+ priv->regmap = devm_regmap_init(dev, NULL, base, -+ &meson_txc_hdmi_regmap_config); -+ if (IS_ERR(priv->regmap)) -+ return PTR_ERR(priv->regmap); -+ -+ priv->pclk = devm_clk_get(dev, "pclk"); -+ if (IS_ERR(priv->pclk)) { -+ ret = PTR_ERR(priv->pclk); -+ return dev_err_probe(dev, ret, "Failed to get the pclk\n"); -+ } -+ -+ priv->sys_clk = devm_clk_get(dev, "sys"); -+ if (IS_ERR(priv->sys_clk)) { -+ ret = PTR_ERR(priv->sys_clk); -+ return dev_err_probe(dev, ret, -+ "Failed to get the sys clock\n"); -+ } -+ -+ priv->phy = devm_phy_get(dev, "hdmi"); -+ if (IS_ERR(priv->phy)) { -+ ret = PTR_ERR(priv->phy); -+ return dev_err_probe(dev, ret, "Failed to get the HDMI PHY\n"); -+ } -+ -+ ret = meson_txc_hdmi_parse_dt(priv); -+ if (ret) -+ return ret; -+ -+ ret = clk_prepare_enable(priv->pclk); -+ if (ret) { -+ dev_err_probe(dev, ret, "Failed to enable the pclk\n"); -+ return ret; -+ } -+ -+ regval = readl(base + HDMI_CTRL_PORT); -+ regval |= HDMI_CTRL_PORT_APB3_ERR_EN; -+ writel(regval, base + HDMI_CTRL_PORT); -+ -+ ret = meson_txc_hdmi_hw_init(priv); -+ if (ret) -+ goto err_disable_clk; -+ -+ ret = meson_txc_hdmi_hdmi_codec_init(priv); -+ if (ret) -+ goto err_hw_exit; -+ -+ priv->bridge.driver_private = priv; -+ priv->bridge.funcs = &meson_txc_hdmi_bridge_funcs; -+ priv->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID; -+ priv->bridge.of_node = dev->of_node; -+ priv->bridge.interlace_allowed = true; -+ -+ drm_bridge_add(&priv->bridge); -+ -+ return 0; -+ -+err_hw_exit: -+ meson_txc_hdmi_hw_exit(priv); -+err_disable_clk: -+ clk_disable_unprepare(priv->pclk); -+ return ret; -+} -+ -+static void meson_txc_hdmi_unbind(struct device *dev, struct device *master, -+ void *data) -+{ -+ struct meson_txc_hdmi *priv = dev_get_drvdata(dev); -+ -+ platform_device_unregister(priv->hdmi_codec_pdev); -+ -+ drm_bridge_remove(&priv->bridge); -+ -+ meson_txc_hdmi_hw_exit(priv); -+ -+ clk_disable_unprepare(priv->pclk); -+} -+ -+static const struct component_ops meson_txc_hdmi_component_ops = { -+ .bind = meson_txc_hdmi_bind, -+ .unbind = meson_txc_hdmi_unbind, -+}; -+ -+static int meson_txc_hdmi_probe(struct platform_device *pdev) -+{ -+ return component_add(&pdev->dev, &meson_txc_hdmi_component_ops); -+} -+ -+static int meson_txc_hdmi_remove(struct platform_device *pdev) -+{ -+ component_del(&pdev->dev, &meson_txc_hdmi_component_ops); -+ -+ return 0; -+} -+ -+static const struct of_device_id meson_txc_hdmi_of_table[] = { -+ { .compatible = "amlogic,meson8-hdmi-tx" }, -+ { .compatible = "amlogic,meson8b-hdmi-tx" }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, meson_txc_hdmi_of_table); -+ -+static struct platform_driver meson_txc_hdmi_platform_driver = { -+ .probe = meson_txc_hdmi_probe, -+ .remove = meson_txc_hdmi_remove, -+ .driver = { -+ .name = "meson-transwitch-hdmi", -+ .of_match_table = meson_txc_hdmi_of_table, -+ }, -+}; -+module_platform_driver(meson_txc_hdmi_platform_driver); -+ -+MODULE_AUTHOR("Martin Blumenstingl "); -+MODULE_DESCRIPTION("Amlogic Meson8 and Meson8b TranSwitch HDMI 1.4 TX driver"); -+MODULE_LICENSE("GPL v2"); -diff --git a/drivers/gpu/drm/meson/meson_transwitch_hdmi.h b/drivers/gpu/drm/meson/meson_transwitch_hdmi.h -new file mode 100644 -index 00000000000..14929475c0c ---- /dev/null -+++ b/drivers/gpu/drm/meson/meson_transwitch_hdmi.h -@@ -0,0 +1,536 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2021 Martin Blumenstingl -+ * -+ * All registers and magic values are taken from Amlogic's GPL kernel sources: -+ * Copyright (C) 2010 Amlogic, Inc. -+ */ -+ -+#include -+#include -+ -+#ifndef __MESON_TRANSWITCH_HDMI_H__ -+#define __MESON_TRANSWITCH_HDMI_H__ -+ -+/* HDMI TX register */ -+ -+// System config 0 -+#define TX_SYS0_AFE_SIGNAL 0x0000 -+#define TX_SYS0_AFE_LOOP 0x0001 -+#define TX_SYS0_ACR_CTS_0 0x0002 -+ #define TX_SYS0_ACR_CTS_0_AUDIO_CTS_BYTE0 GENMASK(7, 0) -+#define TX_SYS0_ACR_CTS_1 0x0003 -+ #define TX_SYS0_ACR_CTS_1_AUDIO_CTS_BYTE1 GENMASK(7, 0) -+#define TX_SYS0_ACR_CTS_2 0x0004 -+ #define TX_SYS0_ACR_CTS_2_FORCE_ARC_STABLE BIT(5) -+#define TX_SYS0_BIST_CONTROL 0x0005 -+ #define TX_SYS0_BIST_CONTROL_AFE_BIST_ENABLE BIT(7) -+ #define TX_SYS0_BIST_CONTROL_TMDS_SHIFT_PATTERN_SELECT BIT(6) -+ #define TX_SYS0_BIST_CONTROL_TMDS_PRBS_PATTERN_SELECT GENMASK(5, 4) -+ #define TX_SYS0_BIST_CONTROL_TMDS_REPEAT_BIST_PATTERN GENMASK(2, 0) -+ -+#define TX_SYS0_BIST_DATA_0 0x0006 -+#define TX_SYS0_BIST_DATA_1 0x0007 -+#define TX_SYS0_BIST_DATA_2 0x0008 -+#define TX_SYS0_BIST_DATA_3 0x0009 -+#define TX_SYS0_BIST_DATA_4 0x000A -+#define TX_SYS0_BIST_DATA_5 0x000B -+#define TX_SYS0_BIST_DATA_6 0x000C -+#define TX_SYS0_BIST_DATA_7 0x000D -+#define TX_SYS0_BIST_DATA_8 0x000E -+#define TX_SYS0_BIST_DATA_9 0x000F -+ -+// system config 1 -+#define TX_HDMI_PHY_CONFIG0 0x0010 -+ #define TX_HDMI_PHY_CONFIG0_HDMI_COMMON_B7_B0 GENMASK(7, 0) -+#define TX_HDMI_PHY_CONFIG1 0x0010 -+ #define TX_HDMI_PHY_CONFIG1_HDMI_COMMON_B11_B8 GENMASK(3, 0) -+ #define TX_HDMI_PHY_CONFIG1_HDMI_CTL_REG_B3_B0 GENMASK(7, 4) -+#define TX_HDMI_PHY_CONFIG2 0x0012 -+ #define TX_HDMI_PHY_CONFIG_HDMI_CTL_REG_B11_B4 GENMASK(7, 0) -+#define TX_HDMI_PHY_CONFIG3 0x0013 -+ #define TX_HDMI_PHY_CONFIG3_HDMI_L2H_CTL GENMASK(3, 0) -+ #define TX_HDMI_PHY_CONFIG3_HDMI_MDR_PU GENMASK(7, 4) -+#define TX_HDMI_PHY_CONFIG4 0x0014 -+ #define TX_HDMI_PHY_CONFIG4_HDMI_LF_PD BIT(0) -+ #define TX_HDMI_PHY_CONFIG4_HDMI_PHY_CLK_EN BIT(1) -+ #define TX_HDMI_PHY_CONFIG4_HDMI_MODE GENMASK(3, 2) -+ #define TX_HDMI_PHY_CONFIG4_HDMI_MODE_NORMAL 0x0 -+ #define TX_HDMI_PHY_CONFIG4_HDMI_MODE_CLK_CH3_EQUAL_CH0 0x1 -+ #define TX_HDMI_PHY_CONFIG4_HDMI_MODE_ALTERNATE_HIGH_LOW 0x2 -+ #define TX_HDMI_PHY_CONFIG4_HDMI_MODE_ALTERNATE_LOW_HIGH 0x3 -+ #define TX_HDMI_PHY_CONFIG4_HDMI_PREM_CTL GENMASK(7, 4) -+#define TX_HDMI_PHY_CONFIG5 0x0015 -+ #define TX_HDMI_PHY_CONFIG5_HDMI_VCM_CTL GENMASK(7, 5) -+ #define TX_HDMI_PHY_CONFIG5_HDMI_PREFCTL GENMASK(2, 0) -+#define TX_HDMI_PHY_CONFIG6 0x0016 -+ #define TX_HDMI_PHY_CONFIG6_HDMI_RTERM_CTL GENMASK(3, 0) -+ #define TX_HDMI_PHY_CONFIG6_HDMI_SWING_CTL GENMASK(7, 4) -+#define TX_SYS1_AFE_TEST 0x0017 -+#define TX_SYS1_PLL 0x0018 -+#define TX_SYS1_TUNE 0x0019 -+#define TX_SYS1_AFE_CONNECT 0x001A -+ -+#define TX_SYS1_ACR_N_0 0x001C -+ #define TX_SYS1_ACR_N_0_N_BYTE0 GENMASK(7, 0) -+#define TX_SYS1_ACR_N_1 0x001D -+ #define TX_SYS1_ACR_N_1_N_BYTE1 GENMASK(7, 0) -+#define TX_SYS1_ACR_N_2 0x001E -+ #define TX_SYS1_ACR_N_2_N_MEAS_TOLERANCE GENMASK(7, 4) -+ #define TX_SYS1_ACR_N_2_N_UPPER_NIBBLE GENMASK(3, 0) -+#define TX_SYS1_PRBS_DATA 0x001F -+ #define TX_SYS1_PRBS_DATA_PRBS_MODE GENMASK(1, 0) -+ #define TX_SYS1_PRBS_DATA_PRBS_MODE_11 0x0 -+ #define TX_SYS1_PRBS_DATA_PRBS_MODE_15 0x1 -+ #define TX_SYS1_PRBS_DATA_PRBS_MODE_7 0x2 -+ #define TX_SYS1_PRBS_DATA_PRBS_MODE_31 0x3 -+ -+// HDCP CONFIG -+#define TX_HDCP_ECC_CONFIG 0x0024 -+#define TX_HDCP_CRC_CONFIG 0x0025 -+#define TX_HDCP_EDID_CONFIG 0x0026 -+ #define TX_HDCP_EDID_CONFIG_FORCED_SYS_TRIGGER BIT(7) -+ #define TX_HDCP_EDID_CONFIG_SYS_TRIGGER_CONFIG BIT(6) -+ #define TX_HDCP_EDID_CONFIG_MEM_ACC_SEQ_MODE BIT(5) -+ #define TX_HDCP_EDID_CONFIG_MEM_ACC_SEQ_START BIT(4) -+ #define TX_HDCP_EDID_CONFIG_FORCED_MEM_COPY_DONE BIT(3) -+ #define TX_HDCP_EDID_CONFIG_MEM_COPY_DONE_CONFIG BIT(2) -+ #define TX_HDCP_EDID_CONFIG_SYS_TRIGGER_CONFIG_SEMI_MANU BIT(1) -+ -+#define TX_HDCP_MEM_CONFIG 0x0027 -+ #define TX_HDCP_MEM_CONFIG_READ_DECRYPT BIT(3) -+ -+#define TX_HDCP_HPD_FILTER_L 0x0028 -+#define TX_HDCP_HPD_FILTER_H 0x0029 -+#define TX_HDCP_ENCRYPT_BYTE 0x002A -+#define TX_HDCP_CONFIG0 0x002B -+ #define TX_HDCP_CONFIG0_ROM_ENCRYPT_OFF GENMASK(4, 3) -+ -+#define TX_HDCP_CONFIG1 0x002C -+#define TX_HDCP_CONFIG2 0x002D -+#define TX_HDCP_CONFIG3 0x002E -+ #define TX_HDCP_CONFIG3_DDC_I2C_BUS_CLOCK_TIME_DIVIDER GENMASK(7, 0) -+ -+#define TX_HDCP_MODE 0x002F -+ #define TX_HDCP_MODE_CP_DESIRED BIT(7) -+ #define TX_HDCP_MODE_ESS_CONFIG BIT(6) -+ #define TX_HDCP_MODE_SET_AVMUTE BIT(5) -+ #define TX_HDCP_MODE_CLEAR_AVMUTE BIT(4) -+ #define TX_HDCP_MODE_HDCP_1_1 BIT(3) -+ #define TX_HDCP_MODE_VSYNC_HSYNC_FORCED_POLARITY_SELECT BIT(2) -+ #define TX_HDCP_MODE_FORCED_VSYNC_POLARITY BIT(1) -+ #define TX_HDCP_MODE_FORCED_HSYNC_POLARITY BIT(0) -+ -+// Video config, part 1 -+#define TX_VIDEO_ACTIVE_PIXELS_0 0x0030 -+#define TX_VIDEO_ACTIVE_PIXELS_1 0x0031 -+#define TX_VIDEO_FRONT_PIXELS 0x0032 -+#define TX_VIDEO_HSYNC_PIXELS 0x0033 -+#define TX_VIDEO_BACK_PIXELS 0x0034 -+#define TX_VIDEO_ACTIVE_LINES_0 0x0035 -+#define TX_VIDEO_ACTIVE_LINES_1 0x0036 -+#define TX_VIDEO_EOF_LINES 0x0037 -+#define TX_VIDEO_VSYNC_LINES 0x0038 -+#define TX_VIDEO_SOF_LINES 0x0039 -+#define TX_VIDEO_DTV_TIMING 0x003A -+ #define TX_VIDEO_DTV_TIMING_FORCE_DTV_TIMING_AUTO BIT(7) -+ #define TX_VIDEO_DTV_TIMING_FORCE_VIDEO_SCAN BIT(6) -+ #define TX_VIDEO_DTV_TIMING_FORCE_VIDEO_FIELD BIT(5) -+ #define TX_VIDEO_DTV_TIMING_DISABLE_VIC39_CORRECTION BIT(4) -+ -+#define TX_VIDEO_DTV_MODE 0x003B -+ #define TX_VIDEO_DTV_MODE_FORCED_DEFAULT_PHASE BIT(7) -+ #define TX_VIDEO_DTV_MODE_COLOR_DEPTH GENMASK(1, 0) -+ -+#define TX_VIDEO_DTV_FORMAT0 0x003C -+#define TX_VIDEO_DTV_FORMAT1 0x003D -+#define TX_VIDEO_PIXEL_PACK 0x003F -+// video config, part 2 -+#define TX_VIDEO_CSC_COEFF_B0 0x0040 -+#define TX_VIDEO_CSC_COEFF_B1 0x0041 -+#define TX_VIDEO_CSC_COEFF_R0 0x0042 -+#define TX_VIDEO_CSC_COEFF_R1 0x0043 -+#define TX_VIDEO_CSC_COEFF_CB0 0x0044 -+#define TX_VIDEO_CSC_COEFF_CB1 0x0045 -+#define TX_VIDEO_CSC_COEFF_CR0 0x0046 -+#define TX_VIDEO_CSC_COEFF_CR1 0x0047 -+#define TX_VIDEO_DTV_OPTION_L 0x0048 -+ #define TX_VIDEO_DTV_OPTION_L_OUTPUT_COLOR_FORMAT GENMASK(7, 6) -+ #define TX_VIDEO_DTV_OPTION_L_INPUT_COLOR_FORMAT GENMASK(5, 4) -+ #define TX_VIDEO_DTV_OPTION_L_OUTPUT_COLOR_DEPTH GENMASK(3, 2) -+ #define TX_VIDEO_DTV_OPTION_L_INPUT_COLOR_DEPTH GENMASK(1, 0) -+ -+#define TX_VIDEO_DTV_OPTION_H 0x0049 -+ #define TX_VIDEO_DTV_OPTION_H_COLOR_RANGE_16_235 0x0 -+ #define TX_VIDEO_DTV_OPTION_H_COLOR_RANGE_16_240 0x1 -+ #define TX_VIDEO_DTV_OPTION_H_COLOR_RANGE_1_254 0x2 -+ #define TX_VIDEO_DTV_OPTION_H_COLOR_RANGE_0_255 0x3 -+ #define TX_VIDEO_DTV_OPTION_H_OUTPUT_COLOR_RANGE GENMASK(3, 2) -+ #define TX_VIDEO_DTV_OPTION_H_INPUT_COLOR_RANGE GENMASK(1, 0) -+ -+#define TX_VIDEO_DTV_FILTER 0x004A -+#define TX_VIDEO_DTV_DITHER 0x004B -+#define TX_VIDEO_DTV_DEDITHER 0x004C -+#define TX_VIDEO_PROC_CONFIG0 0x004E -+#define TX_VIDEO_PROC_CONFIG1 0x004F -+ -+// Audio config -+#define TX_AUDIO_FORMAT 0x0058 -+ #define TX_AUDIO_FORMAT_SPDIF_OR_I2S BIT(7) -+ #define TX_AUDIO_FORMAT_I2S_2_OR_8_CH BIT(6) -+ #define TX_AUDIO_FORMAT_I2S_FORMAT GENMASK(5, 4) -+ #define TX_AUDIO_FORMAT_BIT_WIDTH_MASK GENMASK(3, 2) -+ #define TX_AUDIO_FORMAT_BIT_WIDTH_16 0x1 -+ #define TX_AUDIO_FORMAT_BIT_WIDTH_20 0x2 -+ #define TX_AUDIO_FORMAT_BIT_WIDTH_24 0x3 -+ #define TX_AUDIO_FORMAT_WS_POLARITY BIT(1) -+ #define TX_AUDIO_FORMAT_I2S_ONE_BIT_OR_I2S BIT(0) -+ #define TX_AUDIO_FORMAT_SPDIF_CHANNEL_STATUS_FROM_DATA_OR_REG BIT(0) -+ -+#define TX_AUDIO_SPDIF 0x0059 -+ #define TX_AUDIO_SPDIF_ENABLE BIT(0) -+#define TX_AUDIO_I2S 0x005A -+ #define TX_AUDIO_I2S_ENABLE BIT(0) -+#define TX_AUDIO_FIFO 0x005B -+ #define TX_AUDIO_FIFO_FIFO_DEPTH_MASK GENMASK(7, 4) -+ #define TX_AUDIO_FIFO_FIFO_DEPTH_512 0x4 -+ #define TX_AUDIO_FIFO_CRITICAL_THRESHOLD_MASK GENMASK(3, 2) -+ #define TX_AUDIO_FIFO_CRITICAL_THRESHOLD_DEPTH_DIV16 0x2 -+ #define TX_AUDIO_FIFO_NORMAL_THRESHOLD_MASK GENMASK(1, 0) -+ #define TX_AUDIO_FIFO_NORMAL_THRESHOLD_DEPTH_DIV8 0x1 -+#define TX_AUDIO_LIPSYNC 0x005C -+ #define TX_AUDIO_LIPSYNC_NORMALIZED_LIPSYNC_PARAM GENMASK(7, 0) -+#define TX_AUDIO_CONTROL 0x005D -+ #define TX_AUDIO_CONTROL_FORCED_AUDIO_FIFO_CLEAR BIT(7) -+ #define TX_AUDIO_CONTROL_AUTO_AUDIO_FIFO_CLEAR BIT(6) -+ #define TX_AUDIO_CONTROL_AUDIO_PACKET_TYPE_MASK GENMASK(5, 4) -+ #define TX_AUDIO_CONTROL_AUDIO_PACKET_TYPE_AUDIO_SAMPLE_PACKET 0x0 -+ #define TX_AUDIO_CONTROL_AUDIO_PACKET_TYPE_ONE_BIT_AUDIO 0x1 -+ #define TX_AUDIO_CONTROL_AUDIO_PACKET_TYPE_HBR_AUDIO_PACKET 0x2 -+ #define TX_AUDIO_CONTROL_AUDIO_PACKET_TYPE_DST_AUDIO_PACKET 0x3 -+ #define TX_AUDIO_CONTROL_AUDIO_SAMPLE_PACKET_VALID BIT(2) -+ #define TX_AUDIO_CONTROL_AUDIO_SAMPLE_PACKET_USER BIT(1) -+ #define TX_AUDIO_CONTROL_AUDIO_SAMPLE_PACKET_FLAT BIT(0) -+#define TX_AUDIO_HEADER 0x005E -+ #define TX_AUDIO_HEADER_AUDIO_SAMPLE_PACKET_HEADER_LAYOUT1 BIT(7) -+ #define TX_AUDIO_HEADER_SET_NORMAL_DOUBLE_IN_DST_PACKET_HEADER BIT(6) -+#define TX_AUDIO_SAMPLE 0x005F -+ #define TX_AUDIO_SAMPLE_CHANNEL_VALID GENMASK(7, 0) -+#define TX_AUDIO_VALID 0x0060 -+#define TX_AUDIO_USER 0x0061 -+#define TX_AUDIO_PACK 0x0062 -+ #define TX_AUDIO_PACK_AUDIO_SAMPLE_PACKETS_ENABLE BIT(0) -+#define TX_AUDIO_CONTROL_MORE 0x0064 -+ #define TX_AUDIO_CONTROL_MORE_ENABLE BIT(0) -+ -+// tmds config -+#define TX_TMDS_MODE 0x0068 -+ #define TX_TMDS_MODE_FORCED_HDMI BIT(7) -+ #define TX_TMDS_MODE_HDMI_CONFIG BIT(6) -+ #define TX_TMDS_MODE_BIT_SWAP BIT(3) -+ #define TX_TMDS_MODE_CHANNEL_SWAP GENMASK(2, 0) -+ -+#define TX_TMDS_CONFIG0 0x006C -+#define TX_TMDS_CONFIG1 0x006D -+ -+// packet config -+#define TX_PACKET_ALLOC_ACTIVE_1 0x0078 -+#define TX_PACKET_ALLOC_ACTIVE_2 0x0079 -+#define TX_PACKET_ALLOC_EOF_1 0x007A -+#define TX_PACKET_ALLOC_EOF_2 0x007B -+#define TX_PACKET_ALLOC_SOF_1 0x007C -+#define TX_PACKET_ALLOC_SOF_2 0x007D -+#define TX_PACKET_CONTROL_1 0x007E -+ #define TX_PACKET_CONTROL_1_FORCE_PACKET_TIMING BIT(7) -+ #define TX_PACKET_CONTROL_1_PACKET_ALLOC_MODE BIT(6) -+ #define TX_PACKET_CONTROL_1_PACKET_START_LATENCY GENMASK(5, 0) -+ -+#define TX_PACKET_CONTROL_2 0x007F -+ #define TX_PACKET_CONTROL_2_AUDIO_REQUEST_DISABLE BIT(3) -+ #define TX_PACKET_CONTROL_2_HORIZONTAL_GC_PACKET_TRANSPORT_EN BIT(1) -+ -+#define TX_CORE_EDID_CONFIG_MORE 0x0080 -+ #define TX_CORE_EDID_CONFIG_MORE_KEEP_EDID_ERROR BIT(1) -+ #define TX_CORE_EDID_CONFIG_MORE_SYS_TRIGGER_CONFIG_SEMI_MANU BIT(0) -+ -+#define TX_CORE_ALLOC_VSYNC_0 0x0081 -+#define TX_CORE_ALLOC_VSYNC_1 0x0082 -+#define TX_CORE_ALLOC_VSYNC_2 0x0083 -+#define TX_MEM_PD_REG0 0x0084 -+ -+// core config -+#define TX_CORE_DATA_CAPTURE_1 0x00F0 -+#define TX_CORE_DATA_CAPTURE_2 0x00F1 -+ #define TX_CORE_DATA_CAPTURE_2_AUDIO_SOURCE_SELECT GENMASK(7, 6) -+ #define TX_CORE_DATA_CAPTURE_2_EXTERNAL_PACKET_ENABLE BIT(5) -+ #define TX_CORE_DATA_CAPTURE_2_INTERNAL_PACKET_ENABLE BIT(4) -+ #define TX_CORE_DATA_CAPTURE_2_AFE_FIFO_SRC_LANE1 GENMASK(3, 2) -+ #define TX_CORE_DATA_CAPTURE_2_AFE_FIFO_SRC_LANE0 GENMASK(1, 0) -+ -+#define TX_CORE_DATA_MONITOR_1 0x00F2 -+ #define TX_CORE_DATA_MONITOR_1_LANE1 BIT(7) -+ #define TX_CORE_DATA_MONITOR_1_SELECT_LANE1 GENMASK(6, 4) -+ #define TX_CORE_DATA_MONITOR_1_LANE0 BIT(3) -+ #define TX_CORE_DATA_MONITOR_1_SELECT_LANE0 GENMASK(2, 0) -+ -+#define TX_CORE_DATA_MONITOR_2 0x00F3 -+ #define TX_CORE_DATA_MONITOR_2_MONITOR_SELECT GENMASK(2, 0) -+ -+#define TX_CORE_CALIB_MODE 0x00F4 -+#define TX_CORE_CALIB_SAMPLE_DELAY 0x00F5 -+#define TX_CORE_CALIB_VALUE_AUTO 0x00F6 -+#define TX_CORE_CALIB_VALUE 0x00F7 -+ -+// system config 4 -+#define TX_SYS4_TX_CKI_DDR 0x00A0 -+#define TX_SYS4_TX_CKO_DDR 0x00A1 -+#define TX_SYS4_RX_CKI_DDR 0x00A2 -+#define TX_SYS4_RX_CKO_DDR 0x00A3 -+#define TX_SYS4_CONNECT_SEL_0 0x00A4 -+#define TX_SYS4_CONNECT_SEL_1 0x00A5 -+ #define TX_SYS4_CONNECT_SEL_1_TX_CONNECT_SEL_UPPER_CHANNEL_DATA BIT(6) -+ -+#define TX_SYS4_CONNECT_SEL_2 0x00A6 -+#define TX_SYS4_CONNECT_SEL_3 0x00A7 -+#define TX_SYS4_CK_INV_VIDEO 0x00A8 -+ #define TX_SYS4_CK_INV_VIDEO_TMDS_CLK_PATTERN BIT(4) -+#define TX_SYS4_CK_INV_AUDIO 0x00A9 -+#define TX_SYS4_CK_INV_AFE 0x00AA -+#define TX_SYS4_CK_INV_CH01 0x00AB -+#define TX_SYS4_CK_INV_CH2 0x00AC -+#define TX_SYS4_CK_CEC 0x00AD -+#define TX_SYS4_CK_SOURCE_1 0x00AE -+#define TX_SYS4_CK_SOURCE_2 0x00AF -+ -+#define TX_IEC60958_SUB1_OFFSET 0x00B0 -+#define TX_IEC60958_SUB2_OFFSET 0x00C8 -+ -+// system config 5 -+#define TX_SYS5_TX_SOFT_RESET_1 0x00E0 -+ #define TX_SYS5_TX_SOFT_RESET_1_TX_PIXEL_RSTN BIT(7) -+ #define TX_SYS5_TX_SOFT_RESET_1_TX_TMDS_RSTN BIT(6) -+ #define TX_SYS5_TX_SOFT_RESET_1_TX_AUDIO_MASTER_RSTN BIT(5) -+ #define TX_SYS5_TX_SOFT_RESET_1_TX_AUDIO_RESAMPLE_RSTN BIT(4) -+ #define TX_SYS5_TX_SOFT_RESET_1_TX_I2S_RESET_RSTN BIT(3) -+ #define TX_SYS5_TX_SOFT_RESET_1_TX_DIG_RESET_N_CH2 BIT(2) -+ #define TX_SYS5_TX_SOFT_RESET_1_TX_DIG_RESET_N_CH1 BIT(1) -+ #define TX_SYS5_TX_SOFT_RESET_1_TX_DIG_RESET_N_CH0 BIT(0) -+ -+#define TX_SYS5_TX_SOFT_RESET_2 0x00E1 -+ #define TX_SYS5_TX_SOFT_RESET_2_HDMI_CH3_RST_IN BIT(7) -+ #define TX_SYS5_TX_SOFT_RESET_2_HDMI_CH2_RST_IN BIT(6) -+ #define TX_SYS5_TX_SOFT_RESET_2_HDMI_CH1_RST_IN BIT(5) -+ #define TX_SYS5_TX_SOFT_RESET_2_HDMI_CH0_RST_IN BIT(4) -+ #define TX_SYS5_TX_SOFT_RESET_2_HDMI_SR_RST BIT(3) -+ #define TX_SYS5_TX_SOFT_RESET_2_TX_DDC_HDCP_RSTN BIT(2) -+ #define TX_SYS5_TX_SOFT_RESET_2_TX_DDC_EDID_RSTN BIT(1) -+ #define TX_SYS5_TX_SOFT_RESET_2_TX_DIG_RESET_N_CH3 BIT(0) -+ -+#define TX_SYS5_RX_SOFT_RESET_1 0x00E2 -+#define TX_SYS5_RX_SOFT_RESET_2 0x00E3 -+#define TX_SYS5_RX_SOFT_RESET_3 0x00E4 -+#define TX_SYS5_SSTL_BIDIR_IN 0x00E5 -+#define TX_SYS5_SSTL_IN 0x00E6 -+#define TX_SYS5_SSTL_DIFF_IN 0x00E7 -+#define TX_SYS5_FIFO_CONFIG 0x00E8 -+ #define TX_SYS5_FIFO_CONFIG_AFE_FIFO_CHANNEL2_BYPASS BIT(6) -+ #define TX_SYS5_FIFO_CONFIG_AFE_FIFO_CHANNEL1_BYPASS BIT(5) -+ #define TX_SYS5_FIFO_CONFIG_AFE_FIFO_CHANNEL0_BYPASS BIT(4) -+ #define TX_SYS5_FIFO_CONFIG_CLK_CHANNEL3_OUTPUT_ENABLE BIT(3) -+ #define TX_SYS5_FIFO_CONFIG_AFE_FIFO_CHANNEL2_ENABLE BIT(2) -+ #define TX_SYS5_FIFO_CONFIG_AFE_FIFO_CHANNEL1_ENABLE BIT(1) -+ #define TX_SYS5_FIFO_CONFIG_AFE_FIFO_CHANNEL0_ENABLE BIT(0) -+ -+#define TX_SYS5_FIFO_SAMP01_CFG 0x00E9 -+#define TX_SYS5_FIFO_SAMP23_CFG 0x00EA -+#define TX_SYS5_CONNECT_FIFO_CFG 0x00EB -+#define TX_SYS5_IO_CALIB_CONTROL 0x00EC -+#define TX_SYS5_SSTL_BIDIR_OUT 0x00ED -+#define TX_SYS5_SSTL_OUT 0x00EE -+#define TX_SYS5_SSTL_DIFF_OUT 0x00EF -+ -+// HDCP shadow register -+#define TX_HDCP_SHW_BKSV_0 0x0100 -+#define TX_HDCP_SHW_BKSV_1 0x0101 -+#define TX_HDCP_SHW_BKSV_2 0x0102 -+#define TX_HDCP_SHW_BKSV_3 0x0103 -+#define TX_HDCP_SHW_BKSV_4 0x0104 -+#define TX_HDCP_SHW_RI1_0 0x0108 -+#define TX_HDCP_SHW_RI1_1 0x0109 -+#define TX_HDCP_SHW_PJ1 0x010A -+#define TX_HDCP_SHW_AKSV_0 0x0110 -+#define TX_HDCP_SHW_AKSV_1 0x0111 -+#define TX_HDCP_SHW_AKSV_2 0x0112 -+#define TX_HDCP_SHW_AKSV_3 0x0113 -+#define TX_HDCP_SHW_AKSV_4 0x0114 -+#define TX_HDCP_SHW_AINFO 0x0115 -+#define TX_HDCP_SHW_AN_0 0x0118 -+#define TX_HDCP_SHW_AN_1 0x0119 -+#define TX_HDCP_SHW_AN_2 0x011A -+#define TX_HDCP_SHW_AN_3 0x011B -+#define TX_HDCP_SHW_AN_4 0x011C -+#define TX_HDCP_SHW_AN_5 0x011D -+#define TX_HDCP_SHW_AN_6 0x011E -+#define TX_HDCP_SHW_AN_7 0x011F -+#define TX_HDCP_SHW_V1_H0_0 0x0120 -+#define TX_HDCP_SHW_V1_H0_1 0x0121 -+#define TX_HDCP_SHW_V1_H0_2 0x0122 -+#define TX_HDCP_SHW_V1_H0_3 0x0123 -+#define TX_HDCP_SHW_V1_H1_0 0x0124 -+#define TX_HDCP_SHW_V1_H1_1 0x0125 -+#define TX_HDCP_SHW_V1_H1_2 0x0126 -+#define TX_HDCP_SHW_V1_H1_3 0x0127 -+#define TX_HDCP_SHW_V1_H2_0 0x0128 -+#define TX_HDCP_SHW_V1_H2_1 0x0129 -+#define TX_HDCP_SHW_V1_H2_2 0x012A -+#define TX_HDCP_SHW_V1_H2_3 0x012B -+#define TX_HDCP_SHW_V1_H3_0 0x012C -+#define TX_HDCP_SHW_V1_H3_1 0x012D -+#define TX_HDCP_SHW_V1_H3_2 0x012E -+#define TX_HDCP_SHW_V1_H3_3 0x012F -+#define TX_HDCP_SHW_V1_H4_0 0x0130 -+#define TX_HDCP_SHW_V1_H4_1 0x0131 -+#define TX_HDCP_SHW_V1_H4_2 0x0132 -+#define TX_HDCP_SHW_V1_H4_3 0x0133 -+#define TX_HDCP_SHW_BCAPS 0x0140 -+#define TX_HDCP_SHW_BSTATUS_0 0x0141 -+#define TX_HDCP_SHW_BSTATUS_1 0x0142 -+#define TX_HDCP_SHW_KSV_FIFO 0x0143 -+ -+// system status 0 -+#define TX_SYSST0_CONNECT_FIFO 0x0180 -+#define TX_SYSST0_PLL_MONITOR 0x0181 -+#define TX_SYSST0_AFE_FIFO 0x0182 -+#define TX_SYSST0_ROM_STATUS 0x018F -+ -+// hdcp status -+#define TX_HDCP_ST_AUTHENTICATION 0x0190 -+#define TX_HDCP_ST_FRAME_COUNT 0x0191 -+#define TX_HDCP_ST_STATUS_0 0x0192 -+#define TX_HDCP_ST_STATUS_1 0x0193 -+#define TX_HDCP_ST_STATUS_2 0x0194 -+#define TX_HDCP_ST_STATUS_3 0x0195 -+#define TX_HDCP_ST_EDID_STATUS 0x0196 -+ #define TX_HDCP_ST_EDID_STATUS_SYSTEM_STATUS GENMASK(7, 6) -+ #define TX_HDCP_ST_EDID_STATUS_SYSTEM_STATUS_NO_SINK_ATTACHED 0x0 -+ #define TX_HDCP_ST_EDID_STATUS_SYSTEM_STATUS_READING_EDID 0x1 -+ #define TX_HDCP_ST_EDID_STATUS_SYSTEM_STATUS_DVI_MODE 0x2 -+ #define TX_HDCP_ST_EDID_STATUS_SYSTEM_STATUS_HDMI_MODE 0x3 -+ #define TX_HDCP_ST_EDID_STATUS_EDID_DATA_READY BIT(4) -+ #define TX_HDCP_ST_EDID_STATUS_HPD_STATUS BIT(1) -+ -+#define TX_HDCP_ST_MEM_STATUS 0x0197 -+#define TX_HDCP_ST_ST_MODE 0x019F -+ -+// video status -+#define TX_VIDEO_ST_ACTIVE_PIXELS_1 0x01A0 -+#define TX_VIDEO_ST_ACTIVE_PIXELS_2 0x01A1 -+#define TX_VIDEO_ST_FRONT_PIXELS 0x01A2 -+#define TX_VIDEO_ST_HSYNC_PIXELS 0x01A3 -+#define TX_VIDEO_ST_BACK_PIXELS 0x01A4 -+#define TX_VIDEO_ST_ACTIVE_LINES_1 0x01A5 -+#define TX_VIDEO_ST_ACTIVE_LINES_2 0x01A6 -+#define TX_VIDEO_ST_EOF_LINES 0x01A7 -+#define TX_VIDEO_ST_VSYNC_LINES 0x01A8 -+#define TX_VIDEO_ST_SOF_LINES 0x01A9 -+#define TX_VIDEO_ST_DTV_TIMING 0x01AA -+#define TX_VIDEO_ST_DTV_MODE 0x01AB -+// audio status -+#define TX_VIDEO_ST_AUDIO_STATUS 0x01AC -+#define TX_AFE_STATUS_0 0x01AE -+#define TX_AFE_STATUS_1 0x01AF -+ -+#define TX_IEC60958_ST_SUB1_OFFSET 0x01B0 -+#define TX_IEC60958_ST_SUB2_OFFSET 0x01C8 -+ -+// system status 1 -+#define TX_SYSST1_CALIB_BIT_RESULT_0 0x01E0 -+#define TX_SYSST1_CALIB_BIT_RESULT_1 0x01E1 -+//HDMI_STATUS_OUT[7:0] -+#define TX_HDMI_PHY_READBACK_0 0x01E2 -+//HDMI_COMP_OUT[4] -+//HDMI_STATUS_OUT[11:8] -+#define TX_HDMI_PHY_READBACK_1 0x01E3 -+#define TX_SYSST1_CALIB_BIT_RESULT_4 0x01E4 -+#define TX_SYSST1_CALIB_BIT_RESULT_5 0x01E5 -+#define TX_SYSST1_CALIB_BIT_RESULT_6 0x01E6 -+#define TX_SYSST1_CALIB_BIT_RESULT_7 0x01E7 -+#define TX_SYSST1_CALIB_BUS_RESULT_0 0x01E8 -+#define TX_SYSST1_CALIB_BUS_RESULT_1 0x01E9 -+#define TX_SYSST1_CALIB_BUS_RESULT_2 0x01EA -+#define TX_SYSST1_CALIB_BUS_RESULT_3 0x01EB -+#define TX_SYSST1_CALIB_BUS_RESULT_4 0x01EC -+#define TX_SYSST1_CALIB_BUS_RESULT_5 0x01ED -+#define TX_SYSST1_CALIB_BUS_RESULT_6 0x01EE -+#define TX_SYSST1_CALIB_BUS_RESULT_7 0x01EF -+ -+// Packet status -+#define TX_PACKET_ST_REQUEST_STATUS_1 0x01F0 -+#define TX_PACKET_ST_REQUEST_STATUS_2 0x01F1 -+#define TX_PACKET_ST_REQUEST_MISSED_1 0x01F2 -+#define TX_PACKET_ST_REQUEST_MISSED_2 0x01F3 -+#define TX_PACKET_ST_ENCODE_STATUS_0 0x01F4 -+#define TX_PACKET_ST_ENCODE_STATUS_1 0x01F5 -+#define TX_PACKET_ST_ENCODE_STATUS_2 0x01F6 -+#define TX_PACKET_ST_TIMER_STATUS 0x01F7 -+ -+// tmds status -+#define TX_TMDS_ST_CLOCK_METER_1 0x01F8 -+#define TX_TMDS_ST_CLOCK_METER_2 0x01F9 -+#define TX_TMDS_ST_CLOCK_METER_3 0x01FA -+#define TX_TMDS_ST_TMDS_STATUS_1 0x01FC -+#define TX_TMDS_ST_TMDS_STATUS_2 0x01FD -+#define TX_TMDS_ST_TMDS_STATUS_3 0x01FE -+#define TX_TMDS_ST_TMDS_STATUS_4 0x01FF -+ -+// Packet register -+#define TX_PKT_REG_SPD_INFO_BASE_ADDR 0x0200 -+#define TX_PKT_REG_VEND_INFO_BASE_ADDR 0x0220 -+#define TX_PKT_REG_MPEG_INFO_BASE_ADDR 0x0240 -+#define TX_PKT_REG_AVI_INFO_BASE_ADDR 0x0260 -+#define TX_PKT_REG_AUDIO_INFO_BASE_ADDR 0x0280 -+#define TX_PKT_REG_ACP_INFO_BASE_ADDR 0x02A0 -+#define TX_PKT_REG_ISRC1_BASE_ADDR 0x02C0 -+#define TX_PKT_REG_ISRC2_BASE_ADDR 0x02E0 -+#define TX_PKT_REG_EXCEPT0_BASE_ADDR 0x0300 -+#define TX_PKT_REG_EXCEPT1_BASE_ADDR 0x0320 -+#define TX_PKT_REG_EXCEPT2_BASE_ADDR 0x0340 -+#define TX_PKT_REG_EXCEPT3_BASE_ADDR 0x0360 -+#define TX_PKT_REG_EXCEPT4_BASE_ADDR 0x0380 -+#define TX_PKT_REG_GAMUT_P0_BASE_ADDR 0x03A0 -+#define TX_PKT_REG_GAMUT_P1_1_BASE_ADDR 0x03C0 -+#define TX_PKT_REG_GAMUT_P1_2_BASE_ADDR 0x03E0 -+ -+#define TX_RX_EDID_OFFSET 0x0600 -+ -+/* HDMI OTHER registers */ -+ -+#define HDMI_OTHER_CTRL0 0x8000 -+#define HDMI_OTHER_CTRL1 0x8001 -+ #define HDMI_OTHER_CTRL1_POWER_ON BIT(15) -+ #define HDMI_OTHER_CTRL1_HDMI_AUDIO_CLOCK_ON BIT(13) -+ -+#define HDMI_OTHER_STATUS0 0x8002 -+#define HDMI_OTHER_CTRL2 0x8003 -+#define HDMI_OTHER_INTR_MASKN 0x8004 -+ #define HDMI_OTHER_INTR_MASKN_TX_EDID_INT_RISE BIT(2) -+ #define HDMI_OTHER_INTR_MASKN_TX_HPD_INT_FALL BIT(1) -+ #define HDMI_OTHER_INTR_MASKN_TX_HPD_INT_RISE BIT(0) -+ -+#define HDMI_OTHER_INTR_STAT 0x8005 -+ #define HDMI_OTHER_INTR_STAT_EDID_RISING BIT(2) -+ #define HDMI_OTHER_INTR_STAT_HPD_FALLING BIT(1) -+ #define HDMI_OTHER_INTR_STAT_HPD_RISING BIT(0) -+ -+#define HDMI_OTHER_INTR_STAT_CLR 0x8006 -+ #define HDMI_OTHER_INTR_STAT_CLR_EDID_RISING BIT(2) -+ #define HDMI_OTHER_INTR_STAT_CLR_HPD_FALLING BIT(1) -+ #define HDMI_OTHER_INTR_STAT_CLR_HPD_RISING BIT(0) -+ -+#define HDMI_OTHER_AVI_INTR_MASKN0 0x8008 -+#define HDMI_OTHER_AVI_INTR_MASKN1 0x8009 -+#define HDMI_OTHER_RX_AINFO_INTR_MASKN0 0x800a -+#define HDMI_OTHER_RX_AINFO_INTR_MASKN1 0x800b -+#define HDMI_OTHER_RX_PACKET_INTR_CLR 0x800c -+ -+#endif /* __MESON_TRANSWITCH_HDMI_H__ */ -diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c -index 2a82119eb58..a2c1bf1aed7 100644 ---- a/drivers/gpu/drm/meson/meson_vclk.c -+++ b/drivers/gpu/drm/meson/meson_vclk.c -@@ -732,6 +732,11 @@ meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq) - return MODE_CLOCK_HIGH; - } - -+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) -+ return MODE_OK; -+ - if (meson_hdmi_pll_find_params(priv, freq, &m, &frac, &od)) - return MODE_OK; - -@@ -784,6 +789,11 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq, - return MODE_CLOCK_HIGH; - } - -+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) -+ return MODE_OK; -+ - for (i = 0 ; params[i].pixel_freq ; ++i) { - DRM_DEBUG_DRIVER("i = %d pixel_freq = %d alt = %d\n", - i, params[i].pixel_freq, -@@ -1024,6 +1034,128 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, - regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, VCLK_EN, VCLK_EN); - } - -+static int meson_vclk_set_rate_exclusive(struct meson_drm *priv, -+ enum vpu_bulk_clk_id clk_id, -+ unsigned int rate_khz) -+{ -+ struct clk *clk = priv->vid_clks[clk_id].clk; -+ int ret; -+ -+ ret = clk_set_rate_exclusive(clk, rate_khz * 1000UL); -+ if (ret) -+ return ret; -+ -+ priv->vid_clk_rate_exclusive[clk_id] = true; -+ -+ return 0; -+} -+ -+static void meson_vclk_disable_ccf(struct meson_drm *priv) -+{ -+ unsigned int i; -+ -+ /* allow all clocks to be changed in _enable again */ -+ for (i = 0; i < VPU_VID_CLK_NUM; i++) { -+ if (!priv->vid_clk_rate_exclusive[i]) -+ continue; -+ -+ clk_rate_exclusive_put(priv->vid_clks[i].clk); -+ priv->vid_clk_rate_exclusive[i] = false; -+ } -+ -+ if (priv->clk_dac_enabled) { -+ clk_disable(priv->clk_dac); -+ priv->clk_dac_enabled = false; -+ } -+ -+ if (priv->clk_venc_enabled) { -+ clk_disable(priv->clk_venc); -+ priv->clk_venc_enabled = false; -+ } -+} -+ -+static int meson_vclk_enable_ccf(struct meson_drm *priv, unsigned int target, -+ bool hdmi_use_enci, unsigned int phy_freq, -+ unsigned int dac_freq, unsigned int venc_freq) -+{ -+ enum vpu_bulk_clk_id venc_clk_id, dac_clk_id; -+ int ret; -+ -+ if (target == MESON_VCLK_TARGET_CVBS || hdmi_use_enci) -+ venc_clk_id = VPU_VID_CLK_CTS_ENCI; -+ else -+ venc_clk_id = VPU_VID_CLK_CTS_ENCP; -+ -+ if (target == MESON_VCLK_TARGET_CVBS) -+ dac_clk_id = VPU_VID_CLK_CTS_VDAC0; -+ else -+ dac_clk_id = VPU_VID_CLK_HDMI_TX_PIXEL; -+ -+ /* -+ * The TMDS clock also updates the PLL. Protect the PLL rate so all -+ * following clocks are derived from the PLL setting which matches the -+ * TMDS clock. -+ */ -+ ret = meson_vclk_set_rate_exclusive(priv, VPU_VID_CLK_TMDS, phy_freq); -+ if (ret) { -+ dev_err(priv->dev, "Failed to set TMDS clock to %ukHz: %d\n", -+ phy_freq, ret); -+ goto out_enable_clocks; -+ } -+ -+ /* -+ * The DAC clock may be derived from a parent of the VENC clock so we -+ * must protect the VENC clock from changing it's rate. This works -+ * because the DAC freq can be divided by the VENC clock. -+ */ -+ ret = meson_vclk_set_rate_exclusive(priv, venc_clk_id, venc_freq); -+ if (ret) { -+ dev_warn(priv->dev, -+ "Failed to set VENC clock to %ukHz while TMDS clock is %ukHz: %d\n", -+ venc_freq, phy_freq, ret); -+ goto out_enable_clocks; -+ } -+ -+ priv->clk_venc = priv->vid_clks[venc_clk_id].clk; -+ -+ /* -+ * after changing any of the VID_PLL_* clocks (which can happen when -+ * update the VENC clock rate) we need to assert and then de-assert the -+ * VID_DIVIDER_CNTL_* reset lines. -+ */ -+ reset_control_bulk_assert(VPU_RESET_VID_PLL_NUM, priv->vid_pll_resets); -+ reset_control_bulk_deassert(VPU_RESET_VID_PLL_NUM, priv->vid_pll_resets); -+ -+ ret = meson_vclk_set_rate_exclusive(priv, dac_clk_id, dac_freq); -+ if (ret) { -+ dev_warn(priv->dev, -+ "Failed to set pixel clock to %ukHz while TMDS clock is %ukHz: %d\n", -+ dac_freq, phy_freq, ret); -+ goto out_enable_clocks; -+ } -+ -+ priv->clk_dac = priv->vid_clks[dac_clk_id].clk; -+ -+out_enable_clocks: -+ ret = clk_enable(priv->clk_venc); -+ if (ret) -+ dev_err(priv->dev, -+ "Failed to re-enable the VENC clock at %ukHz: %d\n", -+ venc_freq, ret); -+ else -+ priv->clk_venc_enabled = true; -+ -+ ret = clk_enable(priv->clk_dac); -+ if (ret) -+ dev_err(priv->dev, -+ "Failed to re-enable the pixel clock at %ukHz: %d\n", -+ dac_freq, ret); -+ else -+ priv->clk_dac_enabled = true; -+ -+ return ret; -+} -+ - void meson_vclk_setup(struct meson_drm *priv, unsigned int target, - unsigned int phy_freq, unsigned int vclk_freq, - unsigned int venc_freq, unsigned int dac_freq, -@@ -1034,6 +1166,20 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, - unsigned int hdmi_tx_div; - unsigned int venc_div; - -+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) { -+ /* CVBS video clocks are generated off a 1296MHz base clock */ -+ if (target == MESON_VCLK_TARGET_CVBS) -+ phy_freq = 1296000; -+ -+ dev_err(priv->dev, "%s(target: %u, phy: %u, dac: %u, venc: %u, hdmi_use_enci: %u)\n", __func__, target, phy_freq, dac_freq, venc_freq, hdmi_use_enci); -+ meson_vclk_disable_ccf(priv); -+ meson_vclk_enable_ccf(priv, target, hdmi_use_enci, phy_freq, -+ dac_freq, venc_freq); -+ return; -+ } -+ - if (target == MESON_VCLK_TARGET_CVBS) { - meson_venci_cvbs_clock_config(priv); - return; -diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c -index 3c55ed00335..009882bda7b 100644 ---- a/drivers/gpu/drm/meson/meson_venc.c -+++ b/drivers/gpu/drm/meson/meson_venc.c -@@ -60,10 +60,6 @@ - - /* HHI Registers */ - #define HHI_GCLK_MPEG2 0x148 /* 0x52 offset in data sheet */ --#define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */ --#define HHI_VDAC_CNTL0_G12A 0x2EC /* 0xbb offset in data sheet */ --#define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */ --#define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbc offset in data sheet */ - #define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 offset in data sheet */ - - struct meson_cvbs_enci_mode meson_cvbs_enci_pal = { -@@ -1749,31 +1745,47 @@ void meson_venc_enable_vsync(struct meson_drm *priv) - { - writel_relaxed(VENC_INTCTRL_ENCI_LNRST_INT_EN, - priv->io_base + _REG(VENC_INTCTRL)); -- regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), BIT(25)); -+ -+ if (priv->intr_clks[0].clk) { -+ if (!priv->intr_clks_enabled) { -+ int ret; -+ -+ ret = clk_bulk_enable(priv->num_intr_clks, -+ priv->intr_clks); -+ if (ret) -+ dev_err(priv->dev, -+ "Failed to enable the interrupt clocks\n"); -+ else -+ priv->intr_clks_enabled = true; -+ } -+ } else { -+ regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), BIT(25)); -+ } - } - - void meson_venc_disable_vsync(struct meson_drm *priv) - { -- regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), 0); -+ if (priv->intr_clks[0].clk) { -+ if (priv->intr_clks_enabled) { -+ clk_bulk_disable(priv->num_intr_clks, -+ priv->intr_clks); -+ priv->intr_clks_enabled = false; -+ } -+ } else { -+ regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), 0); -+ } -+ - writel_relaxed(0, priv->io_base + _REG(VENC_INTCTRL)); - } - - void meson_venc_init(struct meson_drm *priv) - { -- /* Disable CVBS VDAC */ -- if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { -- regmap_write(priv->hhi, HHI_VDAC_CNTL0_G12A, 0); -- regmap_write(priv->hhi, HHI_VDAC_CNTL1_G12A, 8); -- } else { -- regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0); -- regmap_write(priv->hhi, HHI_VDAC_CNTL1, 8); -- } -- - /* Power Down Dacs */ - writel_relaxed(0xff, priv->io_base + _REG(VENC_VDAC_SETTING)); - - /* Disable HDMI PHY */ -- regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0); -+ if (priv->hhi) -+ regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0); - - /* Disable HDMI */ - writel_bits_relaxed(VPU_HDMI_ENCI_DATA_TO_HDMI | -diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c -index cd399b0b718..bdfa342c4ca 100644 ---- a/drivers/gpu/drm/meson/meson_viu.c -+++ b/drivers/gpu/drm/meson/meson_viu.c -@@ -448,13 +448,17 @@ void meson_viu_init(struct meson_drm *priv) - writel_relaxed(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT)); - writel_relaxed(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT)); - -- /* Set OSD alpha replace value */ -- writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT, -- 0xff << OSD_REPLACE_SHIFT, -- priv->io_base + _REG(VIU_OSD1_CTRL_STAT2)); -- writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT, -- 0xff << OSD_REPLACE_SHIFT, -- priv->io_base + _REG(VIU_OSD2_CTRL_STAT2)); -+ if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) && -+ !meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) && -+ !meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) { -+ /* Set OSD alpha replace value */ -+ writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT, -+ 0xff << OSD_REPLACE_SHIFT, -+ priv->io_base + _REG(VIU_OSD1_CTRL_STAT2)); -+ writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT, -+ 0xff << OSD_REPLACE_SHIFT, -+ priv->io_base + _REG(VIU_OSD2_CTRL_STAT2)); -+ } - - /* Disable VD1 AFBC */ - /* di_mif0_en=0 mif0_to_vpp_en=0 di_mad_en=0 and afbc vd1 set=0*/ -diff --git a/drivers/phy/amlogic/Kconfig b/drivers/phy/amlogic/Kconfig -index ce7ba3eb2a8..671435b605f 100644 ---- a/drivers/phy/amlogic/Kconfig -+++ b/drivers/phy/amlogic/Kconfig -@@ -25,6 +25,16 @@ config PHY_MESON8B_USB2 - Meson8b and GXBB SoCs. - If unsure, say N. - -+config PHY_MESON_CVBS_DAC -+ tristate "Amlogic Meson CVBS DAC PHY driver" -+ depends on ARCH_MESON || COMPILE_TEST -+ depends on OF -+ select MFD_SYSCON -+ help -+ Enable this to support the CVBS DAC (PHY) found in Amlogic -+ Meson SoCs. -+ If unsure, say N. -+ - config PHY_MESON_GXL_USB2 - tristate "Meson GXL and GXM USB2 PHY drivers" - default ARCH_MESON -diff --git a/drivers/phy/amlogic/Makefile b/drivers/phy/amlogic/Makefile -index 91e3b9790c0..f6c38f7386a 100644 ---- a/drivers/phy/amlogic/Makefile -+++ b/drivers/phy/amlogic/Makefile -@@ -1,6 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0-only - obj-$(CONFIG_PHY_MESON8_HDMI_TX) += phy-meson8-hdmi-tx.o - obj-$(CONFIG_PHY_MESON8B_USB2) += phy-meson8b-usb2.o -+obj-$(CONFIG_PHY_MESON_CVBS_DAC) += phy-meson-cvbs-dac.o - obj-$(CONFIG_PHY_MESON_GXL_USB2) += phy-meson-gxl-usb2.o - obj-$(CONFIG_PHY_MESON_G12A_USB2) += phy-meson-g12a-usb2.o - obj-$(CONFIG_PHY_MESON_G12A_USB3_PCIE) += phy-meson-g12a-usb3-pcie.o -diff --git a/drivers/phy/amlogic/phy-meson-cvbs-dac.c b/drivers/phy/amlogic/phy-meson-cvbs-dac.c -new file mode 100644 -index 00000000000..96549e63bc1 ---- /dev/null -+++ b/drivers/phy/amlogic/phy-meson-cvbs-dac.c -@@ -0,0 +1,375 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Copyright (C) 2016 BayLibre, SAS -+ * Copyright (C) 2021 Martin Blumenstingl -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define HHI_VDAC_CNTL0_MESON8 0x2F4 /* 0xbd offset in data sheet */ -+#define HHI_VDAC_CNTL1_MESON8 0x2F8 /* 0xbe offset in data sheet */ -+ -+#define HHI_VDAC_CNTL0_G12A 0x2EC /* 0xbd offset in data sheet */ -+#define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbe offset in data sheet */ -+ -+enum phy_meson_cvbs_dac_reg { -+ MESON_CDAC_CTRL_RESV1, -+ MESON_CDAC_CTRL_RESV2, -+ MESON_CDAC_VREF_ADJ, -+ MESON_CDAC_RL_ADJ, -+ MESON_CDAC_CLK_PHASE_SEL, -+ MESON_CDAC_DRIVER_ADJ, -+ MESON_CDAC_EXT_VREF_EN, -+ MESON_CDAC_BIAS_C, -+ MESON_VDAC_CNTL0_RESERVED, -+ MESON_CDAC_GSW, -+ MESON_CDAC_PWD, -+ MESON_VDAC_CNTL1_RESERVED, -+ MESON_CVBS_DAC_NUM_REGS -+}; -+ -+struct phy_meson_cvbs_dac_data { -+ const struct reg_field *reg_fields; -+ u8 cdac_ctrl_resv2_enable_val; -+ u8 cdac_vref_adj_enable_val; -+ u8 cdac_rl_adj_enable_val; -+ bool disable_ignore_cdac_pwd; -+ bool needs_cvbs_trimming_nvmem_cell; -+}; -+ -+struct phy_meson_cvbs_dac_priv { -+ struct regmap_field *regs[MESON_CVBS_DAC_NUM_REGS]; -+ const struct phy_meson_cvbs_dac_data *data; -+ u8 cdac_gsw_enable_val; -+}; -+ -+static const struct reg_field phy_meson8_cvbs_dac_reg_fields[] = { -+ [MESON_CDAC_CTRL_RESV1] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 0, 7), -+ [MESON_CDAC_CTRL_RESV2] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 8, 15), -+ [MESON_CDAC_VREF_ADJ] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 16, 20), -+ [MESON_CDAC_RL_ADJ] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 21, 23), -+ [MESON_CDAC_CLK_PHASE_SEL] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 24, 24), -+ [MESON_CDAC_DRIVER_ADJ] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 25, 25), -+ [MESON_CDAC_EXT_VREF_EN] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 26, 26), -+ [MESON_CDAC_BIAS_C] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 27, 27), -+ [MESON_VDAC_CNTL0_RESERVED] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 28, 31), -+ [MESON_CDAC_GSW] = REG_FIELD(HHI_VDAC_CNTL1_MESON8, 0, 2), -+ [MESON_CDAC_PWD] = REG_FIELD(HHI_VDAC_CNTL1_MESON8, 3, 3), -+ [MESON_VDAC_CNTL1_RESERVED] = REG_FIELD(HHI_VDAC_CNTL1_MESON8, 4, 31), -+}; -+ -+static const struct reg_field phy_meson_g12a_cvbs_dac_reg_fields[] = { -+ [MESON_CDAC_CTRL_RESV1] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 0, 7), -+ [MESON_CDAC_CTRL_RESV2] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 8, 15), -+ [MESON_CDAC_VREF_ADJ] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 16, 20), -+ [MESON_CDAC_RL_ADJ] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 21, 23), -+ [MESON_CDAC_CLK_PHASE_SEL] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 24, 24), -+ [MESON_CDAC_DRIVER_ADJ] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 25, 25), -+ [MESON_CDAC_EXT_VREF_EN] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 26, 26), -+ [MESON_CDAC_BIAS_C] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 27, 27), -+ [MESON_VDAC_CNTL0_RESERVED] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 28, 31), -+ [MESON_CDAC_GSW] = REG_FIELD(HHI_VDAC_CNTL1_G12A, 0, 2), -+ [MESON_CDAC_PWD] = REG_FIELD(HHI_VDAC_CNTL1_G12A, 3, 3), -+ [MESON_VDAC_CNTL1_RESERVED] = REG_FIELD(HHI_VDAC_CNTL1_G12A, 4, 31), -+}; -+ -+static const struct phy_meson_cvbs_dac_data phy_meson8_cvbs_dac_data = { -+ .reg_fields = phy_meson8_cvbs_dac_reg_fields, -+ .cdac_ctrl_resv2_enable_val = 0x0, -+ .cdac_vref_adj_enable_val = 0x0, -+ .cdac_rl_adj_enable_val = 0x0, -+ .disable_ignore_cdac_pwd = false, -+ .needs_cvbs_trimming_nvmem_cell = true, -+}; -+ -+static const struct phy_meson_cvbs_dac_data phy_meson_gxbb_cvbs_dac_data = { -+ .reg_fields = phy_meson8_cvbs_dac_reg_fields, -+ .cdac_ctrl_resv2_enable_val = 0x0, -+ .cdac_vref_adj_enable_val = 0x0, -+ .cdac_rl_adj_enable_val = 0x0, -+ .disable_ignore_cdac_pwd = false, -+ .needs_cvbs_trimming_nvmem_cell = false, -+}; -+ -+static const struct phy_meson_cvbs_dac_data phy_meson_gxl_cvbs_dac_data = { -+ .reg_fields = phy_meson8_cvbs_dac_reg_fields, -+ .cdac_ctrl_resv2_enable_val = 0x0, -+ .cdac_vref_adj_enable_val = 0xf, -+ .cdac_rl_adj_enable_val = 0x0, -+ .disable_ignore_cdac_pwd = false, -+ .needs_cvbs_trimming_nvmem_cell = false, -+}; -+ -+static const struct phy_meson_cvbs_dac_data phy_meson_g12a_cvbs_dac_data = { -+ .reg_fields = phy_meson_g12a_cvbs_dac_reg_fields, -+ .cdac_ctrl_resv2_enable_val = 0x60, -+ .cdac_vref_adj_enable_val = 0x10, -+ .cdac_rl_adj_enable_val = 0x4, -+ .disable_ignore_cdac_pwd = true, -+ .needs_cvbs_trimming_nvmem_cell = false, -+}; -+ -+static int phy_meson_cvbs_dac_power_on(struct phy *phy) -+{ -+ struct phy_meson_cvbs_dac_priv *priv = phy_get_drvdata(phy); -+ -+ regmap_field_write(priv->regs[MESON_CDAC_CTRL_RESV1], 0x1); -+ regmap_field_write(priv->regs[MESON_CDAC_CTRL_RESV2], -+ priv->data->cdac_ctrl_resv2_enable_val); -+ regmap_field_write(priv->regs[MESON_CDAC_VREF_ADJ], -+ priv->data->cdac_vref_adj_enable_val); -+ regmap_field_write(priv->regs[MESON_CDAC_RL_ADJ], -+ priv->data->cdac_rl_adj_enable_val); -+ regmap_field_write(priv->regs[MESON_CDAC_GSW], -+ priv->cdac_gsw_enable_val); -+ regmap_field_write(priv->regs[MESON_CDAC_PWD], 0x0); -+ -+ return 0; -+} -+ -+static int phy_meson_cvbs_dac_power_off(struct phy *phy) -+{ -+ struct phy_meson_cvbs_dac_priv *priv = phy_get_drvdata(phy); -+ -+ regmap_field_write(priv->regs[MESON_CDAC_CTRL_RESV1], 0x0); -+ regmap_field_write(priv->regs[MESON_CDAC_CTRL_RESV2], 0x0); -+ regmap_field_write(priv->regs[MESON_CDAC_VREF_ADJ], 0x0); -+ regmap_field_write(priv->regs[MESON_CDAC_RL_ADJ], 0x0); -+ regmap_field_write(priv->regs[MESON_CDAC_GSW], 0x0); -+ -+ if (priv->data->disable_ignore_cdac_pwd) -+ regmap_field_write(priv->regs[MESON_CDAC_PWD], 0x0); -+ else -+ regmap_field_write(priv->regs[MESON_CDAC_PWD], 0x1); -+ -+ return 0; -+} -+ -+static int phy_meson_cvbs_dac_init(struct phy *phy) -+{ -+ struct phy_meson_cvbs_dac_priv *priv = phy_get_drvdata(phy); -+ -+ regmap_field_write(priv->regs[MESON_CDAC_CLK_PHASE_SEL], 0x0); -+ regmap_field_write(priv->regs[MESON_CDAC_DRIVER_ADJ], 0x0); -+ regmap_field_write(priv->regs[MESON_CDAC_EXT_VREF_EN], 0x0); -+ regmap_field_write(priv->regs[MESON_CDAC_BIAS_C], 0x0); -+ regmap_field_write(priv->regs[MESON_VDAC_CNTL0_RESERVED], 0x0); -+ regmap_field_write(priv->regs[MESON_VDAC_CNTL1_RESERVED], 0x0); -+ -+ return phy_meson_cvbs_dac_power_off(phy); -+} -+ -+static const struct phy_ops phy_meson_cvbs_dac_ops = { -+ .init = phy_meson_cvbs_dac_init, -+ .power_on = phy_meson_cvbs_dac_power_on, -+ .power_off = phy_meson_cvbs_dac_power_off, -+ .owner = THIS_MODULE, -+}; -+ -+static u8 phy_meson_cvbs_trimming_version(u8 trimming1) -+{ -+ if ((trimming1 & 0xf0) == 0xa0) -+ return 5; -+ else if ((trimming1 & 0xf0) == 0x40) -+ return 2; -+ else if ((trimming1 & 0xc0) == 0x80) -+ return 1; -+ else if ((trimming1 & 0xc0) == 0x00) -+ return 0; -+ else -+ return 0xff; -+} -+ -+static int phy_meson_cvbs_read_trimming(struct device *dev, -+ struct phy_meson_cvbs_dac_priv *priv) -+{ -+ struct nvmem_cell *cell; -+ u8 *trimming; -+ size_t len; -+ -+ cell = devm_nvmem_cell_get(dev, "cvbs_trimming"); -+ if (IS_ERR(cell)) -+ return dev_err_probe(dev, PTR_ERR(cell), -+ "Failed to get the 'cvbs_trimming' nvmem-cell\n"); -+ -+ trimming = nvmem_cell_read(cell, &len); -+ if (IS_ERR(trimming)) { -+ /* -+ * TrustZone firmware may block access to the CVBS trimming -+ * data stored in the eFuse. On those devices the trimming data -+ * is stored in the u-boot environment. However, the known -+ * examples of trimming data in the u-boot environment are all -+ * zero. -+ */ -+ dev_dbg(dev, -+ "Failed to read the 'cvbs_trimming' nvmem-cell - falling back to a default value\n"); -+ priv->cdac_gsw_enable_val = 0x0; -+ return 0; -+ } -+ -+ if (len != 2) { -+ kfree(trimming); -+ return dev_err_probe(dev, -EINVAL, -+ "Read the 'cvbs_trimming' nvmem-cell with invalid length\n"); -+ } -+ -+ switch (phy_meson_cvbs_trimming_version(trimming[1])) { -+ case 1: -+ case 2: -+ case 5: -+ priv->cdac_gsw_enable_val = trimming[0] & 0x7; -+ break; -+ default: -+ priv->cdac_gsw_enable_val = 0x0; -+ break; -+ } -+ -+ kfree(trimming); -+ -+ return 0; -+} -+ -+static int phy_meson_cvbs_dac_probe(struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ struct phy_meson_cvbs_dac_priv *priv; -+ struct phy_provider *phy_provider; -+ struct device *dev = &pdev->dev; -+ struct regmap *hhi; -+ struct phy *phy; -+ int ret; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ if (np) { -+ priv->data = device_get_match_data(dev); -+ if (!priv->data) -+ return dev_err_probe(dev, -EINVAL, -+ "Could not find the OF match data\n"); -+ -+ hhi = syscon_node_to_regmap(np->parent); -+ if (IS_ERR(hhi)) -+ return dev_err_probe(dev, PTR_ERR(hhi), -+ "Failed to get the parent syscon\n"); -+ } else { -+ const struct platform_device_id *pdev_id; -+ -+ pdev_id = platform_get_device_id(pdev); -+ if (!pdev_id) -+ return dev_err_probe(dev, -EINVAL, -+ "Failed to find platform device ID\n"); -+ -+ priv->data = (void *)pdev_id->driver_data; -+ if (!priv->data) -+ return dev_err_probe(dev, -EINVAL, -+ "Could not find the platform driver data\n"); -+ -+ hhi = syscon_regmap_lookup_by_compatible("amlogic,meson-gx-hhi-sysctrl"); -+ if (IS_ERR(hhi)) -+ return dev_err_probe(dev, PTR_ERR(hhi), -+ "Failed to get the \"amlogic,meson-gx-hhi-sysctrl\" syscon\n"); -+ } -+ -+ if (priv->data->needs_cvbs_trimming_nvmem_cell) { -+ ret = phy_meson_cvbs_read_trimming(dev, priv); -+ if (ret) -+ return ret; -+ } -+ -+ ret = devm_regmap_field_bulk_alloc(dev, hhi, priv->regs, -+ priv->data->reg_fields, -+ MESON_CVBS_DAC_NUM_REGS); -+ if (ret) -+ return dev_err_probe(dev, ret, -+ "Failed to create regmap fields\n"); -+ -+ phy = devm_phy_create(dev, np, &phy_meson_cvbs_dac_ops); -+ if (IS_ERR(phy)) -+ return PTR_ERR(phy); -+ -+ phy_set_drvdata(phy, priv); -+ -+ if (np) { -+ phy_provider = devm_of_phy_provider_register(dev, -+ of_phy_simple_xlate); -+ ret = PTR_ERR_OR_ZERO(phy_provider); -+ if (ret) -+ return dev_err_probe(dev, ret, -+ "Failed to register PHY provider\n"); -+ } -+ -+ platform_set_drvdata(pdev, phy); -+ -+ return 0; -+} -+ -+static const struct of_device_id phy_meson_cvbs_dac_of_match[] = { -+ { -+ .compatible = "amlogic,meson8-cvbs-dac", -+ .data = &phy_meson8_cvbs_dac_data, -+ }, -+ { -+ .compatible = "amlogic,meson-gxbb-cvbs-dac", -+ .data = &phy_meson_gxbb_cvbs_dac_data, -+ }, -+ { -+ .compatible = "amlogic,meson-gxl-cvbs-dac", -+ .data = &phy_meson_gxl_cvbs_dac_data, -+ }, -+ { -+ .compatible = "amlogic,meson-g12a-cvbs-dac", -+ .data = &phy_meson_g12a_cvbs_dac_data, -+ }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, phy_meson_cvbs_dac_of_match); -+ -+/* -+ * The platform_device_id table is used for backwards compatibility with old -+ * .dtbs which don't have a CVBS DAC node (where the VPU DRM driver registers -+ * this as a platform device. Support for additional SoCs should only be added -+ * to the of_device_id table above. -+ */ -+static const struct platform_device_id phy_meson_cvbs_dac_device_ids[] = { -+ { -+ .name = "meson-gxbb-cvbs-dac", -+ .driver_data = (kernel_ulong_t)&phy_meson_gxbb_cvbs_dac_data, -+ }, -+ { -+ .name = "meson-gxl-cvbs-dac", -+ .driver_data = (kernel_ulong_t)&phy_meson_gxl_cvbs_dac_data, -+ }, -+ { -+ .name = "meson-g12a-cvbs-dac", -+ .driver_data = (kernel_ulong_t)&phy_meson_g12a_cvbs_dac_data, -+ }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(platform, phy_meson_cvbs_dac_device_ids); -+ -+static struct platform_driver phy_meson_cvbs_dac_driver = { -+ .driver = { -+ .name = "phy-meson-cvbs-dac", -+ .of_match_table = phy_meson_cvbs_dac_of_match, -+ }, -+ .id_table = phy_meson_cvbs_dac_device_ids, -+ .probe = phy_meson_cvbs_dac_probe, -+}; -+module_platform_driver(phy_meson_cvbs_dac_driver); -+ -+MODULE_AUTHOR("Martin Blumenstingl "); -+MODULE_DESCRIPTION("Amlogic Meson CVBS DAC driver"); -+MODULE_LICENSE("GPL v2"); --- -2.34.1 - diff --git a/patch/kernel/archive/meson-6.1/generic-0002-m8-m8b-m8m2-drm-forcefully-enable-XRGB-format.patch b/patch/kernel/archive/meson-6.1/generic-0002-m8-m8b-m8m2-drm-forcefully-enable-XRGB-format.patch deleted file mode 100644 index fcb18fae8f2e..000000000000 --- a/patch/kernel/archive/meson-6.1/generic-0002-m8-m8b-m8m2-drm-forcefully-enable-XRGB-format.patch +++ /dev/null @@ -1,22 +0,0 @@ -meson8/meson8b/meson8m2: drm: Forcefully enable XRGB format - ---- - drivers/gpu/drm/meson/meson_plane.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c -index 27e39577218..027b2fe7ff8 100644 ---- a/drivers/gpu/drm/meson/meson_plane.c -+++ b/drivers/gpu/drm/meson/meson_plane.c -@@ -483,6 +483,8 @@ static const struct drm_plane_funcs meson_plane_funcs = { - static const uint32_t supported_drm_formats_m8[] = { - DRM_FORMAT_ARGB8888, - DRM_FORMAT_ABGR8888, -+ DRM_FORMAT_XRGB8888, -+ DRM_FORMAT_XBGR8888, - DRM_FORMAT_RGB888, - DRM_FORMAT_RGB565, - }; --- -2.34.1 - diff --git a/patch/kernel/archive/meson-6.1/generic-Revert-mmc-core-Set-HS-clock-speed-before-sending-HS-CMD13.patch b/patch/kernel/archive/meson-6.1/generic-Revert-mmc-core-Set-HS-clock-speed-before-sending-HS-CMD13.patch deleted file mode 100644 index a69258f9dd6d..000000000000 --- a/patch/kernel/archive/meson-6.1/generic-Revert-mmc-core-Set-HS-clock-speed-before-sending-HS-CMD13.patch +++ /dev/null @@ -1,74 +0,0 @@ -Revert "mmc: core: Set HS clock speed before sending HS CMD13" - -This reverts commit 4bc31edebde51fcf8ad0794763b8679a7ecb5ec0. - ---- - drivers/mmc/core/mmc.c | 23 ++++------------------- - 1 file changed, 4 insertions(+), 19 deletions(-) - -diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c -index 89cd48fcec7..a776ac64154 100644 ---- a/drivers/mmc/core/mmc.c -+++ b/drivers/mmc/core/mmc.c -@@ -1391,17 +1391,13 @@ static int mmc_select_hs400es(struct mmc_card *card) - goto out_err; - } - -- /* -- * Bump to HS timing and frequency. Some cards don't handle -- * SEND_STATUS reliably at the initial frequency. -- */ - mmc_set_timing(host, MMC_TIMING_MMC_HS); -- mmc_set_bus_speed(card); -- - err = mmc_switch_status(card, true); - if (err) - goto out_err; - -+ mmc_set_clock(host, card->ext_csd.hs_max_dtr); -+ - /* Switch card to DDR with strobe bit */ - val = EXT_CSD_DDR_BUS_WIDTH_8 | EXT_CSD_BUS_WIDTH_STROBE; - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, -@@ -1459,7 +1455,7 @@ static int mmc_select_hs400es(struct mmc_card *card) - static int mmc_select_hs200(struct mmc_card *card) - { - struct mmc_host *host = card->host; -- unsigned int old_timing, old_signal_voltage, old_clock; -+ unsigned int old_timing, old_signal_voltage; - int err = -EINVAL; - u8 val; - -@@ -1490,17 +1486,8 @@ static int mmc_select_hs200(struct mmc_card *card) - false, true, MMC_CMD_RETRIES); - if (err) - goto err; -- -- /* -- * Bump to HS timing and frequency. Some cards don't handle -- * SEND_STATUS reliably at the initial frequency. -- * NB: We can't move to full (HS200) speeds until after we've -- * successfully switched over. -- */ - old_timing = host->ios.timing; -- old_clock = host->ios.clock; - mmc_set_timing(host, MMC_TIMING_MMC_HS200); -- mmc_set_clock(card->host, card->ext_csd.hs_max_dtr); - - /* - * For HS200, CRC errors are not a reliable way to know the -@@ -1513,10 +1500,8 @@ static int mmc_select_hs200(struct mmc_card *card) - * mmc_select_timing() assumes timing has not changed if - * it is a switch error. - */ -- if (err == -EBADMSG) { -- mmc_set_clock(host, old_clock); -+ if (err == -EBADMSG) - mmc_set_timing(host, old_timing); -- } - } - err: - if (err) { --- -2.34.1 - diff --git a/patch/kernel/archive/meson-6.1/generic-Revert-pwm-meson-modify-and-simplify-calculation-in-.patch b/patch/kernel/archive/meson-6.1/generic-Revert-pwm-meson-modify-and-simplify-calculation-in-.patch deleted file mode 100644 index 510ab8d73bbb..000000000000 --- a/patch/kernel/archive/meson-6.1/generic-Revert-pwm-meson-modify-and-simplify-calculation-in-.patch +++ /dev/null @@ -1,35 +0,0 @@ -Revert "pwm: meson: modify and simplify calculation in meson_pwm_get_state" - -This reverts commit 6b9352f3f8a1a35faf0efc1ad1807ee303467796. ---- - drivers/pwm/pwm-meson.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c -index 33107204a951..1d0b69d08cdd 100644 ---- a/drivers/pwm/pwm-meson.c -+++ b/drivers/pwm/pwm-meson.c -@@ -351,8 +351,18 @@ static int meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, - channel->lo = FIELD_GET(PWM_LOW_MASK, value); - channel->hi = FIELD_GET(PWM_HIGH_MASK, value); - -- state->period = meson_pwm_cnt_to_ns(chip, pwm, channel->lo + channel->hi); -- state->duty_cycle = meson_pwm_cnt_to_ns(chip, pwm, channel->hi); -+ if (channel->lo == 0) { -+ state->period = meson_pwm_cnt_to_ns(chip, pwm, channel->hi); -+ state->duty_cycle = state->period; -+ } else if (channel->lo >= channel->hi) { -+ state->period = meson_pwm_cnt_to_ns(chip, pwm, -+ channel->lo + channel->hi); -+ state->duty_cycle = meson_pwm_cnt_to_ns(chip, pwm, -+ channel->hi); -+ } else { -+ state->period = 0; -+ state->duty_cycle = 0; -+ } - - state->polarity = PWM_POLARITY_NORMAL; - --- -2.34.1 - diff --git a/patch/kernel/archive/meson-6.1/odroidc1-dts-Enable-HDMI.patch b/patch/kernel/archive/meson-6.1/odroidc1-dts-Enable-HDMI.patch deleted file mode 100644 index 33ec4ce3a589..000000000000 --- a/patch/kernel/archive/meson-6.1/odroidc1-dts-Enable-HDMI.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 9e961c5c05f0b90d1fde647c996077c84d198157 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Fri, 20 Mar 2020 15:17:51 +0100 -Subject: [PATCH 57/89] ARM: dts: meson8b: odroid-c1: enable HDMI for the - Odroid-C1 - WiP - -WiP - -Signed-off-by: Martin Blumenstingl ---- - arch/arm/boot/dts/meson8b-odroidc1.dts | 59 ++++++++++++++++++++++++++ - 1 file changed, 59 insertions(+) - -diff --git a/arch/arm/boot/dts/meson8b-odroidc1.dts b/arch/arm/boot/dts/meson8b-odroidc1.dts -index 04356bc639f..3359255f8d6 100644 ---- a/arch/arm/boot/dts/meson8b-odroidc1.dts -+++ b/arch/arm/boot/dts/meson8b-odroidc1.dts -@@ -32,6 +32,17 @@ emmc_pwrseq: emmc-pwrseq { - reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>; - }; - -+ hdmi-connector { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi_connector_in: endpoint { -+ remote-endpoint = <&hdmi_tx_tmds_out>; -+ }; -+ }; -+ }; -+ - leds { - compatible = "gpio-leds"; - blue { -@@ -93,6 +104,38 @@ rtc32k_xtal: rtc32k-xtal-clk { - #clock-cells = <0>; - }; - -+ sound { -+ compatible = "amlogic,gx-sound-card"; -+ model = "ODROID-C1"; -+ -+ assigned-clocks = <&clkc CLKID_MPLL0>, -+ <&clkc CLKID_MPLL1>; -+ assigned-clock-rates = <294912000>, -+ <270950400>; -+ -+ dai-link-0 { -+ sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>; -+ }; -+ -+ dai-link-1 { -+ sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>; -+ dai-format = "i2s"; -+ mclk-fs = <256>; -+ -+ codec-0 { -+ sound-dai = <&aiu AIU_HDMI CTRL_I2S>; -+ }; -+ }; -+ -+ dai-link-2 { -+ sound-dai = <&aiu AIU_HDMI CTRL_OUT>; -+ -+ codec-0 { -+ sound-dai = <&hdmi_tx 0>; -+ }; -+ }; -+ }; -+ - vcc_1v8: regulator-vcc-1v8 { - /* - * RICHTEK RT9179 configured for a fixed output voltage of -@@ -187,6 +230,10 @@ vdd_rtc: regulator-vdd-rtc { - }; - }; - -+&aiu { -+ status = "okay"; -+}; -+ - &cpu0 { - cpu-supply = <&vcck>; - }; -@@ -296,6 +343,18 @@ usb-hub { - }; - }; - -+&hdmi_tx { -+ status = "okay"; -+ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; -+ pinctrl-names = "default"; -+}; -+ -+&hdmi_tx_tmds_port { -+ hdmi_tx_tmds_out: endpoint { -+ remote-endpoint = <&hdmi_connector_in>; -+ }; -+}; -+ - &ir_receiver { - status = "okay"; - pinctrl-0 = <&ir_recv_pins>; --- -2.25.1 - diff --git a/patch/kernel/archive/meson-6.1/onecloud-0001-add-dts.patch b/patch/kernel/archive/meson-6.1/onecloud-0001-add-dts.patch deleted file mode 100644 index 2723bea897d5..000000000000 --- a/patch/kernel/archive/meson-6.1/onecloud-0001-add-dts.patch +++ /dev/null @@ -1,443 +0,0 @@ -From 7ee5e1ab3026c8011af1e49d7930bdcf782c3c56 Mon Sep 17 00:00:00 2001 -From: hzy -Date: Sat, 1 Apr 2023 13:24:42 +0800 -Subject: [PATCH 1/2] ARM: dts: meson8b: Add DTS for Xunlei Onecloud - -Signed-off-by: hzy ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/meson8b-onecloud.dts | 410 +++++++++++++++++++++++++ - 2 files changed, 411 insertions(+) - create mode 100644 arch/arm/boot/dts/meson8b-onecloud.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 6aa7dc4d..e3a3577b 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -401,6 +401,7 @@ dtb-$(CONFIG_MACH_MESON8) += \ - meson8b-ec100.dtb \ - meson8b-mxq.dtb \ - meson8b-odroidc1.dtb \ -+ meson8b-onecloud.dtb \ - meson8m2-mxiii-plus.dtb - dtb-$(CONFIG_ARCH_MMP) += \ - pxa168-aspenite.dtb \ -diff --git a/arch/arm/boot/dts/meson8b-onecloud.dts b/arch/arm/boot/dts/meson8b-onecloud.dts -new file mode 100644 -index 00000000..1fa5420f ---- /dev/null -+++ b/arch/arm/boot/dts/meson8b-onecloud.dts -@@ -0,0 +1,410 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Author: hzy -+ */ -+ -+/dts-v1/; -+ -+#include "meson8b.dtsi" -+#include -+#include -+ -+/ { -+ model = "Xunlei OneCloud"; -+ compatible = "xunlei,onecloud", "amlogic,meson8b"; -+ -+ aliases { -+ serial0 = &uart_AO; -+ mmc0 = &sd_card_slot; -+ mmc1 = &sdhc; -+ }; -+ -+ chosen { -+ stdout-path = "serial0:115200n8"; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0x40000000 0x40000000>; -+ }; -+ -+ emmc_pwrseq: emmc-pwrseq { -+ compatible = "mmc-pwrseq-emmc"; -+ reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>; -+ }; -+ -+ button { -+ // compatible = "gpio-keys-polled"; -+ // poll-interval = <100>; -+ -+ compatible = "gpio-keys"; -+ -+ autorepeat; -+ -+ reset-button { -+ label = "reset"; -+ linux,code = ; -+ -+ // gpios = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_LOW>; -+ -+ interrupt-parent = <&gpio_intc>; -+ interrupts = <5 IRQ_TYPE_LEVEL_LOW>; // GPIOAO 5 -+ }; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ -+ red { -+ label = "onecloud:red:alive"; -+ gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>; -+ -+ default-state = "on"; -+ linux,default-trigger = "default-on"; -+ }; -+ -+ green { -+ label = "onecloud:green:alive"; -+ gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_HIGH>; -+ -+ default-state = "off"; -+ linux,default-trigger = "mmc1"; -+ }; -+ -+ blue { -+ label = "onecloud:blue:alive"; -+ gpios = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_HIGH>; -+ -+ default-state = "off"; -+ linux,default-trigger = "usb-host"; -+ }; -+ }; -+ -+ p12v: regulator-p12v { -+ compatible = "regulator-fixed"; -+ -+ regulator-name = "P12V"; -+ regulator-min-microvolt = <12000000>; -+ regulator-max-microvolt = <12000000>; -+ }; -+ -+ vcc_5v: regulator-vcc-5v { -+ compatible = "regulator-fixed"; -+ -+ regulator-name = "VCC5V"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ -+ vin-supply = <&p12v>; -+ -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ vcc_3v3: regulator-vcc-3v3 { -+ compatible = "regulator-fixed"; -+ -+ regulator-name = "VCC3V3"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ -+ vin-supply = <&p12v>; -+ -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ vcc_1v8: regulator-vcc-1v8 { -+ compatible = "regulator-fixed"; -+ -+ regulator-name = "VCC1V8"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ vin-supply = <&p12v>; -+ -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ vcc_ddr: regulator-vcc-ddr { -+ compatible = "regulator-fixed"; -+ -+ regulator-name = "VCC_DDR"; -+ regulator-min-microvolt = <1500000>; -+ regulator-max-microvolt = <1500000>; -+ -+ vin-supply = <&vcc_3v3>; -+ -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ vcc_core: regulator-vcc-core { -+ compatible = "pwm-regulator"; -+ -+ regulator-name = "VCC_CORE"; -+ -+ // +---------------------------------------------------+ -+ // | The actual mapping in phyical | -+ // +------+--------+--------+--------+--------+--------+ -+ // | | 100% | 60% | 30% | 10% | 0% | -+ // +------+--------+--------+--------+--------+--------+ -+ // | V1.0 | 677mV | 857mV | 992mV | 1082mV | 1127mV | -+ // | V1.3 | 1116mV | 1121mV | 1125mV | 1128mV | 1129mV | -+ // +------+--------+--------+--------+--------+--------+ -+ // -+ // According to meson8b.dtsi, the CPU should be able to -+ // run at 504MHz with 870mV. But this regulator supplies -+ // not only CPU but also GPU. And according to the users' -+ // tests on V1.0, we need such higher voltages. -+ -+ pwms = <&pwm_cd 1 12001 0>; // PWM_D -+ pwm-dutycycle-range = <10 0>; -+ regulator-min-microvolt = <860000>; -+ regulator-max-microvolt = <1140000>; -+ -+ pwm-supply = <&p12v>; -+ -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+}; -+ -+&uart_AO { -+ status = "okay"; -+ pinctrl-0 = <&uart_ao_a_pins>; -+ pinctrl-names = "default"; -+}; -+ -+&pwm_cd { -+ status = "okay"; -+ pinctrl-0 = <&pwm_c1_pins>, <&pwm_d_pins>; -+ pinctrl-names = "default"; -+ clocks = <&xtal>, <&xtal>; -+ clock-names = "clkin0", "clkin1"; -+}; -+ -+&cpu0 { -+ cpu-supply = <&vcc_core>; -+}; -+ -+&saradc { -+ status = "okay"; -+ vref-supply = <&vcc_1v8>; -+}; -+ -+&mali { -+ // commented to allow cpufreq tweaking -+ // mali-supply = <&vcc_core>; -+}; -+ -+&gpio { -+ gpio-line-names = -+ /* 0 */ "WIFI_SDIO_D0 PIN18 (GPIOX_0)", -+ /* 1 */ "WIFI_SDIO_D1 PIN19 (GPIOX_1)", -+ /* 2 */ "WIFI_SDIO_D2 PIN14 (GPIOX_2)", -+ /* 3 */ "WIFI_SDIO_D3 PIN15 (GPIOX_3)", -+ /* 4 */ "WIFI_PCM_DIN PIN27 (GPIOX_4)", -+ /* 5 */ "WIFI_PCM_DOUT PIN25 (GPIOX_5)", -+ /* 6 */ "WIFI_PCM_SYNC PIN28 (GPIOX_6)", -+ /* 7 */ "WIFI_PCM_CLK PIN26 (GPIOX_7)", -+ /* 8 */ "WIFI_SDIO_CLK PIN17_Resistor (GPIOX_8)", -+ /* 9 */ "WIFI_SDIO_CMD PIN16 (GPIOX_9)", -+ /* 10 */ "GPIOX_10", -+ /* 11 */ "WIFI PIN12 (GPIOX_11)", -+ /* 12 */ "WIFI_UART_RX PIN43 (GPIOX_16)", -+ /* 13 */ "WIFI_UART_TX PIN42 (GPIOX_17)", -+ /* 14 */ "WIFI_UART_RTS PIN41_Resistor (GPIOX_18)", -+ /* 15 */ "WIFI_UART_CTS PIN44 (GPIOX_19)", -+ /* 16 */ "WIFI PIN34 (GPIOX_20)", -+ /* 17 */ "WIFI_WAKE PIN13 (GPIOX_21)", -+ -+ /* 18 */ "Resistor_TopOf_LED (GPIOY_0)", -+ /* 19 */ "GPIOY_1", -+ /* 20 */ "GPIOY_3", -+ /* 21 */ "GPIOY_6", -+ /* 22 */ "GPIOY_7", -+ /* 23 */ "GPIOY_8", -+ /* 24 */ "GPIOY_9", -+ /* 25 */ "GPIOY_10", -+ /* 26 */ "GPIOY_11", -+ /* 27 */ "GPIOY_12", -+ /* 28 */ "Left_BottomOf_CPU (GPIOY_13)", -+ /* 29 */ "Right_BottomOf_CPU (GPIOY_14)", -+ -+ /* 30 */ "GPIODV_9 (PWM_C)", -+ /* 31 */ "GPIODV_24", -+ /* 32 */ "GPIODV_25", -+ /* 33 */ "GPIODV_26", -+ /* 34 */ "GPIODV_27", -+ /* 35 */ "VCC_CPU_PWM (GPIODV_28)", -+ /* 36 */ "GPIODV_29", -+ -+ /* 37 */ "HDMI_HPD (GPIOH_0)", -+ /* 38 */ "HDMI_SDA (GPIOH_1)", -+ /* 39 */ "HDMI_SCL (GPIOH_2)", -+ /* 40 */ "ETH_PHY_INTR (GPIOH_3)", -+ /* 41 */ "ETH_PHY_nRST (GPIOH_4)", -+ /* 42 */ "ETH_TXD1 (GPIOH_5)", -+ /* 43 */ "ETH_TXD0 (GPIOH_6)", -+ /* 44 */ "ETH_TXD3 (GPIOH_7)", -+ /* 45 */ "ETH_TXD2 (GPIOH_8)", -+ /* 46 */ "ETH_TX_CLK (GPIOH_9)", -+ -+ /* 47 */ "SDCARD_D1 (CARD_0)", -+ /* 48 */ "SDCARD_D0 (CARD_1)", -+ /* 49 */ "SDCARD_CLK (CARD_2)", -+ /* 50 */ "SDCARD_CMD (CARD_3)", -+ /* 51 */ "SDCARD_D3 (CARD_4)", -+ /* 52 */ "SDCARD_D2 (CARD_5)", -+ /* 53 */ "SDCARD_CD (CARD_6)", -+ -+ /* 54 */ "EMMC_D0 (BOOT_0)", -+ /* 55 */ "EMMC_D1 (BOOT_1)", -+ /* 56 */ "EMMC_D2 (BOOT_2)", -+ /* 57 */ "EMMC_D3 (BOOT_3)", -+ /* 58 */ "EMMC_D4 (BOOT_4)", -+ /* 59 */ "EMMC_D5 (BOOT_5)", -+ /* 60 */ "EMMC_D6 (BOOT_6)", -+ /* 61 */ "EMMC_D7 (BOOT_7)", -+ /* 62 */ "EMMC_CLK (BOOT_8)", -+ /* 63 */ "EMMC_nRST (BOOT_9)", -+ /* 64 */ "EMMC_CMD (BOOT_10)", -+ /* 65 */ "BOOT_11", -+ /* 66 */ "BOOT_12", -+ /* 67 */ "BOOT_13", -+ /* 68 */ "BOOT_14", -+ /* 69 */ "BOOT_15", -+ /* 70 */ "BOOT_16", -+ /* 71 */ "BOOT_17", -+ /* 72 */ "BOOT_18", -+ -+ /* 73 */ "ETH_RXD1 (DIF_0_P)", -+ /* 74 */ "ETH_RXD0 (DIF_0_N)", -+ /* 75 */ "ETH_RX_DV (DIF_1_P)", -+ /* 76 */ "ETH_RX_CLK (DIF_1_N)", -+ /* 77 */ "ETH_RXD3 (DIF_2_P)", -+ /* 78 */ "ETH_RXD2 (DIF_2_N)", -+ /* 79 */ "ETH_TX_EN (DIF_3_P)", -+ /* 80 */ "ETH_REF_CLK (DIF_3_N)", -+ /* 81 */ "ETH_MDC (DIF_4_P)", -+ /* 82 */ "ETH_MDIO_EN (DIF_4_N)"; -+}; -+ -+&gpio_ao { -+ gpio-line-names = -+ /* 0 */ "UART TX (GPIOAO_0)", -+ /* 1 */ "UART RX (GPIOAO_1)", -+ /* 2 */ "RED_LED (GPIOAO_2)", -+ /* 3 */ "GREEN_LED (GPIOAO_3)", -+ /* 4 */ "BLUE_LED (GPIOAO_4)", -+ /* 5 */ "BUTTON (GPIOAO_5)", -+ /* 6 */ "GPIOAO_6", -+ /* 7 */ "IR_IN (GPIOAO_7)", -+ /* 8 */ "GPIOAO_8", -+ /* 9 */ "GPIOAO_9", -+ /* 10 */ "GPIOAO_10", -+ /* 11 */ "GPIOAO_11", -+ /* 12 */ "GPIOAO_12", -+ /* 13 */ "GPIOAO_13", -+ -+ /* 14 */ "GPIO_BSD_EN", -+ /* 15 */ "GPIO_TEST_N"; -+}; -+ -+// eMMC -+&sdhc { -+ status = "okay"; -+ -+ pinctrl-0 = <&sdxc_c_pins>; -+ pinctrl-names = "default"; -+ -+ non-removable; -+ bus-width = <8>; -+ max-frequency = <200000000>; -+ cap-mmc-highspeed; -+ mmc-hs200-1_8v; -+ -+ mmc-pwrseq = <&emmc_pwrseq>; -+ vmmc-supply = <&vcc_3v3>; -+ // vqmmc-supply = <&vcc_3v3>; -+}; -+ -+&sdio { -+ status = "okay"; -+ -+ pinctrl-0 = <&sd_b_pins>; -+ pinctrl-names = "default"; -+ -+ // SD card -+ sd_card_slot: slot@1 { -+ compatible = "mmc-slot"; -+ reg = <1>; -+ status = "okay"; -+ -+ bus-width = <4>; -+ no-sdio; -+ cap-mmc-highspeed; -+ cap-sd-highspeed; -+ disable-wp; -+ -+ cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; -+ -+ vmmc-supply = <&vcc_3v3>; -+ // vqmmc-supply = <&vcc_3v3>; -+ }; -+}; -+ -+ðmac { -+ status = "okay"; -+ -+ pinctrl-0 = <ð_rgmii_pins>; -+ pinctrl-names = "default"; -+ -+ phy-handle = <ð_phy>; -+ phy-mode = "rgmii-rxid"; -+ -+ mdio { -+ compatible = "snps,dwmac-mdio"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ // Realtek RTL8211F (0x001cc916) -+ eth_phy: ethernet-phy@0 { -+ reg = <0>; -+ -+ reset-assert-us = <10000>; -+ reset-deassert-us = <80000>; -+ reset-gpios = <&gpio GPIOH_4 GPIO_ACTIVE_LOW>; -+ -+ interrupt-parent = <&gpio_intc>; -+ interrupts = <17 IRQ_TYPE_LEVEL_LOW>; // GPIOH 3 -+ }; -+ }; -+}; -+ -+&usb0 { -+ status = "okay"; -+ dr_mode = "otg"; -+ usb-role-switch; -+ role-switch-default-mode = "host"; -+}; -+ -+&usb0_phy { -+ status = "okay"; -+}; -+ -+&usb1 { -+ status = "okay"; -+}; -+ -+&usb1_phy { -+ status = "okay"; -+}; -+ -+&ir_receiver { -+ status = "okay"; -+ pinctrl-0 = <&ir_recv_pins>; -+ pinctrl-names = "default"; -+}; --- -2.34.1 - diff --git a/patch/kernel/archive/meson-6.10/0007-dt-bindings-phy-meson8b-usb2-Add-support-for-reading.patch b/patch/kernel/archive/meson-6.12/0007-dt-bindings-phy-meson8b-usb2-Add-support-for-reading.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0007-dt-bindings-phy-meson8b-usb2-Add-support-for-reading.patch rename to patch/kernel/archive/meson-6.12/0007-dt-bindings-phy-meson8b-usb2-Add-support-for-reading.patch diff --git a/patch/kernel/archive/meson-6.10/0008-phy-amlogic-meson8b-usb2-Add-support-for-reading-the.patch b/patch/kernel/archive/meson-6.12/0008-phy-amlogic-meson8b-usb2-Add-support-for-reading-the.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0008-phy-amlogic-meson8b-usb2-Add-support-for-reading-the.patch rename to patch/kernel/archive/meson-6.12/0008-phy-amlogic-meson8b-usb2-Add-support-for-reading-the.patch diff --git a/patch/kernel/archive/meson-6.10/0009-usb-common-usb-conn-gpio-Fall-back-to-polling-the-GP.patch b/patch/kernel/archive/meson-6.12/0009-usb-common-usb-conn-gpio-Fall-back-to-polling-the-GP.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0009-usb-common-usb-conn-gpio-Fall-back-to-polling-the-GP.patch rename to patch/kernel/archive/meson-6.12/0009-usb-common-usb-conn-gpio-Fall-back-to-polling-the-GP.patch diff --git a/patch/kernel/archive/meson-6.10/0010-usb-dwc2-register-child-USB-connector-devices.patch b/patch/kernel/archive/meson-6.12/0010-usb-dwc2-register-child-USB-connector-devices.patch similarity index 95% rename from patch/kernel/archive/meson-6.10/0010-usb-dwc2-register-child-USB-connector-devices.patch rename to patch/kernel/archive/meson-6.12/0010-usb-dwc2-register-child-USB-connector-devices.patch index 4153e833ff88..31685f2abf66 100644 --- a/patch/kernel/archive/meson-6.10/0010-usb-dwc2-register-child-USB-connector-devices.patch +++ b/patch/kernel/archive/meson-6.12/0010-usb-dwc2-register-child-USB-connector-devices.patch @@ -24,7 +24,7 @@ index 111111111111..222222222222 100644 #include #include #include -@@ -620,6 +621,19 @@ static int dwc2_driver_probe(struct platform_device *dev) +@@ -622,6 +623,19 @@ static int dwc2_driver_probe(struct platform_device *dev) } } #endif /* CONFIG_USB_DWC2_PERIPHERAL || CONFIG_USB_DWC2_DUAL_ROLE */ diff --git a/patch/kernel/archive/meson-6.10/0011-ARM-dts-meson-Add-GPIO-controller-capabilities-to-th.patch b/patch/kernel/archive/meson-6.12/0011-ARM-dts-meson-Add-GPIO-controller-capabilities-to-th.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0011-ARM-dts-meson-Add-GPIO-controller-capabilities-to-th.patch rename to patch/kernel/archive/meson-6.12/0011-ARM-dts-meson-Add-GPIO-controller-capabilities-to-th.patch diff --git a/patch/kernel/archive/meson-6.10/0012-ARM-dts-meson8b-odroidc1-Enable-the-Micro-USB-OTG-co.patch b/patch/kernel/archive/meson-6.12/0012-ARM-dts-meson8b-odroidc1-Enable-the-Micro-USB-OTG-co.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0012-ARM-dts-meson8b-odroidc1-Enable-the-Micro-USB-OTG-co.patch rename to patch/kernel/archive/meson-6.12/0012-ARM-dts-meson8b-odroidc1-Enable-the-Micro-USB-OTG-co.patch diff --git a/patch/kernel/archive/meson-6.10/0013-dt-bindings-phy-Add-bindings-for-the-Amlogic-Meson-C.patch b/patch/kernel/archive/meson-6.12/0013-dt-bindings-phy-Add-bindings-for-the-Amlogic-Meson-C.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0013-dt-bindings-phy-Add-bindings-for-the-Amlogic-Meson-C.patch rename to patch/kernel/archive/meson-6.12/0013-dt-bindings-phy-Add-bindings-for-the-Amlogic-Meson-C.patch diff --git a/patch/kernel/archive/meson-6.10/0014-phy-amlogic-Add-a-new-driver-for-the-CVBS-DAC-CVBS-P.patch b/patch/kernel/archive/meson-6.12/0014-phy-amlogic-Add-a-new-driver-for-the-CVBS-DAC-CVBS-P.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0014-phy-amlogic-Add-a-new-driver-for-the-CVBS-DAC-CVBS-P.patch rename to patch/kernel/archive/meson-6.12/0014-phy-amlogic-Add-a-new-driver-for-the-CVBS-DAC-CVBS-P.patch diff --git a/patch/kernel/archive/meson-6.10/0015-dt-bindings-display-meson-vpu-Add-the-CVBS-DAC-prope.patch b/patch/kernel/archive/meson-6.12/0015-dt-bindings-display-meson-vpu-Add-the-CVBS-DAC-prope.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0015-dt-bindings-display-meson-vpu-Add-the-CVBS-DAC-prope.patch rename to patch/kernel/archive/meson-6.12/0015-dt-bindings-display-meson-vpu-Add-the-CVBS-DAC-prope.patch diff --git a/patch/kernel/archive/meson-6.10/0016-drm-meson-Add-support-for-using-a-PHY-for-the-CVBS-D.patch b/patch/kernel/archive/meson-6.12/0016-drm-meson-Add-support-for-using-a-PHY-for-the-CVBS-D.patch similarity index 99% rename from patch/kernel/archive/meson-6.10/0016-drm-meson-Add-support-for-using-a-PHY-for-the-CVBS-D.patch rename to patch/kernel/archive/meson-6.12/0016-drm-meson-Add-support-for-using-a-PHY-for-the-CVBS-D.patch index 4ef1ee3d5e9f..7336fe7198cf 100644 --- a/patch/kernel/archive/meson-6.10/0016-drm-meson-Add-support-for-using-a-PHY-for-the-CVBS-D.patch +++ b/patch/kernel/archive/meson-6.12/0016-drm-meson-Add-support-for-using-a-PHY-for-the-CVBS-D.patch @@ -25,7 +25,7 @@ diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/meson/Kconfig +++ b/drivers/gpu/drm/meson/Kconfig -@@ -10,6 +10,7 @@ config DRM_MESON +@@ -12,6 +12,7 @@ config DRM_MESON select REGMAP_MMIO select MESON_CANVAS select CEC_CORE if CEC_NOTIFIER diff --git a/patch/kernel/archive/meson-6.10/0018-dt-bindings-clock-meson8b-Add-the-RMII-reference-clo.patch b/patch/kernel/archive/meson-6.12/0018-dt-bindings-clock-meson8b-Add-the-RMII-reference-clo.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0018-dt-bindings-clock-meson8b-Add-the-RMII-reference-clo.patch rename to patch/kernel/archive/meson-6.12/0018-dt-bindings-clock-meson8b-Add-the-RMII-reference-clo.patch diff --git a/patch/kernel/archive/meson-6.10/0019-dt-bindings-clock-meson8b-Add-the-Meson8-Ethernet-RM.patch b/patch/kernel/archive/meson-6.12/0019-dt-bindings-clock-meson8b-Add-the-Meson8-Ethernet-RM.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0019-dt-bindings-clock-meson8b-Add-the-Meson8-Ethernet-RM.patch rename to patch/kernel/archive/meson-6.12/0019-dt-bindings-clock-meson8b-Add-the-Meson8-Ethernet-RM.patch diff --git a/patch/kernel/archive/meson-6.10/0020-clk-meson-meson8b-Add-the-Ethernet-RMII-clock-tree-o.patch b/patch/kernel/archive/meson-6.12/0020-clk-meson-meson8b-Add-the-Ethernet-RMII-clock-tree-o.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0020-clk-meson-meson8b-Add-the-Ethernet-RMII-clock-tree-o.patch rename to patch/kernel/archive/meson-6.12/0020-clk-meson-meson8b-Add-the-Ethernet-RMII-clock-tree-o.patch diff --git a/patch/kernel/archive/meson-6.10/0021-dt-bindings-net-dwmac-meson-Add-the-Ethernet-clock-i.patch b/patch/kernel/archive/meson-6.12/0021-dt-bindings-net-dwmac-meson-Add-the-Ethernet-clock-i.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0021-dt-bindings-net-dwmac-meson-Add-the-Ethernet-clock-i.patch rename to patch/kernel/archive/meson-6.12/0021-dt-bindings-net-dwmac-meson-Add-the-Ethernet-clock-i.patch diff --git a/patch/kernel/archive/meson-6.10/0022-net-stmmac-dwmac-meson-Rename-the-SPEED_100-macro.patch b/patch/kernel/archive/meson-6.12/0022-net-stmmac-dwmac-meson-Rename-the-SPEED_100-macro.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0022-net-stmmac-dwmac-meson-Rename-the-SPEED_100-macro.patch rename to patch/kernel/archive/meson-6.12/0022-net-stmmac-dwmac-meson-Rename-the-SPEED_100-macro.patch diff --git a/patch/kernel/archive/meson-6.10/0023-net-stmmac-dwmac-meson-Manage-the-ethernet-clock.patch b/patch/kernel/archive/meson-6.12/0023-net-stmmac-dwmac-meson-Manage-the-ethernet-clock.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0023-net-stmmac-dwmac-meson-Manage-the-ethernet-clock.patch rename to patch/kernel/archive/meson-6.12/0023-net-stmmac-dwmac-meson-Manage-the-ethernet-clock.patch diff --git a/patch/kernel/archive/meson-6.10/0024-net-stmmac-dwmac-meson-Initialize-all-known-PREG_ETH.patch b/patch/kernel/archive/meson-6.12/0024-net-stmmac-dwmac-meson-Initialize-all-known-PREG_ETH.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0024-net-stmmac-dwmac-meson-Initialize-all-known-PREG_ETH.patch rename to patch/kernel/archive/meson-6.12/0024-net-stmmac-dwmac-meson-Initialize-all-known-PREG_ETH.patch diff --git a/patch/kernel/archive/meson-6.10/0025-ARM-dts-meson-meson8-Add-the-clock-input-to-the-Ethe.patch b/patch/kernel/archive/meson-6.12/0025-ARM-dts-meson-meson8-Add-the-clock-input-to-the-Ethe.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0025-ARM-dts-meson-meson8-Add-the-clock-input-to-the-Ethe.patch rename to patch/kernel/archive/meson-6.12/0025-ARM-dts-meson-meson8-Add-the-clock-input-to-the-Ethe.patch diff --git a/patch/kernel/archive/meson-6.10/0026-dt-bindings-clock-meson8b-add-the-rtc_32k-oscillator.patch b/patch/kernel/archive/meson-6.12/0026-dt-bindings-clock-meson8b-add-the-rtc_32k-oscillator.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0026-dt-bindings-clock-meson8b-add-the-rtc_32k-oscillator.patch rename to patch/kernel/archive/meson-6.12/0026-dt-bindings-clock-meson8b-add-the-rtc_32k-oscillator.patch diff --git a/patch/kernel/archive/meson-6.10/0027-clk-meson-meson8b-Add-the-mpeg_rtc_osc_sel-clock.patch b/patch/kernel/archive/meson-6.12/0027-clk-meson-meson8b-Add-the-mpeg_rtc_osc_sel-clock.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0027-clk-meson-meson8b-Add-the-mpeg_rtc_osc_sel-clock.patch rename to patch/kernel/archive/meson-6.12/0027-clk-meson-meson8b-Add-the-mpeg_rtc_osc_sel-clock.patch diff --git a/patch/kernel/archive/meson-6.10/0028-ARM-dts-meson-Add-address-cells-size-cells-and-range.patch b/patch/kernel/archive/meson-6.12/0028-ARM-dts-meson-Add-address-cells-size-cells-and-range.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0028-ARM-dts-meson-Add-address-cells-size-cells-and-range.patch rename to patch/kernel/archive/meson-6.12/0028-ARM-dts-meson-Add-address-cells-size-cells-and-range.patch diff --git a/patch/kernel/archive/meson-6.10/0029-dt-bindings-firmware-Document-the-Amlogic-Meson6-8-8.patch b/patch/kernel/archive/meson-6.12/0029-dt-bindings-firmware-Document-the-Amlogic-Meson6-8-8.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0029-dt-bindings-firmware-Document-the-Amlogic-Meson6-8-8.patch rename to patch/kernel/archive/meson-6.12/0029-dt-bindings-firmware-Document-the-Amlogic-Meson6-8-8.patch diff --git a/patch/kernel/archive/meson-6.10/0030-dt-bindings-arm-cpus-Document-Meson8-TrustZone-firmw.patch b/patch/kernel/archive/meson-6.12/0030-dt-bindings-arm-cpus-Document-Meson8-TrustZone-firmw.patch similarity index 97% rename from patch/kernel/archive/meson-6.10/0030-dt-bindings-arm-cpus-Document-Meson8-TrustZone-firmw.patch rename to patch/kernel/archive/meson-6.12/0030-dt-bindings-arm-cpus-Document-Meson8-TrustZone-firmw.patch index 1c5b8d4bd6f9..a602b08b3840 100644 --- a/patch/kernel/archive/meson-6.10/0030-dt-bindings-arm-cpus-Document-Meson8-TrustZone-firmw.patch +++ b/patch/kernel/archive/meson-6.12/0030-dt-bindings-arm-cpus-Document-Meson8-TrustZone-firmw.patch @@ -18,7 +18,7 @@ diff --git a/Documentation/devicetree/bindings/arm/cpus.yaml b/Documentation/dev index 111111111111..222222222222 100644 --- a/Documentation/devicetree/bindings/arm/cpus.yaml +++ b/Documentation/devicetree/bindings/arm/cpus.yaml -@@ -216,6 +216,7 @@ properties: +@@ -222,6 +222,7 @@ properties: - allwinner,sun9i-a80-smp - allwinner,sun8i-a83t-smp - amlogic,meson8-smp diff --git a/patch/kernel/archive/meson-6.10/0031-ARM-meson-Add-support-for-the-TrustZone-firmware.patch b/patch/kernel/archive/meson-6.12/0031-ARM-meson-Add-support-for-the-TrustZone-firmware.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0031-ARM-meson-Add-support-for-the-TrustZone-firmware.patch rename to patch/kernel/archive/meson-6.12/0031-ARM-meson-Add-support-for-the-TrustZone-firmware.patch diff --git a/patch/kernel/archive/meson-6.10/0032-ARM-meson-platsmp-Add-support-for-SoCs-running-on-Tr.patch b/patch/kernel/archive/meson-6.12/0032-ARM-meson-platsmp-Add-support-for-SoCs-running-on-Tr.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0032-ARM-meson-platsmp-Add-support-for-SoCs-running-on-Tr.patch rename to patch/kernel/archive/meson-6.12/0032-ARM-meson-platsmp-Add-support-for-SoCs-running-on-Tr.patch diff --git a/patch/kernel/archive/meson-6.10/0033-soc-amlogic-meson-mx-socinfo-Add-support-for-the-Tru.patch b/patch/kernel/archive/meson-6.12/0033-soc-amlogic-meson-mx-socinfo-Add-support-for-the-Tru.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0033-soc-amlogic-meson-mx-socinfo-Add-support-for-the-Tru.patch rename to patch/kernel/archive/meson-6.12/0033-soc-amlogic-meson-mx-socinfo-Add-support-for-the-Tru.patch diff --git a/patch/kernel/archive/meson-6.10/0034-nvmem-meson-mx-efuse-Add-support-for-the-TrustZone-f.patch b/patch/kernel/archive/meson-6.12/0034-nvmem-meson-mx-efuse-Add-support-for-the-TrustZone-f.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0034-nvmem-meson-mx-efuse-Add-support-for-the-TrustZone-f.patch rename to patch/kernel/archive/meson-6.12/0034-nvmem-meson-mx-efuse-Add-support-for-the-TrustZone-f.patch diff --git a/patch/kernel/archive/meson-6.10/0036-ARM-dts-meson8-Add-the-PWM_C-DV9-and-PWM_D-pins.patch b/patch/kernel/archive/meson-6.12/0036-ARM-dts-meson8-Add-the-PWM_C-DV9-and-PWM_D-pins.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0036-ARM-dts-meson8-Add-the-PWM_C-DV9-and-PWM_D-pins.patch rename to patch/kernel/archive/meson-6.12/0036-ARM-dts-meson8-Add-the-PWM_C-DV9-and-PWM_D-pins.patch diff --git a/patch/kernel/archive/meson-6.10/0045-dt-bindings-display-meson-vpu-add-support-for-Meson8.patch b/patch/kernel/archive/meson-6.12/0045-dt-bindings-display-meson-vpu-add-support-for-Meson8.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0045-dt-bindings-display-meson-vpu-add-support-for-Meson8.patch rename to patch/kernel/archive/meson-6.12/0045-dt-bindings-display-meson-vpu-add-support-for-Meson8.patch diff --git a/patch/kernel/archive/meson-6.10/0046-drm-meson-add-Meson8-Meson8b-Meson8m2-specific-vpu_c.patch b/patch/kernel/archive/meson-6.12/0046-drm-meson-add-Meson8-Meson8b-Meson8m2-specific-vpu_c.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0046-drm-meson-add-Meson8-Meson8b-Meson8m2-specific-vpu_c.patch rename to patch/kernel/archive/meson-6.12/0046-drm-meson-add-Meson8-Meson8b-Meson8m2-specific-vpu_c.patch diff --git a/patch/kernel/archive/meson-6.10/0047-drm-meson-Use-24-bits-per-pixel-for-the-framebuffer-.patch b/patch/kernel/archive/meson-6.12/0047-drm-meson-Use-24-bits-per-pixel-for-the-framebuffer-.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0047-drm-meson-Use-24-bits-per-pixel-for-the-framebuffer-.patch rename to patch/kernel/archive/meson-6.12/0047-drm-meson-Use-24-bits-per-pixel-for-the-framebuffer-.patch diff --git a/patch/kernel/archive/meson-6.10/0048-drm-meson-Use-a-separate-list-of-supported-formats-f.patch b/patch/kernel/archive/meson-6.12/0048-drm-meson-Use-a-separate-list-of-supported-formats-f.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0048-drm-meson-Use-a-separate-list-of-supported-formats-f.patch rename to patch/kernel/archive/meson-6.12/0048-drm-meson-Use-a-separate-list-of-supported-formats-f.patch diff --git a/patch/kernel/archive/meson-6.10/0049-drm-meson-Skip-VIU_OSD1_CTRL_STAT2-alpha-replace-val.patch b/patch/kernel/archive/meson-6.12/0049-drm-meson-Skip-VIU_OSD1_CTRL_STAT2-alpha-replace-val.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0049-drm-meson-Skip-VIU_OSD1_CTRL_STAT2-alpha-replace-val.patch rename to patch/kernel/archive/meson-6.12/0049-drm-meson-Skip-VIU_OSD1_CTRL_STAT2-alpha-replace-val.patch diff --git a/patch/kernel/archive/meson-6.10/0050-drm-meson-Enable-the-RGB-to-YUV-converter-on-Meson8-.patch b/patch/kernel/archive/meson-6.12/0050-drm-meson-Enable-the-RGB-to-YUV-converter-on-Meson8-.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0050-drm-meson-Enable-the-RGB-to-YUV-converter-on-Meson8-.patch rename to patch/kernel/archive/meson-6.12/0050-drm-meson-Enable-the-RGB-to-YUV-converter-on-Meson8-.patch diff --git a/patch/kernel/archive/meson-6.10/0051-drm-meson-Update-meson_vpu_init-to-work-with-Meson8-.patch b/patch/kernel/archive/meson-6.12/0051-drm-meson-Update-meson_vpu_init-to-work-with-Meson8-.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0051-drm-meson-Update-meson_vpu_init-to-work-with-Meson8-.patch rename to patch/kernel/archive/meson-6.12/0051-drm-meson-Update-meson_vpu_init-to-work-with-Meson8-.patch diff --git a/patch/kernel/archive/meson-6.10/0052-drm-meson-Describe-the-HDMI-PHY-frequency-limits-of-.patch b/patch/kernel/archive/meson-6.12/0052-drm-meson-Describe-the-HDMI-PHY-frequency-limits-of-.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0052-drm-meson-Describe-the-HDMI-PHY-frequency-limits-of-.patch rename to patch/kernel/archive/meson-6.12/0052-drm-meson-Describe-the-HDMI-PHY-frequency-limits-of-.patch diff --git a/patch/kernel/archive/meson-6.10/0053-drm-meson-Update-the-HDMI-encoder-for-Meson8-8b-8m2.patch b/patch/kernel/archive/meson-6.12/0053-drm-meson-Update-the-HDMI-encoder-for-Meson8-8b-8m2.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0053-drm-meson-Update-the-HDMI-encoder-for-Meson8-8b-8m2.patch rename to patch/kernel/archive/meson-6.12/0053-drm-meson-Update-the-HDMI-encoder-for-Meson8-8b-8m2.patch diff --git a/patch/kernel/archive/meson-6.10/0054-drm-meson-Only-set-ycbcr_420_allowed-on-64-bit-SoCs.patch b/patch/kernel/archive/meson-6.12/0054-drm-meson-Only-set-ycbcr_420_allowed-on-64-bit-SoCs.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0054-drm-meson-Only-set-ycbcr_420_allowed-on-64-bit-SoCs.patch rename to patch/kernel/archive/meson-6.12/0054-drm-meson-Only-set-ycbcr_420_allowed-on-64-bit-SoCs.patch diff --git a/patch/kernel/archive/meson-6.10/0055-drm-meson-Make-the-HHI-registers-optional-WIP.patch b/patch/kernel/archive/meson-6.12/0055-drm-meson-Make-the-HHI-registers-optional-WIP.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0055-drm-meson-Make-the-HHI-registers-optional-WIP.patch rename to patch/kernel/archive/meson-6.12/0055-drm-meson-Make-the-HHI-registers-optional-WIP.patch diff --git a/patch/kernel/archive/meson-6.10/0056-drm-meson-Add-support-for-the-Meson8-8b-8m2-TranSwit.patch b/patch/kernel/archive/meson-6.12/0056-drm-meson-Add-support-for-the-Meson8-8b-8m2-TranSwit.patch similarity index 99% rename from patch/kernel/archive/meson-6.10/0056-drm-meson-Add-support-for-the-Meson8-8b-8m2-TranSwit.patch rename to patch/kernel/archive/meson-6.12/0056-drm-meson-Add-support-for-the-Meson8-8b-8m2-TranSwit.patch index f9bbd04e9ff5..b604c99f6b69 100644 --- a/patch/kernel/archive/meson-6.10/0056-drm-meson-Add-support-for-the-Meson8-8b-8m2-TranSwit.patch +++ b/patch/kernel/archive/meson-6.12/0056-drm-meson-Add-support-for-the-Meson8-8b-8m2-TranSwit.patch @@ -18,7 +18,7 @@ diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig index 111111111111..222222222222 100644 --- a/drivers/gpu/drm/meson/Kconfig +++ b/drivers/gpu/drm/meson/Kconfig -@@ -25,3 +25,13 @@ config DRM_MESON_DW_MIPI_DSI +@@ -27,3 +27,13 @@ config DRM_MESON_DW_MIPI_DSI default y if DRM_MESON select DRM_DW_MIPI_DSI select GENERIC_PHY_MIPI_DPHY diff --git a/patch/kernel/archive/meson-6.10/0057-drm-meson-Meson8-Meson8b-Meson8m2-VCLK-HACK.patch b/patch/kernel/archive/meson-6.12/0057-drm-meson-Meson8-Meson8b-Meson8m2-VCLK-HACK.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0057-drm-meson-Meson8-Meson8b-Meson8m2-VCLK-HACK.patch rename to patch/kernel/archive/meson-6.12/0057-drm-meson-Meson8-Meson8b-Meson8m2-VCLK-HACK.patch diff --git a/patch/kernel/archive/meson-6.10/0058-drm-meson-Enable-support-for-Meson8-Meson8b-Meson8m2.patch b/patch/kernel/archive/meson-6.12/0058-drm-meson-Enable-support-for-Meson8-Meson8b-Meson8m2.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0058-drm-meson-Enable-support-for-Meson8-Meson8b-Meson8m2.patch rename to patch/kernel/archive/meson-6.12/0058-drm-meson-Enable-support-for-Meson8-Meson8b-Meson8m2.patch diff --git a/patch/kernel/archive/meson-6.10/0059-ARM-dts-meson-add-the-VPU-WiP.patch b/patch/kernel/archive/meson-6.12/0059-ARM-dts-meson-add-the-VPU-WiP.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0059-ARM-dts-meson-add-the-VPU-WiP.patch rename to patch/kernel/archive/meson-6.12/0059-ARM-dts-meson-add-the-VPU-WiP.patch diff --git a/patch/kernel/archive/meson-6.10/0060-ARM-dts-meson8-add-the-HDMI-controller-WiP.patch b/patch/kernel/archive/meson-6.12/0060-ARM-dts-meson8-add-the-HDMI-controller-WiP.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0060-ARM-dts-meson8-add-the-HDMI-controller-WiP.patch rename to patch/kernel/archive/meson-6.12/0060-ARM-dts-meson8-add-the-HDMI-controller-WiP.patch diff --git a/patch/kernel/archive/meson-6.10/0061-ARM-dts-meson8-Add-the-shared-CMA-dma-memory-pool.patch b/patch/kernel/archive/meson-6.12/0061-ARM-dts-meson8-Add-the-shared-CMA-dma-memory-pool.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0061-ARM-dts-meson8-Add-the-shared-CMA-dma-memory-pool.patch rename to patch/kernel/archive/meson-6.12/0061-ARM-dts-meson8-Add-the-shared-CMA-dma-memory-pool.patch diff --git a/patch/kernel/archive/meson-6.10/0062-ARM-dts-meson8-add-the-AO-CEC-controller-WiP.patch b/patch/kernel/archive/meson-6.12/0062-ARM-dts-meson8-add-the-AO-CEC-controller-WiP.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0062-ARM-dts-meson8-add-the-AO-CEC-controller-WiP.patch rename to patch/kernel/archive/meson-6.12/0062-ARM-dts-meson8-add-the-AO-CEC-controller-WiP.patch diff --git a/patch/kernel/archive/meson-6.10/0063-ARM-dts-meson8b-add-the-HDMI-controller-WiP.patch b/patch/kernel/archive/meson-6.12/0063-ARM-dts-meson8b-add-the-HDMI-controller-WiP.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0063-ARM-dts-meson8b-add-the-HDMI-controller-WiP.patch rename to patch/kernel/archive/meson-6.12/0063-ARM-dts-meson8b-add-the-HDMI-controller-WiP.patch diff --git a/patch/kernel/archive/meson-6.10/0064-ARM-dts-meson8b-add-the-AO-CEC-controller-WiP.patch b/patch/kernel/archive/meson-6.12/0064-ARM-dts-meson8b-add-the-AO-CEC-controller-WiP.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0064-ARM-dts-meson8b-add-the-AO-CEC-controller-WiP.patch rename to patch/kernel/archive/meson-6.12/0064-ARM-dts-meson8b-add-the-AO-CEC-controller-WiP.patch diff --git a/patch/kernel/archive/meson-6.10/0066-ARM-dts-meson8b-odroid-c1-enable-HDMI-for-the-Odroid.patch b/patch/kernel/archive/meson-6.12/0066-ARM-dts-meson8b-odroid-c1-enable-HDMI-for-the-Odroid.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/0066-ARM-dts-meson8b-odroid-c1-enable-HDMI-for-the-Odroid.patch rename to patch/kernel/archive/meson-6.12/0066-ARM-dts-meson8b-odroid-c1-enable-HDMI-for-the-Odroid.patch diff --git a/patch/kernel/archive/meson-6.1/onecloud-0002-dts-Support-HDMI.patch b/patch/kernel/archive/meson-6.12/0067-meson8b-mxq-add-HDMI-support.patch similarity index 53% rename from patch/kernel/archive/meson-6.1/onecloud-0002-dts-Support-HDMI.patch rename to patch/kernel/archive/meson-6.12/0067-meson8b-mxq-add-HDMI-support.patch index abde0aa50c18..ae2200b62de1 100644 --- a/patch/kernel/archive/meson-6.1/onecloud-0002-dts-Support-HDMI.patch +++ b/patch/kernel/archive/meson-6.12/0067-meson8b-mxq-add-HDMI-support.patch @@ -1,19 +1,19 @@ -From c358aa892b4f6f12114ad516b3ce5393f3f6d60a Mon Sep 17 00:00:00 2001 -From: hzy -Date: Sat, 1 Apr 2023 10:26:14 +0800 -Subject: [PATCH 2/2] ARM: dts: meson8b: onecloud: Support HDMI +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dominik=20W=C3=B3jt?= +Date: Tue, 29 Oct 2024 19:31:00 +0100 +Subject: meson8b-mxq: add HDMI support -Signed-off-by: hzy +Copied from 0066-ARM-dts-meson8b-odroid-c1-enable-HDMI-for-the-Odroid.patch --- - arch/arm/boot/dts/meson8b-onecloud.dts | 58 ++++++++++++++++++++++++++ - 1 file changed, 58 insertions(+) + arch/arm/boot/dts/amlogic/meson8b-mxq.dts | 60 ++++++++++ + 1 file changed, 60 insertions(+) -diff --git a/arch/arm/boot/dts/meson8b-onecloud.dts b/arch/arm/boot/dts/meson8b-onecloud.dts -index 1fa5420f..6ed19522 100644 ---- a/arch/arm/boot/dts/meson8b-onecloud.dts -+++ b/arch/arm/boot/dts/meson8b-onecloud.dts -@@ -80,6 +80,48 @@ blue { - }; +diff --git a/arch/arm/boot/dts/amlogic/meson8b-mxq.dts b/arch/arm/boot/dts/amlogic/meson8b-mxq.dts +index 111111111111..222222222222 100644 +--- a/arch/arm/boot/dts/amlogic/meson8b-mxq.dts ++++ b/arch/arm/boot/dts/amlogic/meson8b-mxq.dts +@@ -27,6 +27,50 @@ memory { + reg = <0x40000000 0x40000000>; }; + hdmi-connector { @@ -27,8 +27,10 @@ index 1fa5420f..6ed19522 100644 + }; + }; + ++ + sound { + compatible = "amlogic,gx-sound-card"; ++ model = "ODROID-C1"; + + assigned-clocks = <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>; @@ -58,24 +60,17 @@ index 1fa5420f..6ed19522 100644 + }; + }; + - p12v: regulator-p12v { - compatible = "regulator-fixed"; + vcck: regulator-vcck { + compatible = "pwm-regulator"; -@@ -199,6 +241,10 @@ &mali { - // mali-supply = <&vcc_core>; +@@ -91,6 +135,22 @@ vddee: regulator-vddee { + }; }; +&aiu { + status = "okay"; +}; + - &gpio { - gpio-line-names = - /* 0 */ "WIFI_SDIO_D0 PIN18 (GPIOX_0)", -@@ -403,6 +449,18 @@ &usb1_phy { - status = "okay"; - }; - +&hdmi_tx { + status = "okay"; + pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; @@ -88,9 +83,9 @@ index 1fa5420f..6ed19522 100644 + }; +}; + - &ir_receiver { - status = "okay"; - pinctrl-0 = <&ir_recv_pins>; + &cpu0 { + cpu-supply = <&vcck>; + }; -- -2.34.1 +Armbian diff --git a/patch/kernel/archive/meson-6.10/generic-Revert-mmc-core-Set-HS-clock-speed-before-sending-HS-CMD13.patch b/patch/kernel/archive/meson-6.12/generic-Revert-mmc-core-Set-HS-clock-speed-before-sending-HS-CMD13.patch similarity index 89% rename from patch/kernel/archive/meson-6.10/generic-Revert-mmc-core-Set-HS-clock-speed-before-sending-HS-CMD13.patch rename to patch/kernel/archive/meson-6.12/generic-Revert-mmc-core-Set-HS-clock-speed-before-sending-HS-CMD13.patch index aca6b585a17d..d7fe8f474193 100644 --- a/patch/kernel/archive/meson-6.10/generic-Revert-mmc-core-Set-HS-clock-speed-before-sending-HS-CMD13.patch +++ b/patch/kernel/archive/meson-6.12/generic-Revert-mmc-core-Set-HS-clock-speed-before-sending-HS-CMD13.patch @@ -12,7 +12,7 @@ diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 111111111111..222222222222 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c -@@ -1401,17 +1401,13 @@ static int mmc_select_hs400es(struct mmc_card *card) +@@ -1387,17 +1387,13 @@ static int mmc_select_hs400es(struct mmc_card *card) goto out_err; } @@ -32,7 +32,7 @@ index 111111111111..222222222222 100644 /* Switch card to DDR with strobe bit */ val = EXT_CSD_DDR_BUS_WIDTH_8 | EXT_CSD_BUS_WIDTH_STROBE; err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, -@@ -1469,7 +1465,7 @@ static int mmc_select_hs400es(struct mmc_card *card) +@@ -1455,7 +1451,7 @@ static int mmc_select_hs400es(struct mmc_card *card) static int mmc_select_hs200(struct mmc_card *card) { struct mmc_host *host = card->host; @@ -41,7 +41,7 @@ index 111111111111..222222222222 100644 int err = -EINVAL; u8 val; -@@ -1500,17 +1496,8 @@ static int mmc_select_hs200(struct mmc_card *card) +@@ -1486,17 +1482,8 @@ static int mmc_select_hs200(struct mmc_card *card) false, true, MMC_CMD_RETRIES); if (err) goto err; @@ -59,7 +59,7 @@ index 111111111111..222222222222 100644 /* * For HS200, CRC errors are not a reliable way to know the -@@ -1523,10 +1510,8 @@ static int mmc_select_hs200(struct mmc_card *card) +@@ -1509,10 +1496,8 @@ static int mmc_select_hs200(struct mmc_card *card) * mmc_select_timing() assumes timing has not changed if * it is a switch error. */ diff --git a/patch/kernel/archive/meson-6.10/generic-Revert-pwm-meson-modify-and-simplify-calculation-in-.patch b/patch/kernel/archive/meson-6.12/generic-Revert-pwm-meson-modify-and-simplify-calculation-in-.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/generic-Revert-pwm-meson-modify-and-simplify-calculation-in-.patch rename to patch/kernel/archive/meson-6.12/generic-Revert-pwm-meson-modify-and-simplify-calculation-in-.patch diff --git a/patch/kernel/archive/meson-6.10/onecloud-0001-add-dts.patch b/patch/kernel/archive/meson-6.12/onecloud-0001-add-dts.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/onecloud-0001-add-dts.patch rename to patch/kernel/archive/meson-6.12/onecloud-0001-add-dts.patch diff --git a/patch/kernel/archive/meson-6.10/onecloud-0002-dts-Support-HDMI.patch b/patch/kernel/archive/meson-6.12/onecloud-0002-dts-Support-HDMI.patch similarity index 100% rename from patch/kernel/archive/meson-6.10/onecloud-0002-dts-Support-HDMI.patch rename to patch/kernel/archive/meson-6.12/onecloud-0002-dts-Support-HDMI.patch From 287853f460d675e80233309f432167ea1f5f757b Mon Sep 17 00:00:00 2001 From: Igor Pecovnik Date: Sat, 8 Feb 2025 11:32:16 +0100 Subject: [PATCH 08/33] UX / cosmetics: MOTD ip display needs some limiting - switch MOTD download to new central location https://github.armbian.com/ - move cronjob for MOTD download from weekly to daily - change mord defaults, remove clear from defaults --- packages/bsp/common/etc/cron.daily/armbian-quotes | 3 +++ packages/bsp/common/etc/cron.weekly/armbian-quotes | 3 --- packages/bsp/common/etc/default/armbian-motd.dpkg-dist | 4 ++-- packages/bsp/common/etc/update-motd.d/10-armbian-header | 2 +- packages/bsp/common/etc/update-motd.d/30-armbian-sysinfo | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) create mode 100755 packages/bsp/common/etc/cron.daily/armbian-quotes delete mode 100755 packages/bsp/common/etc/cron.weekly/armbian-quotes diff --git a/packages/bsp/common/etc/cron.daily/armbian-quotes b/packages/bsp/common/etc/cron.daily/armbian-quotes new file mode 100755 index 000000000000..f7958c558fb8 --- /dev/null +++ b/packages/bsp/common/etc/cron.daily/armbian-quotes @@ -0,0 +1,3 @@ +#!/bin/bash + +curl --max-time 2 -L -s -o "/tmp/quotes.txt" "https://github.armbian.com/quotes.txt" diff --git a/packages/bsp/common/etc/cron.weekly/armbian-quotes b/packages/bsp/common/etc/cron.weekly/armbian-quotes deleted file mode 100755 index 0d7ec031a013..000000000000 --- a/packages/bsp/common/etc/cron.weekly/armbian-quotes +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -curl -L -s -o "/etc/update-motd.d/quotes.txt" "https://dl.armbian.com/quotes.txt" diff --git a/packages/bsp/common/etc/default/armbian-motd.dpkg-dist b/packages/bsp/common/etc/default/armbian-motd.dpkg-dist index 612c6982e8fa..40d1811d5bda 100644 --- a/packages/bsp/common/etc/default/armbian-motd.dpkg-dist +++ b/packages/bsp/common/etc/default/armbian-motd.dpkg-dist @@ -4,9 +4,9 @@ # ONE_WIRE="yes" show 1-wire temperature sensor if attached # PRIMARY_DIRECTION="rx" show daily traffic stats, options: "rx", "tx", "both", "off", vnstat needs to be installed -MOTD_DISABLE="" +MOTD_DISABLE="clear" ONE_WIRE="" -HIDE_IP_PATTERN="^dummy0|^lo|^docker|^hassio" +HIDE_IP_PATTERN="^dummy0|^lo|^docker|^hassio|^br-|^veth" PRIMARY_INTERFACE="$(ip route | grep '^default' | sed "s/.*dev //" | cut -d" " -f1)" PRIMARY_DIRECTION="rx" STORAGE=/dev/sda1 diff --git a/packages/bsp/common/etc/update-motd.d/10-armbian-header b/packages/bsp/common/etc/update-motd.d/10-armbian-header index df947c2d56be..f5c8ebe4702e 100755 --- a/packages/bsp/common/etc/update-motd.d/10-armbian-header +++ b/packages/bsp/common/etc/update-motd.d/10-armbian-header @@ -11,7 +11,7 @@ THIS_SCRIPT="header" MOTD_DISABLE="" -HIDE_IP_PATTERN="^dummy0|^lo|^docker" +HIDE_IP_PATTERN="^dummy0|^lo|^docker|^hassio|^br-|^veth" # Read image configuration [[ -f /etc/armbian-image-release ]] && . /etc/armbian-image-release diff --git a/packages/bsp/common/etc/update-motd.d/30-armbian-sysinfo b/packages/bsp/common/etc/update-motd.d/30-armbian-sysinfo index c79647217872..b6f1255489f5 100755 --- a/packages/bsp/common/etc/update-motd.d/30-armbian-sysinfo +++ b/packages/bsp/common/etc/update-motd.d/30-armbian-sysinfo @@ -132,8 +132,8 @@ display " Memory usage" "$memory_usage" "70" "0" "%" " of ${memory_total}" display "Zram usage" "$swap_usage" "75" "0" "%" " of ${swap_total}" echo "" # fixed newline display " CPU temp" "$board_temp" $CPU_TEMP_LIMIT "0" "°C" "" -display "Ambient temp" "$amb_temp" $AMB_TEMP_LIMIT "0" "°C" "" -display "Usage of /" "$root_usage" "90" "1" "%" " of $root_total $overlay_root" +display " Ambient temp" "$amb_temp" $AMB_TEMP_LIMIT "0" "°C" "" +display " Usage of /" "$root_usage" "90" "1" "%" " of $root_total $overlay_root" if command -v overlayroot-chroot > /dev/null 2>&1 && findmnt -k /media/root-ro | tail -1 | grep -w /media/root-ro > /dev/null 2>&1; then echo -ne "\x1B[91m(read only rootfs)\x1B[0m" fi From d96e0486b828cebbed3bccdc21d53bd08ad43013 Mon Sep 17 00:00:00 2001 From: Igor Pecovnik Date: Sat, 8 Feb 2025 12:59:20 +0100 Subject: [PATCH 09/33] Show running Docker containers in the MOTD --- .../bsp/common/etc/default/armbian-motd.dpkg-dist | 2 +- .../common/etc/update-motd.d/10-armbian-header | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/bsp/common/etc/default/armbian-motd.dpkg-dist b/packages/bsp/common/etc/default/armbian-motd.dpkg-dist index 40d1811d5bda..00e19cc468fa 100644 --- a/packages/bsp/common/etc/default/armbian-motd.dpkg-dist +++ b/packages/bsp/common/etc/default/armbian-motd.dpkg-dist @@ -6,7 +6,7 @@ MOTD_DISABLE="clear" ONE_WIRE="" -HIDE_IP_PATTERN="^dummy0|^lo|^docker|^hassio|^br-|^veth" +HIDE_IP_PATTERN="^dummy0|^lo|^docker|^hassio|^br-|^veth|^vnet|^virbr" PRIMARY_INTERFACE="$(ip route | grep '^default' | sed "s/.*dev //" | cut -d" " -f1)" PRIMARY_DIRECTION="rx" STORAGE=/dev/sda1 diff --git a/packages/bsp/common/etc/update-motd.d/10-armbian-header b/packages/bsp/common/etc/update-motd.d/10-armbian-header index f5c8ebe4702e..b19b30e5490b 100755 --- a/packages/bsp/common/etc/update-motd.d/10-armbian-header +++ b/packages/bsp/common/etc/update-motd.d/10-armbian-header @@ -11,7 +11,7 @@ THIS_SCRIPT="header" MOTD_DISABLE="" -HIDE_IP_PATTERN="^dummy0|^lo|^docker|^hassio|^br-|^veth" +HIDE_IP_PATTERN="^dummy0|^lo|^docker|^hassio|^br-|^veth|^vnet|^virbr" # Read image configuration [[ -f /etc/armbian-image-release ]] && . /etc/armbian-image-release @@ -76,8 +76,7 @@ function get_ip_addresses() { [[ -n $ipv6 ]] && ipv6s+=("$ipv6") fi done - - echo "${ipv4s[@]}|${ipv6s[@]}" + echo "${ipv4s[*]}|${ipv6s[*]}" } # get_ip_addresses # Read Armbian kernel version @@ -134,6 +133,11 @@ if [[ $NUM_UPDATES -gt 0 ]]; then UPDATE_STATUS+=" available for upgrade\e[0m " fi +# read running Docker containers if any +if systemctl is-active docker >/dev/null; then + CONTAINERS_STATUS=$(docker ps --format "{{.Names}}" | tr '\n' ',' | sed 's/,/, /g' | sed 's/, $//') +fi + echo "" # Display packages status @@ -160,6 +164,11 @@ if [[ -n $wan_ip_address ]]; then echo -e "\x1B[93m(WAN)\x1B[0m $wan_ip_address" fi +# Display running docker containers +if [[ -n "${CONTAINERS_STATUS}" ]]; then + echo -e " Containers: \x1B[92m$CONTAINERS_STATUS\x1B[0m" +fi + # Display hostapd if [[ -n $ssid ]]; then echo -e " WiFi AP: SSID: (\x1B[91m$ssid\x1B[0m), $(iw $interface info | grep channel | xargs)" From 2f1fa5f40f9354ee6e7fb268bdd8ed431b163433 Mon Sep 17 00:00:00 2001 From: Arend-Jan van Hilten Date: Sat, 8 Feb 2025 23:11:35 +0100 Subject: [PATCH 10/33] Fix orangepi 3b audio jack download 'button' (#7794) --- ...6-orangepi-3b-remove_download_button.patch | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 patch/u-boot/v2024.10/board_orangepi3b/rockchip-rk3566-orangepi-3b-remove_download_button.patch diff --git a/patch/u-boot/v2024.10/board_orangepi3b/rockchip-rk3566-orangepi-3b-remove_download_button.patch b/patch/u-boot/v2024.10/board_orangepi3b/rockchip-rk3566-orangepi-3b-remove_download_button.patch new file mode 100644 index 000000000000..cc57c78afdff --- /dev/null +++ b/patch/u-boot/v2024.10/board_orangepi3b/rockchip-rk3566-orangepi-3b-remove_download_button.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Arend-Jan van Hilten +Date: Thu, 6 Feb 2025 13:50:45 +0000 +Subject: rk3566-orangepi-3b disable download button audio jack +The download button on the Orange Pi 3B is connected to the audio jack microphone input. +Plugging in any 3 pin audio jack will trigger the download button, which is not desired as it will not boot. + +Signed-off-by: Arend-Jan van Hilten +--- + configs/orangepi-3b-rk3566_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/configs/orangepi-3b-rk3566_defconfig b/configs/orangepi-3b-rk3566_defconfig +index 575dc4340d..c64f689975 100644 +--- a/configs/orangepi-3b-rk3566_defconfig ++++ b/configs/orangepi-3b-rk3566_defconfig +@@ -94,5 +94,6 @@ CONFIG_USB_XHCI_HCD=y + CONFIG_USB_EHCI_HCD=y + CONFIG_USB_EHCI_GENERIC=y + CONFIG_USB_DWC3=y + CONFIG_USB_DWC3_GENERIC=y + CONFIG_ERRNO_STR=y ++CONFIG_ROCKCHIP_BOOT_MODE_REG=0 +-- +Created with Armbian build tools https://github.com/armbian/build + From c3be0a42167ed93a35843bd89c6cb8197038bc83 Mon Sep 17 00:00:00 2001 From: qbisi Date: Sat, 8 Feb 2025 05:55:05 +0800 Subject: [PATCH 11/33] hinlink-h88k: fix usb dr_mode to host --- patch/kernel/archive/rockchip64-6.12/dt/rk3588-hinlink-h88k.dts | 1 + patch/kernel/archive/rockchip64-6.13/dt/rk3588-hinlink-h88k.dts | 1 + 2 files changed, 2 insertions(+) diff --git a/patch/kernel/archive/rockchip64-6.12/dt/rk3588-hinlink-h88k.dts b/patch/kernel/archive/rockchip64-6.12/dt/rk3588-hinlink-h88k.dts index 9363eef2d592..79332016bebf 100644 --- a/patch/kernel/archive/rockchip64-6.12/dt/rk3588-hinlink-h88k.dts +++ b/patch/kernel/archive/rockchip64-6.12/dt/rk3588-hinlink-h88k.dts @@ -849,6 +849,7 @@ }; &usb_host1_xhci { + dr_mode = "host"; status = "okay"; }; diff --git a/patch/kernel/archive/rockchip64-6.13/dt/rk3588-hinlink-h88k.dts b/patch/kernel/archive/rockchip64-6.13/dt/rk3588-hinlink-h88k.dts index 9363eef2d592..79332016bebf 100644 --- a/patch/kernel/archive/rockchip64-6.13/dt/rk3588-hinlink-h88k.dts +++ b/patch/kernel/archive/rockchip64-6.13/dt/rk3588-hinlink-h88k.dts @@ -849,6 +849,7 @@ }; &usb_host1_xhci { + dr_mode = "host"; status = "okay"; }; From cb6f2fbef89d2047347baa9678be440a49eee728 Mon Sep 17 00:00:00 2001 From: qbisi Date: Sat, 8 Feb 2025 22:03:07 +0800 Subject: [PATCH 12/33] hinlink-h88k: add 5g modem enable and reset pin --- .../dt/rk3588-hinlink-h88k.dts | 40 +++++++++++++++++++ .../dt/rk3588-hinlink-h88k.dts | 40 +++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/patch/kernel/archive/rockchip64-6.12/dt/rk3588-hinlink-h88k.dts b/patch/kernel/archive/rockchip64-6.12/dt/rk3588-hinlink-h88k.dts index 79332016bebf..3114c35fe93b 100644 --- a/patch/kernel/archive/rockchip64-6.12/dt/rk3588-hinlink-h88k.dts +++ b/patch/kernel/archive/rockchip64-6.12/dt/rk3588-hinlink-h88k.dts @@ -126,6 +126,36 @@ vin-supply = <&vcc12v_dcin>; }; + /* it's modem reset pin */ + modem_enable: modem-enable { + compatible = "regulator-fixed"; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpios = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "modem-enable"; + vin-supply = <&vcc_3v3_s3>; + startup-delay-us = <500000>; + pinctrl-names = "default"; + pintctrl-0 = <&modem_reset_en>; + }; + + vcc3v3_modem: vcc3v3-modem { + compatible = "regulator-fixed"; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpios = <&gpio4 RK_PA3 GPIO_ACTIVE_HIGH>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc3v3_modem"; + pinctrl-names = "default"; + pintctrl-0 = <&modem_power_en>; + vin-supply = <&vcc_3v3_s3>; + }; + vcc5v0_host: vcc5v0-host-regulator { compatible = "regulator-fixed"; regulator-name = "vcc5v0_host"; @@ -413,6 +443,16 @@ }; }; + modem { + modem_power_en: modem-power-en { + rockchip,pins = <4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + modem_reset_en: modem-reset-en { + rockchip,pins = <4 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + rtl8211f { rtl8211f_rst: rtl8211f-rst { rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; diff --git a/patch/kernel/archive/rockchip64-6.13/dt/rk3588-hinlink-h88k.dts b/patch/kernel/archive/rockchip64-6.13/dt/rk3588-hinlink-h88k.dts index 79332016bebf..3114c35fe93b 100644 --- a/patch/kernel/archive/rockchip64-6.13/dt/rk3588-hinlink-h88k.dts +++ b/patch/kernel/archive/rockchip64-6.13/dt/rk3588-hinlink-h88k.dts @@ -126,6 +126,36 @@ vin-supply = <&vcc12v_dcin>; }; + /* it's modem reset pin */ + modem_enable: modem-enable { + compatible = "regulator-fixed"; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpios = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "modem-enable"; + vin-supply = <&vcc_3v3_s3>; + startup-delay-us = <500000>; + pinctrl-names = "default"; + pintctrl-0 = <&modem_reset_en>; + }; + + vcc3v3_modem: vcc3v3-modem { + compatible = "regulator-fixed"; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpios = <&gpio4 RK_PA3 GPIO_ACTIVE_HIGH>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc3v3_modem"; + pinctrl-names = "default"; + pintctrl-0 = <&modem_power_en>; + vin-supply = <&vcc_3v3_s3>; + }; + vcc5v0_host: vcc5v0-host-regulator { compatible = "regulator-fixed"; regulator-name = "vcc5v0_host"; @@ -413,6 +443,16 @@ }; }; + modem { + modem_power_en: modem-power-en { + rockchip,pins = <4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + modem_reset_en: modem-reset-en { + rockchip,pins = <4 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + rtl8211f { rtl8211f_rst: rtl8211f-rst { rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; From 51b300ebdf716ba984b40c722b0e345f6ba73ac6 Mon Sep 17 00:00:00 2001 From: Ricardo Pardini Date: Wed, 8 Jan 2025 00:46:45 +0100 Subject: [PATCH 13/33] armbian-kernel.sh: introduce `KERNEL_BTF=no` to opt-out of BTF/CO-RE type-info on low-RAM machines - turns out `pahole` for `vmlinux` can take multiple gigabytes of RAM to run successfully - I can't simply decide based on available RAM, as that would make .config hashes mismatch - thus, introduce: - default is to enable BTF; if on low-ram host, error out unless KERNEL_BTF=yes is passed - if KERNEL_BTF=no is passed, the BTF debug info is always disabled - if KERNEL_BTF=yes is passed, then a warning is produced, but BTF is still enabled - the magic number "6451 MiB" was determined empirically (and is probably bs) --- lib/functions/compilation/armbian-kernel.sh | 101 +++++++++++++------- 1 file changed, 65 insertions(+), 36 deletions(-) diff --git a/lib/functions/compilation/armbian-kernel.sh b/lib/functions/compilation/armbian-kernel.sh index 1378fef5391d..385cab058657 100644 --- a/lib/functions/compilation/armbian-kernel.sh +++ b/lib/functions/compilation/armbian-kernel.sh @@ -57,51 +57,46 @@ function armbian_kernel_config__disable_various_options() { fi } -function armbian_kernel_config__600_enable_ebpf_and_btf_info() { - display_alert "Enabling eBPF and BTF info" "for fully BTF & CO-RE enabled kernel" "info" - +function armbian_kernel_config__force_pa_va_48_bits_on_arm64() { declare -A opts_val=() - declare -a opts_n=("CONFIG_DEBUG_INFO_NONE") - declare -a opts_y=( - "CONFIG_BPF_JIT" "CONFIG_BPF_JIT_DEFAULT_ON" "CONFIG_FTRACE_SYSCALLS" "CONFIG_PROBE_EVENTS_BTF_ARGS" "CONFIG_BPF_KPROBE_OVERRIDE" - "CONFIG_DEBUG_INFO" "CONFIG_DEBUG_INFO_DWARF5" - "CONFIG_DEBUG_INFO_BTF" "CONFIG_DEBUG_INFO_BTF_MODULES" - ) - + declare -a opts_y=() opts_n=() if [[ "${ARCH}" == "arm64" ]]; then opts_y+=("CONFIG_ARM64_VA_BITS_48") opts_val["CONFIG_ARM64_PA_BITS"]="48" fi + armbian_kernel_config_apply_opts_from_arrays +} - declare opt_y opt_val opt_n - for opt_n in "${opts_n[@]}"; do - kernel_config_modifying_hashes+=("${opt_n}=n") - done - - for opt_y in "${opts_y[@]}"; do - kernel_config_modifying_hashes+=("${opt_y}=y") - done - - for opt_val in "${!opts_val[@]}"; do - kernel_config_modifying_hashes+=("${opt_val}=${opts_val[$opt_val]}") - done - - if [[ -f .config ]]; then - for opt_n in "${opts_n[@]}"; do - display_alert "Disabling kernel opt" "${opt_n}=n" "debug" - kernel_config_set_n "${opt_n}" - done +function armbian_kernel_config__600_enable_ebpf_and_btf_info() { + declare -A opts_val=() + declare -a opts_y=() opts_n=() - for opt_y in "${opts_y[@]}"; do - display_alert "Enabling kernel opt" "${opt_y}=y" "debug" - kernel_config_set_y "${opt_y}" - done + if [[ "${KERNEL_BTF}" == "no" ]]; then # If user is explicit by passing "KERNEL_BTF=no", then actually disable all debug info. + display_alert "Disabling eBPF and BTF info for kernel" "as requested by KERNEL_BTF=no" "info" + opts_y+=("CONFIG_DEBUG_INFO_NONE") # Enable the "none" option + opts_n+=("CONFIG_DEBUG_INFO" "CONFIG_DEBUG_INFO_DWARF5" "CONFIG_DEBUG_INFO_BTF" "CONFIG_DEBUG_INFO_BTF_MODULES") # BTF & CO-RE == off + # We don't disable the eBPF options, as eBPF itself doesn't require BTF (debug info) and doesnt' consume as much memory during build as BTF debug info does. + else + declare -i available_physical_memory_mib + available_physical_memory_mib=$(($(awk '/MemAvailable/ {print $2}' /proc/meminfo) / 1024)) # MiB + display_alert "Considering available RAM for BTF build" "${available_physical_memory_mib} MiB" "info" + + if [[ ${available_physical_memory_mib} -lt 6451 ]]; then # If less than 6451 MiB of RAM is available, then exit with an error, telling the user to avoid pain and set KERNEL_BTF=no ... + if [[ "${KERNEL_BTF}" == "yes" ]]; then # ... except if the user knows better, and has set KERNEL_BTF=yes, then we'll just warn. + display_alert "Not enough RAM available (${available_physical_memory_mib}Mib) for BTF build" "but KERNEL_BTF=yes is set; enabling BTF" "warn" + else + exit_with_error "Not enough RAM available (${available_physical_memory_mib}Mib) for BTF build. Please set 'KERNEL_BTF=no' to avoid running out of memory during the kernel LD/BTF build step; or ignore this check by setting 'KERNEL_BTF=yes' -- that might put a lot of load on your swap disk, if any." + fi + fi - for opt_val in "${!opts_val[@]}"; do - display_alert "Setting kernel opt" "${opt_val}=${opts_val[$opt_val]}" "debug" - kernel_config_set_val "${opt_val}" "${opts_val[$opt_val]}" - done + display_alert "Enabling eBPF and BTF info" "for fully BTF & CO-RE enabled kernel" "info" + opts_n+=("CONFIG_DEBUG_INFO_NONE") # Make sure the "none" option is disabled + opts_y+=( + "CONFIG_BPF_JIT" "CONFIG_BPF_JIT_DEFAULT_ON" "CONFIG_FTRACE_SYSCALLS" "CONFIG_PROBE_EVENTS_BTF_ARGS" "CONFIG_BPF_KPROBE_OVERRIDE" # eBPF == on + "CONFIG_DEBUG_INFO" "CONFIG_DEBUG_INFO_DWARF5" "CONFIG_DEBUG_INFO_BTF" "CONFIG_DEBUG_INFO_BTF_MODULES" # BTF & CO-RE == off + ) fi + armbian_kernel_config_apply_opts_from_arrays return 0 } @@ -166,3 +161,37 @@ function kernel_config_set_val() { display_alert "Setting kernel config/module value" "${config}=${value}" "debug" run_host_command_logged ./scripts/config --set-val "${config}" "${value}" } + +# This takes opts_n, opts_y, arrays from parent scope; also the opts_val dictionary; +# it and applies them to the hashes and to the .config if it exists. +function armbian_kernel_config_apply_opts_from_arrays() { + declare opt_y opt_val opt_n + for opt_n in "${opts_n[@]}"; do + kernel_config_modifying_hashes+=("${opt_n}=n") + done + + for opt_y in "${opts_y[@]}"; do + kernel_config_modifying_hashes+=("${opt_y}=y") + done + + for opt_val in "${!opts_val[@]}"; do + kernel_config_modifying_hashes+=("${opt_val}=${opts_val[$opt_val]}") + done + + if [[ -f .config ]]; then + for opt_n in "${opts_n[@]}"; do + display_alert "Disabling kernel opt" "${opt_n}=n" "debug" + kernel_config_set_n "${opt_n}" + done + + for opt_y in "${opts_y[@]}"; do + display_alert "Enabling kernel opt" "${opt_y}=y" "debug" + kernel_config_set_y "${opt_y}" + done + + for opt_val in "${!opts_val[@]}"; do + display_alert "Setting kernel opt" "${opt_val}=${opts_val[$opt_val]}" "debug" + kernel_config_set_val "${opt_val}" "${opts_val[$opt_val]}" + done + fi +} From fc20fb8639414f8fc088b2ccb6f577cfb8e86e4c Mon Sep 17 00:00:00 2001 From: Werner Date: Mon, 10 Feb 2025 05:47:20 +0100 Subject: [PATCH 14/33] nanopi-r3s: set `HAS_VIDEO_OUTPUT` (#7810) --- config/boards/nanopi-r3s.csc | 1 + 1 file changed, 1 insertion(+) diff --git a/config/boards/nanopi-r3s.csc b/config/boards/nanopi-r3s.csc index 965a4044a18f..6fdf8b6320e7 100644 --- a/config/boards/nanopi-r3s.csc +++ b/config/boards/nanopi-r3s.csc @@ -2,6 +2,7 @@ BOARD_NAME="NanoPi R3S" BOARDFAMILY="rk35xx" BOARD_MAINTAINER="" +HAS_VIDEO_OUTPUT="no" BOOTCONFIG="nanopi-r3s-rk3566_defconfig" KERNEL_TARGET="current,edge" KERNEL_TEST_TARGET="current,edge" From 7faaf639fac44c7dd8994b3a2327faa4c00e1bab Mon Sep 17 00:00:00 2001 From: amazingfate Date: Mon, 10 Feb 2025 12:28:05 +0800 Subject: [PATCH 15/33] extensions: fix outdated ghproxy mirror address --- extensions/bcmdhd.sh | 2 +- extensions/radxa-aic8800.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/bcmdhd.sh b/extensions/bcmdhd.sh index 5a5bcbd9da75..efdd8b494899 100644 --- a/extensions/bcmdhd.sh +++ b/extensions/bcmdhd.sh @@ -18,7 +18,7 @@ function post_install_kernel_debs__install_bcmdhd_dkms_package() { bcmdhd_sdio_url="https://github.com/armbian/bcmdhd-dkms/releases/download/${latest_version}/bcmdhd-sdio-dkms_${latest_version}_all.deb" bcmdhd_usb_url="https://github.com/armbian/bcmdhd-dkms/releases/download/${latest_version}/bcmdhd-usb-dkms_${latest_version}_all.deb" if [[ "${GITHUB_MIRROR}" == "ghproxy" ]]; then - ghproxy_header="https://mirror.ghproxy.com/" + ghproxy_header="https://ghfast.top/" bcmdhd_pcie_url=${ghproxy_header}${bcmdhd_pcie_url} bcmdhd_sdio_url=${ghproxy_header}${bcmdhd_sdio_url} bcmdhd_usb_url=${ghproxy_header}${bcmdhd_usb_url} diff --git a/extensions/radxa-aic8800.sh b/extensions/radxa-aic8800.sh index a383d573dbd9..506a78289f6b 100644 --- a/extensions/radxa-aic8800.sh +++ b/extensions/radxa-aic8800.sh @@ -23,7 +23,7 @@ function post_install_kernel_debs__install_aic8800_dkms_package() { aic8800_sdio_url="https://github.com/radxa-pkg/aic8800/releases/download/${latest_version}/aic8800-sdio-dkms_${latest_version}_all.deb" aic8800_usb_url="https://github.com/radxa-pkg/aic8800/releases/download/${latest_version}/aic8800-usb-dkms_${latest_version}_all.deb" if [[ "${GITHUB_MIRROR}" == "ghproxy" ]]; then - ghproxy_header="https://mirror.ghproxy.com/" + ghproxy_header="https://ghfast.top/" aic8800_firmware_url=${ghproxy_header}${aic8800_firmware_url} aic8800_pcie_url=${ghproxy_header}${aic8800_pcie_url} aic8800_sdio_url=${ghproxy_header}${aic8800_sdio_url} From 31b3c5f75247c3562c2c80c4abe0ed2887e3fbc9 Mon Sep 17 00:00:00 2001 From: igorpecovnik <6281704+igorpecovnik@users.noreply.github.com> Date: Mon, 10 Feb 2025 05:07:32 +0000 Subject: [PATCH 16/33] `Automatic` board configs status synchronise --- .github/CODEOWNERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index cf3f835afec8..0b5f2cb0aef9 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -91,7 +91,7 @@ config/boards/nanopineo.csc @spendist config/boards/nanopineo2.csc @spendist config/boards/nanopineocore2.csc @AGM1968 config/boards/nanopineoplus2.csc @teknoid -config/boards/odroidc1.eos @juanlufont +config/boards/odroidc1.csc @juanlufont config/boards/odroidc2.conf @teknoid config/boards/odroidc4.conf @igorpecovnik config/boards/odroidhc4.conf @igorpecovnik @@ -99,7 +99,7 @@ config/boards/odroidm1.conf @rpardini config/boards/odroidn2.conf @NicoD-SBC config/boards/odroidxu4.conf @joekhoobyar config/boards/olimex-teres-a64.csc @Kreyren -config/boards/onecloud.eos @hzyitc +config/boards/onecloud.csc @hzyitc config/boards/oneplus-kebab.conf @amazingfate config/boards/orangepi4-lts.conf @paolosabatino config/boards/orangepi4.csc @paolosabatino From fe50e4a283bf283ab0f60f4756e0dbf8b5d220c7 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Sun, 9 Feb 2025 11:15:33 +0100 Subject: [PATCH 17/33] mkspi: do not build desktop images There is not practival sense in Gnome for this kind of boards. Usually we use KlipperScreen or/and WEB UI. --- config/boards/mkspi.csc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/boards/mkspi.csc b/config/boards/mkspi.csc index d2f3e785732d..e6cf8792eb36 100644 --- a/config/boards/mkspi.csc +++ b/config/boards/mkspi.csc @@ -11,7 +11,8 @@ BOARD_MAINTAINER="redrathnure" BOOTCONFIG="mkspi-rk3328_defconfig" KERNEL_TARGET="current,edge" KERNEL_TEST_TARGET="current" -FULL_DESKTOP="yes" +#No need to build Desktop images, minimal set will be installed together with KlipperScreen +HAS_VIDEO_OUTPUT="no" BOOT_LOGO="desktop" MODULES="ads7846 spidev" BOOTFS_TYPE="fat" From 1716d6c1b6792bbe4cc103558ec8f788cd04abab Mon Sep 17 00:00:00 2001 From: Thorsten Maerz Date: Sat, 8 Feb 2025 22:08:48 +0100 Subject: [PATCH 18/33] build only CLI images --- config/boards/mksklipad50.csc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/boards/mksklipad50.csc b/config/boards/mksklipad50.csc index 772f9d87a5d2..2f7c9e71209d 100644 --- a/config/boards/mksklipad50.csc +++ b/config/boards/mksklipad50.csc @@ -5,7 +5,7 @@ BOARD_MAINTAINER="torte71" BOOTCONFIG="mksklipad50-rk3328_defconfig" KERNEL_TARGET="current,edge" KERNEL_TEST_TARGET="current" -FULL_DESKTOP="yes" +HAS_VIDEO_OUTPUT="no" BOOT_LOGO="desktop" MODULES="pinctrl-rk805 ads7846 spidev" BOOTFS_TYPE="fat" From af131c02cdc44f0476cc4ab677ca542902c2a520 Mon Sep 17 00:00:00 2001 From: Igor Pecovnik Date: Sun, 9 Feb 2025 08:42:09 +0100 Subject: [PATCH 19/33] Meson: drop (long) broken legacy code which is also breaking CI --- config/boards/aml-s805-mxq.tvb | 2 +- config/boards/odroidc1.csc | 2 +- config/boards/onecloud.csc | 2 +- config/kernel/linux-meson-legacy.config | 1648 ------- .../sources/families/include/meson_common.inc | 4 - ...-size-if-no-ZONE_DMA-bouncing-needed.patch | 56 - ...eneric-0001-m8-m8b-m8m2-Support-HDMI.patch | 4394 ----------------- ...upport-meson-8-8b-hdmi-tx-components.patch | 26 - ...-clock-speed-before-sending-HS-CMD13.patch | 76 - ...-modify-and-simplify-calculation-in-.patch | 39 - .../meson-6.6/odroidc1-dts-Enable-HDMI.patch | 106 - .../meson-6.6/onecloud-0001-add-dts.patch | 440 -- .../onecloud-0002-dts-Support-HDMI.patch | 96 - 13 files changed, 3 insertions(+), 6888 deletions(-) delete mode 100644 config/kernel/linux-meson-legacy.config delete mode 100644 patch/kernel/archive/meson-6.6/0010-arm64-swiotlb-Reduce-the-default-size-if-no-ZONE_DMA-bouncing-needed.patch delete mode 100644 patch/kernel/archive/meson-6.6/generic-0001-m8-m8b-m8m2-Support-HDMI.patch delete mode 100644 patch/kernel/archive/meson-6.6/generic-0003-drm-meson-Support-meson-8-8b-hdmi-tx-components.patch delete mode 100644 patch/kernel/archive/meson-6.6/generic-Revert-mmc-core-Set-HS-clock-speed-before-sending-HS-CMD13.patch delete mode 100644 patch/kernel/archive/meson-6.6/generic-Revert-pwm-meson-modify-and-simplify-calculation-in-.patch delete mode 100644 patch/kernel/archive/meson-6.6/odroidc1-dts-Enable-HDMI.patch delete mode 100644 patch/kernel/archive/meson-6.6/onecloud-0001-add-dts.patch delete mode 100644 patch/kernel/archive/meson-6.6/onecloud-0002-dts-Support-HDMI.patch diff --git a/config/boards/aml-s805-mxq.tvb b/config/boards/aml-s805-mxq.tvb index 2426958b9503..48bcfc546bac 100644 --- a/config/boards/aml-s805-mxq.tvb +++ b/config/boards/aml-s805-mxq.tvb @@ -2,7 +2,7 @@ BOARD_NAME="MXQ" BOARDFAMILY="meson8b" BOARD_MAINTAINER="" -KERNEL_TARGET="legacy,current" +KERNEL_TARGET="current" KERNEL_TEST_TARGET="current" BOOTCONFIG="none" BOOTSCRIPT="boot-aml-s805-mxq.cmd:boot.cmd" diff --git a/config/boards/odroidc1.csc b/config/boards/odroidc1.csc index f31fd4fd50de..c673009f2824 100644 --- a/config/boards/odroidc1.csc +++ b/config/boards/odroidc1.csc @@ -2,7 +2,7 @@ BOARD_NAME="Odroid C1" BOARDFAMILY="meson8b" BOARD_MAINTAINER="juanlufont" -KERNEL_TARGET="legacy,current" +KERNEL_TARGET="current" KERNEL_TEST_TARGET="current" BOOTDIR='u-boot-odroidc1' diff --git a/config/boards/onecloud.csc b/config/boards/onecloud.csc index 881be89a5d8f..9a35a7cd5d5c 100644 --- a/config/boards/onecloud.csc +++ b/config/boards/onecloud.csc @@ -2,7 +2,7 @@ BOARD_NAME="OneCloud" BOARDFAMILY="meson8b" BOARD_MAINTAINER="hzyitc" -KERNEL_TARGET="legacy,current" +KERNEL_TARGET="current" KERNEL_TEST_TARGET="current" BOOTCONFIG="none" BOOTSCRIPT="boot-onecloud.cmd:boot.cmd" diff --git a/config/kernel/linux-meson-legacy.config b/config/kernel/linux-meson-legacy.config deleted file mode 100644 index 028a28dc6373..000000000000 --- a/config/kernel/linux-meson-legacy.config +++ /dev/null @@ -1,1648 +0,0 @@ -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_WATCH_QUEUE=y -CONFIG_USELIB=y -CONFIG_AUDIT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_BPF_SYSCALL=y -CONFIG_BPF_JIT=y -CONFIG_IRQ_TIME_ACCOUNTING=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_BSD_PROCESS_ACCT_V3=y -CONFIG_TASKSTATS=y -CONFIG_TASK_DELAY_ACCT=y -CONFIG_TASK_XACCT=y -CONFIG_TASK_IO_ACCOUNTING=y -CONFIG_PSI=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_CGROUPS=y -CONFIG_CGROUP_FAVOR_DYNMODS=y -CONFIG_MEMCG=y -CONFIG_BLK_CGROUP=y -CONFIG_CGROUP_SCHED=y -CONFIG_CFS_BANDWIDTH=y -CONFIG_RT_GROUP_SCHED=y -CONFIG_CGROUP_PIDS=y -CONFIG_CGROUP_RDMA=y -CONFIG_CGROUP_FREEZER=y -CONFIG_CPUSETS=y -CONFIG_CGROUP_DEVICE=y -CONFIG_CGROUP_CPUACCT=y -CONFIG_CGROUP_PERF=y -CONFIG_CGROUP_BPF=y -CONFIG_CGROUP_MISC=y -CONFIG_CGROUP_DEBUG=y -CONFIG_NAMESPACES=y -CONFIG_USER_NS=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_EXPERT=y -CONFIG_PERF_EVENTS=y -CONFIG_KEXEC=y -CONFIG_ARCH_MESON=y -CONFIG_ARM_THUMBEE=y -CONFIG_PL310_ERRATA_588369=y -CONFIG_PL310_ERRATA_727915=y -CONFIG_PL310_ERRATA_753970=y -CONFIG_PL310_ERRATA_769419=y -# CONFIG_ARM_ERRATA_643719 is not set -CONFIG_ARM_ERRATA_814220=y -CONFIG_SMP=y -CONFIG_HAVE_ARM_ARCH_TIMER=y -CONFIG_MCPM=y -CONFIG_NR_CPUS=16 -CONFIG_ARM_PSCI=y -CONFIG_HIGHMEM=y -CONFIG_ARCH_FORCE_MAX_ORDER=11 -CONFIG_ARM_APPENDED_DTB=y -CONFIG_ARM_ATAG_DTB_COMPAT=y -CONFIG_EFI=y -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=m -CONFIG_CPU_FREQ_GOV_USERSPACE=m -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m -CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y -CONFIG_CPUFREQ_DT=y -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_MENU=y -CONFIG_CPU_IDLE_GOV_TEO=y -CONFIG_ARM_CPUIDLE=y -CONFIG_VFP=y -CONFIG_NEON=y -CONFIG_KERNEL_MODE_NEON=y -CONFIG_KPROBES=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_PARTITION_ADVANCED=y -CONFIG_CMDLINE_PARTITION=y -CONFIG_BINFMT_MISC=m -CONFIG_CMA=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_PACKET_DIAG=m -CONFIG_UNIX=y -CONFIG_UNIX_DIAG=m -CONFIG_TLS=m -CONFIG_TLS_DEVICE=y -CONFIG_TLS_TOE=y -CONFIG_XFRM_USER=m -CONFIG_XFRM_INTERFACE=m -CONFIG_XFRM_SUB_POLICY=y -CONFIG_XFRM_STATISTICS=y -CONFIG_NET_KEY=m -CONFIG_NET_KEY_MIGRATE=y -CONFIG_XDP_SOCKETS=y -CONFIG_XDP_SOCKETS_DIAG=m -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_FIB_TRIE_STATS=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE_DEMUX=m -CONFIG_NET_IPGRE=m -CONFIG_NET_IPGRE_BROADCAST=y -CONFIG_IP_MROUTE=y -CONFIG_IP_MROUTE_MULTIPLE_TABLES=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -CONFIG_NET_IPVTI=m -CONFIG_NET_FOU_IP_TUNNELS=y -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -CONFIG_INET_ESP_OFFLOAD=m -CONFIG_INET_ESPINTCP=y -CONFIG_INET_IPCOMP=m -CONFIG_INET_DIAG=m -CONFIG_INET_UDP_DIAG=m -CONFIG_INET_RAW_DIAG=m -CONFIG_INET_DIAG_DESTROY=y -CONFIG_TCP_CONG_ADVANCED=y -CONFIG_TCP_CONG_HSTCP=m -CONFIG_TCP_CONG_HYBLA=m -CONFIG_TCP_CONG_NV=m -CONFIG_TCP_CONG_SCALABLE=m -CONFIG_TCP_CONG_LP=m -CONFIG_TCP_CONG_VENO=m -CONFIG_TCP_CONG_YEAH=m -CONFIG_TCP_CONG_ILLINOIS=m -CONFIG_TCP_CONG_DCTCP=m -CONFIG_TCP_CONG_CDG=m -CONFIG_TCP_CONG_BBR=m -CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y -CONFIG_IPV6_OPTIMISTIC_DAD=y -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_ESP_OFFLOAD=m -CONFIG_INET6_ESPINTCP=y -CONFIG_INET6_IPCOMP=m -CONFIG_IPV6_MIP6=m -CONFIG_IPV6_VTI=m -CONFIG_IPV6_SIT=m -CONFIG_IPV6_SIT_6RD=y -CONFIG_IPV6_GRE=m -CONFIG_IPV6_SUBTREES=y -CONFIG_IPV6_MROUTE=y -CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y -CONFIG_IPV6_PIMSM_V2=y -CONFIG_IPV6_SEG6_LWTUNNEL=y -CONFIG_IPV6_SEG6_HMAC=y -CONFIG_IPV6_RPL_LWTUNNEL=y -CONFIG_IPV6_IOAM6_LWTUNNEL=y -CONFIG_MPTCP=y -CONFIG_NETWORK_SECMARK=y -CONFIG_NETFILTER=y -CONFIG_BRIDGE_NETFILTER=m -CONFIG_NETFILTER_NETLINK_HOOK=m -CONFIG_NF_CONNTRACK=m -CONFIG_NF_CONNTRACK_SECMARK=y -CONFIG_NF_CONNTRACK_ZONES=y -CONFIG_NF_CONNTRACK_PROCFS=y -CONFIG_NF_CONNTRACK_EVENTS=y -CONFIG_NF_CONNTRACK_TIMEOUT=y -CONFIG_NF_CONNTRACK_TIMESTAMP=y -CONFIG_NF_CONNTRACK_AMANDA=m -CONFIG_NF_CONNTRACK_FTP=m -CONFIG_NF_CONNTRACK_H323=m -CONFIG_NF_CONNTRACK_IRC=m -CONFIG_NF_CONNTRACK_NETBIOS_NS=m -CONFIG_NF_CONNTRACK_SNMP=m -CONFIG_NF_CONNTRACK_PPTP=m -CONFIG_NF_CONNTRACK_SANE=m -CONFIG_NF_CONNTRACK_SIP=m -CONFIG_NF_CONNTRACK_TFTP=m -CONFIG_NF_CT_NETLINK=m -CONFIG_NF_CT_NETLINK_TIMEOUT=m -CONFIG_NF_CT_NETLINK_HELPER=m -CONFIG_NETFILTER_NETLINK_GLUE_CT=y -CONFIG_NF_TABLES=m -CONFIG_NF_TABLES_INET=y -CONFIG_NF_TABLES_NETDEV=y -CONFIG_NFT_NUMGEN=m -CONFIG_NFT_CT=m -CONFIG_NFT_FLOW_OFFLOAD=m -CONFIG_NFT_CONNLIMIT=m -CONFIG_NFT_LOG=m -CONFIG_NFT_LIMIT=m -CONFIG_NFT_MASQ=m -CONFIG_NFT_REDIR=m -CONFIG_NFT_NAT=m -CONFIG_NFT_TUNNEL=m -CONFIG_NFT_QUEUE=m -CONFIG_NFT_QUOTA=m -CONFIG_NFT_REJECT=m -CONFIG_NFT_COMPAT=m -CONFIG_NFT_HASH=m -CONFIG_NFT_FIB_INET=m -CONFIG_NFT_XFRM=m -CONFIG_NFT_SOCKET=m -CONFIG_NFT_OSF=m -CONFIG_NFT_TPROXY=m -CONFIG_NFT_SYNPROXY=m -CONFIG_NFT_DUP_NETDEV=m -CONFIG_NFT_FWD_NETDEV=m -CONFIG_NFT_FIB_NETDEV=m -CONFIG_NFT_REJECT_NETDEV=m -CONFIG_NF_FLOW_TABLE_INET=m -CONFIG_NF_FLOW_TABLE=m -CONFIG_NF_FLOW_TABLE_PROCFS=y -CONFIG_NETFILTER_XT_SET=m -CONFIG_NETFILTER_XT_TARGET_AUDIT=m -CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m -CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -CONFIG_NETFILTER_XT_TARGET_CONNMARK=m -CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m -CONFIG_NETFILTER_XT_TARGET_DSCP=m -CONFIG_NETFILTER_XT_TARGET_HMARK=m -CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m -CONFIG_NETFILTER_XT_TARGET_LED=m -CONFIG_NETFILTER_XT_TARGET_LOG=m -CONFIG_NETFILTER_XT_TARGET_MARK=m -CONFIG_NETFILTER_XT_TARGET_NFLOG=m -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -CONFIG_NETFILTER_XT_TARGET_NOTRACK=m -CONFIG_NETFILTER_XT_TARGET_TEE=m -CONFIG_NETFILTER_XT_TARGET_TPROXY=m -CONFIG_NETFILTER_XT_TARGET_TRACE=m -CONFIG_NETFILTER_XT_TARGET_SECMARK=m -CONFIG_NETFILTER_XT_TARGET_TCPMSS=m -CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m -CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m -CONFIG_NETFILTER_XT_MATCH_BPF=m -CONFIG_NETFILTER_XT_MATCH_CGROUP=m -CONFIG_NETFILTER_XT_MATCH_CLUSTER=m -CONFIG_NETFILTER_XT_MATCH_COMMENT=m -CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m -CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m -CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m -CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -CONFIG_NETFILTER_XT_MATCH_CPU=m -CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m -CONFIG_NETFILTER_XT_MATCH_DSCP=m -CONFIG_NETFILTER_XT_MATCH_ESP=m -CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m -CONFIG_NETFILTER_XT_MATCH_HELPER=m -CONFIG_NETFILTER_XT_MATCH_IPCOMP=m -CONFIG_NETFILTER_XT_MATCH_IPRANGE=m -CONFIG_NETFILTER_XT_MATCH_IPVS=m -CONFIG_NETFILTER_XT_MATCH_LENGTH=m -CONFIG_NETFILTER_XT_MATCH_LIMIT=m -CONFIG_NETFILTER_XT_MATCH_MAC=m -CONFIG_NETFILTER_XT_MATCH_MARK=m -CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m -CONFIG_NETFILTER_XT_MATCH_NFACCT=m -CONFIG_NETFILTER_XT_MATCH_OSF=m -CONFIG_NETFILTER_XT_MATCH_OWNER=m -CONFIG_NETFILTER_XT_MATCH_POLICY=m -CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m -CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -CONFIG_NETFILTER_XT_MATCH_QUOTA=m -CONFIG_NETFILTER_XT_MATCH_RATEEST=m -CONFIG_NETFILTER_XT_MATCH_REALM=m -CONFIG_NETFILTER_XT_MATCH_RECENT=m -CONFIG_NETFILTER_XT_MATCH_SOCKET=m -CONFIG_NETFILTER_XT_MATCH_STATE=m -CONFIG_NETFILTER_XT_MATCH_STATISTIC=m -CONFIG_NETFILTER_XT_MATCH_STRING=m -CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -CONFIG_NETFILTER_XT_MATCH_TIME=m -CONFIG_NETFILTER_XT_MATCH_U32=m -CONFIG_IP_SET=m -CONFIG_IP_SET_BITMAP_IP=m -CONFIG_IP_SET_BITMAP_IPMAC=m -CONFIG_IP_SET_BITMAP_PORT=m -CONFIG_IP_SET_HASH_IP=m -CONFIG_IP_SET_HASH_IPMARK=m -CONFIG_IP_SET_HASH_IPPORT=m -CONFIG_IP_SET_HASH_IPPORTIP=m -CONFIG_IP_SET_HASH_IPPORTNET=m -CONFIG_IP_SET_HASH_IPMAC=m -CONFIG_IP_SET_HASH_MAC=m -CONFIG_IP_SET_HASH_NETPORTNET=m -CONFIG_IP_SET_HASH_NET=m -CONFIG_IP_SET_HASH_NETNET=m -CONFIG_IP_SET_HASH_NETPORT=m -CONFIG_IP_SET_HASH_NETIFACE=m -CONFIG_IP_SET_LIST_SET=m -CONFIG_IP_VS=m -CONFIG_IP_VS_IPV6=y -CONFIG_IP_VS_DEBUG=y -CONFIG_IP_VS_PROTO_TCP=y -CONFIG_IP_VS_PROTO_UDP=y -CONFIG_IP_VS_PROTO_ESP=y -CONFIG_IP_VS_PROTO_AH=y -CONFIG_IP_VS_PROTO_SCTP=y -CONFIG_IP_VS_RR=m -CONFIG_IP_VS_WRR=m -CONFIG_IP_VS_LC=m -CONFIG_IP_VS_WLC=m -CONFIG_IP_VS_FO=m -CONFIG_IP_VS_OVF=m -CONFIG_IP_VS_LBLC=m -CONFIG_IP_VS_LBLCR=m -CONFIG_IP_VS_DH=m -CONFIG_IP_VS_SH=m -CONFIG_IP_VS_MH=m -CONFIG_IP_VS_SED=m -CONFIG_IP_VS_NQ=m -CONFIG_IP_VS_TWOS=m -CONFIG_IP_VS_FTP=m -CONFIG_IP_VS_PE_SIP=m -CONFIG_NFT_DUP_IPV4=m -CONFIG_NFT_FIB_IPV4=m -CONFIG_NF_TABLES_ARP=y -CONFIG_NF_LOG_ARP=m -CONFIG_NF_LOG_IPV4=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_AH=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_RPFILTER=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_SYNPROXY=m -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_NETMAP=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_TTL=m -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_ARP_MANGLE=m -CONFIG_NFT_DUP_IPV6=m -CONFIG_NFT_FIB_IPV6=m -CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_AH=m -CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_MATCH_FRAG=m -CONFIG_IP6_NF_MATCH_OPTS=m -CONFIG_IP6_NF_MATCH_HL=m -CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_MATCH_MH=m -CONFIG_IP6_NF_MATCH_RPFILTER=m -CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_MATCH_SRH=m -CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_TARGET_REJECT=m -CONFIG_IP6_NF_TARGET_SYNPROXY=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_RAW=m -CONFIG_IP6_NF_NAT=m -CONFIG_IP6_NF_TARGET_MASQUERADE=m -CONFIG_IP6_NF_TARGET_NPT=m -CONFIG_NF_TABLES_BRIDGE=m -CONFIG_NFT_BRIDGE_META=m -CONFIG_NFT_BRIDGE_REJECT=m -CONFIG_NF_CONNTRACK_BRIDGE=m -CONFIG_BRIDGE_NF_EBTABLES=m -CONFIG_BRIDGE_EBT_BROUTE=m -CONFIG_BRIDGE_EBT_T_FILTER=m -CONFIG_BRIDGE_EBT_T_NAT=m -CONFIG_BRIDGE_EBT_802_3=m -CONFIG_BRIDGE_EBT_AMONG=m -CONFIG_BRIDGE_EBT_ARP=m -CONFIG_BRIDGE_EBT_IP=m -CONFIG_BRIDGE_EBT_IP6=m -CONFIG_BRIDGE_EBT_LIMIT=m -CONFIG_BRIDGE_EBT_MARK=m -CONFIG_BRIDGE_EBT_PKTTYPE=m -CONFIG_BRIDGE_EBT_STP=m -CONFIG_BRIDGE_EBT_VLAN=m -CONFIG_BRIDGE_EBT_ARPREPLY=m -CONFIG_BRIDGE_EBT_DNAT=m -CONFIG_BRIDGE_EBT_MARK_T=m -CONFIG_BRIDGE_EBT_REDIRECT=m -CONFIG_BRIDGE_EBT_SNAT=m -CONFIG_BRIDGE_EBT_LOG=m -CONFIG_BRIDGE_EBT_NFLOG=m -CONFIG_BPFILTER=y -CONFIG_IP_DCCP=m -CONFIG_RDS=m -CONFIG_RDS_TCP=m -CONFIG_TIPC=m -CONFIG_ATM=m -CONFIG_ATM_CLIP=m -CONFIG_ATM_LANE=m -CONFIG_ATM_MPOA=m -CONFIG_ATM_BR2684=m -CONFIG_ATM_BR2684_IPFILTER=y -CONFIG_L2TP=m -CONFIG_L2TP_DEBUGFS=m -CONFIG_L2TP_V3=y -CONFIG_L2TP_IP=m -CONFIG_L2TP_ETH=m -CONFIG_BRIDGE=m -CONFIG_BRIDGE_VLAN_FILTERING=y -CONFIG_BRIDGE_MRP=y -CONFIG_BRIDGE_CFM=y -CONFIG_VLAN_8021Q=m -CONFIG_VLAN_8021Q_GVRP=y -CONFIG_VLAN_8021Q_MVRP=y -CONFIG_LLC2=m -CONFIG_ATALK=m -CONFIG_DEV_APPLETALK=m -CONFIG_IPDDP=m -CONFIG_IPDDP_ENCAP=y -CONFIG_X25=m -CONFIG_LAPB=m -CONFIG_PHONET=m -CONFIG_6LOWPAN=m -CONFIG_6LOWPAN_DEBUGFS=y -CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m -CONFIG_6LOWPAN_GHC_UDP=m -CONFIG_6LOWPAN_GHC_ICMPV6=m -CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m -CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m -CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m -CONFIG_IEEE802154=m -CONFIG_IEEE802154_NL802154_EXPERIMENTAL=y -CONFIG_IEEE802154_6LOWPAN=m -CONFIG_MAC802154=m -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_HFSC=m -CONFIG_NET_SCH_PRIO=m -CONFIG_NET_SCH_MULTIQ=m -CONFIG_NET_SCH_RED=m -CONFIG_NET_SCH_SFB=m -CONFIG_NET_SCH_SFQ=m -CONFIG_NET_SCH_TEQL=m -CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_CBS=m -CONFIG_NET_SCH_ETF=m -CONFIG_NET_SCH_TAPRIO=m -CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_NETEM=m -CONFIG_NET_SCH_DRR=m -CONFIG_NET_SCH_MQPRIO=m -CONFIG_NET_SCH_SKBPRIO=m -CONFIG_NET_SCH_CHOKE=m -CONFIG_NET_SCH_QFQ=m -CONFIG_NET_SCH_CODEL=m -CONFIG_NET_SCH_FQ_CODEL=m -CONFIG_NET_SCH_CAKE=m -CONFIG_NET_SCH_FQ=m -CONFIG_NET_SCH_HHF=m -CONFIG_NET_SCH_PIE=m -CONFIG_NET_SCH_FQ_PIE=m -CONFIG_NET_SCH_INGRESS=m -CONFIG_NET_SCH_PLUG=m -CONFIG_NET_SCH_ETS=m -CONFIG_NET_SCH_DEFAULT=y -CONFIG_NET_CLS_BASIC=m -CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_U32=m -CONFIG_CLS_U32_PERF=y -CONFIG_CLS_U32_MARK=y -CONFIG_NET_CLS_FLOW=m -CONFIG_NET_CLS_CGROUP=m -CONFIG_NET_CLS_BPF=m -CONFIG_NET_CLS_FLOWER=m -CONFIG_NET_CLS_MATCHALL=m -CONFIG_NET_EMATCH=y -CONFIG_NET_EMATCH_CMP=m -CONFIG_NET_EMATCH_NBYTE=m -CONFIG_NET_EMATCH_U32=m -CONFIG_NET_EMATCH_META=m -CONFIG_NET_EMATCH_TEXT=m -CONFIG_NET_EMATCH_IPSET=m -CONFIG_NET_EMATCH_IPT=m -CONFIG_NET_CLS_ACT=y -CONFIG_NET_ACT_POLICE=m -CONFIG_NET_ACT_GACT=m -CONFIG_GACT_PROB=y -CONFIG_NET_ACT_MIRRED=m -CONFIG_NET_ACT_SAMPLE=m -CONFIG_NET_ACT_IPT=m -CONFIG_NET_ACT_NAT=m -CONFIG_NET_ACT_PEDIT=m -CONFIG_NET_ACT_SIMP=m -CONFIG_NET_ACT_SKBEDIT=m -CONFIG_NET_ACT_CSUM=m -CONFIG_NET_ACT_MPLS=m -CONFIG_NET_ACT_VLAN=m -CONFIG_NET_ACT_BPF=m -CONFIG_NET_ACT_CONNMARK=m -CONFIG_NET_ACT_CTINFO=m -CONFIG_NET_ACT_SKBMOD=m -CONFIG_NET_ACT_IFE=m -CONFIG_NET_ACT_TUNNEL_KEY=m -CONFIG_NET_ACT_CT=m -CONFIG_NET_ACT_GATE=m -CONFIG_NET_IFE_SKBMARK=m -CONFIG_NET_IFE_SKBPRIO=m -CONFIG_NET_IFE_SKBTCINDEX=m -CONFIG_NET_TC_SKB_EXT=y -CONFIG_DCB=y -CONFIG_BATMAN_ADV=m -CONFIG_BATMAN_ADV_NC=y -CONFIG_OPENVSWITCH=m -CONFIG_VSOCKETS=m -CONFIG_VIRTIO_VSOCKETS=m -CONFIG_NETLINK_DIAG=m -CONFIG_MPLS_ROUTING=m -CONFIG_MPLS_IPTUNNEL=m -CONFIG_HSR=m -CONFIG_NET_SWITCHDEV=y -CONFIG_QRTR=m -CONFIG_QRTR_SMD=m -CONFIG_QRTR_TUN=m -CONFIG_NET_NCSI=y -CONFIG_NCSI_OEM_CMD_GET_MAC=y -CONFIG_NCSI_OEM_CMD_KEEP_PHY=y -CONFIG_CGROUP_NET_PRIO=y -CONFIG_BPF_STREAM_PARSER=y -CONFIG_BT=m -CONFIG_BT_RFCOMM=m -CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=m -CONFIG_BT_BNEP_MC_FILTER=y -CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_HIDP=m -CONFIG_BT_6LOWPAN=m -CONFIG_BT_LEDS=y -CONFIG_BT_MSFTEXT=y -CONFIG_BT_AOSPEXT=y -CONFIG_BT_FEATURE_DEBUG=y -CONFIG_BT_HCIBTUSB=m -CONFIG_BT_HCIBTUSB_AUTOSUSPEND=y -CONFIG_BT_HCIBTUSB_MTK=y -CONFIG_BT_HCIBTSDIO=m -CONFIG_BT_HCIUART=m -CONFIG_BT_HCIUART_NOKIA=m -CONFIG_BT_HCIUART_BCSP=y -CONFIG_BT_HCIUART_ATH3K=y -CONFIG_BT_HCIUART_LL=y -CONFIG_BT_HCIUART_INTEL=y -CONFIG_BT_HCIUART_BCM=y -CONFIG_BT_HCIUART_RTL=y -CONFIG_BT_HCIUART_QCA=y -CONFIG_BT_HCIUART_AG6XX=y -CONFIG_BT_HCIUART_MRVL=y -CONFIG_BT_HCIBCM203X=m -CONFIG_BT_HCIBPA10X=m -CONFIG_BT_HCIBFUSB=m -CONFIG_BT_HCIVHCI=m -CONFIG_BT_MRVL=m -CONFIG_BT_MRVL_SDIO=m -CONFIG_BT_ATH3K=m -CONFIG_BT_MTKSDIO=m -CONFIG_BT_MTKUART=m -CONFIG_BT_VIRTIO=m -CONFIG_AF_RXRPC_IPV6=y -CONFIG_AF_RXRPC_INJECT_LOSS=y -CONFIG_AF_RXRPC_DEBUG=y -CONFIG_RXKAD=y -CONFIG_CFG80211=m -CONFIG_CFG80211_DEBUGFS=y -CONFIG_CFG80211_WEXT=y -CONFIG_MAC80211=m -CONFIG_MAC80211_MESH=y -CONFIG_MAC80211_DEBUGFS=y -CONFIG_RFKILL=m -CONFIG_RFKILL_INPUT=y -CONFIG_RFKILL_GPIO=m -CONFIG_PCI=y -# CONFIG_PCIEASPM is not set -CONFIG_PCI_MSI=y -# CONFIG_VGA_ARB is not set -CONFIG_PCI_HOST_GENERIC=y -# CONFIG_PCI_MESON is not set -CONFIG_UEVENT_HELPER=y -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -CONFIG_FW_LOADER_USER_HELPER=y -CONFIG_FW_LOADER_COMPRESS=y -CONFIG_VEXPRESS_CONFIG=y -CONFIG_ARM_SCMI_PROTOCOL=m -CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE=y -CONFIG_ARM_SCMI_POWER_CONTROL=m -CONFIG_EFI_BOOTLOADER_CONTROL=m -CONFIG_EFI_CAPSULE_LOADER=m -CONFIG_OF_OVERLAY=y -CONFIG_ZRAM=m -CONFIG_ZRAM_WRITEBACK=y -CONFIG_ZRAM_MEMORY_TRACKING=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_DRBD=m -CONFIG_DRBD_FAULT_INJECTION=y -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=65536 -CONFIG_ATA_OVER_ETH=m -CONFIG_BLK_DEV_RBD=m -CONFIG_BLK_DEV_UBLK=m -CONFIG_AD525X_DPOT=m -CONFIG_AD525X_DPOT_I2C=m -CONFIG_AD525X_DPOT_SPI=m -CONFIG_DUMMY_IRQ=m -CONFIG_SRAM=y -CONFIG_MISC_RTSX_USB=m -CONFIG_BLK_DEV_SD=y -CONFIG_BLK_DEV_SR=y -CONFIG_SCSI_SPI_ATTRS=m -CONFIG_SCSI_FC_ATTRS=m -CONFIG_SCSI_SAS_LIBSAS=m -CONFIG_SCSI_SAS_ATA=y -CONFIG_SCSI_SRP_ATTRS=m -CONFIG_ISCSI_TCP=m -CONFIG_ISCSI_BOOT_SYSFS=m -CONFIG_ATA=y -CONFIG_SATA_AHCI=y -CONFIG_SATA_AHCI_PLATFORM=y -CONFIG_SATA_MV=y -CONFIG_MD=y -CONFIG_MD_LINEAR=m -CONFIG_MD_MULTIPATH=m -CONFIG_MD_FAULTY=m -CONFIG_BCACHE=m -CONFIG_BCACHE_ASYNC_REGISTRATION=y -CONFIG_BLK_DEV_DM=m -CONFIG_DM_DEBUG=y -CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING=y -CONFIG_DM_UNSTRIPED=m -CONFIG_DM_CRYPT=m -CONFIG_DM_SNAPSHOT=m -CONFIG_DM_THIN_PROVISIONING=m -CONFIG_DM_CACHE=m -CONFIG_DM_WRITECACHE=m -CONFIG_DM_ERA=m -CONFIG_DM_CLONE=m -CONFIG_DM_MIRROR=m -CONFIG_DM_LOG_USERSPACE=m -CONFIG_DM_RAID=m -CONFIG_DM_ZERO=m -CONFIG_DM_MULTIPATH=m -CONFIG_DM_MULTIPATH_QL=m -CONFIG_DM_MULTIPATH_ST=m -CONFIG_DM_MULTIPATH_HST=m -CONFIG_DM_MULTIPATH_IOA=m -CONFIG_DM_DELAY=m -CONFIG_DM_DUST=m -CONFIG_DM_UEVENT=y -CONFIG_DM_FLAKEY=m -CONFIG_DM_VERITY=m -CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y -CONFIG_DM_VERITY_FEC=y -CONFIG_DM_SWITCH=m -CONFIG_DM_LOG_WRITES=m -CONFIG_DM_INTEGRITY=m -CONFIG_NETDEVICES=y -CONFIG_BONDING=m -CONFIG_DUMMY=m -CONFIG_WIREGUARD=m -CONFIG_EQUALIZER=m -CONFIG_IFB=m -CONFIG_NET_TEAM=m -CONFIG_NET_TEAM_MODE_BROADCAST=m -CONFIG_NET_TEAM_MODE_ROUNDROBIN=m -CONFIG_NET_TEAM_MODE_RANDOM=m -CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m -CONFIG_NET_TEAM_MODE_LOADBALANCE=m -CONFIG_MACVLAN=m -CONFIG_MACVTAP=m -CONFIG_IPVLAN=m -CONFIG_IPVTAP=m -CONFIG_VXLAN=m -CONFIG_GENEVE=m -CONFIG_BAREUDP=m -CONFIG_GTP=m -CONFIG_AMT=m -CONFIG_MACSEC=m -CONFIG_NETCONSOLE=m -CONFIG_NETCONSOLE_DYNAMIC=y -CONFIG_TUN=m -CONFIG_TUN_VNET_CROSS_LE=y -CONFIG_VETH=m -CONFIG_VIRTIO_NET=m -CONFIG_NLMON=m -CONFIG_NET_VRF=m -CONFIG_VSOCKMON=m -# CONFIG_ATM_DRIVERS is not set -# CONFIG_NET_VENDOR_ALACRITECH is not set -# CONFIG_NET_VENDOR_AMAZON is not set -# CONFIG_NET_VENDOR_AQUANTIA is not set -# CONFIG_NET_VENDOR_ARC is not set -# CONFIG_NET_VENDOR_ASIX is not set -# CONFIG_NET_VENDOR_BROADCOM is not set -# CONFIG_NET_VENDOR_CADENCE is not set -# CONFIG_NET_VENDOR_CAVIUM is not set -# CONFIG_NET_VENDOR_CIRRUS is not set -# CONFIG_NET_VENDOR_CORTINA is not set -# CONFIG_NET_VENDOR_DAVICOM is not set -# CONFIG_NET_VENDOR_ENGLEDER is not set -# CONFIG_NET_VENDOR_EZCHIP is not set -# CONFIG_NET_VENDOR_FARADAY is not set -# CONFIG_NET_VENDOR_FUNGIBLE is not set -# CONFIG_NET_VENDOR_GOOGLE is not set -# CONFIG_NET_VENDOR_HISILICON is not set -# CONFIG_NET_VENDOR_HUAWEI is not set -# CONFIG_NET_VENDOR_INTEL is not set -# CONFIG_NET_VENDOR_ADI is not set -# CONFIG_NET_VENDOR_LITEX is not set -# CONFIG_NET_VENDOR_MARVELL is not set -# CONFIG_NET_VENDOR_MELLANOX is not set -# CONFIG_NET_VENDOR_MICREL is not set -# CONFIG_NET_VENDOR_MICROCHIP is not set -# CONFIG_NET_VENDOR_MICROSEMI is not set -# CONFIG_NET_VENDOR_MICROSOFT is not set -# CONFIG_NET_VENDOR_NI is not set -# CONFIG_NET_VENDOR_NATSEMI is not set -# CONFIG_NET_VENDOR_NETRONOME is not set -# CONFIG_NET_VENDOR_PENSANDO is not set -# CONFIG_NET_VENDOR_QUALCOMM is not set -# CONFIG_NET_VENDOR_RENESAS is not set -# CONFIG_NET_VENDOR_ROCKER is not set -# CONFIG_NET_VENDOR_SAMSUNG is not set -# CONFIG_NET_VENDOR_SEEQ is not set -# CONFIG_NET_VENDOR_SOLARFLARE is not set -# CONFIG_NET_VENDOR_SMSC is not set -# CONFIG_NET_VENDOR_SOCIONEXT is not set -CONFIG_STMMAC_ETH=y -CONFIG_DWMAC_DWC_QOS_ETH=y -# CONFIG_NET_VENDOR_SYNOPSYS is not set -# CONFIG_NET_VENDOR_VERTEXCOM is not set -# CONFIG_NET_VENDOR_VIA is not set -# CONFIG_NET_VENDOR_WANGXUN is not set -# CONFIG_NET_VENDOR_WIZNET is not set -# CONFIG_NET_VENDOR_XILINX is not set -CONFIG_REALTEK_PHY=y -# CONFIG_MDIO_BUS_MUX_MESON_G12A is not set -CONFIG_PPP=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_MPPE=m -CONFIG_PPP_MULTILINK=y -CONFIG_PPPOATM=m -CONFIG_PPPOE=m -CONFIG_PPTP=m -CONFIG_PPPOL2TP=m -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_SLIP=m -CONFIG_SLIP_COMPRESSED=y -CONFIG_SLIP_SMART=y -CONFIG_SLIP_MODE_SLIP6=y -CONFIG_USB_NET_DRIVERS=m -CONFIG_USB_CATC=m -CONFIG_USB_KAWETH=m -CONFIG_USB_PEGASUS=m -CONFIG_USB_RTL8150=m -CONFIG_USB_RTL8152=m -CONFIG_USB_LAN78XX=m -CONFIG_USB_NET_CDC_EEM=m -CONFIG_USB_NET_HUAWEI_CDC_NCM=m -CONFIG_USB_NET_CDC_MBIM=m -CONFIG_USB_NET_DM9601=m -CONFIG_USB_NET_SR9700=m -CONFIG_USB_NET_SR9800=m -CONFIG_USB_NET_SMSC75XX=m -CONFIG_USB_NET_SMSC95XX=m -CONFIG_USB_NET_GL620A=m -CONFIG_USB_NET_PLUSB=m -CONFIG_USB_NET_MCS7830=m -CONFIG_USB_ALI_M5632=y -CONFIG_USB_AN2720=y -CONFIG_USB_EPSON2888=y -CONFIG_USB_KC2190=y -CONFIG_USB_NET_CX82310_ETH=m -CONFIG_USB_NET_KALMIA=m -CONFIG_USB_NET_QMI_WWAN=m -CONFIG_USB_HSO=m -CONFIG_USB_NET_INT51X1=m -CONFIG_USB_CDC_PHONET=m -CONFIG_USB_IPHETH=m -CONFIG_USB_SIERRA_NET=m -CONFIG_USB_VL600=m -CONFIG_USB_NET_CH9200=m -CONFIG_USB_NET_AQC111=m -CONFIG_ATH9K_HTC=m -CONFIG_CARL9170=m -CONFIG_ATH6KL=m -CONFIG_ATH6KL_SDIO=m -CONFIG_ATH6KL_USB=m -CONFIG_AR5523=m -CONFIG_ATH10K=m -CONFIG_ATH10K_SDIO=m -CONFIG_ATH10K_USB=m -CONFIG_AT76C50X_USB=m -CONFIG_B43=m -CONFIG_B43_SDIO=y -CONFIG_BRCMFMAC=m -CONFIG_BRCMFMAC_USB=y -CONFIG_P54_COMMON=m -CONFIG_P54_USB=m -CONFIG_P54_SPI=m -CONFIG_LIBERTAS=m -CONFIG_LIBERTAS_USB=m -CONFIG_LIBERTAS_SDIO=m -CONFIG_LIBERTAS_SPI=m -CONFIG_LIBERTAS_MESH=y -CONFIG_LIBERTAS_THINFIRM=m -CONFIG_LIBERTAS_THINFIRM_USB=m -CONFIG_MWIFIEX=m -CONFIG_MWIFIEX_SDIO=m -CONFIG_MWIFIEX_USB=m -CONFIG_MT7601U=m -CONFIG_MT76x0U=m -CONFIG_MT76x2U=m -CONFIG_MT7663U=m -CONFIG_MT7663S=m -CONFIG_MT7915E=m -CONFIG_MT7921S=m -CONFIG_MT7921U=m -CONFIG_WILC1000_SDIO=m -CONFIG_WILC1000_SPI=m -CONFIG_PLFXLC=m -CONFIG_RT2X00=m -CONFIG_RT2500USB=m -CONFIG_RT73USB=m -CONFIG_RT2800USB=m -CONFIG_RT2800USB_RT3573=y -CONFIG_RT2800USB_RT53XX=y -CONFIG_RT2800USB_RT55XX=y -CONFIG_RT2800USB_UNKNOWN=y -CONFIG_RTL8187=m -CONFIG_RTL8192CU=m -# CONFIG_RTLWIFI_DEBUG is not set -CONFIG_RTL8XXXU=m -CONFIG_RTL8XXXU_UNTESTED=y -CONFIG_RTW88=m -CONFIG_RTW89=m -CONFIG_RSI_91X=m -# CONFIG_RSI_DEBUGFS is not set -CONFIG_WFX=m -CONFIG_CW1200=m -CONFIG_CW1200_WLAN_SDIO=m -CONFIG_CW1200_WLAN_SPI=m -CONFIG_WL1251=m -CONFIG_WL1251_SPI=m -CONFIG_WL1251_SDIO=m -CONFIG_WL12XX=m -CONFIG_WL18XX=m -CONFIG_WLCORE_SPI=m -CONFIG_WLCORE_SDIO=m -CONFIG_RTL8723DU=m -CONFIG_RTL8723DS=m -CONFIG_RTL8822BU=m -CONFIG_RTL8821CU=m -CONFIG_88XXAU=m -CONFIG_RTL8192EU=m -CONFIG_RTL8189FS=m -CONFIG_RTL8189ES=m -CONFIG_USB_ZD1201=m -CONFIG_ZD1211RW=m -CONFIG_USB_NET_RNDIS_WLAN=m -CONFIG_VIRT_WIFI=m -CONFIG_NETDEVSIM=m -CONFIG_NET_FAILOVER=y -CONFIG_INPUT_FF_MEMLESS=m -CONFIG_INPUT_MOUSEDEV=m -CONFIG_INPUT_JOYDEV=m -CONFIG_INPUT_EVDEV=m -CONFIG_KEYBOARD_GPIO=y -CONFIG_KEYBOARD_GPIO_POLLED=y -# CONFIG_MOUSE_PS2 is not set -CONFIG_MOUSE_APPLETOUCH=m -CONFIG_MOUSE_BCM5974=m -CONFIG_MOUSE_SYNAPTICS_USB=m -CONFIG_SERIAL_MESON=y -CONFIG_SERIAL_MESON_CONSOLE=y -CONFIG_SERIAL_DEV_BUS=y -CONFIG_TTY_PRINTK=y -CONFIG_VIRTIO_CONSOLE=y -CONFIG_HW_RANDOM=y -# CONFIG_HW_RANDOM_ARM_SMCCC_TRNG is not set -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_ARB_GPIO_CHALLENGE=m -CONFIG_I2C_MUX_GPIO=m -CONFIG_I2C_MUX_PINCTRL=m -CONFIG_I2C_MUX_REG=m -CONFIG_I2C_DEMUX_PINCTRL=m -CONFIG_I2C_GPIO=m -CONFIG_I2C_MESON=y -CONFIG_I2C_SLAVE=y -CONFIG_I2C_SLAVE_EEPROM=y -CONFIG_SPI=y -CONFIG_SPI_MEM=y -CONFIG_SPI_GPIO=m -CONFIG_SPI_MESON_SPICC=y -CONFIG_SPI_MESON_SPIFC=y -CONFIG_SPI_SPIDEV=y -CONFIG_PPS=y -# CONFIG_PTP_1588_CLOCK is not set -CONFIG_PINCTRL_SINGLE=y -CONFIG_GPIO_SYSFS=y -CONFIG_GPIO_GENERIC_PLATFORM=y -CONFIG_GPIO_SYSCON=y -CONFIG_POWER_RESET=y -CONFIG_POWER_RESET_GPIO=y -CONFIG_POWER_RESET_GPIO_RESTART=y -CONFIG_POWER_RESET_REGULATOR=y -CONFIG_POWER_RESET_RESTART=y -CONFIG_POWER_RESET_VERSATILE=y -CONFIG_POWER_RESET_VEXPRESS=y -CONFIG_POWER_RESET_SYSCON=y -CONFIG_POWER_RESET_SYSCON_POWEROFF=y -CONFIG_SYSCON_REBOOT_MODE=y -# CONFIG_POWER_SUPPLY_HWMON is not set -CONFIG_SENSORS_ARM_SCMI=m -CONFIG_SENSORS_IIO_HWMON=y -CONFIG_SENSORS_PWM_FAN=m -CONFIG_THERMAL=y -CONFIG_CPU_THERMAL=y -CONFIG_DEVFREQ_THERMAL=y -CONFIG_GENERIC_ADC_THERMAL=m -CONFIG_WATCHDOG=y -CONFIG_WATCHDOG_SYSFS=y -CONFIG_MESON_WATCHDOG=y -# CONFIG_MFD_VEXPRESS_SYSREG is not set -CONFIG_REGULATOR=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_REGULATOR_GPIO=y -CONFIG_REGULATOR_PWM=y -CONFIG_RC_CORE=m -CONFIG_LIRC=y -CONFIG_RC_DECODERS=y -CONFIG_IR_IMON_DECODER=m -CONFIG_IR_JVC_DECODER=m -CONFIG_IR_MCE_KBD_DECODER=m -CONFIG_IR_NEC_DECODER=m -CONFIG_IR_RC5_DECODER=m -CONFIG_IR_RC6_DECODER=m -CONFIG_IR_RCMM_DECODER=m -CONFIG_IR_SANYO_DECODER=m -CONFIG_IR_SHARP_DECODER=m -CONFIG_IR_SONY_DECODER=m -CONFIG_IR_XMP_DECODER=m -CONFIG_RC_DEVICES=y -CONFIG_IR_GPIO_CIR=m -CONFIG_IR_GPIO_TX=m -CONFIG_IR_IGORPLUGUSB=m -CONFIG_IR_IGUANA=m -CONFIG_IR_MCEUSB=m -CONFIG_IR_MESON=m -CONFIG_IR_MESON_TX=m -CONFIG_IR_TTUSBIR=m -CONFIG_RC_ATI_REMOTE=m -CONFIG_CEC_MESON_AO=y -CONFIG_MEDIA_SUPPORT=m -CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -CONFIG_MEDIA_USB_SUPPORT=y -CONFIG_USB_GSPCA=m -CONFIG_USB_GSPCA_BENQ=m -CONFIG_USB_GSPCA_CONEX=m -CONFIG_USB_GSPCA_CPIA1=m -CONFIG_USB_GSPCA_DTCS033=m -CONFIG_USB_GSPCA_ETOMS=m -CONFIG_USB_GSPCA_FINEPIX=m -CONFIG_USB_GSPCA_JEILINJ=m -CONFIG_USB_GSPCA_JL2005BCD=m -CONFIG_USB_GSPCA_KINECT=m -CONFIG_USB_GSPCA_KONICA=m -CONFIG_USB_GSPCA_MARS=m -CONFIG_USB_GSPCA_MR97310A=m -CONFIG_USB_GSPCA_NW80X=m -CONFIG_USB_GSPCA_OV519=m -CONFIG_USB_GSPCA_OV534=m -CONFIG_USB_GSPCA_OV534_9=m -CONFIG_USB_GSPCA_PAC207=m -CONFIG_USB_GSPCA_PAC7302=m -CONFIG_USB_GSPCA_PAC7311=m -CONFIG_USB_GSPCA_SE401=m -CONFIG_USB_GSPCA_SN9C2028=m -CONFIG_USB_GSPCA_SN9C20X=m -CONFIG_USB_GSPCA_SONIXB=m -CONFIG_USB_GSPCA_SONIXJ=m -CONFIG_USB_GSPCA_SPCA1528=m -CONFIG_USB_GSPCA_SPCA500=m -CONFIG_USB_GSPCA_SPCA501=m -CONFIG_USB_GSPCA_SPCA505=m -CONFIG_USB_GSPCA_SPCA506=m -CONFIG_USB_GSPCA_SPCA508=m -CONFIG_USB_GSPCA_SPCA561=m -CONFIG_USB_GSPCA_SQ905=m -CONFIG_USB_GSPCA_SQ905C=m -CONFIG_USB_GSPCA_SQ930X=m -CONFIG_USB_GSPCA_STK014=m -CONFIG_USB_GSPCA_STK1135=m -CONFIG_USB_GSPCA_STV0680=m -CONFIG_USB_GSPCA_SUNPLUS=m -CONFIG_USB_GSPCA_T613=m -CONFIG_USB_GSPCA_TOPRO=m -CONFIG_USB_GSPCA_TOUPTEK=m -CONFIG_USB_GSPCA_TV8532=m -CONFIG_USB_GSPCA_VC032X=m -CONFIG_USB_GSPCA_VICAM=m -CONFIG_USB_GSPCA_XIRLINK_CIT=m -CONFIG_USB_GSPCA_ZC3XX=m -CONFIG_USB_GL860=m -CONFIG_USB_M5602=m -CONFIG_USB_STV06XX=m -CONFIG_USB_PWC=m -CONFIG_USB_S2255=m -CONFIG_VIDEO_USBTV=m -CONFIG_USB_VIDEO_CLASS=m -CONFIG_VIDEO_GO7007=m -CONFIG_VIDEO_GO7007_USB=m -CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m -CONFIG_VIDEO_HDPVR=m -CONFIG_VIDEO_PVRUSB2=m -CONFIG_VIDEO_STK1160=m -CONFIG_VIDEO_AU0828=m -CONFIG_VIDEO_AU0828_RC=y -CONFIG_VIDEO_CX231XX=m -CONFIG_VIDEO_CX231XX_ALSA=m -CONFIG_VIDEO_CX231XX_DVB=m -CONFIG_DVB_AS102=m -CONFIG_DVB_B2C2_FLEXCOP_USB=m -CONFIG_DVB_USB_V2=m -CONFIG_DVB_USB_AF9015=m -CONFIG_DVB_USB_AF9035=m -CONFIG_DVB_USB_ANYSEE=m -CONFIG_DVB_USB_AU6610=m -CONFIG_DVB_USB_AZ6007=m -CONFIG_DVB_USB_CE6230=m -CONFIG_DVB_USB_DVBSKY=m -CONFIG_DVB_USB_EC168=m -CONFIG_DVB_USB_GL861=m -CONFIG_DVB_USB_LME2510=m -CONFIG_DVB_USB_MXL111SF=m -CONFIG_DVB_USB_RTL28XXU=m -CONFIG_DVB_USB_ZD1301=m -CONFIG_DVB_USB=m -CONFIG_DVB_USB_A800=m -CONFIG_DVB_USB_AF9005=m -CONFIG_DVB_USB_AF9005_REMOTE=m -CONFIG_DVB_USB_AZ6027=m -CONFIG_DVB_USB_CINERGY_T2=m -CONFIG_DVB_USB_CXUSB=m -CONFIG_DVB_USB_CXUSB_ANALOG=y -CONFIG_DVB_USB_DIB0700=m -CONFIG_DVB_USB_DIBUSB_MB=m -CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y -CONFIG_DVB_USB_DIBUSB_MC=m -CONFIG_DVB_USB_DIGITV=m -CONFIG_DVB_USB_DTT200U=m -CONFIG_DVB_USB_DTV5100=m -CONFIG_DVB_USB_DW2102=m -CONFIG_DVB_USB_GP8PSK=m -CONFIG_DVB_USB_M920X=m -CONFIG_DVB_USB_NOVA_T_USB2=m -CONFIG_DVB_USB_OPERA1=m -CONFIG_DVB_USB_PCTV452E=m -CONFIG_DVB_USB_TECHNISAT_USB2=m -CONFIG_DVB_USB_TTUSB2=m -CONFIG_DVB_USB_UMT_010=m -CONFIG_DVB_USB_VP702X=m -CONFIG_DVB_USB_VP7045=m -CONFIG_SMS_USB_DRV=m -CONFIG_DVB_TTUSB_BUDGET=m -CONFIG_DVB_TTUSB_DEC=m -CONFIG_VIDEO_EM28XX=m -CONFIG_VIDEO_EM28XX_V4L2=m -CONFIG_VIDEO_EM28XX_ALSA=m -CONFIG_VIDEO_EM28XX_DVB=m -CONFIG_USB_AIRSPY=m -CONFIG_USB_HACKRF=m -CONFIG_USB_MSI2500=m -CONFIG_RADIO_SHARK=m -CONFIG_RADIO_SHARK2=m -CONFIG_RADIO_SI4713=m -CONFIG_USB_DSBR=m -CONFIG_USB_KEENE=m -CONFIG_USB_MA901=m -CONFIG_USB_MR800=m -CONFIG_USB_RAREMONO=m -CONFIG_RADIO_SI470X=m -CONFIG_USB_SI470X=m -CONFIG_USB_SI4713=m -CONFIG_V4L_PLATFORM_DRIVERS=y -CONFIG_SDR_PLATFORM_DRIVERS=y -CONFIG_DVB_PLATFORM_DRIVERS=y -CONFIG_V4L_MEM2MEM_DRIVERS=y -CONFIG_VIDEO_MEM2MEM_DEINTERLACE=m -CONFIG_VIDEO_MUX=m -CONFIG_VIDEO_MESON_GE2D=m -CONFIG_V4L_TEST_DRIVERS=y -CONFIG_VIDEO_VIM2M=m -CONFIG_VIDEO_VICODEC=m -CONFIG_VIDEO_VIMC=m -CONFIG_VIDEO_VIVID=m -CONFIG_VIDEO_VIVID_CEC=y -CONFIG_DVB_MB86A16=m -CONFIG_DRM=y -CONFIG_DRM_MALI_DISPLAY=y -# CONFIG_DRM_DW_HDMI_I2S_AUDIO is not set -CONFIG_DRM_MESON=y -CONFIG_DRM_LIMA=y -CONFIG_FB=y -CONFIG_FB_SIMPLE=y -CONFIG_FB_MODE_HELPERS=y -CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y -CONFIG_SOUND=m -CONFIG_SND=m -CONFIG_SND_DYNAMIC_MINORS=y -# CONFIG_SND_PCI is not set -# CONFIG_SND_SPI is not set -CONFIG_SND_USB_AUDIO=m -CONFIG_SND_USB_UA101=m -CONFIG_SND_USB_CAIAQ=m -CONFIG_SND_USB_CAIAQ_INPUT=y -CONFIG_SND_USB_6FIRE=m -CONFIG_SND_USB_HIFACE=m -CONFIG_SND_BCD2000=m -CONFIG_SND_USB_POD=m -CONFIG_SND_USB_PODHD=m -CONFIG_SND_USB_TONEPORT=m -CONFIG_SND_USB_VARIAX=m -CONFIG_SND_SOC=m -CONFIG_SND_MESON_AIU=m -# CONFIG_SND_SOC_MESON_T9015 is not set -CONFIG_SND_SIMPLE_CARD=m -CONFIG_SND_AUDIO_GRAPH_CARD=m -CONFIG_USB_LED_TRIG=y -CONFIG_USB_ULPI_BUS=y -CONFIG_USB_CONN_GPIO=y -CONFIG_USB=y -# CONFIG_USB_PCI is not set -CONFIG_USB_OTG=y -CONFIG_USB_LEDS_TRIGGER_USBPORT=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_ROOT_HUB_TT=y -CONFIG_USB_EHCI_HCD_PLATFORM=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_OHCI_HCD_PLATFORM=y -CONFIG_USB_PRINTER=m -CONFIG_USB_TMC=m -CONFIG_USB_STORAGE=y -CONFIG_USB_STORAGE_REALTEK=m -CONFIG_USB_STORAGE_DATAFAB=m -CONFIG_USB_STORAGE_FREECOM=m -CONFIG_USB_STORAGE_ISD200=m -CONFIG_USB_STORAGE_USBAT=m -CONFIG_USB_STORAGE_SDDR09=m -CONFIG_USB_STORAGE_SDDR55=m -CONFIG_USB_STORAGE_JUMPSHOT=m -CONFIG_USB_STORAGE_ALAUDA=m -CONFIG_USB_STORAGE_ONETOUCH=m -CONFIG_USB_STORAGE_KARMA=m -CONFIG_USB_STORAGE_CYPRESS_ATACB=m -CONFIG_USB_STORAGE_ENE_UB6250=m -CONFIG_USB_UAS=m -CONFIG_USB_MDC800=m -CONFIG_USB_MICROTEK=m -CONFIG_USBIP_CORE=m -CONFIG_USBIP_VHCI_HCD=m -CONFIG_USBIP_HOST=m -CONFIG_USBIP_VUDC=m -CONFIG_USB_DWC2=y -CONFIG_USB_SERIAL=m -CONFIG_USB_SERIAL_GENERIC=y -CONFIG_USB_SERIAL_SIMPLE=m -CONFIG_USB_SERIAL_AIRCABLE=m -CONFIG_USB_SERIAL_ARK3116=m -CONFIG_USB_SERIAL_BELKIN=m -CONFIG_USB_SERIAL_CH341=m -CONFIG_USB_SERIAL_WHITEHEAT=m -CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m -CONFIG_USB_SERIAL_CP210X=m -CONFIG_USB_SERIAL_CYPRESS_M8=m -CONFIG_USB_SERIAL_EMPEG=m -CONFIG_USB_SERIAL_FTDI_SIO=m -CONFIG_USB_SERIAL_VISOR=m -CONFIG_USB_SERIAL_IPAQ=m -CONFIG_USB_SERIAL_IR=m -CONFIG_USB_SERIAL_EDGEPORT=m -CONFIG_USB_SERIAL_EDGEPORT_TI=m -CONFIG_USB_SERIAL_F81232=m -CONFIG_USB_SERIAL_F8153X=m -CONFIG_USB_SERIAL_GARMIN=m -CONFIG_USB_SERIAL_IPW=m -CONFIG_USB_SERIAL_IUU=m -CONFIG_USB_SERIAL_KEYSPAN_PDA=m -CONFIG_USB_SERIAL_KEYSPAN=m -CONFIG_USB_SERIAL_KLSI=m -CONFIG_USB_SERIAL_KOBIL_SCT=m -CONFIG_USB_SERIAL_MCT_U232=m -CONFIG_USB_SERIAL_METRO=m -CONFIG_USB_SERIAL_MOS7720=m -CONFIG_USB_SERIAL_MOS7840=m -CONFIG_USB_SERIAL_MXUPORT=m -CONFIG_USB_SERIAL_NAVMAN=m -CONFIG_USB_SERIAL_PL2303=m -CONFIG_USB_SERIAL_OTI6858=m -CONFIG_USB_SERIAL_QCAUX=m -CONFIG_USB_SERIAL_QUALCOMM=m -CONFIG_USB_SERIAL_SPCP8X5=m -CONFIG_USB_SERIAL_SAFE=m -CONFIG_USB_SERIAL_SAFE_PADDED=y -CONFIG_USB_SERIAL_SIERRAWIRELESS=m -CONFIG_USB_SERIAL_SYMBOL=m -CONFIG_USB_SERIAL_TI=m -CONFIG_USB_SERIAL_CYBERJACK=m -CONFIG_USB_SERIAL_OPTION=m -CONFIG_USB_SERIAL_OMNINET=m -CONFIG_USB_SERIAL_OPTICON=m -CONFIG_USB_SERIAL_XSENS_MT=m -CONFIG_USB_SERIAL_WISHBONE=m -CONFIG_USB_SERIAL_SSU100=m -CONFIG_USB_SERIAL_QT2=m -CONFIG_USB_SERIAL_UPD78F0730=m -CONFIG_USB_SERIAL_XR=m -CONFIG_USB_SERIAL_DEBUG=m -CONFIG_USB_EMI62=m -CONFIG_USB_EMI26=m -CONFIG_USB_ADUTUX=m -CONFIG_USB_SEVSEG=m -CONFIG_USB_LEGOTOWER=m -CONFIG_USB_LCD=m -CONFIG_USB_CYPRESS_CY7C63=m -CONFIG_USB_CYTHERM=m -CONFIG_USB_IDMOUSE=m -CONFIG_USB_APPLEDISPLAY=m -CONFIG_APPLE_MFI_FASTCHARGE=m -CONFIG_USB_SISUSBVGA=m -CONFIG_USB_LD=m -CONFIG_USB_TRANCEVIBRATOR=m -CONFIG_USB_ISIGHTFW=m -CONFIG_USB_YUREX=m -CONFIG_USB_ULPI=y -CONFIG_USB_GADGET=y -CONFIG_U_SERIAL_CONSOLE=y -CONFIG_USB_CONFIGFS=m -CONFIG_USB_CONFIGFS_SERIAL=y -CONFIG_USB_CONFIGFS_ACM=y -CONFIG_USB_CONFIGFS_OBEX=y -CONFIG_USB_CONFIGFS_NCM=y -CONFIG_USB_CONFIGFS_ECM=y -CONFIG_USB_CONFIGFS_ECM_SUBSET=y -CONFIG_USB_CONFIGFS_RNDIS=y -CONFIG_USB_CONFIGFS_EEM=y -CONFIG_USB_CONFIGFS_MASS_STORAGE=y -CONFIG_USB_CONFIGFS_F_LB_SS=y -CONFIG_USB_CONFIGFS_F_FS=y -CONFIG_USB_CONFIGFS_F_UAC1=y -CONFIG_USB_CONFIGFS_F_UAC1_LEGACY=y -CONFIG_USB_CONFIGFS_F_UAC2=y -CONFIG_USB_CONFIGFS_F_MIDI=y -CONFIG_USB_CONFIGFS_F_HID=y -CONFIG_USB_CONFIGFS_F_UVC=y -CONFIG_USB_CONFIGFS_F_PRINTER=y -CONFIG_USB_ZERO=m -CONFIG_USB_AUDIO=m -CONFIG_USB_ETH=m -CONFIG_USB_ETH_EEM=y -CONFIG_USB_G_NCM=m -CONFIG_USB_GADGETFS=m -CONFIG_USB_FUNCTIONFS=m -CONFIG_USB_FUNCTIONFS_ETH=y -CONFIG_USB_FUNCTIONFS_RNDIS=y -CONFIG_USB_FUNCTIONFS_GENERIC=y -CONFIG_USB_MASS_STORAGE=m -CONFIG_USB_G_SERIAL=m -CONFIG_USB_MIDI_GADGET=m -CONFIG_USB_G_PRINTER=m -CONFIG_USB_CDC_COMPOSITE=m -CONFIG_USB_G_ACM_MS=m -CONFIG_USB_G_MULTI=m -CONFIG_USB_G_MULTI_CDC=y -CONFIG_USB_G_HID=m -CONFIG_USB_G_WEBCAM=m -CONFIG_USB_RAW_GADGET=m -CONFIG_MMC=y -CONFIG_MMC_BLOCK_MINORS=16 -CONFIG_MMC_MESON_MX_SDHC=y -CONFIG_MMC_MESON_MX_SDIO=y -CONFIG_MMC_VUB300=m -CONFIG_MMC_USHC=m -CONFIG_MMC_REALTEK_USB=m -CONFIG_MMC_CQHCI=y -CONFIG_MMC_HSQ=m -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_PWM=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_ONESHOT=y -CONFIG_LEDS_TRIGGER_DISK=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_LEDS_TRIGGER_BACKLIGHT=y -CONFIG_LEDS_TRIGGER_CPU=y -CONFIG_LEDS_TRIGGER_ACTIVITY=y -CONFIG_LEDS_TRIGGER_DEFAULT_ON=y -CONFIG_LEDS_TRIGGER_TRANSIENT=y -CONFIG_LEDS_TRIGGER_CAMERA=y -CONFIG_LEDS_TRIGGER_PANIC=y -CONFIG_LEDS_TRIGGER_NETDEV=y -CONFIG_LEDS_TRIGGER_PATTERN=y -CONFIG_LEDS_TRIGGER_AUDIO=y -CONFIG_LEDS_TRIGGER_TTY=y -CONFIG_EDAC=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_EFI=m -CONFIG_RTC_DRV_MESON=y -CONFIG_RTC_DRV_MESON_VRTC=y -CONFIG_DMADEVICES=y -# CONFIG_VIRTIO_MENU is not set -CONFIG_VHOST_NET=m -CONFIG_VHOST_VSOCK=m -CONFIG_HWSPINLOCK=y -CONFIG_ARM_GT_INITIAL_PRESCALER_VAL=2 -CONFIG_MAILBOX=y -CONFIG_IOMMU_IO_PGTABLE_LPAE=y -CONFIG_IOMMU_DEBUGFS=y -CONFIG_REMOTEPROC=y -CONFIG_REMOTEPROC_CDEV=y -CONFIG_MESON_MX_AO_ARC_REMOTEPROC=y -CONFIG_RPMSG_VIRTIO=m -# CONFIG_MESON_GX_PM_DOMAINS is not set -CONFIG_DEVFREQ_GOV_PERFORMANCE=m -CONFIG_DEVFREQ_GOV_POWERSAVE=m -CONFIG_DEVFREQ_GOV_USERSPACE=m -CONFIG_DEVFREQ_GOV_PASSIVE=m -CONFIG_PM_DEVFREQ_EVENT=y -CONFIG_EXTCON=y -CONFIG_EXTCON_USB_GPIO=y -CONFIG_MEMORY=y -CONFIG_IIO=y -CONFIG_IIO_BUFFER_CB=m -CONFIG_IIO_BUFFER_DMAENGINE=m -CONFIG_IIO_BUFFER_HW_CONSUMER=m -CONFIG_IIO_SW_TRIGGER=y -CONFIG_IIO_TRIGGERED_EVENT=m -CONFIG_MESON_SARADC=m -CONFIG_MPU3050_I2C=y -CONFIG_IIO_HRTIMER_TRIGGER=y -CONFIG_PWM=y -CONFIG_PWM_MESON=y -CONFIG_RESET_MESON_AUDIO_ARB=m -CONFIG_PHY_MESON8_HDMI_TX=y -# CONFIG_PHY_MESON_GXL_USB2 is not set -# CONFIG_PHY_MESON_G12A_MIPI_DPHY_ANALOG is not set -# CONFIG_PHY_MESON_G12A_USB2 is not set -# CONFIG_PHY_MESON_G12A_USB3_PCIE is not set -# CONFIG_PHY_MESON_AXG_PCIE is not set -# CONFIG_PHY_MESON_AXG_MIPI_PCIE_ANALOG is not set -# CONFIG_PHY_MESON_AXG_MIPI_DPHY is not set -CONFIG_RAS=y -CONFIG_ANDROID_BINDER_IPC=y -CONFIG_ANDROID_BINDERFS=y -CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder,vndbinder,anbox-binder,anbox-hwbinder,anbox-vndbinder" -CONFIG_DAX=m -CONFIG_NVMEM_MESON_MX_EFUSE=y -CONFIG_NVMEM_RMEM=m -CONFIG_COUNTER=m -CONFIG_VALIDATE_FS_PARSER=y -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_EXT2_FS_SECURITY=y -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_EXT3_FS_SECURITY=y -CONFIG_REISERFS_FS=y -CONFIG_REISERFS_PROC_INFO=y -CONFIG_REISERFS_FS_XATTR=y -CONFIG_REISERFS_FS_POSIX_ACL=y -CONFIG_REISERFS_FS_SECURITY=y -CONFIG_JFS_FS=y -CONFIG_JFS_POSIX_ACL=y -CONFIG_JFS_SECURITY=y -CONFIG_JFS_STATISTICS=y -CONFIG_XFS_FS=y -CONFIG_XFS_QUOTA=y -CONFIG_XFS_POSIX_ACL=y -CONFIG_XFS_RT=y -CONFIG_XFS_ONLINE_SCRUB=y -CONFIG_XFS_ONLINE_REPAIR=y -CONFIG_GFS2_FS=y -CONFIG_OCFS2_FS=y -CONFIG_OCFS2_DEBUG_FS=y -CONFIG_BTRFS_FS=y -CONFIG_BTRFS_FS_POSIX_ACL=y -CONFIG_BTRFS_ASSERT=y -CONFIG_NILFS2_FS=y -CONFIG_F2FS_FS=y -CONFIG_F2FS_FS_SECURITY=y -CONFIG_F2FS_CHECK_FS=y -CONFIG_F2FS_FAULT_INJECTION=y -CONFIG_F2FS_FS_COMPRESSION=y -CONFIG_FS_ENCRYPTION=y -CONFIG_FS_VERITY=y -CONFIG_FANOTIFY=y -CONFIG_QUOTA_NETLINK_INTERFACE=y -CONFIG_QFMT_V1=y -CONFIG_QFMT_V2=y -CONFIG_AUTOFS_FS=y -CONFIG_FUSE_FS=y -CONFIG_CUSE=y -CONFIG_VIRTIO_FS=y -CONFIG_OVERLAY_FS=y -CONFIG_FSCACHE=y -CONFIG_FSCACHE_STATS=y -CONFIG_CACHEFILES=y -CONFIG_ISO9660_FS=y -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_UDF_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_UTF8=y -CONFIG_EXFAT_FS=y -CONFIG_NTFS_FS=y -CONFIG_NTFS_RW=y -CONFIG_NTFS3_FS=y -CONFIG_NTFS3_LZX_XPRESS=y -CONFIG_NTFS3_FS_POSIX_ACL=y -CONFIG_PROC_CHILDREN=y -CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y -CONFIG_ORANGEFS_FS=m -CONFIG_ADFS_FS=m -CONFIG_AFFS_FS=m -CONFIG_ECRYPT_FS=m -CONFIG_ECRYPT_FS_MESSAGING=y -CONFIG_HFS_FS=m -CONFIG_HFSPLUS_FS=m -CONFIG_BEFS_FS=m -CONFIG_BFS_FS=m -CONFIG_EFS_FS=m -CONFIG_CRAMFS=m -CONFIG_SQUASHFS=m -CONFIG_SQUASHFS_XATTR=y -CONFIG_SQUASHFS_LZ4=y -CONFIG_SQUASHFS_LZO=y -CONFIG_SQUASHFS_XZ=y -CONFIG_SQUASHFS_ZSTD=y -CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y -CONFIG_SQUASHFS_EMBEDDED=y -CONFIG_VXFS_FS=m -CONFIG_MINIX_FS=m -CONFIG_OMFS_FS=m -CONFIG_HPFS_FS=m -CONFIG_QNX4FS_FS=m -CONFIG_QNX6FS_FS=m -CONFIG_ROMFS_FS=m -CONFIG_PSTORE=m -CONFIG_PSTORE_CONSOLE=y -CONFIG_PSTORE_PMSG=y -CONFIG_PSTORE_RAM=m -CONFIG_PSTORE_BLK=m -CONFIG_SYSV_FS=m -CONFIG_UFS_FS=m -CONFIG_EROFS_FS=m -CONFIG_EROFS_FS_ZIP_LZMA=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3_ACL=y -CONFIG_NFS_V4=y -CONFIG_NFS_SWAP=y -CONFIG_NFS_V4_1=y -CONFIG_NFS_V4_2=y -CONFIG_NFS_V4_1_MIGRATION=y -CONFIG_ROOT_NFS=y -CONFIG_NFS_FSCACHE=y -CONFIG_NFSD=m -CONFIG_NFSD_V3_ACL=y -CONFIG_NFSD_V4=y -CONFIG_NFSD_BLOCKLAYOUT=y -CONFIG_NFSD_SCSILAYOUT=y -CONFIG_NFSD_FLEXFILELAYOUT=y -CONFIG_NFSD_V4_2_INTER_SSC=y -CONFIG_RPCSEC_GSS_KRB5=m -CONFIG_SUNRPC_DEBUG=y -CONFIG_CEPH_FS=m -CONFIG_CEPH_FSCACHE=y -CONFIG_CEPH_FS_POSIX_ACL=y -CONFIG_CIFS=m -CONFIG_CIFS_UPCALL=y -CONFIG_CIFS_XATTR=y -CONFIG_CIFS_POSIX=y -CONFIG_CIFS_DFS_UPCALL=y -CONFIG_CIFS_SWN_UPCALL=y -CONFIG_CIFS_FSCACHE=y -CONFIG_SMB_SERVER=m -CONFIG_SMB_SERVER_KERBEROS5=y -CONFIG_CODA_FS=m -CONFIG_AFS_FS=m -CONFIG_AFS_FSCACHE=y -CONFIG_NLS_DEFAULT="utf-8" -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_737=m -CONFIG_NLS_CODEPAGE_775=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_852=m -CONFIG_NLS_CODEPAGE_855=m -CONFIG_NLS_CODEPAGE_857=m -CONFIG_NLS_CODEPAGE_860=m -CONFIG_NLS_CODEPAGE_861=m -CONFIG_NLS_CODEPAGE_862=m -CONFIG_NLS_CODEPAGE_863=m -CONFIG_NLS_CODEPAGE_864=m -CONFIG_NLS_CODEPAGE_865=m -CONFIG_NLS_CODEPAGE_866=m -CONFIG_NLS_CODEPAGE_869=m -CONFIG_NLS_CODEPAGE_936=m -CONFIG_NLS_CODEPAGE_950=m -CONFIG_NLS_CODEPAGE_932=m -CONFIG_NLS_CODEPAGE_949=m -CONFIG_NLS_CODEPAGE_874=m -CONFIG_NLS_ISO8859_8=m -CONFIG_NLS_CODEPAGE_1250=m -CONFIG_NLS_CODEPAGE_1251=m -CONFIG_NLS_ASCII=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_ISO8859_6=m -CONFIG_NLS_ISO8859_7=m -CONFIG_NLS_ISO8859_9=m -CONFIG_NLS_ISO8859_13=m -CONFIG_NLS_ISO8859_14=m -CONFIG_NLS_ISO8859_15=m -CONFIG_NLS_KOI8_R=m -CONFIG_NLS_KOI8_U=m -CONFIG_NLS_MAC_ROMAN=m -CONFIG_NLS_MAC_CELTIC=m -CONFIG_NLS_MAC_CENTEURO=m -CONFIG_NLS_MAC_CROATIAN=m -CONFIG_NLS_MAC_CYRILLIC=m -CONFIG_NLS_MAC_GAELIC=m -CONFIG_NLS_MAC_GREEK=m -CONFIG_NLS_MAC_ICELAND=m -CONFIG_NLS_MAC_INUIT=m -CONFIG_NLS_MAC_ROMANIAN=m -CONFIG_NLS_MAC_TURKISH=m -CONFIG_NLS_UTF8=y -CONFIG_DLM=y -CONFIG_UNICODE=y -CONFIG_SECURITYFS=y -CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,integrity,bpf" -CONFIG_CRYPTO_USER=m -CONFIG_CRYPTO_PCRYPT=m -CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_DH=m -CONFIG_CRYPTO_DH_RFC7919_GROUPS=y -CONFIG_CRYPTO_ECDSA=m -CONFIG_CRYPTO_ECRDSA=m -CONFIG_CRYPTO_SM2=m -CONFIG_CRYPTO_CURVE25519=m -CONFIG_CRYPTO_AES=m -CONFIG_CRYPTO_AES_TI=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_ARIA=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_DES=m -CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_SEED=m -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_SM4_GENERIC=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ADIANTUM=m -CONFIG_CRYPTO_ARC4=m -CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_CFB=m -CONFIG_CRYPTO_CTS=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_HCTR2=m -CONFIG_CRYPTO_KEYWRAP=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_OFB=m -CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_AEGIS128=m -CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_RMD160=m -CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_SM3_GENERIC=m -CONFIG_CRYPTO_VMAC=m -CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_842=m -CONFIG_CRYPTO_LZ4=m -CONFIG_CRYPTO_LZ4HC=m -CONFIG_CRYPTO_ZSTD=y -CONFIG_CRYPTO_ANSI_CPRNG=m -CONFIG_CRYPTO_DRBG_HASH=y -CONFIG_CRYPTO_DRBG_CTR=y -CONFIG_CRYPTO_USER_API_HASH=m -CONFIG_CRYPTO_USER_API_SKCIPHER=m -CONFIG_CRYPTO_USER_API_RNG=m -CONFIG_CRYPTO_USER_API_AEAD=m -CONFIG_CRYPTO_STATS=y -CONFIG_CRYPTO_GHASH_ARM_CE=m -CONFIG_CRYPTO_NHPOLY1305_NEON=m -CONFIG_CRYPTO_BLAKE2B_NEON=m -CONFIG_CRYPTO_SHA1_ARM_NEON=m -CONFIG_CRYPTO_SHA1_ARM_CE=m -CONFIG_CRYPTO_SHA2_ARM_CE=m -CONFIG_CRYPTO_SHA512_ARM=m -CONFIG_CRYPTO_AES_ARM=m -CONFIG_CRYPTO_AES_ARM_BS=m -CONFIG_CRYPTO_AES_ARM_CE=m -CONFIG_CRYPTO_CRC32_ARM_CE=m -CONFIG_CRYPTO_CRCT10DIF_ARM_CE=m -# CONFIG_CRYPTO_HW is not set -CONFIG_PKCS8_PRIVATE_KEY_PARSER=m -CONFIG_SIGNED_PE_FILE_VERIFICATION=y -CONFIG_SYSTEM_EXTRA_CERTIFICATE=y -CONFIG_SECONDARY_TRUSTED_KEYRING=y -CONFIG_SYSTEM_BLACKLIST_KEYRING=y -CONFIG_PACKING=y -CONFIG_PRIME_NUMBERS=m -CONFIG_CRC4=m -CONFIG_CRC8=m -CONFIG_DMA_CMA=y -CONFIG_CMA_SIZE_MBYTES=64 -CONFIG_PRINTK_TIME=y -CONFIG_DEBUG_INFO_DWARF5=y -CONFIG_DEBUG_INFO_BTF=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_FTRACE_SYSCALLS=y diff --git a/config/sources/families/include/meson_common.inc b/config/sources/families/include/meson_common.inc index 436b83e09361..f009354ee72c 100644 --- a/config/sources/families/include/meson_common.inc +++ b/config/sources/families/include/meson_common.inc @@ -23,10 +23,6 @@ SKIP_BOOTSPLASH="yes" case $BRANCH in - legacy) - declare -g KERNEL_MAJOR_MINOR="6.6" - ;; - current) declare -g KERNEL_MAJOR_MINOR="6.12" ;; diff --git a/patch/kernel/archive/meson-6.6/0010-arm64-swiotlb-Reduce-the-default-size-if-no-ZONE_DMA-bouncing-needed.patch b/patch/kernel/archive/meson-6.6/0010-arm64-swiotlb-Reduce-the-default-size-if-no-ZONE_DMA-bouncing-needed.patch deleted file mode 100644 index 393055343872..000000000000 --- a/patch/kernel/archive/meson-6.6/0010-arm64-swiotlb-Reduce-the-default-size-if-no-ZONE_DMA-bouncing-needed.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Catalin Marinas -Date: Wed, 10 Apr 2024 08:25:37 -0400 -Subject: arm64: swiotlb: Reduce the default size if no ZONE_DMA bouncing - needed - -With CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC enabled, the arm64 kernel still -allocates the default SWIOTLB buffer (64MB) even if ZONE_DMA is disabled -or all the RAM fits into this zone. However, this potentially wastes a -non-negligible amount of memory on platforms with little RAM. - -Reduce the SWIOTLB size to 1MB per 1GB of RAM if only needed for -kmalloc() buffer bouncing. - -Signed-off-by: Catalin Marinas -Suggested-by: Ross Burton -Cc: Ross Burton -Cc: Will Deacon -Reviewed-by: Robin Murphy ---- - arch/arm64/mm/init.c | 11 +++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c -index 111111111111..222222222222 100644 ---- a/arch/arm64/mm/init.c -+++ b/arch/arm64/mm/init.c -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -493,8 +494,16 @@ void __init mem_init(void) - { - bool swiotlb = max_pfn > PFN_DOWN(arm64_dma_phys_limit); - -- if (IS_ENABLED(CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC)) -+ if (IS_ENABLED(CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC) && !swiotlb) { -+ /* -+ * If no bouncing needed for ZONE_DMA, reduce the swiotlb -+ * buffer for kmalloc() bouncing to 1MB per 1GB of RAM. -+ */ -+ unsigned long size = -+ DIV_ROUND_UP(memblock_phys_mem_size(), 1024); -+ swiotlb_adjust_size(min(swiotlb_size_or_default(), size)); - swiotlb = true; -+ } - - swiotlb_init(swiotlb, SWIOTLB_VERBOSE); - --- -Armbian - diff --git a/patch/kernel/archive/meson-6.6/generic-0001-m8-m8b-m8m2-Support-HDMI.patch b/patch/kernel/archive/meson-6.6/generic-0001-m8-m8b-m8m2-Support-HDMI.patch deleted file mode 100644 index 6b78146c6c61..000000000000 --- a/patch/kernel/archive/meson-6.6/generic-0001-m8-m8b-m8m2-Support-HDMI.patch +++ /dev/null @@ -1,4394 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Sat, 18 Nov 2023 01:22:02 +0800 -Subject: meson8/meson8b/meson8m2: Support HDMI - -The following codes are come from https://github.com/xdarklight/linux/commits/meson-mx-integration-5.18-20220516. - -Special thank to Martin Blumenstingl. ---- - Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml | 16 + - Documentation/devicetree/bindings/phy/amlogic,meson-cvbs-dac-phy.yaml | 81 + - arch/arm/boot/dts/amlogic/meson.dtsi | 13 + - arch/arm/boot/dts/amlogic/meson8.dtsi | 168 +- - arch/arm/boot/dts/amlogic/meson8b.dtsi | 171 +- - arch/arm/boot/dts/amlogic/meson8m2.dtsi | 4 + - drivers/gpu/drm/meson/Kconfig | 9 + - drivers/gpu/drm/meson/Makefile | 1 + - drivers/gpu/drm/meson/meson_drv.c | 313 +- - drivers/gpu/drm/meson/meson_drv.h | 49 +- - drivers/gpu/drm/meson/meson_encoder_cvbs.c | 61 +- - drivers/gpu/drm/meson/meson_encoder_hdmi.c | 69 +- - drivers/gpu/drm/meson/meson_plane.c | 37 +- - drivers/gpu/drm/meson/meson_transwitch_hdmi.c | 1579 ++++++++++ - drivers/gpu/drm/meson/meson_transwitch_hdmi.h | 536 ++++ - drivers/gpu/drm/meson/meson_vclk.c | 146 + - drivers/gpu/drm/meson/meson_venc.c | 44 +- - drivers/gpu/drm/meson/meson_viu.c | 18 +- - drivers/phy/amlogic/Kconfig | 10 + - drivers/phy/amlogic/Makefile | 1 + - drivers/phy/amlogic/phy-meson-cvbs-dac.c | 375 +++ - 21 files changed, 3576 insertions(+), 125 deletions(-) - -diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml -index 111111111111..222222222222 100644 ---- a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml -+++ b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml -@@ -66,8 +66,12 @@ properties: - - const: amlogic,meson-gx-vpu - - enum: - - amlogic,meson-g12a-vpu # G12A (S905X2, S905Y2, S905D2) -+ - amlogic,meson8-vpu -+ - amlogic,meson8b-vpu -+ - amlogic,meson8m2-vpu - - reg: -+ minItems: 1 - maxItems: 2 - - reg-names: -@@ -82,6 +86,15 @@ properties: - description: should point to a canvas provider node - $ref: /schemas/types.yaml#/definitions/phandle - -+ phys: -+ maxItems: 1 -+ description: -+ PHY specifier for the CVBS DAC -+ -+ phy-names: -+ items: -+ - const: cvbs-dac -+ - power-domains: - maxItems: 1 - description: phandle to the associated power domain -@@ -130,6 +143,9 @@ examples: - #size-cells = <0>; - amlogic,canvas = <&canvas>; - -+ phys = <&cvbs_dac_phy>; -+ phy-names = "cvbs-dac"; -+ - /* CVBS VDAC output port */ - port@0 { - reg = <0>; -diff --git a/Documentation/devicetree/bindings/phy/amlogic,meson-cvbs-dac-phy.yaml b/Documentation/devicetree/bindings/phy/amlogic,meson-cvbs-dac-phy.yaml -new file mode 100644 -index 000000000000..111111111111 ---- /dev/null -+++ b/Documentation/devicetree/bindings/phy/amlogic,meson-cvbs-dac-phy.yaml -@@ -0,0 +1,81 @@ -+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: "http://devicetree.org/schemas/phy/amlogic,meson-cvbs-dac-phy.yaml#" -+$schema: "http://devicetree.org/meta-schemas/core.yaml#" -+ -+title: Amlogic Meson Composite Video Baseband Signal DAC -+ -+maintainers: -+ - Martin Blumenstingl -+ -+description: |+ -+ The CVBS DAC node should be the child of a syscon node with the -+ required property: -+ -+ compatible = "amlogic,meson-hhi-sysctrl", "simple-mfd", "syscon" -+ -+ Refer to the bindings described in -+ Documentation/devicetree/bindings/mfd/syscon.yaml -+ -+properties: -+ $nodename: -+ pattern: "^video-dac@[0-9a-f]+$" -+ -+ compatible: -+ oneOf: -+ - items: -+ - enum: -+ - amlogic,meson8-cvbs-dac -+ - amlogic,meson-gxbb-cvbs-dac -+ - amlogic,meson-gxl-cvbs-dac -+ - amlogic,meson-g12a-cvbs-dac -+ - const: amlogic,meson-cvbs-dac -+ - const: amlogic,meson-cvbs-dac -+ -+ reg: -+ maxItems: 1 -+ -+ clocks: -+ minItems: 1 -+ -+ nvmem-cells: -+ minItems: 1 -+ -+ nvmem-cell-names: -+ items: -+ - const: cvbs_trimming -+ -+ "#phy-cells": -+ const: 0 -+ -+required: -+ - compatible -+ - reg -+ - clocks -+ - "#phy-cells" -+ -+additionalProperties: false -+ -+examples: -+ - | -+ video-dac@2f4 { -+ compatible = "amlogic,meson8-cvbs-dac", "amlogic,meson-cvbs-dac"; -+ reg = <0x2f4 0x8>; -+ -+ #phy-cells = <0>; -+ -+ clocks = <&vdac_clock>; -+ -+ nvmem-cells = <&cvbs_trimming>; -+ nvmem-cell-names = "cvbs_trimming"; -+ }; -+ - | -+ video-dac@2ec { -+ compatible = "amlogic,meson-g12a-cvbs-dac", "amlogic,meson-cvbs-dac"; -+ reg = <0x2ec 0x8>; -+ -+ #phy-cells = <0>; -+ -+ clocks = <&vdac_clock>; -+ }; -diff --git a/arch/arm/boot/dts/amlogic/meson.dtsi b/arch/arm/boot/dts/amlogic/meson.dtsi -index 111111111111..222222222222 100644 ---- a/arch/arm/boot/dts/amlogic/meson.dtsi -+++ b/arch/arm/boot/dts/amlogic/meson.dtsi -@@ -35,6 +35,19 @@ hhi: system-controller@4000 { - "simple-mfd", - "syscon"; - reg = <0x4000 0x400>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0x0 0x4000 0x400>; -+ -+ -+ cvbs_dac: video-dac@2f4 { -+ compatible = "amlogic,meson-cvbs-dac"; -+ reg = <0x2f4 0x8>; -+ -+ #phy-cells = <0>; -+ -+ status = "disabled"; -+ }; - }; - - aiu: audio-controller@5400 { -diff --git a/arch/arm/boot/dts/amlogic/meson8.dtsi b/arch/arm/boot/dts/amlogic/meson8.dtsi -index 111111111111..222222222222 100644 ---- a/arch/arm/boot/dts/amlogic/meson8.dtsi -+++ b/arch/arm/boot/dts/amlogic/meson8.dtsi -@@ -314,6 +314,113 @@ mali: gpu@c0000 { - operating-points-v2 = <&gpu_opp_table>; - #cooling-cells = <2>; /* min followed by max */ - }; -+ -+ hdmi_tx: hdmi-tx@42000 { -+ compatible = "amlogic,meson8-hdmi-tx"; -+ reg = <0x42000 0xc>; -+ interrupts = ; -+ phys = <&hdmi_tx_phy>; -+ phy-names = "hdmi"; -+ clocks = <&clkc CLKID_HDMI_PCLK>, -+ <&clkc CLKID_HDMI_SYS>; -+ clock-names = "pclk", "sys"; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ #sound-dai-cells = <1>; -+ sound-name-prefix = "HDMITX"; -+ -+ status = "disabled"; -+ -+ /* VPU VENC Input */ -+ hdmi_tx_venc_port: port@0 { -+ reg = <0>; -+ -+ hdmi_tx_in: endpoint { -+ remote-endpoint = <&hdmi_tx_out>; -+ }; -+ }; -+ -+ /* TMDS Output */ -+ hdmi_tx_tmds_port: port@1 { -+ reg = <1>; -+ }; -+ }; -+ -+ vpu: vpu@100000 { -+ compatible = "amlogic,meson8-vpu"; -+ -+ reg = <0x100000 0x10000>; -+ reg-names = "vpu"; -+ -+ interrupts = ; -+ -+ amlogic,canvas = <&canvas>; -+ -+ /* -+ * The VCLK{,2}_IN path always needs to derived from -+ * the CLKID_VID_PLL_FINAL_DIV so other clocks like -+ * MPLL1 are not used (MPLL1 is reserved for audio -+ * purposes). -+ */ -+ assigned-clocks = <&clkc CLKID_VCLK_IN_SEL>, -+ <&clkc CLKID_VCLK2_IN_SEL>; -+ assigned-clock-parents = <&clkc CLKID_VID_PLL_FINAL_DIV>, -+ <&clkc CLKID_VID_PLL_FINAL_DIV>; -+ -+ clocks = <&clkc CLKID_VPU_INTR>, -+ <&clkc CLKID_HDMI_INTR_SYNC>, -+ <&clkc CLKID_GCLK_VENCI_INT>, -+ <&clkc CLKID_HDMI_PLL_HDMI_OUT>, -+ <&clkc CLKID_HDMI_TX_PIXEL>, -+ <&clkc CLKID_CTS_ENCP>, -+ <&clkc CLKID_CTS_ENCI>, -+ <&clkc CLKID_CTS_ENCT>, -+ <&clkc CLKID_CTS_ENCL>, -+ <&clkc CLKID_CTS_VDAC0>; -+ clock-names = "vpu_intr", -+ "hdmi_intr_sync", -+ "venci_int", -+ "tmds", -+ "hdmi_tx_pixel", -+ "cts_encp", -+ "cts_enci", -+ "cts_enct", -+ "cts_encl", -+ "cts_vdac0"; -+ -+ resets = <&clkc CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_PRE>, -+ <&clkc CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_POST>, -+ <&clkc CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_PRE>, -+ <&clkc CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_POST>; -+ reset-names = "vid_pll_pre", -+ "vid_pll_post", -+ "vid_pll_soft_pre", -+ "vid_pll_soft_post"; -+ -+ phys = <&cvbs_dac>; -+ phy-names = "cvbs-dac"; -+ -+ power-domains = <&pwrc PWRC_MESON8_VPU_ID>; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ /* CVBS VDAC output port */ -+ cvbs_vdac_port: port@0 { -+ reg = <0>; -+ }; -+ -+ /* HDMI-TX output port */ -+ hdmi_tx_port: port@1 { -+ reg = <1>; -+ -+ hdmi_tx_out: endpoint { -+ remote-endpoint = <&hdmi_tx_in>; -+ }; -+ }; -+ }; - }; - }; /* end of / */ - -@@ -363,6 +470,14 @@ gpio_ao: ao-bank@14 { - gpio-ranges = <&pinctrl_aobus 0 0 16>; - }; - -+ hdmi_cec_ao_pins: hdmi-cec-ao { -+ mux { -+ groups = "hdmi_cec_ao"; -+ function = "hdmi_cec_ao"; -+ bias-pull-up; -+ }; -+ }; -+ - i2s_am_clk_pins: i2s-am-clk-out { - mux { - groups = "i2s_am_clk_out_ao"; -@@ -427,6 +542,15 @@ mux { - }; - }; - }; -+ -+ cec_AO: cec@100 { -+ compatible = "amlogic,meson-gx-ao-cec"; // FIXME -+ reg = <0x100 0x14>; -+ interrupts = ; -+ // TODO: 32768HZ clock -+ hdmi-phandle = <&hdmi_tx>; -+ status = "disabled"; -+ }; - }; - - &ao_arc_rproc { -@@ -479,6 +603,22 @@ gpio: banks@80b0 { - gpio-ranges = <&pinctrl_cbus 0 0 120>; - }; - -+ hdmi_hpd_pins: hdmi-hpd { -+ mux { -+ groups = "hdmi_hpd"; -+ function = "hdmi"; -+ bias-disable; -+ }; -+ }; -+ -+ hdmi_i2c_pins: hdmi-i2c { -+ mux { -+ groups = "hdmi_sda", "hdmi_scl"; -+ function = "hdmi"; -+ bias-disable; -+ }; -+ }; -+ - sd_a_pins: sd-a { - mux { - groups = "sd_d0_a", "sd_d1_a", "sd_d2_a", -@@ -601,6 +741,17 @@ smp-sram@1ff80 { - }; - }; - -+&cvbs_dac { -+ compatible = "amlogic,meson8-cvbs-dac", "amlogic,meson-cvbs-dac"; -+ -+ clocks = <&clkc CLKID_CTS_VDAC0>; -+ -+ nvmem-cells = <&cvbs_trimming>; -+ nvmem-cell-names = "cvbs_trimming"; -+ -+ status = "okay"; -+}; -+ - &efuse { - compatible = "amlogic,meson8-efuse"; - clocks = <&clkc CLKID_EFUSE>; -@@ -610,6 +761,10 @@ temperature_calib: calib@1f4 { - /* only the upper two bytes are relevant */ - reg = <0x1f4 0x4>; - }; -+ -+ cvbs_trimming: calib@1f8 { -+ reg = <0x1f8 0x2>; -+ }; - }; - - ðmac { -@@ -625,16 +780,18 @@ &gpio_intc { - }; - - &hhi { -- clkc: clock-controller { -+ clkc: clock-controller@0 { - compatible = "amlogic,meson8-clkc"; -+ reg = <0x0 0x39c>; - clocks = <&xtal>, <&ddr_clkc DDR_CLKID_DDR_PLL>; - clock-names = "xtal", "ddr_pll"; - #clock-cells = <1>; - #reset-cells = <1>; - }; - -- pwrc: power-controller { -+ pwrc: power-controller@100 { - compatible = "amlogic,meson8-pwrc"; -+ reg = <0x100 0x10>; - #power-domain-cells = <1>; - amlogic,ao-sysctrl = <&pmu>; - clocks = <&clkc CLKID_VPU>; -@@ -642,6 +799,13 @@ pwrc: power-controller { - assigned-clocks = <&clkc CLKID_VPU>; - assigned-clock-rates = <364285714>; - }; -+ -+ hdmi_tx_phy: hdmi-phy@3a0 { -+ compatible = "amlogic,meson8-hdmi-tx-phy"; -+ clocks = <&clkc CLKID_HDMI_PLL_HDMI_OUT>; -+ reg = <0x3a0 0xc>; -+ #phy-cells = <0>; -+ }; - }; - - &hwrng { -diff --git a/arch/arm/boot/dts/amlogic/meson8b.dtsi b/arch/arm/boot/dts/amlogic/meson8b.dtsi -index 111111111111..222222222222 100644 ---- a/arch/arm/boot/dts/amlogic/meson8b.dtsi -+++ b/arch/arm/boot/dts/amlogic/meson8b.dtsi -@@ -276,6 +276,116 @@ mali: gpu@c0000 { - operating-points-v2 = <&gpu_opp_table>; - #cooling-cells = <2>; /* min followed by max */ - }; -+ -+ hdmi_tx: hdmi-tx@42000 { -+ compatible = "amlogic,meson8b-hdmi-tx"; -+ reg = <0x42000 0xc>; -+ interrupts = ; -+ phys = <&hdmi_tx_phy>; -+ phy-names = "hdmi"; -+ clocks = <&clkc CLKID_HDMI_PCLK>, -+ <&clkc CLKID_HDMI_SYS>; -+ clock-names = "pclk", "sys"; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ #sound-dai-cells = <1>; -+ sound-name-prefix = "HDMITX"; -+ -+ status = "disabled"; -+ -+ /* VPU VENC Input */ -+ hdmi_tx_venc_port: port@0 { -+ reg = <0>; -+ -+ hdmi_tx_in: endpoint { -+ remote-endpoint = <&hdmi_tx_out>; -+ }; -+ }; -+ -+ /* TMDS Output */ -+ hdmi_tx_tmds_port: port@1 { -+ reg = <1>; -+ }; -+ }; -+ -+ vpu: vpu@100000 { -+ compatible = "amlogic,meson8b-vpu"; -+ -+ reg = <0x100000 0x10000>; -+ reg-names = "vpu"; -+ -+ interrupts = ; -+ -+ amlogic,canvas = <&canvas>; -+ -+ /* -+ * The VCLK{,2}_IN path always needs to derived from -+ * the CLKID_VID_PLL_FINAL_DIV so other clocks like -+ * MPLL1 are not used (MPLL1 is reserved for audio -+ * purposes). -+ */ -+ assigned-clocks = <&clkc CLKID_VCLK_IN_SEL>, -+ <&clkc CLKID_VCLK2_IN_SEL>; -+ assigned-clock-parents = <&clkc CLKID_VID_PLL_FINAL_DIV>, -+ <&clkc CLKID_VID_PLL_FINAL_DIV>; -+ -+ clocks = <&clkc CLKID_VPU_INTR>, -+ <&clkc CLKID_HDMI_INTR_SYNC>, -+ <&clkc CLKID_GCLK_VENCI_INT>, -+ <&clkc CLKID_HDMI_PLL_HDMI_OUT>, -+ <&clkc CLKID_HDMI_TX_PIXEL>, -+ <&clkc CLKID_CTS_ENCP>, -+ <&clkc CLKID_CTS_ENCI>, -+ <&clkc CLKID_CTS_ENCT>, -+ <&clkc CLKID_CTS_ENCL>, -+ <&clkc CLKID_CTS_VDAC0>; -+ clock-names = "vpu_intr", -+ "hdmi_intr_sync", -+ "venci_int", -+ "tmds", -+ "hdmi_tx_pixel", -+ "cts_encp", -+ "cts_enci", -+ "cts_enct", -+ "cts_encl", -+ "cts_vdac0"; -+ -+ resets = <&clkc CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_PRE>, -+ <&clkc CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_POST>, -+ <&clkc CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_PRE>, -+ <&clkc CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_POST>; -+ reset-names = "vid_pll_pre", -+ "vid_pll_post", -+ "vid_pll_soft_pre", -+ "vid_pll_soft_post"; -+ -+ phys = <&cvbs_dac>; -+ phy-names = "cvbs-dac"; -+ -+ power-domains = <&pwrc PWRC_MESON8_VPU_ID>; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ #sound-dai-cells = <0>; -+ sound-name-prefix = "HDMITX"; -+ -+ /* CVBS VDAC output port */ -+ cvbs_vdac_port: port@0 { -+ reg = <0>; -+ }; -+ -+ /* HDMI-TX output port */ -+ hdmi_tx_port: port@1 { -+ reg = <1>; -+ -+ hdmi_tx_out: endpoint { -+ remote-endpoint = <&hdmi_tx_in>; -+ }; -+ }; -+ }; - }; - }; /* end of / */ - -@@ -325,6 +435,14 @@ gpio_ao: ao-bank@14 { - gpio-ranges = <&pinctrl_aobus 0 0 16>; - }; - -+ hdmi_cec_ao_pins: hdmi-cec-ao { -+ mux { -+ groups = "hdmi_cec_1"; -+ function = "hdmi_cec"; -+ bias-pull-up; -+ }; -+ }; -+ - i2s_am_clk_pins: i2s-am-clk-out { - mux { - groups = "i2s_am_clk_out"; -@@ -381,6 +499,15 @@ mux { - }; - }; - }; -+ -+ cec_AO: cec@100 { -+ compatible = "amlogic,meson-gx-ao-cec"; // FIXME -+ reg = <0x100 0x14>; -+ interrupts = ; -+ // TODO: 32768HZ clock -+ hdmi-phandle = <&hdmi_tx>; -+ status = "disabled"; -+ }; - }; - - &ao_arc_rproc { -@@ -471,6 +598,22 @@ mux { - }; - }; - -+ hdmi_hpd_pins: hdmi-hpd { -+ mux { -+ groups = "hdmi_hpd"; -+ function = "hdmi"; -+ bias-disable; -+ }; -+ }; -+ -+ hdmi_i2c_pins: hdmi-i2c { -+ mux { -+ groups = "hdmi_sda", "hdmi_scl"; -+ function = "hdmi"; -+ bias-disable; -+ }; -+ }; -+ - i2c_a_pins: i2c-a { - mux { - groups = "i2c_sda_a", "i2c_sck_a"; -@@ -547,6 +690,16 @@ smp-sram@1ff80 { - }; - }; - -+&cvbs_dac { -+ compatible = "amlogic,meson8-cvbs-dac", "amlogic,meson-cvbs-dac"; -+ -+ clocks = <&clkc CLKID_CTS_VDAC0>; -+ -+ nvmem-cells = <&cvbs_trimming>; -+ nvmem-cell-names = "cvbs_trimming"; -+ -+ status = "okay"; -+}; - - &efuse { - compatible = "amlogic,meson8b-efuse"; -@@ -557,6 +710,10 @@ temperature_calib: calib@1f4 { - /* only the upper two bytes are relevant */ - reg = <0x1f4 0x4>; - }; -+ -+ cvbs_trimming: calib@1f8 { -+ reg = <0x1f8 0x2>; -+ }; - }; - - ðmac { -@@ -586,16 +743,18 @@ &gpio_intc { - }; - - &hhi { -- clkc: clock-controller { -+ clkc: clock-controller@0 { - compatible = "amlogic,meson8b-clkc"; -+ reg = <0x0 0x39c>; - clocks = <&xtal>, <&ddr_clkc DDR_CLKID_DDR_PLL>; - clock-names = "xtal", "ddr_pll"; - #clock-cells = <1>; - #reset-cells = <1>; - }; - -- pwrc: power-controller { -+ pwrc: power-controller@100 { - compatible = "amlogic,meson8b-pwrc"; -+ reg = <0x100 0x10>; - #power-domain-cells = <1>; - amlogic,ao-sysctrl = <&pmu>; - resets = <&reset RESET_DBLK>, -@@ -617,6 +776,14 @@ pwrc: power-controller { - assigned-clocks = <&clkc CLKID_VPU>; - assigned-clock-rates = <182142857>; - }; -+ -+ hdmi_tx_phy: hdmi-phy@3a0 { -+ compatible = "amlogic,meson8b-hdmi-tx-phy", -+ "amlogic,meson8-hdmi-tx-phy"; -+ clocks = <&clkc CLKID_HDMI_PLL_HDMI_OUT>; -+ reg = <0x3a0 0xc>; -+ #phy-cells = <0>; -+ }; - }; - - &hwrng { -diff --git a/arch/arm/boot/dts/amlogic/meson8m2.dtsi b/arch/arm/boot/dts/amlogic/meson8m2.dtsi -index 111111111111..222222222222 100644 ---- a/arch/arm/boot/dts/amlogic/meson8m2.dtsi -+++ b/arch/arm/boot/dts/amlogic/meson8m2.dtsi -@@ -96,6 +96,10 @@ &usb1_phy { - compatible = "amlogic,meson8m2-usb2-phy", "amlogic,meson-mx-usb2-phy"; - }; - -+&vpu { -+ compatible = "amlogic,meson8m2-vpu"; -+}; -+ - &wdt { - compatible = "amlogic,meson8m2-wdt", "amlogic,meson8b-wdt"; - }; -diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig -index 111111111111..222222222222 100644 ---- a/drivers/gpu/drm/meson/Kconfig -+++ b/drivers/gpu/drm/meson/Kconfig -@@ -10,6 +10,7 @@ config DRM_MESON - select REGMAP_MMIO - select MESON_CANVAS - select CEC_CORE if CEC_NOTIFIER -+ imply PHY_MESON_CVBS_DAC - - config DRM_MESON_DW_HDMI - tristate "HDMI Synopsys Controller support for Amlogic Meson Display" -@@ -24,3 +25,11 @@ config DRM_MESON_DW_MIPI_DSI - default y if DRM_MESON - select DRM_DW_MIPI_DSI - select GENERIC_PHY_MIPI_DPHY -+ -+config DRM_MESON_TRANSWITCH_HDMI -+ tristate "Amlogic Meson8/8b/8m2 TranSwitch HDMI 1.4 Controller support" -+ depends on ARM || COMPILE_TEST -+ depends on DRM_MESON -+ default y if DRM_MESON -+ select REGMAP_MMIO -+ select SND_SOC_HDMI_CODEC if SND_SOC -diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile -index 111111111111..222222222222 100644 ---- a/drivers/gpu/drm/meson/Makefile -+++ b/drivers/gpu/drm/meson/Makefile -@@ -7,3 +7,4 @@ meson-drm-y += meson_encoder_hdmi.o meson_encoder_dsi.o - obj-$(CONFIG_DRM_MESON) += meson-drm.o - obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o - obj-$(CONFIG_DRM_MESON_DW_MIPI_DSI) += meson_dw_mipi_dsi.o -+obj-$(CONFIG_DRM_MESON_TRANSWITCH_HDMI) += meson_transwitch_hdmi.o -diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c -index 111111111111..222222222222 100644 ---- a/drivers/gpu/drm/meson/meson_drv.c -+++ b/drivers/gpu/drm/meson/meson_drv.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -133,30 +134,147 @@ static struct regmap_config meson_regmap_config = { - .max_register = 0x1000, - }; - -+static int meson_cvbs_dac_phy_init(struct meson_drm *priv) -+{ -+ struct platform_device *pdev; -+ const char *platform_id_name; -+ -+ priv->cvbs_dac = devm_phy_optional_get(priv->dev, "cvbs-dac"); -+ if (IS_ERR(priv->cvbs_dac)) -+ return dev_err_probe(priv->dev, PTR_ERR(priv->cvbs_dac), -+ "Failed to get the 'cvbs-dac' PHY\n"); -+ else if (priv->cvbs_dac) -+ return 0; -+ -+ switch (priv->compat) { -+ case VPU_COMPATIBLE_GXBB: -+ platform_id_name = "meson-gxbb-cvbs-dac"; -+ break; -+ case VPU_COMPATIBLE_GXL: -+ case VPU_COMPATIBLE_GXM: -+ platform_id_name = "meson-gxl-cvbs-dac"; -+ break; -+ case VPU_COMPATIBLE_G12A: -+ platform_id_name = "meson-g12a-cvbs-dac"; -+ break; -+ default: -+ return dev_err_probe(priv->dev, -EINVAL, -+ "No CVBS DAC platform ID found\n"); -+ } -+ -+ pdev = platform_device_register_data(priv->dev, platform_id_name, -+ PLATFORM_DEVID_AUTO, NULL, 0); -+ if (IS_ERR(pdev)) -+ return dev_err_probe(priv->dev, PTR_ERR(pdev), -+ "Failed to register fallback CVBS DAC PHY platform device\n"); -+ -+ priv->cvbs_dac = platform_get_drvdata(pdev); -+ if (IS_ERR(priv->cvbs_dac)) { -+ platform_device_unregister(pdev); -+ return dev_err_probe(priv->dev, PTR_ERR(priv->cvbs_dac), -+ "Failed to get the 'cvbs-dac' PHY from it's platform device\n"); -+ } -+ -+ dev_warn(priv->dev, "Using fallback for old .dtbs without CVBS DAC\n"); -+ -+ priv->cvbs_dac_pdev = pdev; -+ -+ return 0; -+} -+ -+static void meson_cvbs_dac_phy_exit(struct meson_drm *priv) -+{ -+ platform_device_unregister(priv->cvbs_dac_pdev); -+} -+ - static void meson_vpu_init(struct meson_drm *priv) - { -- u32 value; -+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) { -+ writel(0x0, priv->io_base + _REG(VPU_MEM_PD_REG0)); -+ writel(0x0, priv->io_base + _REG(VPU_MEM_PD_REG1)); -+ } else { -+ u32 value; -+ -+ /* -+ * Slave dc0 and dc5 connected to master port 1. -+ * By default other slaves are connected to master port 0. -+ */ -+ value = VPU_RDARB_SLAVE_TO_MASTER_PORT(0, 1) | -+ VPU_RDARB_SLAVE_TO_MASTER_PORT(5, 1); -+ writel_relaxed(value, -+ priv->io_base + _REG(VPU_RDARB_MODE_L1C1)); -+ -+ /* Slave dc0 connected to master port 1 */ -+ value = VPU_RDARB_SLAVE_TO_MASTER_PORT(0, 1); -+ writel_relaxed(value, -+ priv->io_base + _REG(VPU_RDARB_MODE_L1C2)); -+ -+ /* Slave dc4 and dc7 connected to master port 1 */ -+ value = VPU_RDARB_SLAVE_TO_MASTER_PORT(4, 1) | -+ VPU_RDARB_SLAVE_TO_MASTER_PORT(7, 1); -+ writel_relaxed(value, -+ priv->io_base + _REG(VPU_RDARB_MODE_L2C1)); -+ -+ /* Slave dc1 connected to master port 1 */ -+ value = VPU_RDARB_SLAVE_TO_MASTER_PORT(1, 1); -+ writel_relaxed(value, -+ priv->io_base + _REG(VPU_WRARB_MODE_L2C1)); -+ } -+} -+ -+static int meson_video_clock_init(struct meson_drm *priv) -+{ -+ int ret; -+ -+ ret = clk_bulk_prepare(VPU_VID_CLK_NUM, priv->vid_clks); -+ if (ret) -+ return dev_err_probe(priv->dev, ret, -+ "Failed to prepare the video clocks\n"); -+ -+ ret = clk_bulk_prepare(priv->num_intr_clks, priv->intr_clks); -+ if (ret) -+ return dev_err_probe(priv->dev, ret, -+ "Failed to prepare the interrupt clocks\n"); -+ -+ return 0; -+} -+ -+static void meson_video_clock_exit(struct meson_drm *priv) -+{ -+ if (priv->clk_dac_enabled) -+ clk_disable(priv->clk_dac); -+ -+ if (priv->clk_venc_enabled) -+ clk_disable(priv->clk_venc); -+ -+ clk_bulk_unprepare(priv->num_intr_clks, priv->intr_clks); -+ clk_bulk_unprepare(VPU_VID_CLK_NUM, priv->vid_clks); -+} -+ -+static void meson_fbdev_setup(struct meson_drm *priv) -+{ -+ unsigned int preferred_bpp; - - /* -- * Slave dc0 and dc5 connected to master port 1. -- * By default other slaves are connected to master port 0. -+ * All SoC generations before GXBB don't have a way to configure the -+ * alpha value for DRM_FORMAT_XRGB8888 and DRM_FORMAT_XBGR8888. These -+ * formats have an X component instead of an alpha component. On -+ * Meson8/8b/8m2 there is no way to configure the alpha value to use -+ * instead of the X component. This results in the fact that the -+ * formats with X component are only supported on GXBB and newer. Use -+ * 24 bits per pixel and therefore DRM_FORMAT_RGB888 to get a -+ * working framebuffer console. - */ -- value = VPU_RDARB_SLAVE_TO_MASTER_PORT(0, 1) | -- VPU_RDARB_SLAVE_TO_MASTER_PORT(5, 1); -- writel_relaxed(value, priv->io_base + _REG(VPU_RDARB_MODE_L1C1)); -- -- /* Slave dc0 connected to master port 1 */ -- value = VPU_RDARB_SLAVE_TO_MASTER_PORT(0, 1); -- writel_relaxed(value, priv->io_base + _REG(VPU_RDARB_MODE_L1C2)); -- -- /* Slave dc4 and dc7 connected to master port 1 */ -- value = VPU_RDARB_SLAVE_TO_MASTER_PORT(4, 1) | -- VPU_RDARB_SLAVE_TO_MASTER_PORT(7, 1); -- writel_relaxed(value, priv->io_base + _REG(VPU_RDARB_MODE_L2C1)); -- -- /* Slave dc1 connected to master port 1 */ -- value = VPU_RDARB_SLAVE_TO_MASTER_PORT(1, 1); -- writel_relaxed(value, priv->io_base + _REG(VPU_WRARB_MODE_L2C1)); -+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) -+ preferred_bpp = 24; -+ else -+ preferred_bpp = 32; -+ -+ drm_fbdev_dma_setup(priv->drm, preferred_bpp); - } - - struct meson_drm_soc_attr { -@@ -165,13 +283,29 @@ struct meson_drm_soc_attr { - }; - - static const struct meson_drm_soc_attr meson_drm_soc_attrs[] = { -- /* S805X/S805Y HDMI PLL won't lock for HDMI PHY freq > 1,65GHz */ -+ /* The maximum frequency of HDMI PHY on Meson8 and Meson8m2 is ~3GHz */ -+ { -+ .limits = { -+ .max_hdmi_phy_freq = 2976000, -+ }, -+ .attrs = (const struct soc_device_attribute []) { -+ { .soc_id = "Meson8 (S802)", }, -+ { .soc_id = "Meson8m2 (S812)", }, -+ { /* sentinel */ }, -+ } -+ }, -+ /* -+ * GXL S805X/S805Y HDMI PLL won't lock for HDMI PHY freq > 1,65GHz. -+ * Meson8b (S805) only supports "1200p@60 max resolution" according to -+ * the public datasheet. -+ */ - { - .limits = { - .max_hdmi_phy_freq = 1650000, - }, - .attrs = (const struct soc_device_attribute []) { - { .soc_id = "GXL (S805*)", }, -+ { .soc_id = "Meson8b (S805)", }, - { /* sentinel */ } - } - }, -@@ -212,67 +346,123 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) - priv->compat = match->compat; - priv->afbcd.ops = match->afbcd_ops; - -+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) { -+ priv->vid_pll_resets[VPU_RESET_VID_PLL_PRE].id = "vid_pll_pre"; -+ priv->vid_pll_resets[VPU_RESET_VID_PLL_POST].id = "vid_pll_post"; -+ priv->vid_pll_resets[VPU_RESET_VID_PLL_SOFT_PRE].id = "vid_pll_soft_pre"; -+ priv->vid_pll_resets[VPU_RESET_VID_PLL_SOFT_POST].id = "vid_pll_soft_post"; -+ -+ ret = devm_reset_control_bulk_get_exclusive(dev, -+ VPU_RESET_VID_PLL_NUM, -+ priv->vid_pll_resets); -+ if (ret) -+ goto free_drm; -+ -+ priv->intr_clks[0].id = "vpu_intr"; -+ priv->intr_clks[1].id = "hdmi_intr_sync"; -+ priv->intr_clks[2].id = "venci_int"; -+ priv->num_intr_clks = 3; -+ -+ ret = devm_clk_bulk_get(dev, priv->num_intr_clks, -+ priv->intr_clks); -+ if (ret) -+ goto free_drm; -+ -+ priv->vid_clks[VPU_VID_CLK_TMDS].id = "tmds"; -+ priv->vid_clks[VPU_VID_CLK_HDMI_TX_PIXEL].id = "hdmi_tx_pixel"; -+ priv->vid_clks[VPU_VID_CLK_CTS_ENCP].id = "cts_encp"; -+ priv->vid_clks[VPU_VID_CLK_CTS_ENCI].id = "cts_enci"; -+ priv->vid_clks[VPU_VID_CLK_CTS_ENCT].id = "cts_enct"; -+ priv->vid_clks[VPU_VID_CLK_CTS_ENCL].id = "cts_encl"; -+ priv->vid_clks[VPU_VID_CLK_CTS_VDAC0].id = "cts_vdac0"; -+ -+ ret = devm_clk_bulk_get(dev, VPU_VID_CLK_NUM, priv->vid_clks); -+ if (ret) -+ goto free_drm; -+ } else { -+ priv->intr_clks[0].id = "vpu_intr"; -+ priv->num_intr_clks = 1; -+ -+ ret = devm_clk_bulk_get_optional(dev, priv->num_intr_clks, -+ priv->intr_clks); -+ if (ret) -+ goto free_drm; -+ } -+ -+ ret = meson_video_clock_init(priv); -+ if (ret) -+ goto free_drm; -+ - regs = devm_platform_ioremap_resource_byname(pdev, "vpu"); - if (IS_ERR(regs)) { - ret = PTR_ERR(regs); -- goto free_drm; -+ goto video_clock_exit; - } - - priv->io_base = regs; - -+ /* -+ * The HHI resource is optional because it contains the clocks and CVBS -+ * encoder registers. These are managed by separate drivers though. -+ */ - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hhi"); -- if (!res) { -- ret = -EINVAL; -- goto free_drm; -- } -- /* Simply ioremap since it may be a shared register zone */ -- regs = devm_ioremap(dev, res->start, resource_size(res)); -- if (!regs) { -- ret = -EADDRNOTAVAIL; -- goto free_drm; -- } -+ if (res) { -+ /* Simply ioremap since it may be a shared register zone */ -+ regs = devm_ioremap(dev, res->start, resource_size(res)); -+ if (!regs) { -+ ret = -EADDRNOTAVAIL; -+ goto video_clock_exit; -+ } - -- priv->hhi = devm_regmap_init_mmio(dev, regs, -- &meson_regmap_config); -- if (IS_ERR(priv->hhi)) { -- dev_err(&pdev->dev, "Couldn't create the HHI regmap\n"); -- ret = PTR_ERR(priv->hhi); -- goto free_drm; -+ priv->hhi = devm_regmap_init_mmio(dev, regs, -+ &meson_regmap_config); -+ if (IS_ERR(priv->hhi)) { -+ dev_err(&pdev->dev, -+ "Couldn't create the HHI regmap\n"); -+ ret = PTR_ERR(priv->hhi); -+ goto video_clock_exit; -+ } - } - - priv->canvas = meson_canvas_get(dev); - if (IS_ERR(priv->canvas)) { - ret = PTR_ERR(priv->canvas); -- goto free_drm; -+ goto video_clock_exit; - } - - ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_osd1); - if (ret) -- goto free_drm; -+ goto video_clock_exit; - ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_0); - if (ret) { - meson_canvas_free(priv->canvas, priv->canvas_id_osd1); -- goto free_drm; -+ goto video_clock_exit; - } - ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_1); - if (ret) { - meson_canvas_free(priv->canvas, priv->canvas_id_osd1); - meson_canvas_free(priv->canvas, priv->canvas_id_vd1_0); -- goto free_drm; -+ goto video_clock_exit; - } - ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_2); - if (ret) { - meson_canvas_free(priv->canvas, priv->canvas_id_osd1); - meson_canvas_free(priv->canvas, priv->canvas_id_vd1_0); - meson_canvas_free(priv->canvas, priv->canvas_id_vd1_1); -- goto free_drm; -+ goto video_clock_exit; - } - -+ ret = meson_cvbs_dac_phy_init(priv); -+ if (ret) -+ goto free_drm; -+ - priv->vsync_irq = platform_get_irq(pdev, 0); - - ret = drm_vblank_init(drm, 1); - if (ret) -- goto free_drm; -+ goto exit_cvbs_dac_phy; - - /* Assign limits per soc revision/package */ - for (i = 0 ; i < ARRAY_SIZE(meson_drm_soc_attrs) ; ++i) { -@@ -288,11 +478,11 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) - */ - ret = drm_aperture_remove_framebuffers(&meson_driver); - if (ret) -- goto free_drm; -+ goto exit_cvbs_dac_phy; - - ret = drmm_mode_config_init(drm); - if (ret) -- goto free_drm; -+ goto exit_cvbs_dac_phy; - drm->mode_config.max_width = 3840; - drm->mode_config.max_height = 2160; - drm->mode_config.funcs = &meson_mode_config_funcs; -@@ -307,7 +497,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) - if (priv->afbcd.ops) { - ret = priv->afbcd.ops->init(priv); - if (ret) -- goto free_drm; -+ goto exit_cvbs_dac_phy; - } - - /* Encoder Initialization */ -@@ -362,7 +552,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) - if (ret) - goto uninstall_irq; - -- drm_fbdev_dma_setup(drm, 32); -+ meson_fbdev_setup(priv); - - return 0; - -@@ -371,6 +561,10 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) - exit_afbcd: - if (priv->afbcd.ops) - priv->afbcd.ops->exit(priv); -+exit_cvbs_dac_phy: -+ meson_cvbs_dac_phy_exit(priv); -+video_clock_exit: -+ meson_video_clock_exit(priv); - free_drm: - drm_dev_put(drm); - -@@ -415,6 +609,10 @@ static void meson_drv_unbind(struct device *dev) - - if (priv->afbcd.ops) - priv->afbcd.ops->exit(priv); -+ -+ meson_cvbs_dac_phy_exit(priv); -+ -+ meson_video_clock_exit(priv); - } - - static const struct component_master_ops meson_drv_master_ops = { -@@ -429,6 +627,8 @@ static int __maybe_unused meson_drv_pm_suspend(struct device *dev) - if (!priv) - return 0; - -+ // TODO: video clock suspend -+ - return drm_mode_config_helper_suspend(priv->drm); - } - -@@ -439,6 +639,7 @@ static int __maybe_unused meson_drv_pm_resume(struct device *dev) - if (!priv) - return 0; - -+ meson_video_clock_init(priv); - meson_vpu_init(priv); - meson_venc_init(priv); - meson_vpp_init(priv); -@@ -521,6 +722,18 @@ static void meson_drv_remove(struct platform_device *pdev) - component_master_del(&pdev->dev, &meson_drv_master_ops); - } - -+static struct meson_drm_match_data meson_drm_m8_data = { -+ .compat = VPU_COMPATIBLE_M8, -+}; -+ -+static struct meson_drm_match_data meson_drm_m8b_data = { -+ .compat = VPU_COMPATIBLE_M8B, -+}; -+ -+static struct meson_drm_match_data meson_drm_m8m2_data = { -+ .compat = VPU_COMPATIBLE_M8M2, -+}; -+ - static struct meson_drm_match_data meson_drm_gxbb_data = { - .compat = VPU_COMPATIBLE_GXBB, - }; -@@ -540,6 +753,12 @@ static struct meson_drm_match_data meson_drm_g12a_data = { - }; - - static const struct of_device_id dt_match[] = { -+ { .compatible = "amlogic,meson8-vpu", -+ .data = (void *)&meson_drm_m8_data }, -+ { .compatible = "amlogic,meson8b-vpu", -+ .data = (void *)&meson_drm_m8b_data }, -+ { .compatible = "amlogic,meson8m2-vpu", -+ .data = (void *)&meson_drm_m8m2_data }, - { .compatible = "amlogic,meson-gxbb-vpu", - .data = (void *)&meson_drm_gxbb_data }, - { .compatible = "amlogic,meson-gxl-vpu", -diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h -index 111111111111..222222222222 100644 ---- a/drivers/gpu/drm/meson/meson_drv.h -+++ b/drivers/gpu/drm/meson/meson_drv.h -@@ -7,21 +7,28 @@ - #ifndef __MESON_DRV_H - #define __MESON_DRV_H - -+#include - #include - #include - #include -+#include - - struct drm_crtc; - struct drm_device; - struct drm_plane; - struct meson_drm; - struct meson_afbcd_ops; -+struct phy; -+struct platform_device; - - enum vpu_compatible { -- VPU_COMPATIBLE_GXBB = 0, -- VPU_COMPATIBLE_GXL = 1, -- VPU_COMPATIBLE_GXM = 2, -- VPU_COMPATIBLE_G12A = 3, -+ VPU_COMPATIBLE_M8 = 0, -+ VPU_COMPATIBLE_M8B = 1, -+ VPU_COMPATIBLE_M8M2 = 2, -+ VPU_COMPATIBLE_GXBB = 3, -+ VPU_COMPATIBLE_GXL = 4, -+ VPU_COMPATIBLE_GXM = 5, -+ VPU_COMPATIBLE_G12A = 6, - }; - - enum { -@@ -40,6 +47,25 @@ struct meson_drm_soc_limits { - unsigned int max_hdmi_phy_freq; - }; - -+enum vpu_bulk_clk_id { -+ VPU_VID_CLK_TMDS = 0, -+ VPU_VID_CLK_HDMI_TX_PIXEL, -+ VPU_VID_CLK_CTS_ENCP, -+ VPU_VID_CLK_CTS_ENCI, -+ VPU_VID_CLK_CTS_ENCT, -+ VPU_VID_CLK_CTS_ENCL, -+ VPU_VID_CLK_CTS_VDAC0, -+ VPU_VID_CLK_NUM -+}; -+ -+enum vpu_bulk_vid_pll_reset_id { -+ VPU_RESET_VID_PLL_PRE = 0, -+ VPU_RESET_VID_PLL_POST, -+ VPU_RESET_VID_PLL_SOFT_PRE, -+ VPU_RESET_VID_PLL_SOFT_POST, -+ VPU_RESET_VID_PLL_NUM -+}; -+ - struct meson_drm { - struct device *dev; - enum vpu_compatible compat; -@@ -61,6 +87,21 @@ struct meson_drm { - - const struct meson_drm_soc_limits *limits; - -+ struct phy *cvbs_dac; -+ bool cvbs_dac_enabled; -+ struct platform_device *cvbs_dac_pdev; -+ -+ struct clk_bulk_data intr_clks[3]; -+ unsigned int num_intr_clks; -+ bool intr_clks_enabled; -+ struct clk_bulk_data vid_clks[VPU_VID_CLK_NUM]; -+ bool vid_clk_rate_exclusive[VPU_VID_CLK_NUM]; -+ struct clk *clk_venc; -+ bool clk_venc_enabled; -+ struct clk *clk_dac; -+ bool clk_dac_enabled; -+ struct reset_control_bulk_data vid_pll_resets[VPU_RESET_VID_PLL_NUM]; -+ - /* Components Data */ - struct { - bool osd1_enabled; -diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c -index 111111111111..222222222222 100644 ---- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c -+++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c -@@ -11,6 +11,7 @@ - - #include - #include -+#include - - #include - #include -@@ -24,12 +25,6 @@ - #include "meson_vclk.h" - #include "meson_encoder_cvbs.h" - --/* HHI VDAC Registers */ --#define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */ --#define HHI_VDAC_CNTL0_G12A 0x2EC /* 0xbd offset in data sheet */ --#define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */ --#define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbe offset in data sheet */ -- - struct meson_encoder_cvbs { - struct drm_encoder encoder; - struct drm_bridge bridge; -@@ -87,11 +82,28 @@ static int meson_encoder_cvbs_attach(struct drm_bridge *bridge, - { - struct meson_encoder_cvbs *meson_encoder_cvbs = - bridge_to_meson_encoder_cvbs(bridge); -+ int ret; -+ -+ ret = phy_init(meson_encoder_cvbs->priv->cvbs_dac); -+ if (ret) -+ return ret; - - return drm_bridge_attach(bridge->encoder, meson_encoder_cvbs->next_bridge, - &meson_encoder_cvbs->bridge, flags); - } - -+static void meson_encoder_cvbs_detach(struct drm_bridge *bridge) -+{ -+ struct meson_encoder_cvbs *meson_encoder_cvbs = -+ bridge_to_meson_encoder_cvbs(bridge); -+ int ret; -+ -+ ret = phy_exit(meson_encoder_cvbs->priv->cvbs_dac); -+ if (ret) -+ dev_err(meson_encoder_cvbs->priv->dev, -+ "Failed to exit the CVBS DAC\n"); -+} -+ - static int meson_encoder_cvbs_get_modes(struct drm_bridge *bridge, - struct drm_connector *connector) - { -@@ -148,6 +160,7 @@ static void meson_encoder_cvbs_atomic_enable(struct drm_bridge *bridge, - struct drm_connector_state *conn_state; - struct drm_crtc_state *crtc_state; - struct drm_connector *connector; -+ int ret; - - connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); - if (WARN_ON(!connector)) -@@ -177,16 +190,13 @@ static void meson_encoder_cvbs_atomic_enable(struct drm_bridge *bridge, - writel_bits_relaxed(VENC_VDAC_SEL_ATV_DMD, 0, - priv->io_base + _REG(VENC_VDAC_DACSEL0)); - -- if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) { -- regmap_write(priv->hhi, HHI_VDAC_CNTL0, 1); -- regmap_write(priv->hhi, HHI_VDAC_CNTL1, 0); -- } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) || -- meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) { -- regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0xf0001); -- regmap_write(priv->hhi, HHI_VDAC_CNTL1, 0); -- } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { -- regmap_write(priv->hhi, HHI_VDAC_CNTL0_G12A, 0x906001); -- regmap_write(priv->hhi, HHI_VDAC_CNTL1_G12A, 0); -+ if (!priv->cvbs_dac_enabled) { -+ ret = phy_power_on(priv->cvbs_dac); -+ if (ret) -+ dev_err(priv->dev, -+ "Failed to power on the CVBS DAC\n"); -+ else -+ priv->cvbs_dac_enabled = true; - } - } - -@@ -196,19 +206,22 @@ static void meson_encoder_cvbs_atomic_disable(struct drm_bridge *bridge, - struct meson_encoder_cvbs *meson_encoder_cvbs = - bridge_to_meson_encoder_cvbs(bridge); - struct meson_drm *priv = meson_encoder_cvbs->priv; -+ int ret; - -- /* Disable CVBS VDAC */ -- if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { -- regmap_write(priv->hhi, HHI_VDAC_CNTL0_G12A, 0); -- regmap_write(priv->hhi, HHI_VDAC_CNTL1_G12A, 0); -- } else { -- regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0); -- regmap_write(priv->hhi, HHI_VDAC_CNTL1, 8); -- } -+ if (!priv->cvbs_dac_enabled) -+ return; -+ -+ ret = phy_power_off(priv->cvbs_dac); -+ if (ret) -+ dev_err(priv->dev, -+ "Failed to power off the CVBS DAC\n"); -+ else -+ priv->cvbs_dac_enabled = false; - } - - static const struct drm_bridge_funcs meson_encoder_cvbs_bridge_funcs = { - .attach = meson_encoder_cvbs_attach, -+ .detach = meson_encoder_cvbs_detach, - .mode_valid = meson_encoder_cvbs_mode_valid, - .get_modes = meson_encoder_cvbs_get_modes, - .atomic_enable = meson_encoder_cvbs_atomic_enable, -diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c -index 111111111111..222222222222 100644 ---- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c -+++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c -@@ -190,13 +190,13 @@ static void meson_encoder_hdmi_atomic_enable(struct drm_bridge *bridge, - { - struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge); - struct drm_atomic_state *state = bridge_state->base.state; -- unsigned int ycrcb_map = VPU_HDMI_OUTPUT_CBYCR; - struct meson_drm *priv = encoder_hdmi->priv; - struct drm_connector_state *conn_state; - const struct drm_display_mode *mode; - struct drm_crtc_state *crtc_state; - struct drm_connector *connector; - bool yuv420_mode = false; -+ unsigned int ycrcb_map; - int vic; - - connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); -@@ -217,7 +217,14 @@ static void meson_encoder_hdmi_atomic_enable(struct drm_bridge *bridge, - - dev_dbg(priv->dev, "\"%s\" vic %d\n", mode->name, vic); - -- if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) { -+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) { -+ if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_RGB888_1X24) -+ ycrcb_map = VPU_HDMI_OUTPUT_YCBCR; -+ else -+ ycrcb_map = VPU_HDMI_OUTPUT_CRYCB; -+ } else if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) { - ycrcb_map = VPU_HDMI_OUTPUT_CRYCB; - yuv420_mode = true; - } else if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYVY8_1X16) -@@ -229,17 +236,22 @@ static void meson_encoder_hdmi_atomic_enable(struct drm_bridge *bridge, - /* VCLK Set clock */ - meson_encoder_hdmi_set_vclk(encoder_hdmi, mode); - -- if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) -- /* Setup YUV420 to HDMI-TX, no 10bit diphering */ -- writel_relaxed(2 | (2 << 2), -- priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); -- else if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYVY8_1X16) -- /* Setup YUV422 to HDMI-TX, no 10bit diphering */ -- writel_relaxed(1 | (2 << 2), -- priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); -- else -- /* Setup YUV444 to HDMI-TX, no 10bit diphering */ -- writel_relaxed(0, priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); -+ if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) && -+ !meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) && -+ !meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) { -+ if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) -+ /* Setup YUV420 to HDMI-TX, no 10bit diphering */ -+ writel_relaxed(2 | (2 << 2), -+ priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); -+ else if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYVY8_1X16) -+ /* Setup YUV422 to HDMI-TX, no 10bit diphering */ -+ writel_relaxed(1 | (2 << 2), -+ priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); -+ else -+ /* Setup YUV444 to HDMI-TX, no 10bit diphering */ -+ writel_relaxed(0, -+ priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); -+ } - - dev_dbg(priv->dev, "%s\n", priv->venc.hdmi_use_enci ? "VENCI" : "VENCP"); - -@@ -262,7 +274,11 @@ static void meson_encoder_hdmi_atomic_disable(struct drm_bridge *bridge, - writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN)); - } - --static const u32 meson_encoder_hdmi_out_bus_fmts[] = { -+static const u32 meson8_encoder_hdmi_out_bus_fmts[] = { -+ MEDIA_BUS_FMT_YUV8_1X24, -+}; -+ -+static const u32 meson_gx_encoder_hdmi_out_bus_fmts[] = { - MEDIA_BUS_FMT_YUV8_1X24, - MEDIA_BUS_FMT_UYVY8_1X16, - MEDIA_BUS_FMT_UYYVYY8_0_5X24, -@@ -276,13 +292,27 @@ meson_encoder_hdmi_get_inp_bus_fmts(struct drm_bridge *bridge, - u32 output_fmt, - unsigned int *num_input_fmts) - { -+ struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge); -+ struct meson_drm *priv = encoder_hdmi->priv; -+ unsigned int num_out_bus_fmts; -+ const u32 *out_bus_fmts; - u32 *input_fmts = NULL; - int i; - -+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) { -+ num_out_bus_fmts = ARRAY_SIZE(meson8_encoder_hdmi_out_bus_fmts); -+ out_bus_fmts = meson8_encoder_hdmi_out_bus_fmts; -+ } else { -+ num_out_bus_fmts = ARRAY_SIZE(meson_gx_encoder_hdmi_out_bus_fmts); -+ out_bus_fmts = meson_gx_encoder_hdmi_out_bus_fmts; -+ } -+ - *num_input_fmts = 0; - -- for (i = 0 ; i < ARRAY_SIZE(meson_encoder_hdmi_out_bus_fmts) ; ++i) { -- if (output_fmt == meson_encoder_hdmi_out_bus_fmts[i]) { -+ for (i = 0 ; i < num_out_bus_fmts ; ++i) { -+ if (output_fmt == out_bus_fmts[i]) { - *num_input_fmts = 1; - input_fmts = kcalloc(*num_input_fmts, - sizeof(*input_fmts), -@@ -436,8 +466,11 @@ int meson_encoder_hdmi_init(struct meson_drm *priv) - - drm_connector_attach_max_bpc_property(meson_encoder_hdmi->connector, 8, 8); - -- /* Handle this here until handled by drm_bridge_connector_init() */ -- meson_encoder_hdmi->connector->ycbcr_420_allowed = true; -+ if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) && -+ !meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) && -+ !meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) -+ /* Handle this here until handled by drm_bridge_connector_init() */ -+ meson_encoder_hdmi->connector->ycbcr_420_allowed = true; - - pdev = of_find_device_by_node(remote); - of_node_put(remote); -diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c -index 111111111111..222222222222 100644 ---- a/drivers/gpu/drm/meson/meson_plane.c -+++ b/drivers/gpu/drm/meson/meson_plane.c -@@ -200,8 +200,11 @@ static void meson_plane_atomic_update(struct drm_plane *plane, - priv->viu.osd1_ctrl_stat2 &= ~OSD_DPATH_MALI_AFBCD; - } - -- /* On GXBB, Use the old non-HDR RGB2YUV converter */ -- if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) -+ /* On GXBB and earlier, Use the old non-HDR RGB2YUV converter */ -+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) - priv->viu.osd1_blk0_cfg[0] |= OSD_OUTPUT_COLOR_RGB; - - if (priv->viu.osd1_afbcd && -@@ -471,7 +474,20 @@ static const struct drm_plane_funcs meson_plane_funcs = { - .format_mod_supported = meson_plane_format_mod_supported, - }; - --static const uint32_t supported_drm_formats[] = { -+/* -+ * X components (for example in DRM_FORMAT_XRGB8888 and DRM_FORMAT_XBGR8888) -+ * are not supported because these older SoC's are lacking the OSD_REPLACE_EN -+ * bit to replace the X alpha component with a static value, leaving the alpha -+ * component in an undefined state. -+ */ -+static const uint32_t supported_drm_formats_m8[] = { -+ DRM_FORMAT_ARGB8888, -+ DRM_FORMAT_ABGR8888, -+ DRM_FORMAT_RGB888, -+ DRM_FORMAT_RGB565, -+}; -+ -+static const uint32_t supported_drm_formats_gx[] = { - DRM_FORMAT_ARGB8888, - DRM_FORMAT_ABGR8888, - DRM_FORMAT_XRGB8888, -@@ -533,6 +549,8 @@ int meson_plane_create(struct meson_drm *priv) - { - struct meson_plane *meson_plane; - struct drm_plane *plane; -+ unsigned int num_drm_formats; -+ const uint32_t *drm_formats; - const uint64_t *format_modifiers = format_modifiers_default; - - meson_plane = devm_kzalloc(priv->drm->dev, sizeof(*meson_plane), -@@ -548,10 +566,19 @@ int meson_plane_create(struct meson_drm *priv) - else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) - format_modifiers = format_modifiers_afbc_g12a; - -+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) { -+ drm_formats = supported_drm_formats_m8; -+ num_drm_formats = ARRAY_SIZE(supported_drm_formats_m8); -+ } else { -+ drm_formats = supported_drm_formats_gx; -+ num_drm_formats = ARRAY_SIZE(supported_drm_formats_gx); -+ } -+ - drm_universal_plane_init(priv->drm, plane, 0xFF, - &meson_plane_funcs, -- supported_drm_formats, -- ARRAY_SIZE(supported_drm_formats), -+ drm_formats, num_drm_formats, - format_modifiers, - DRM_PLANE_TYPE_PRIMARY, "meson_primary_plane"); - -diff --git a/drivers/gpu/drm/meson/meson_transwitch_hdmi.c b/drivers/gpu/drm/meson/meson_transwitch_hdmi.c -new file mode 100644 -index 000000000000..111111111111 ---- /dev/null -+++ b/drivers/gpu/drm/meson/meson_transwitch_hdmi.c -@@ -0,0 +1,1579 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2021 Martin Blumenstingl -+ * -+ * All registers and magic values are taken from Amlogic's GPL kernel sources: -+ * Copyright (C) 2010 Amlogic, Inc. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+ -+#include "meson_transwitch_hdmi.h" -+ -+#define HDMI_ADDR_PORT 0x0 -+#define HDMI_DATA_PORT 0x4 -+#define HDMI_CTRL_PORT 0x8 -+ #define HDMI_CTRL_PORT_APB3_ERR_EN BIT(15) -+ -+struct meson_txc_hdmi { -+ struct device *dev; -+ -+ struct regmap *regmap; -+ -+ struct clk *pclk; -+ struct clk *sys_clk; -+ -+ struct phy *phy; -+ bool phy_is_on; -+ -+ struct mutex codec_mutex; -+ enum drm_connector_status last_connector_status; -+ hdmi_codec_plugged_cb codec_plugged_cb; -+ struct device *codec_dev; -+ -+ struct platform_device *hdmi_codec_pdev; -+ -+ struct drm_connector *current_connector; -+ -+ struct drm_bridge bridge; -+ struct drm_bridge *next_bridge; -+ -+ bool sink_is_hdmi; -+}; -+ -+#define bridge_to_meson_txc_hdmi(x) container_of(x, struct meson_txc_hdmi, bridge) -+ -+static const struct regmap_range meson_txc_hdmi_regmap_ranges[] = { -+ regmap_reg_range(0x0000, 0x07ff), -+ regmap_reg_range(0x8000, 0x800c), -+}; -+ -+static const struct regmap_access_table meson_txc_hdmi_regmap_access = { -+ .yes_ranges = meson_txc_hdmi_regmap_ranges, -+ .n_yes_ranges = ARRAY_SIZE(meson_txc_hdmi_regmap_ranges), -+}; -+ -+static int meson_txc_hdmi_reg_read(void *context, unsigned int addr, -+ unsigned int *data) -+{ -+ void __iomem *base = context; -+ -+ writel(addr, base + HDMI_ADDR_PORT); -+ writel(addr, base + HDMI_ADDR_PORT); -+ -+ *data = readl(base + HDMI_DATA_PORT); -+ -+ return 0; -+} -+ -+static int meson_txc_hdmi_reg_write(void *context, unsigned int addr, -+ unsigned int data) -+{ -+ void __iomem *base = context; -+ -+ writel(addr, base + HDMI_ADDR_PORT); -+ writel(addr, base + HDMI_ADDR_PORT); -+ -+ writel(data, base + HDMI_DATA_PORT); -+ -+ return 0; -+} -+ -+static const struct regmap_config meson_txc_hdmi_regmap_config = { -+ .reg_bits = 16, -+ .val_bits = 16, -+ .reg_stride = 1, -+ .reg_read = meson_txc_hdmi_reg_read, -+ .reg_write = meson_txc_hdmi_reg_write, -+ .rd_table = &meson_txc_hdmi_regmap_access, -+ .wr_table = &meson_txc_hdmi_regmap_access, -+ .max_register = HDMI_OTHER_RX_PACKET_INTR_CLR, -+ .fast_io = true, -+}; -+ -+static void meson_txc_hdmi_write_infoframe(struct regmap *regmap, -+ unsigned int tx_pkt_reg, u8 *buf, -+ unsigned int len, bool enable) -+{ -+ unsigned int i; -+ -+ /* Write the data bytes by starting at register offset 1 */ -+ for (i = HDMI_INFOFRAME_HEADER_SIZE; i < len; i++) -+ regmap_write(regmap, -+ tx_pkt_reg + i - HDMI_INFOFRAME_HEADER_SIZE + 1, -+ buf[i]); -+ -+ /* Zero all remaining data bytes */ -+ for (; i < 0x1c; i++) -+ regmap_write(regmap, tx_pkt_reg + i, 0x00); -+ -+ /* Write the header (which we skipped above) */ -+ regmap_write(regmap, tx_pkt_reg + 0x00, buf[3]); -+ regmap_write(regmap, tx_pkt_reg + 0x1c, buf[0]); -+ regmap_write(regmap, tx_pkt_reg + 0x1d, buf[1]); -+ regmap_write(regmap, tx_pkt_reg + 0x1e, buf[2]); -+ -+ regmap_write(regmap, tx_pkt_reg + 0x1f, enable ? 0xff : 0x00); -+} -+ -+static void meson_txc_hdmi_disable_infoframe(struct meson_txc_hdmi *priv, -+ unsigned int tx_pkt_reg) -+{ -+ u8 buf[HDMI_INFOFRAME_HEADER_SIZE] = { 0 }; -+ -+ meson_txc_hdmi_write_infoframe(priv->regmap, tx_pkt_reg, buf, -+ HDMI_INFOFRAME_HEADER_SIZE, false); -+} -+ -+static void meson_txc_hdmi_sys5_reset_assert(struct meson_txc_hdmi *priv) -+{ -+ /* A comment in the vendor driver says: bit5,6 is converted */ -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_2, -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH3_RST_IN | -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH0_RST_IN); -+ usleep_range(10, 20); -+ -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_2, -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH2_RST_IN | -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH1_RST_IN); -+ usleep_range(10, 20); -+ -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_1, -+ TX_SYS5_TX_SOFT_RESET_1_TX_PIXEL_RSTN | -+ TX_SYS5_TX_SOFT_RESET_1_TX_TMDS_RSTN | -+ TX_SYS5_TX_SOFT_RESET_1_TX_AUDIO_MASTER_RSTN | -+ TX_SYS5_TX_SOFT_RESET_1_TX_AUDIO_RESAMPLE_RSTN | -+ TX_SYS5_TX_SOFT_RESET_1_TX_I2S_RESET_RSTN | -+ TX_SYS5_TX_SOFT_RESET_1_TX_DIG_RESET_N_CH2 | -+ TX_SYS5_TX_SOFT_RESET_1_TX_DIG_RESET_N_CH1 | -+ TX_SYS5_TX_SOFT_RESET_1_TX_DIG_RESET_N_CH0); -+ usleep_range(10, 20); -+} -+ -+static void meson_txc_hdmi_sys5_reset_deassert(struct meson_txc_hdmi *priv) -+{ -+ /* Release the resets except tmds_clk */ -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_1, -+ TX_SYS5_TX_SOFT_RESET_1_TX_TMDS_RSTN); -+ usleep_range(10, 20); -+ -+ /* Release the tmds_clk reset as well */ -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_1, 0x0); -+ usleep_range(10, 20); -+ -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_2, -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH2_RST_IN | -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH1_RST_IN | -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_SR_RST); -+ usleep_range(10, 20); -+ -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_2, -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH2_RST_IN | -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH1_RST_IN); -+ usleep_range(10, 20); -+} -+ -+static void meson_txc_hdmi_config_hdcp_registers(struct meson_txc_hdmi *priv) -+{ -+ regmap_write(priv->regmap, TX_HDCP_CONFIG0, -+ FIELD_PREP(TX_HDCP_CONFIG0_ROM_ENCRYPT_OFF, 0x3)); -+ regmap_write(priv->regmap, TX_HDCP_MEM_CONFIG, 0x0); -+ regmap_write(priv->regmap, TX_HDCP_ENCRYPT_BYTE, 0x0); -+ -+ regmap_write(priv->regmap, TX_HDCP_MODE, TX_HDCP_MODE_CLEAR_AVMUTE); -+ -+ regmap_write(priv->regmap, TX_HDCP_MODE, TX_HDCP_MODE_ESS_CONFIG); -+} -+ -+static u8 meson_txc_hdmi_bus_fmt_to_color_depth(unsigned int bus_format) -+{ -+ switch (bus_format) { -+ case MEDIA_BUS_FMT_RGB888_1X24: -+ case MEDIA_BUS_FMT_YUV8_1X24: -+ case MEDIA_BUS_FMT_UYVY8_1X16: -+ /* 8 bit */ -+ return 0x0; -+ -+ case MEDIA_BUS_FMT_RGB101010_1X30: -+ case MEDIA_BUS_FMT_YUV10_1X30: -+ case MEDIA_BUS_FMT_UYVY10_1X20: -+ /* 10 bit */ -+ return 0x1; -+ -+ case MEDIA_BUS_FMT_RGB121212_1X36: -+ case MEDIA_BUS_FMT_YUV12_1X36: -+ case MEDIA_BUS_FMT_UYVY12_1X24: -+ /* 12 bit */ -+ return 0x2; -+ -+ case MEDIA_BUS_FMT_RGB161616_1X48: -+ case MEDIA_BUS_FMT_YUV16_1X48: -+ /* 16 bit */ -+ return 0x3; -+ -+ default: -+ /* unknown, default to 8 bit */ -+ return 0x0; -+ } -+} -+ -+static u8 meson_txc_hdmi_bus_fmt_to_color_format(unsigned int bus_format) -+{ -+ switch (bus_format) { -+ case MEDIA_BUS_FMT_YUV8_1X24: -+ case MEDIA_BUS_FMT_YUV10_1X30: -+ case MEDIA_BUS_FMT_YUV12_1X36: -+ case MEDIA_BUS_FMT_YUV16_1X48: -+ /* Documented as YCbCr444 */ -+ return 0x1; -+ -+ case MEDIA_BUS_FMT_UYVY8_1X16: -+ case MEDIA_BUS_FMT_UYVY10_1X20: -+ case MEDIA_BUS_FMT_UYVY12_1X24: -+ /* Documented as YCbCr422 */ -+ return 0x3; -+ -+ case MEDIA_BUS_FMT_RGB888_1X24: -+ case MEDIA_BUS_FMT_RGB101010_1X30: -+ case MEDIA_BUS_FMT_RGB121212_1X36: -+ case MEDIA_BUS_FMT_RGB161616_1X48: -+ default: -+ /* Documented as RGB444 */ -+ return 0x0; -+ } -+} -+ -+static void meson_txc_hdmi_config_color_space(struct meson_txc_hdmi *priv, -+ unsigned int input_bus_format, -+ unsigned int output_bus_format, -+ enum hdmi_quantization_range quant_range, -+ enum hdmi_colorimetry colorimetry) -+{ -+ unsigned int regval; -+ -+ regmap_write(priv->regmap, TX_VIDEO_DTV_MODE, -+ FIELD_PREP(TX_VIDEO_DTV_MODE_COLOR_DEPTH, -+ meson_txc_hdmi_bus_fmt_to_color_depth(output_bus_format))); -+ -+ regmap_write(priv->regmap, TX_VIDEO_DTV_OPTION_L, -+ FIELD_PREP(TX_VIDEO_DTV_OPTION_L_OUTPUT_COLOR_FORMAT, -+ meson_txc_hdmi_bus_fmt_to_color_format(output_bus_format)) | -+ FIELD_PREP(TX_VIDEO_DTV_OPTION_L_INPUT_COLOR_FORMAT, -+ meson_txc_hdmi_bus_fmt_to_color_format(input_bus_format)) | -+ FIELD_PREP(TX_VIDEO_DTV_OPTION_L_OUTPUT_COLOR_DEPTH, -+ meson_txc_hdmi_bus_fmt_to_color_depth(output_bus_format)) | -+ FIELD_PREP(TX_VIDEO_DTV_OPTION_L_INPUT_COLOR_DEPTH, -+ meson_txc_hdmi_bus_fmt_to_color_depth(input_bus_format))); -+ -+ if (quant_range == HDMI_QUANTIZATION_RANGE_LIMITED) -+ regval = FIELD_PREP(TX_VIDEO_DTV_OPTION_H_OUTPUT_COLOR_RANGE, -+ TX_VIDEO_DTV_OPTION_H_COLOR_RANGE_16_235) | -+ FIELD_PREP(TX_VIDEO_DTV_OPTION_H_INPUT_COLOR_RANGE, -+ TX_VIDEO_DTV_OPTION_H_COLOR_RANGE_16_235); -+ else -+ regval = FIELD_PREP(TX_VIDEO_DTV_OPTION_H_OUTPUT_COLOR_RANGE, -+ TX_VIDEO_DTV_OPTION_H_COLOR_RANGE_0_255) | -+ FIELD_PREP(TX_VIDEO_DTV_OPTION_H_INPUT_COLOR_RANGE, -+ TX_VIDEO_DTV_OPTION_H_COLOR_RANGE_0_255); -+ -+ regmap_write(priv->regmap, TX_VIDEO_DTV_OPTION_H, regval); -+ -+ if (colorimetry == HDMI_COLORIMETRY_ITU_601) { -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_B0, 0x2f); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_B1, 0x1d); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_R0, 0x8b); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_R1, 0x4c); -+ -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_CB0, 0x18); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_CB1, 0x58); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_CR0, 0xd0); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_CR1, 0xb6); -+ } else { -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_B0, 0x7b); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_B1, 0x12); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_R0, 0x6c); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_R1, 0x36); -+ -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_CB0, 0xf2); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_CB1, 0x2f); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_CR0, 0xd4); -+ regmap_write(priv->regmap, TX_VIDEO_CSC_COEFF_CR1, 0x77); -+ } -+} -+ -+static void meson_txc_hdmi_config_serializer_clock(struct meson_txc_hdmi *priv, -+ enum hdmi_colorimetry colorimetry) -+{ -+ /* Serializer Internal clock setting */ -+ if (colorimetry == HDMI_COLORIMETRY_ITU_601) -+ regmap_write(priv->regmap, TX_SYS1_PLL, 0x24); -+ else -+ regmap_write(priv->regmap, TX_SYS1_PLL, 0x22); -+ -+#if 0 -+ // TODO: not ported yet -+ if ((param->VIC==HDMI_1080p60)&&(param->color_depth==COLOR_30BIT)&&(hdmi_rd_reg(0x018)==0x22)) { -+ regmap_write(priv->regmap, TX_SYS1_PLL, 0x12); -+ } -+#endif -+} -+ -+static void meson_txc_hdmi_reconfig_packet_setting(struct meson_txc_hdmi *priv, -+ u8 cea_mode) -+{ -+ u8 alloc_active2, alloc_eof1, alloc_sof1, alloc_sof2; -+ -+ regmap_write(priv->regmap, TX_PACKET_CONTROL_1, -+ FIELD_PREP(TX_PACKET_CONTROL_1_PACKET_START_LATENCY, 58)); -+ regmap_write(priv->regmap, TX_PACKET_CONTROL_2, -+ TX_PACKET_CONTROL_2_HORIZONTAL_GC_PACKET_TRANSPORT_EN); -+ -+ switch (cea_mode) { -+ case 31: -+ /* 1920x1080p50 */ -+ alloc_active2 = 0x12; -+ alloc_eof1 = 0x10; -+ alloc_sof1 = 0xb6; -+ alloc_sof2 = 0x11; -+ break; -+ case 93: -+ /* 3840x2160p24 */ -+ alloc_active2 = 0x12; -+ alloc_eof1 = 0x47; -+ alloc_sof1 = 0xf8; -+ alloc_sof2 = 0x52; -+ break; -+ case 94: -+ /* 3840x2160p25 */ -+ alloc_active2 = 0x12; -+ alloc_eof1 = 0x44; -+ alloc_sof1 = 0xda; -+ alloc_sof2 = 0x52; -+ break; -+ case 95: -+ /* 3840x2160p30 */ -+ alloc_active2 = 0x0f; -+ alloc_eof1 = 0x3a; -+ alloc_sof1 = 0x60; -+ alloc_sof2 = 0x52; -+ break; -+ case 98: -+ /* 4096x2160p24 */ -+ alloc_active2 = 0x12; -+ alloc_eof1 = 0x47; -+ alloc_sof1 = 0xf8; -+ alloc_sof2 = 0x52; -+ break; -+ default: -+ /* Disable the special packet settings only */ -+ regmap_write(priv->regmap, TX_PACKET_ALLOC_ACTIVE_1, 0x00); -+ return; -+ } -+ -+ /* -+ * The vendor driver says: manually configure these register to get -+ * stable video timings. -+ */ -+ regmap_write(priv->regmap, TX_PACKET_ALLOC_ACTIVE_1, 0x01); -+ regmap_write(priv->regmap, TX_PACKET_ALLOC_ACTIVE_2, alloc_active2); -+ regmap_write(priv->regmap, TX_PACKET_ALLOC_EOF_1, alloc_eof1); -+ regmap_write(priv->regmap, TX_PACKET_ALLOC_EOF_2, 0x12); -+ regmap_write(priv->regmap, TX_CORE_ALLOC_VSYNC_0, 0x01); -+ regmap_write(priv->regmap, TX_CORE_ALLOC_VSYNC_1, 0x00); -+ regmap_write(priv->regmap, TX_CORE_ALLOC_VSYNC_2, 0x0a); -+ regmap_write(priv->regmap, TX_PACKET_ALLOC_SOF_1, alloc_sof1); -+ regmap_write(priv->regmap, TX_PACKET_ALLOC_SOF_2, alloc_sof2); -+ regmap_update_bits(priv->regmap, TX_PACKET_CONTROL_1, -+ TX_PACKET_CONTROL_1_FORCE_PACKET_TIMING, -+ TX_PACKET_CONTROL_1_FORCE_PACKET_TIMING); -+} -+ -+static void meson_txc_hdmi_set_avi_infoframe(struct meson_txc_hdmi *priv, -+ struct drm_connector *conn, -+ const struct drm_display_mode *mode, -+ const struct drm_connector_state *conn_state, -+ unsigned int output_bus_format, -+ enum hdmi_quantization_range quant_range, -+ enum hdmi_colorimetry colorimetry) -+{ -+ u8 buf[HDMI_INFOFRAME_SIZE(AVI)], *video_code; -+ struct hdmi_avi_infoframe frame; -+ int ret; -+ -+ ret = drm_hdmi_avi_infoframe_from_display_mode(&frame, conn, mode); -+ if (ret < 0) { -+ drm_err(priv->bridge.dev, -+ "Failed to setup AVI infoframe: %d\n", ret); -+ return; -+ } -+ -+ switch (output_bus_format) { -+ case MEDIA_BUS_FMT_YUV8_1X24: -+ case MEDIA_BUS_FMT_YUV10_1X30: -+ case MEDIA_BUS_FMT_YUV12_1X36: -+ case MEDIA_BUS_FMT_YUV16_1X48: -+ frame.colorspace = HDMI_COLORSPACE_YUV444; -+ break; -+ -+ case MEDIA_BUS_FMT_UYVY8_1X16: -+ case MEDIA_BUS_FMT_UYVY10_1X20: -+ case MEDIA_BUS_FMT_UYVY12_1X24: -+ frame.colorspace = HDMI_COLORSPACE_YUV422; -+ break; -+ -+ case MEDIA_BUS_FMT_RGB888_1X24: -+ case MEDIA_BUS_FMT_RGB101010_1X30: -+ case MEDIA_BUS_FMT_RGB121212_1X36: -+ case MEDIA_BUS_FMT_RGB161616_1X48: -+ default: -+ frame.colorspace = HDMI_COLORSPACE_RGB; -+ break; -+ } -+ -+ drm_hdmi_avi_infoframe_colorimetry(&frame, conn_state); -+ drm_hdmi_avi_infoframe_quant_range(&frame, conn, mode, quant_range); -+ drm_hdmi_avi_infoframe_bars(&frame, conn_state); -+ -+ ret = hdmi_avi_infoframe_pack(&frame, buf, sizeof(buf)); -+ if (ret < 0) { -+ drm_err(priv->bridge.dev, -+ "Failed to pack AVI infoframe: %d\n", ret); -+ return; -+ } -+ -+ video_code = &buf[HDMI_INFOFRAME_HEADER_SIZE + 3]; -+ if (*video_code > 108) { -+ regmap_write(priv->regmap, TX_PKT_REG_EXCEPT0_BASE_ADDR, -+ *video_code); -+ *video_code = 0x00; -+ } else { -+ regmap_write(priv->regmap, TX_PKT_REG_EXCEPT0_BASE_ADDR, -+ 0x00); -+ } -+ -+ meson_txc_hdmi_write_infoframe(priv->regmap, -+ TX_PKT_REG_AVI_INFO_BASE_ADDR, buf, -+ sizeof(buf), true); -+} -+ -+static void meson_txc_hdmi_set_vendor_infoframe(struct meson_txc_hdmi *priv, -+ struct drm_connector *conn, -+ const struct drm_display_mode *mode) -+{ -+ u8 buf[HDMI_INFOFRAME_HEADER_SIZE + 6]; -+ struct hdmi_vendor_infoframe frame; -+ int ret; -+ -+ ret = drm_hdmi_vendor_infoframe_from_display_mode(&frame, conn, mode); -+ if (ret) { -+ drm_dbg(priv->bridge.dev, -+ "Failed to setup vendor infoframe: %d\n", ret); -+ return; -+ } -+ -+ ret = hdmi_vendor_infoframe_pack(&frame, buf, sizeof(buf)); -+ if (ret < 0) { -+ drm_err(priv->bridge.dev, -+ "Failed to pack vendor infoframe: %d\n", ret); -+ return; -+ } -+ -+ meson_txc_hdmi_write_infoframe(priv->regmap, -+ TX_PKT_REG_VEND_INFO_BASE_ADDR, buf, -+ sizeof(buf), true); -+} -+ -+static void meson_txc_hdmi_set_spd_infoframe(struct meson_txc_hdmi *priv) -+{ -+ u8 buf[HDMI_INFOFRAME_SIZE(SPD)]; -+ struct hdmi_spd_infoframe frame; -+ int ret; -+ -+ ret = hdmi_spd_infoframe_init(&frame, "Amlogic", "Meson TXC HDMI"); -+ if (ret < 0) { -+ drm_err(priv->bridge.dev, -+ "Failed to setup SPD infoframe: %d\n", ret); -+ return; -+ } -+ -+ ret = hdmi_spd_infoframe_pack(&frame, buf, sizeof(buf)); -+ if (ret < 0) { -+ drm_err(priv->bridge.dev, -+ "Failed to pack SDP infoframe: %d\n", ret); -+ return; -+ } -+ -+ meson_txc_hdmi_write_infoframe(priv->regmap, -+ TX_PKT_REG_SPD_INFO_BASE_ADDR, buf, -+ sizeof(buf), true); -+} -+ -+static void meson_txc_hdmi_handle_plugged_change(struct meson_txc_hdmi *priv) -+{ -+ bool plugged; -+ -+ plugged = priv->last_connector_status == connector_status_connected; -+ -+ if (priv->codec_dev && priv->codec_plugged_cb) -+ priv->codec_plugged_cb(priv->codec_dev, plugged); -+} -+ -+static int meson_txc_hdmi_bridge_attach(struct drm_bridge *bridge, -+ enum drm_bridge_attach_flags flags) -+{ -+ struct meson_txc_hdmi *priv = bridge->driver_private; -+ -+ if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) { -+ drm_err(bridge->dev, -+ "DRM_BRIDGE_ATTACH_NO_CONNECTOR flag is not set but needed\n"); -+ return -EINVAL; -+ } -+ -+ return drm_bridge_attach(bridge->encoder, priv->next_bridge, bridge, -+ flags); -+} -+ -+/* Can return a maximum of 11 possible output formats for a mode/connector */ -+#define MAX_OUTPUT_SEL_FORMATS 11 -+ -+static u32 * -+meson_txc_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, -+ struct drm_bridge_state *bridge_state, -+ struct drm_crtc_state *crtc_state, -+ struct drm_connector_state *conn_state, -+ unsigned int *num_output_fmts) -+{ -+ struct drm_connector *conn = conn_state->connector; -+ struct drm_display_info *info = &conn->display_info; -+ u8 max_bpc = conn_state->max_requested_bpc; -+ unsigned int i = 0; -+ u32 *output_fmts; -+ -+ *num_output_fmts = 0; -+ -+ output_fmts = kcalloc(MAX_OUTPUT_SEL_FORMATS, sizeof(*output_fmts), -+ GFP_KERNEL); -+ if (!output_fmts) -+ return NULL; -+ -+ /* If we are the only bridge, avoid negotiating with ourselves */ -+ if (list_is_singular(&bridge->encoder->bridge_chain)) { -+ *num_output_fmts = 1; -+ output_fmts[0] = MEDIA_BUS_FMT_FIXED; -+ -+ return output_fmts; -+ } -+ -+ /* -+ * Order bus formats from 16bit to 8bit and from YUV422 to RGB -+ * if supported. In any case the default RGB888 format is added -+ */ -+ -+ if (max_bpc >= 16 && info->bpc == 16) { -+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR444) -+ output_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48; -+ -+ output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48; -+ } -+ -+ if (max_bpc >= 12 && info->bpc >= 12) { -+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR422) -+ output_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24; -+ -+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR444) -+ output_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36; -+ -+ output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36; -+ } -+ -+ if (max_bpc >= 10 && info->bpc >= 10) { -+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR422) -+ output_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20; -+ -+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR444) -+ output_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30; -+ -+ output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; -+ } -+ -+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR422) -+ output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16; -+ -+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR444) -+ output_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; -+ -+ /* Default 8bit RGB fallback */ -+ output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; -+ -+ *num_output_fmts = i; -+ -+ return output_fmts; -+} -+ -+/* Can return a maximum of 3 possible input formats for an output format */ -+#define MAX_INPUT_SEL_FORMATS 3 -+ -+static u32 * -+meson_txc_hdmi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, -+ struct drm_bridge_state *bridge_state, -+ struct drm_crtc_state *crtc_state, -+ struct drm_connector_state *conn_state, -+ u32 output_fmt, -+ unsigned int *num_input_fmts) -+{ -+ u32 *input_fmts; -+ unsigned int i = 0; -+ -+ *num_input_fmts = 0; -+ -+ input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts), -+ GFP_KERNEL); -+ if (!input_fmts) -+ return NULL; -+ -+ switch (output_fmt) { -+ /* If MEDIA_BUS_FMT_FIXED is tested, return default bus format */ -+ case MEDIA_BUS_FMT_FIXED: -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; -+ break; -+ -+ /* 8bit */ -+ case MEDIA_BUS_FMT_RGB888_1X24: -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; -+ input_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; -+ input_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16; -+ break; -+ case MEDIA_BUS_FMT_YUV8_1X24: -+ input_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; -+ input_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16; -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; -+ break; -+ case MEDIA_BUS_FMT_UYVY8_1X16: -+ input_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16; -+ input_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; -+ break; -+ -+ /* 10bit */ -+ case MEDIA_BUS_FMT_RGB101010_1X30: -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; -+ input_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30; -+ input_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20; -+ break; -+ case MEDIA_BUS_FMT_YUV10_1X30: -+ input_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30; -+ input_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20; -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; -+ break; -+ case MEDIA_BUS_FMT_UYVY10_1X20: -+ input_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20; -+ input_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30; -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; -+ break; -+ -+ /* 12bit */ -+ case MEDIA_BUS_FMT_RGB121212_1X36: -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36; -+ input_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36; -+ input_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24; -+ break; -+ case MEDIA_BUS_FMT_YUV12_1X36: -+ input_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36; -+ input_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24; -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36; -+ break; -+ case MEDIA_BUS_FMT_UYVY12_1X24: -+ input_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24; -+ input_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36; -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36; -+ break; -+ -+ /* 16bit */ -+ case MEDIA_BUS_FMT_RGB161616_1X48: -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48; -+ input_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48; -+ break; -+ case MEDIA_BUS_FMT_YUV16_1X48: -+ input_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48; -+ input_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48; -+ break; -+ } -+ -+ *num_input_fmts = i; -+ -+ if (*num_input_fmts == 0) { -+ kfree(input_fmts); -+ input_fmts = NULL; -+ } -+ -+ return input_fmts; -+} -+ -+static void meson_txc_hdmi_bridge_atomic_enable(struct drm_bridge *bridge, -+ struct drm_bridge_state *old_bridge_state) -+{ -+ struct meson_txc_hdmi *priv = bridge_to_meson_txc_hdmi(bridge); -+ struct drm_atomic_state *state = old_bridge_state->base.state; -+ enum hdmi_quantization_range quant_range; -+ struct drm_connector_state *conn_state; -+ struct drm_bridge_state *bridge_state; -+ const struct drm_display_mode *mode; -+ enum hdmi_colorimetry colorimetry; -+ struct drm_crtc_state *crtc_state; -+ struct drm_connector *connector; -+ unsigned int i; -+ u8 cea_mode; -+ -+ bridge_state = drm_atomic_get_new_bridge_state(state, bridge); -+ -+ connector = drm_atomic_get_new_connector_for_encoder(state, -+ bridge->encoder); -+ if (WARN_ON(!connector)) -+ return; -+ -+ conn_state = drm_atomic_get_new_connector_state(state, connector); -+ if (WARN_ON(!conn_state)) -+ return; -+ -+ crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); -+ if (WARN_ON(!crtc_state)) -+ return; -+ -+ priv->current_connector = connector; -+ -+ mode = &crtc_state->adjusted_mode; -+ -+ cea_mode = drm_match_cea_mode(mode); -+ -+ if (priv->sink_is_hdmi) { -+ quant_range = drm_default_rgb_quant_range(mode); -+ -+ switch (cea_mode) { -+ case 2 ... 3: -+ case 6 ... 7: -+ case 17 ... 18: -+ case 21 ... 22: -+ colorimetry = HDMI_COLORIMETRY_ITU_601; -+ break; -+ -+ default: -+ colorimetry = HDMI_COLORIMETRY_ITU_709; -+ break; -+ } -+ -+ meson_txc_hdmi_set_avi_infoframe(priv, connector, mode, -+ conn_state, -+ bridge_state->output_bus_cfg.format, -+ quant_range, colorimetry); -+ meson_txc_hdmi_set_vendor_infoframe(priv, connector, mode); -+ meson_txc_hdmi_set_spd_infoframe(priv); -+ } else { -+ quant_range = HDMI_QUANTIZATION_RANGE_FULL; -+ colorimetry = HDMI_COLORIMETRY_NONE; -+ } -+ -+ meson_txc_hdmi_sys5_reset_assert(priv); -+ -+ meson_txc_hdmi_config_hdcp_registers(priv); -+ -+ if (cea_mode == 39) -+ regmap_write(priv->regmap, TX_VIDEO_DTV_TIMING, 0x0); -+ else -+ regmap_write(priv->regmap, TX_VIDEO_DTV_TIMING, -+ TX_VIDEO_DTV_TIMING_DISABLE_VIC39_CORRECTION); -+ -+ regmap_write(priv->regmap, TX_CORE_DATA_CAPTURE_2, -+ TX_CORE_DATA_CAPTURE_2_INTERNAL_PACKET_ENABLE); -+ regmap_write(priv->regmap, TX_CORE_DATA_MONITOR_1, -+ TX_CORE_DATA_MONITOR_1_LANE0 | -+ FIELD_PREP(TX_CORE_DATA_MONITOR_1_SELECT_LANE0, 0x7)); -+ regmap_write(priv->regmap, TX_CORE_DATA_MONITOR_2, -+ FIELD_PREP(TX_CORE_DATA_MONITOR_2_MONITOR_SELECT, 0x2)); -+ -+ if (priv->sink_is_hdmi) -+ regmap_write(priv->regmap, TX_TMDS_MODE, -+ TX_TMDS_MODE_FORCED_HDMI | -+ TX_TMDS_MODE_HDMI_CONFIG); -+ else -+ regmap_write(priv->regmap, TX_TMDS_MODE, -+ TX_TMDS_MODE_FORCED_HDMI); -+ -+ regmap_write(priv->regmap, TX_SYS4_CONNECT_SEL_1, 0x0); -+ -+ /* -+ * Set tmds_clk pattern to be "0000011111" before being sent to AFE -+ * clock channel. -+ */ -+ regmap_write(priv->regmap, TX_SYS4_CK_INV_VIDEO, -+ TX_SYS4_CK_INV_VIDEO_TMDS_CLK_PATTERN); -+ -+ regmap_write(priv->regmap, TX_SYS5_FIFO_CONFIG, -+ TX_SYS5_FIFO_CONFIG_CLK_CHANNEL3_OUTPUT_ENABLE | -+ TX_SYS5_FIFO_CONFIG_AFE_FIFO_CHANNEL2_ENABLE | -+ TX_SYS5_FIFO_CONFIG_AFE_FIFO_CHANNEL1_ENABLE | -+ TX_SYS5_FIFO_CONFIG_AFE_FIFO_CHANNEL0_ENABLE); -+ -+ meson_txc_hdmi_config_color_space(priv, -+ bridge_state->input_bus_cfg.format, -+ bridge_state->output_bus_cfg.format, -+ quant_range, colorimetry); -+ -+ meson_txc_hdmi_sys5_reset_deassert(priv); -+ -+ meson_txc_hdmi_config_serializer_clock(priv, colorimetry); -+ meson_txc_hdmi_reconfig_packet_setting(priv, cea_mode); -+ -+ /* all resets need to be applied twice */ -+ for (i = 0; i < 2; i++) { -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_1, -+ TX_SYS5_TX_SOFT_RESET_1_TX_PIXEL_RSTN | -+ TX_SYS5_TX_SOFT_RESET_1_TX_TMDS_RSTN | -+ TX_SYS5_TX_SOFT_RESET_1_TX_AUDIO_MASTER_RSTN | -+ TX_SYS5_TX_SOFT_RESET_1_TX_AUDIO_RESAMPLE_RSTN | -+ TX_SYS5_TX_SOFT_RESET_1_TX_I2S_RESET_RSTN | -+ TX_SYS5_TX_SOFT_RESET_1_TX_DIG_RESET_N_CH2 | -+ TX_SYS5_TX_SOFT_RESET_1_TX_DIG_RESET_N_CH1 | -+ TX_SYS5_TX_SOFT_RESET_1_TX_DIG_RESET_N_CH0); -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_2, -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH3_RST_IN | -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH2_RST_IN | -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH1_RST_IN | -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_CH0_RST_IN | -+ TX_SYS5_TX_SOFT_RESET_2_HDMI_SR_RST | -+ TX_SYS5_TX_SOFT_RESET_2_TX_DDC_HDCP_RSTN | -+ TX_SYS5_TX_SOFT_RESET_2_TX_DDC_EDID_RSTN | -+ TX_SYS5_TX_SOFT_RESET_2_TX_DIG_RESET_N_CH3); -+ usleep_range(5000, 10000); -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_1, 0x00); -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_2, 0x00); -+ usleep_range(5000, 10000); -+ } -+ -+ if (!priv->phy_is_on) { -+ int ret; -+ -+ ret = phy_power_on(priv->phy); -+ if (ret) -+ drm_err(bridge->dev, "Failed to turn on PHY\n"); -+ else -+ priv->phy_is_on = true; -+ } -+} -+ -+static void meson_txc_hdmi_bridge_atomic_disable(struct drm_bridge *bridge, -+ struct drm_bridge_state *old_bridge_state) -+{ -+ struct meson_txc_hdmi *priv = bridge_to_meson_txc_hdmi(bridge); -+ -+ priv->current_connector = NULL; -+ -+ if (priv->phy_is_on) { -+ int ret; -+ -+ ret = phy_power_off(priv->phy); -+ if (ret) -+ drm_err(bridge->dev, "Failed to turn off PHY\n"); -+ else -+ priv->phy_is_on = false; -+ } -+ -+ meson_txc_hdmi_disable_infoframe(priv, TX_PKT_REG_AUDIO_INFO_BASE_ADDR); -+ meson_txc_hdmi_disable_infoframe(priv, TX_PKT_REG_AVI_INFO_BASE_ADDR); -+ meson_txc_hdmi_disable_infoframe(priv, TX_PKT_REG_EXCEPT0_BASE_ADDR); -+ meson_txc_hdmi_disable_infoframe(priv, TX_PKT_REG_VEND_INFO_BASE_ADDR); -+} -+ -+static enum drm_mode_status -+meson_txc_hdmi_bridge_mode_valid(struct drm_bridge *bridge, -+ const struct drm_display_info *info, -+ const struct drm_display_mode *mode) -+{ -+ return MODE_OK; -+} -+ -+static enum drm_connector_status meson_txc_hdmi_bridge_detect(struct drm_bridge *bridge) -+{ -+ struct meson_txc_hdmi *priv = bridge_to_meson_txc_hdmi(bridge); -+ enum drm_connector_status status; -+ unsigned int val; -+ -+ regmap_read(priv->regmap, TX_HDCP_ST_EDID_STATUS, &val); -+ if (val & TX_HDCP_ST_EDID_STATUS_HPD_STATUS) -+ status = connector_status_connected; -+ else -+ status = connector_status_disconnected; -+ -+ mutex_lock(&priv->codec_mutex); -+ if (priv->last_connector_status != status) { -+ priv->last_connector_status = status; -+ meson_txc_hdmi_handle_plugged_change(priv); -+ } -+ mutex_unlock(&priv->codec_mutex); -+ -+ return status; -+} -+ -+static int meson_txc_hdmi_get_edid_block(void *data, u8 *buf, unsigned int block, -+ size_t len) -+{ -+ unsigned int i, regval, start = block * EDID_LENGTH; -+ struct meson_txc_hdmi *priv = data; -+ int ret; -+ -+ /* Start the DDC transaction */ -+ regmap_update_bits(priv->regmap, TX_HDCP_EDID_CONFIG, -+ TX_HDCP_EDID_CONFIG_SYS_TRIGGER_CONFIG, 0); -+ regmap_update_bits(priv->regmap, TX_HDCP_EDID_CONFIG, -+ TX_HDCP_EDID_CONFIG_SYS_TRIGGER_CONFIG, -+ TX_HDCP_EDID_CONFIG_SYS_TRIGGER_CONFIG); -+ -+ ret = regmap_read_poll_timeout(priv->regmap, -+ TX_HDCP_ST_EDID_STATUS, -+ regval, -+ (regval & TX_HDCP_ST_EDID_STATUS_EDID_DATA_READY), -+ 1000, 200000); -+ -+ regmap_update_bits(priv->regmap, TX_HDCP_EDID_CONFIG, -+ TX_HDCP_EDID_CONFIG_SYS_TRIGGER_CONFIG, 0); -+ -+ if (ret) -+ return ret; -+ -+ for (i = 0; i < len; i++) { -+ regmap_read(priv->regmap, TX_RX_EDID_OFFSET + start + i, -+ ®val); -+ buf[i] = regval; -+ } -+ -+ return 0; -+} -+ -+static struct edid *meson_txc_hdmi_bridge_get_edid(struct drm_bridge *bridge, -+ struct drm_connector *connector) -+{ -+ struct meson_txc_hdmi *priv = bridge_to_meson_txc_hdmi(bridge); -+ struct edid *edid; -+ -+ edid = drm_do_get_edid(connector, meson_txc_hdmi_get_edid_block, priv); -+ if (!edid) { -+ drm_dbg(priv->bridge.dev, "Failed to get EDID\n"); -+ return NULL; -+ } -+ -+ priv->sink_is_hdmi = drm_detect_hdmi_monitor(edid); -+ -+ return edid; -+} -+ -+static const struct drm_bridge_funcs meson_txc_hdmi_bridge_funcs = { -+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, -+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, -+ .atomic_reset = drm_atomic_helper_bridge_reset, -+ .attach = meson_txc_hdmi_bridge_attach, -+ .atomic_get_output_bus_fmts = meson_txc_hdmi_bridge_atomic_get_output_bus_fmts, -+ .atomic_get_input_bus_fmts = meson_txc_hdmi_bridge_atomic_get_input_bus_fmts, -+ .atomic_enable = meson_txc_hdmi_bridge_atomic_enable, -+ .atomic_disable = meson_txc_hdmi_bridge_atomic_disable, -+ .mode_valid = meson_txc_hdmi_bridge_mode_valid, -+ .detect = meson_txc_hdmi_bridge_detect, -+ .get_edid = meson_txc_hdmi_bridge_get_edid, -+}; -+ -+static int meson_txc_hdmi_parse_dt(struct meson_txc_hdmi *priv) -+{ -+ struct device_node *endpoint, *remote; -+ -+ endpoint = of_graph_get_endpoint_by_regs(priv->dev->of_node, 1, -1); -+ if (!endpoint) { -+ dev_err(priv->dev, "Missing endpoint in port@1\n"); -+ return -ENODEV; -+ } -+ -+ remote = of_graph_get_remote_port_parent(endpoint); -+ of_node_put(endpoint); -+ if (!remote) { -+ dev_err(priv->dev, "Endpoint in port@1 unconnected\n"); -+ return -ENODEV; -+ } -+ -+ if (!of_device_is_available(remote)) { -+ dev_err(priv->dev, "port@1 remote device is disabled\n"); -+ of_node_put(remote); -+ return -ENODEV; -+ } -+ -+ priv->next_bridge = of_drm_find_bridge(remote); -+ of_node_put(remote); -+ if (!priv->next_bridge) -+ return -EPROBE_DEFER; -+ -+ return 0; -+} -+ -+static int meson_txc_hdmi_hw_init(struct meson_txc_hdmi *priv) -+{ -+ unsigned long ddc_i2c_bus_clk_hz = 500 * 1000; -+ unsigned long sys_clk_hz = 24 * 1000 * 1000; -+ int ret; -+ -+ ret = phy_init(priv->phy); -+ if (ret) { -+ dev_err(priv->dev, "Failed to initialize the PHY: %d\n", ret); -+ return ret; -+ } -+ -+ ret = clk_set_rate(priv->sys_clk, sys_clk_hz); -+ if (ret) { -+ dev_err(priv->dev, "Failed to set HDMI system clock to 24MHz\n"); -+ goto err_phy_exit; -+ } -+ -+ ret = clk_prepare_enable(priv->sys_clk); -+ if (ret) { -+ dev_err(priv->dev, "Failed to enable the sys clk\n"); -+ goto err_phy_exit; -+ } -+ -+ regmap_update_bits(priv->regmap, HDMI_OTHER_CTRL1, -+ HDMI_OTHER_CTRL1_POWER_ON, -+ HDMI_OTHER_CTRL1_POWER_ON); -+ -+ regmap_write(priv->regmap, TX_HDMI_PHY_CONFIG0, -+ TX_HDMI_PHY_CONFIG0_HDMI_COMMON_B7_B0); -+ -+ regmap_write(priv->regmap, TX_HDCP_MODE, 0x40); -+ -+ /* -+ * The vendor driver comments that this is a setting for "Band-gap and -+ * main-bias". 0x1d = power-up, 0x00 = power-down. -+ */ -+ regmap_write(priv->regmap, TX_SYS1_AFE_TEST, 0x1d); -+ -+ meson_txc_hdmi_config_serializer_clock(priv, HDMI_COLORIMETRY_NONE); -+ -+ /* -+ * The vendor driver has a comment with the following information for -+ * the magic value: -+ * bit[2:0]=011: CK channel output TMDS CLOCK -+ * bit[2:0]=101, ck channel output PHYCLCK -+ */ -+ regmap_write(priv->regmap, TX_SYS1_AFE_CONNECT, 0xfb); -+ -+ /* Termination resistor calib value */ -+ regmap_write(priv->regmap, TX_CORE_CALIB_VALUE, 0x0f); -+ -+ /* HPD glitch filter */ -+ regmap_write(priv->regmap, TX_HDCP_HPD_FILTER_L, 0xa0); -+ regmap_write(priv->regmap, TX_HDCP_HPD_FILTER_H, 0xa0); -+ -+ /* Disable MEM power-down */ -+ regmap_write(priv->regmap, TX_MEM_PD_REG0, 0x0); -+ -+ regmap_write(priv->regmap, TX_HDCP_CONFIG3, -+ FIELD_PREP(TX_HDCP_CONFIG3_DDC_I2C_BUS_CLOCK_TIME_DIVIDER, -+ (sys_clk_hz / ddc_i2c_bus_clk_hz) - 1)); -+ -+ /* Enable software controlled DDC transaction */ -+ regmap_write(priv->regmap, TX_HDCP_EDID_CONFIG, -+ TX_HDCP_EDID_CONFIG_FORCED_MEM_COPY_DONE | -+ TX_HDCP_EDID_CONFIG_MEM_COPY_DONE_CONFIG); -+ regmap_write(priv->regmap, TX_CORE_EDID_CONFIG_MORE, -+ TX_CORE_EDID_CONFIG_MORE_SYS_TRIGGER_CONFIG_SEMI_MANU); -+ -+ /* mask (= disable) all interrupts */ -+ regmap_write(priv->regmap, HDMI_OTHER_INTR_MASKN, 0x0); -+ -+ /* clear any pending interrupt */ -+ regmap_write(priv->regmap, HDMI_OTHER_INTR_STAT_CLR, -+ HDMI_OTHER_INTR_STAT_CLR_EDID_RISING | -+ HDMI_OTHER_INTR_STAT_CLR_HPD_FALLING | -+ HDMI_OTHER_INTR_STAT_CLR_HPD_RISING); -+ -+ return 0; -+ -+err_phy_exit: -+ phy_exit(priv->phy); -+ return 0; -+} -+ -+static void meson_txc_hdmi_hw_exit(struct meson_txc_hdmi *priv) -+{ -+ int ret; -+ -+ /* mask (= disable) all interrupts */ -+ regmap_write(priv->regmap, HDMI_OTHER_INTR_MASKN, -+ HDMI_OTHER_INTR_MASKN_TX_EDID_INT_RISE | -+ HDMI_OTHER_INTR_MASKN_TX_HPD_INT_FALL | -+ HDMI_OTHER_INTR_MASKN_TX_HPD_INT_RISE); -+ -+ regmap_update_bits(priv->regmap, HDMI_OTHER_CTRL1, -+ HDMI_OTHER_CTRL1_POWER_ON, 0); -+ -+ clk_disable_unprepare(priv->sys_clk); -+ -+ ret = phy_exit(priv->phy); -+ if (ret) -+ dev_err(priv->dev, "Failed to exit the PHY: %d\n", ret); -+} -+ -+static u32 meson_txc_hdmi_hdmi_codec_calc_audio_n(struct hdmi_codec_params *hparms) -+{ -+ u32 audio_n; -+ -+ if ((hparms->sample_rate % 44100) == 0) -+ audio_n = (128 * hparms->sample_rate) / 900; -+ else -+ audio_n = (128 * hparms->sample_rate) / 1000; -+ -+ if (hparms->cea.coding_type == HDMI_AUDIO_CODING_TYPE_EAC3 || -+ hparms->cea.coding_type == HDMI_AUDIO_CODING_TYPE_DTS_HD) -+ audio_n *= 4; -+ -+ return audio_n; -+} -+ -+static u8 meson_txc_hdmi_hdmi_codec_coding_type(struct hdmi_codec_params *hparms) -+{ -+ switch (hparms->cea.coding_type) { -+ case HDMI_AUDIO_CODING_TYPE_MLP: -+ return TX_AUDIO_CONTROL_AUDIO_PACKET_TYPE_HBR_AUDIO_PACKET; -+ case HDMI_AUDIO_CODING_TYPE_DSD: -+ return TX_AUDIO_CONTROL_AUDIO_PACKET_TYPE_ONE_BIT_AUDIO; -+ case HDMI_AUDIO_CODING_TYPE_DST: -+ return TX_AUDIO_CONTROL_AUDIO_PACKET_TYPE_DST_AUDIO_PACKET; -+ default: -+ return TX_AUDIO_CONTROL_AUDIO_PACKET_TYPE_AUDIO_SAMPLE_PACKET; -+ } -+} -+ -+static int meson_txc_hdmi_hdmi_codec_hw_params(struct device *dev, void *data, -+ struct hdmi_codec_daifmt *fmt, -+ struct hdmi_codec_params *hparms) -+{ -+ u8 buf[HDMI_INFOFRAME_SIZE(AUDIO)]; -+ struct meson_txc_hdmi *priv = data; -+ u16 audio_tx_format; -+ u32 audio_n; -+ int len, i; -+ -+ if (hparms->cea.coding_type == HDMI_AUDIO_CODING_TYPE_MLP) { -+ /* -+ * TODO: fixed CTS is not supported yet, it needs special -+ * TX_SYS1_ACR_N_* settings -+ */ -+ return -EINVAL; -+ } -+ -+ switch (hparms->sample_width) { -+ case 16: -+ audio_tx_format = FIELD_PREP(TX_AUDIO_FORMAT_BIT_WIDTH_MASK, -+ TX_AUDIO_FORMAT_BIT_WIDTH_16); -+ break; -+ -+ case 20: -+ audio_tx_format = FIELD_PREP(TX_AUDIO_FORMAT_BIT_WIDTH_MASK, -+ TX_AUDIO_FORMAT_BIT_WIDTH_20); -+ break; -+ -+ case 24: -+ audio_tx_format = FIELD_PREP(TX_AUDIO_FORMAT_BIT_WIDTH_MASK, -+ TX_AUDIO_FORMAT_BIT_WIDTH_24); -+ break; -+ -+ default: -+ return -EINVAL; -+ } -+ -+ switch (fmt->fmt) { -+ case HDMI_I2S: -+ regmap_update_bits(priv->regmap, HDMI_OTHER_CTRL1, -+ HDMI_OTHER_CTRL1_HDMI_AUDIO_CLOCK_ON, -+ HDMI_OTHER_CTRL1_HDMI_AUDIO_CLOCK_ON); -+ -+ audio_tx_format |= TX_AUDIO_FORMAT_SPDIF_OR_I2S | -+ TX_AUDIO_FORMAT_I2S_ONE_BIT_OR_I2S | -+ FIELD_PREP(TX_AUDIO_FORMAT_I2S_FORMAT, 0x2); -+ -+ if (hparms->channels > 2) -+ audio_tx_format |= TX_AUDIO_FORMAT_I2S_2_OR_8_CH; -+ -+ regmap_write(priv->regmap, TX_AUDIO_FORMAT, -+ audio_tx_format); -+ -+ regmap_write(priv->regmap, TX_AUDIO_I2S, TX_AUDIO_I2S_ENABLE); -+ regmap_write(priv->regmap, TX_AUDIO_SPDIF, 0x0); -+ break; -+ -+ case HDMI_SPDIF: -+ regmap_update_bits(priv->regmap, HDMI_OTHER_CTRL1, -+ HDMI_OTHER_CTRL1_HDMI_AUDIO_CLOCK_ON, 0x0); -+ -+ if (hparms->cea.coding_type == HDMI_AUDIO_CODING_TYPE_STREAM) -+ audio_tx_format |= TX_AUDIO_FORMAT_SPDIF_CHANNEL_STATUS_FROM_DATA_OR_REG; -+ -+ regmap_write(priv->regmap, TX_AUDIO_FORMAT, -+ audio_tx_format); -+ -+ regmap_write(priv->regmap, TX_AUDIO_I2S, 0x0); -+ regmap_write(priv->regmap, TX_AUDIO_SPDIF, TX_AUDIO_SPDIF_ENABLE); -+ break; -+ -+ default: -+ return -EINVAL; -+ } -+ -+ if (hparms->channels > 2) -+ regmap_write(priv->regmap, TX_AUDIO_HEADER, -+ TX_AUDIO_HEADER_AUDIO_SAMPLE_PACKET_HEADER_LAYOUT1); -+ else -+ regmap_write(priv->regmap, TX_AUDIO_HEADER, 0x0); -+ -+ regmap_write(priv->regmap, TX_AUDIO_SAMPLE, -+ FIELD_PREP(TX_AUDIO_SAMPLE_CHANNEL_VALID, -+ BIT(hparms->channels) - 1)); -+ -+ audio_n = meson_txc_hdmi_hdmi_codec_calc_audio_n(hparms); -+ -+ regmap_write(priv->regmap, TX_SYS1_ACR_N_0, -+ FIELD_PREP(TX_SYS1_ACR_N_0_N_BYTE0, -+ (audio_n >> 0) & 0xff)); -+ regmap_write(priv->regmap, TX_SYS1_ACR_N_1, -+ FIELD_PREP(TX_SYS1_ACR_N_1_N_BYTE1, -+ (audio_n >> 8) & 0xff)); -+ regmap_update_bits(priv->regmap, TX_SYS1_ACR_N_2, -+ TX_SYS1_ACR_N_2_N_UPPER_NIBBLE, -+ FIELD_PREP(TX_SYS1_ACR_N_2_N_UPPER_NIBBLE, -+ (audio_n >> 16) & 0xf)); -+ -+ regmap_write(priv->regmap, TX_SYS0_ACR_CTS_0, 0x0); -+ regmap_write(priv->regmap, TX_SYS0_ACR_CTS_1, 0x0); -+ regmap_write(priv->regmap, TX_SYS0_ACR_CTS_2, -+ TX_SYS0_ACR_CTS_2_FORCE_ARC_STABLE); -+ -+ regmap_write(priv->regmap, TX_AUDIO_CONTROL, -+ TX_AUDIO_CONTROL_AUTO_AUDIO_FIFO_CLEAR | -+ FIELD_PREP(TX_AUDIO_CONTROL_AUDIO_PACKET_TYPE_MASK, -+ meson_txc_hdmi_hdmi_codec_coding_type(hparms)) | -+ TX_AUDIO_CONTROL_AUDIO_SAMPLE_PACKET_FLAT); -+ -+ len = hdmi_audio_infoframe_pack(&hparms->cea, buf, sizeof(buf)); -+ if (len < 0) -+ return len; -+ -+ meson_txc_hdmi_write_infoframe(priv->regmap, -+ TX_PKT_REG_AUDIO_INFO_BASE_ADDR, -+ buf, len, true); -+ -+ for (i = 0; i < ARRAY_SIZE(hparms->iec.status); i++) { -+ unsigned char sub1, sub2; -+ -+ sub1 = sub2 = hparms->iec.status[i]; -+ -+ if (i == 2) { -+ sub1 |= FIELD_PREP(IEC958_AES2_CON_CHANNEL, 1); -+ sub2 |= FIELD_PREP(IEC958_AES2_CON_CHANNEL, 2); -+ } -+ -+ regmap_write(priv->regmap, TX_IEC60958_SUB1_OFFSET + i, sub1); -+ regmap_write(priv->regmap, TX_IEC60958_SUB2_OFFSET + i, sub2); -+ } -+ -+ return 0; -+} -+ -+static int meson_txc_hdmi_hdmi_codec_audio_startup(struct device *dev, -+ void *data) -+{ -+ struct meson_txc_hdmi *priv = data; -+ -+ regmap_update_bits(priv->regmap, TX_PACKET_CONTROL_2, -+ TX_PACKET_CONTROL_2_AUDIO_REQUEST_DISABLE, 0x0); -+ -+ /* reset audio master and sample */ -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_1, -+ TX_SYS5_TX_SOFT_RESET_1_TX_AUDIO_RESAMPLE_RSTN | -+ TX_SYS5_TX_SOFT_RESET_1_TX_AUDIO_MASTER_RSTN); -+ regmap_write(priv->regmap, TX_SYS5_TX_SOFT_RESET_1, 0x0); -+ -+ regmap_write(priv->regmap, TX_AUDIO_CONTROL_MORE, -+ TX_AUDIO_CONTROL_MORE_ENABLE); -+ -+ regmap_write(priv->regmap, TX_AUDIO_FIFO, -+ FIELD_PREP(TX_AUDIO_FIFO_FIFO_DEPTH_MASK, -+ TX_AUDIO_FIFO_FIFO_DEPTH_512) | -+ FIELD_PREP(TX_AUDIO_FIFO_CRITICAL_THRESHOLD_MASK, -+ TX_AUDIO_FIFO_CRITICAL_THRESHOLD_DEPTH_DIV16) | -+ FIELD_PREP(TX_AUDIO_FIFO_NORMAL_THRESHOLD_MASK, -+ TX_AUDIO_FIFO_NORMAL_THRESHOLD_DEPTH_DIV8)); -+ -+ regmap_write(priv->regmap, TX_AUDIO_LIPSYNC, 0x0); -+ -+ regmap_write(priv->regmap, TX_SYS1_ACR_N_2, -+ FIELD_PREP(TX_SYS1_ACR_N_2_N_MEAS_TOLERANCE, 0x3)); -+ -+ return 0; -+} -+ -+static void meson_txc_hdmi_hdmi_codec_audio_shutdown(struct device *dev, -+ void *data) -+{ -+ struct meson_txc_hdmi *priv = data; -+ -+ meson_txc_hdmi_disable_infoframe(priv, TX_PKT_REG_AUDIO_INFO_BASE_ADDR); -+ -+ regmap_write(priv->regmap, TX_AUDIO_CONTROL_MORE, 0x0); -+ regmap_update_bits(priv->regmap, HDMI_OTHER_CTRL1, -+ HDMI_OTHER_CTRL1_HDMI_AUDIO_CLOCK_ON, 0x0); -+ -+ regmap_update_bits(priv->regmap, TX_PACKET_CONTROL_2, -+ TX_PACKET_CONTROL_2_AUDIO_REQUEST_DISABLE, -+ TX_PACKET_CONTROL_2_AUDIO_REQUEST_DISABLE); -+} -+ -+static int meson_txc_hdmi_hdmi_codec_mute_stream(struct device *dev, -+ void *data, -+ bool enable, int direction) -+{ -+ struct meson_txc_hdmi *priv = data; -+ -+ regmap_write(priv->regmap, TX_AUDIO_PACK, -+ enable ? 0 : TX_AUDIO_PACK_AUDIO_SAMPLE_PACKETS_ENABLE); -+ -+ return 0; -+} -+ -+static int meson_txc_hdmi_hdmi_codec_get_eld(struct device *dev, void *data, -+ uint8_t *buf, size_t len) -+{ -+ struct meson_txc_hdmi *priv = data; -+ -+ if (priv->current_connector) -+ memcpy(buf, priv->current_connector->eld, -+ min_t(size_t, MAX_ELD_BYTES, len)); -+ else -+ memset(buf, 0, len); -+ -+ return 0; -+} -+ -+static int meson_txc_hdmi_hdmi_codec_get_dai_id(struct snd_soc_component *component, -+ struct device_node *endpoint) -+{ -+ struct of_endpoint of_ep; -+ int ret; -+ -+ ret = of_graph_parse_endpoint(endpoint, &of_ep); -+ if (ret < 0) -+ return ret; -+ -+ /* -+ * HDMI sound should be located as reg = <2> -+ * Then, it is sound port 0 -+ */ -+ if (of_ep.port == 2) -+ return 0; -+ -+ return -EINVAL; -+} -+ -+static int meson_txc_hdmi_hdmi_codec_hook_plugged_cb(struct device *dev, -+ void *data, -+ hdmi_codec_plugged_cb fn, -+ struct device *codec_dev) -+{ -+ struct meson_txc_hdmi *priv = data; -+ -+ mutex_lock(&priv->codec_mutex); -+ priv->codec_plugged_cb = fn; -+ priv->codec_dev = codec_dev; -+ meson_txc_hdmi_handle_plugged_change(priv); -+ mutex_unlock(&priv->codec_mutex); -+ -+ return 0; -+} -+ -+static struct hdmi_codec_ops meson_txc_hdmi_hdmi_codec_ops = { -+ .hw_params = meson_txc_hdmi_hdmi_codec_hw_params, -+ .audio_startup = meson_txc_hdmi_hdmi_codec_audio_startup, -+ .audio_shutdown = meson_txc_hdmi_hdmi_codec_audio_shutdown, -+ .mute_stream = meson_txc_hdmi_hdmi_codec_mute_stream, -+ .get_eld = meson_txc_hdmi_hdmi_codec_get_eld, -+ .get_dai_id = meson_txc_hdmi_hdmi_codec_get_dai_id, -+ .hook_plugged_cb = meson_txc_hdmi_hdmi_codec_hook_plugged_cb, -+}; -+ -+static int meson_txc_hdmi_hdmi_codec_init(struct meson_txc_hdmi *priv) -+{ -+ struct hdmi_codec_pdata pdata = { -+ .ops = &meson_txc_hdmi_hdmi_codec_ops, -+ .i2s = 1, -+ .spdif = 1, -+ .max_i2s_channels = 8, -+ .data = priv, -+ }; -+ -+ priv->hdmi_codec_pdev = platform_device_register_data(priv->dev, -+ HDMI_CODEC_DRV_NAME, -+ PLATFORM_DEVID_AUTO, -+ &pdata, sizeof(pdata)); -+ return PTR_ERR_OR_ZERO(priv->hdmi_codec_pdev); -+} -+ -+static int meson_txc_hdmi_bind(struct device *dev, struct device *master, -+ void *data) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct meson_txc_hdmi *priv; -+ void __iomem *base; -+ u32 regval; -+ int ret; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->dev = dev; -+ -+ mutex_init(&priv->codec_mutex); -+ -+ dev_set_drvdata(dev, priv); -+ -+ base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); -+ -+ priv->regmap = devm_regmap_init(dev, NULL, base, -+ &meson_txc_hdmi_regmap_config); -+ if (IS_ERR(priv->regmap)) -+ return PTR_ERR(priv->regmap); -+ -+ priv->pclk = devm_clk_get(dev, "pclk"); -+ if (IS_ERR(priv->pclk)) { -+ ret = PTR_ERR(priv->pclk); -+ return dev_err_probe(dev, ret, "Failed to get the pclk\n"); -+ } -+ -+ priv->sys_clk = devm_clk_get(dev, "sys"); -+ if (IS_ERR(priv->sys_clk)) { -+ ret = PTR_ERR(priv->sys_clk); -+ return dev_err_probe(dev, ret, -+ "Failed to get the sys clock\n"); -+ } -+ -+ priv->phy = devm_phy_get(dev, "hdmi"); -+ if (IS_ERR(priv->phy)) { -+ ret = PTR_ERR(priv->phy); -+ return dev_err_probe(dev, ret, "Failed to get the HDMI PHY\n"); -+ } -+ -+ ret = meson_txc_hdmi_parse_dt(priv); -+ if (ret) -+ return ret; -+ -+ ret = clk_prepare_enable(priv->pclk); -+ if (ret) { -+ dev_err_probe(dev, ret, "Failed to enable the pclk\n"); -+ return ret; -+ } -+ -+ regval = readl(base + HDMI_CTRL_PORT); -+ regval |= HDMI_CTRL_PORT_APB3_ERR_EN; -+ writel(regval, base + HDMI_CTRL_PORT); -+ -+ ret = meson_txc_hdmi_hw_init(priv); -+ if (ret) -+ goto err_disable_clk; -+ -+ ret = meson_txc_hdmi_hdmi_codec_init(priv); -+ if (ret) -+ goto err_hw_exit; -+ -+ priv->bridge.driver_private = priv; -+ priv->bridge.funcs = &meson_txc_hdmi_bridge_funcs; -+ priv->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID; -+ priv->bridge.of_node = dev->of_node; -+ priv->bridge.interlace_allowed = true; -+ -+ drm_bridge_add(&priv->bridge); -+ -+ return 0; -+ -+err_hw_exit: -+ meson_txc_hdmi_hw_exit(priv); -+err_disable_clk: -+ clk_disable_unprepare(priv->pclk); -+ return ret; -+} -+ -+static void meson_txc_hdmi_unbind(struct device *dev, struct device *master, -+ void *data) -+{ -+ struct meson_txc_hdmi *priv = dev_get_drvdata(dev); -+ -+ platform_device_unregister(priv->hdmi_codec_pdev); -+ -+ drm_bridge_remove(&priv->bridge); -+ -+ meson_txc_hdmi_hw_exit(priv); -+ -+ clk_disable_unprepare(priv->pclk); -+} -+ -+static const struct component_ops meson_txc_hdmi_component_ops = { -+ .bind = meson_txc_hdmi_bind, -+ .unbind = meson_txc_hdmi_unbind, -+}; -+ -+static int meson_txc_hdmi_probe(struct platform_device *pdev) -+{ -+ return component_add(&pdev->dev, &meson_txc_hdmi_component_ops); -+} -+ -+static int meson_txc_hdmi_remove(struct platform_device *pdev) -+{ -+ component_del(&pdev->dev, &meson_txc_hdmi_component_ops); -+ -+ return 0; -+} -+ -+static const struct of_device_id meson_txc_hdmi_of_table[] = { -+ { .compatible = "amlogic,meson8-hdmi-tx" }, -+ { .compatible = "amlogic,meson8b-hdmi-tx" }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, meson_txc_hdmi_of_table); -+ -+static struct platform_driver meson_txc_hdmi_platform_driver = { -+ .probe = meson_txc_hdmi_probe, -+ .remove = meson_txc_hdmi_remove, -+ .driver = { -+ .name = "meson-transwitch-hdmi", -+ .of_match_table = meson_txc_hdmi_of_table, -+ }, -+}; -+module_platform_driver(meson_txc_hdmi_platform_driver); -+ -+MODULE_AUTHOR("Martin Blumenstingl "); -+MODULE_DESCRIPTION("Amlogic Meson8 and Meson8b TranSwitch HDMI 1.4 TX driver"); -+MODULE_LICENSE("GPL v2"); -diff --git a/drivers/gpu/drm/meson/meson_transwitch_hdmi.h b/drivers/gpu/drm/meson/meson_transwitch_hdmi.h -new file mode 100644 -index 000000000000..111111111111 ---- /dev/null -+++ b/drivers/gpu/drm/meson/meson_transwitch_hdmi.h -@@ -0,0 +1,536 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2021 Martin Blumenstingl -+ * -+ * All registers and magic values are taken from Amlogic's GPL kernel sources: -+ * Copyright (C) 2010 Amlogic, Inc. -+ */ -+ -+#include -+#include -+ -+#ifndef __MESON_TRANSWITCH_HDMI_H__ -+#define __MESON_TRANSWITCH_HDMI_H__ -+ -+/* HDMI TX register */ -+ -+// System config 0 -+#define TX_SYS0_AFE_SIGNAL 0x0000 -+#define TX_SYS0_AFE_LOOP 0x0001 -+#define TX_SYS0_ACR_CTS_0 0x0002 -+ #define TX_SYS0_ACR_CTS_0_AUDIO_CTS_BYTE0 GENMASK(7, 0) -+#define TX_SYS0_ACR_CTS_1 0x0003 -+ #define TX_SYS0_ACR_CTS_1_AUDIO_CTS_BYTE1 GENMASK(7, 0) -+#define TX_SYS0_ACR_CTS_2 0x0004 -+ #define TX_SYS0_ACR_CTS_2_FORCE_ARC_STABLE BIT(5) -+#define TX_SYS0_BIST_CONTROL 0x0005 -+ #define TX_SYS0_BIST_CONTROL_AFE_BIST_ENABLE BIT(7) -+ #define TX_SYS0_BIST_CONTROL_TMDS_SHIFT_PATTERN_SELECT BIT(6) -+ #define TX_SYS0_BIST_CONTROL_TMDS_PRBS_PATTERN_SELECT GENMASK(5, 4) -+ #define TX_SYS0_BIST_CONTROL_TMDS_REPEAT_BIST_PATTERN GENMASK(2, 0) -+ -+#define TX_SYS0_BIST_DATA_0 0x0006 -+#define TX_SYS0_BIST_DATA_1 0x0007 -+#define TX_SYS0_BIST_DATA_2 0x0008 -+#define TX_SYS0_BIST_DATA_3 0x0009 -+#define TX_SYS0_BIST_DATA_4 0x000A -+#define TX_SYS0_BIST_DATA_5 0x000B -+#define TX_SYS0_BIST_DATA_6 0x000C -+#define TX_SYS0_BIST_DATA_7 0x000D -+#define TX_SYS0_BIST_DATA_8 0x000E -+#define TX_SYS0_BIST_DATA_9 0x000F -+ -+// system config 1 -+#define TX_HDMI_PHY_CONFIG0 0x0010 -+ #define TX_HDMI_PHY_CONFIG0_HDMI_COMMON_B7_B0 GENMASK(7, 0) -+#define TX_HDMI_PHY_CONFIG1 0x0010 -+ #define TX_HDMI_PHY_CONFIG1_HDMI_COMMON_B11_B8 GENMASK(3, 0) -+ #define TX_HDMI_PHY_CONFIG1_HDMI_CTL_REG_B3_B0 GENMASK(7, 4) -+#define TX_HDMI_PHY_CONFIG2 0x0012 -+ #define TX_HDMI_PHY_CONFIG_HDMI_CTL_REG_B11_B4 GENMASK(7, 0) -+#define TX_HDMI_PHY_CONFIG3 0x0013 -+ #define TX_HDMI_PHY_CONFIG3_HDMI_L2H_CTL GENMASK(3, 0) -+ #define TX_HDMI_PHY_CONFIG3_HDMI_MDR_PU GENMASK(7, 4) -+#define TX_HDMI_PHY_CONFIG4 0x0014 -+ #define TX_HDMI_PHY_CONFIG4_HDMI_LF_PD BIT(0) -+ #define TX_HDMI_PHY_CONFIG4_HDMI_PHY_CLK_EN BIT(1) -+ #define TX_HDMI_PHY_CONFIG4_HDMI_MODE GENMASK(3, 2) -+ #define TX_HDMI_PHY_CONFIG4_HDMI_MODE_NORMAL 0x0 -+ #define TX_HDMI_PHY_CONFIG4_HDMI_MODE_CLK_CH3_EQUAL_CH0 0x1 -+ #define TX_HDMI_PHY_CONFIG4_HDMI_MODE_ALTERNATE_HIGH_LOW 0x2 -+ #define TX_HDMI_PHY_CONFIG4_HDMI_MODE_ALTERNATE_LOW_HIGH 0x3 -+ #define TX_HDMI_PHY_CONFIG4_HDMI_PREM_CTL GENMASK(7, 4) -+#define TX_HDMI_PHY_CONFIG5 0x0015 -+ #define TX_HDMI_PHY_CONFIG5_HDMI_VCM_CTL GENMASK(7, 5) -+ #define TX_HDMI_PHY_CONFIG5_HDMI_PREFCTL GENMASK(2, 0) -+#define TX_HDMI_PHY_CONFIG6 0x0016 -+ #define TX_HDMI_PHY_CONFIG6_HDMI_RTERM_CTL GENMASK(3, 0) -+ #define TX_HDMI_PHY_CONFIG6_HDMI_SWING_CTL GENMASK(7, 4) -+#define TX_SYS1_AFE_TEST 0x0017 -+#define TX_SYS1_PLL 0x0018 -+#define TX_SYS1_TUNE 0x0019 -+#define TX_SYS1_AFE_CONNECT 0x001A -+ -+#define TX_SYS1_ACR_N_0 0x001C -+ #define TX_SYS1_ACR_N_0_N_BYTE0 GENMASK(7, 0) -+#define TX_SYS1_ACR_N_1 0x001D -+ #define TX_SYS1_ACR_N_1_N_BYTE1 GENMASK(7, 0) -+#define TX_SYS1_ACR_N_2 0x001E -+ #define TX_SYS1_ACR_N_2_N_MEAS_TOLERANCE GENMASK(7, 4) -+ #define TX_SYS1_ACR_N_2_N_UPPER_NIBBLE GENMASK(3, 0) -+#define TX_SYS1_PRBS_DATA 0x001F -+ #define TX_SYS1_PRBS_DATA_PRBS_MODE GENMASK(1, 0) -+ #define TX_SYS1_PRBS_DATA_PRBS_MODE_11 0x0 -+ #define TX_SYS1_PRBS_DATA_PRBS_MODE_15 0x1 -+ #define TX_SYS1_PRBS_DATA_PRBS_MODE_7 0x2 -+ #define TX_SYS1_PRBS_DATA_PRBS_MODE_31 0x3 -+ -+// HDCP CONFIG -+#define TX_HDCP_ECC_CONFIG 0x0024 -+#define TX_HDCP_CRC_CONFIG 0x0025 -+#define TX_HDCP_EDID_CONFIG 0x0026 -+ #define TX_HDCP_EDID_CONFIG_FORCED_SYS_TRIGGER BIT(7) -+ #define TX_HDCP_EDID_CONFIG_SYS_TRIGGER_CONFIG BIT(6) -+ #define TX_HDCP_EDID_CONFIG_MEM_ACC_SEQ_MODE BIT(5) -+ #define TX_HDCP_EDID_CONFIG_MEM_ACC_SEQ_START BIT(4) -+ #define TX_HDCP_EDID_CONFIG_FORCED_MEM_COPY_DONE BIT(3) -+ #define TX_HDCP_EDID_CONFIG_MEM_COPY_DONE_CONFIG BIT(2) -+ #define TX_HDCP_EDID_CONFIG_SYS_TRIGGER_CONFIG_SEMI_MANU BIT(1) -+ -+#define TX_HDCP_MEM_CONFIG 0x0027 -+ #define TX_HDCP_MEM_CONFIG_READ_DECRYPT BIT(3) -+ -+#define TX_HDCP_HPD_FILTER_L 0x0028 -+#define TX_HDCP_HPD_FILTER_H 0x0029 -+#define TX_HDCP_ENCRYPT_BYTE 0x002A -+#define TX_HDCP_CONFIG0 0x002B -+ #define TX_HDCP_CONFIG0_ROM_ENCRYPT_OFF GENMASK(4, 3) -+ -+#define TX_HDCP_CONFIG1 0x002C -+#define TX_HDCP_CONFIG2 0x002D -+#define TX_HDCP_CONFIG3 0x002E -+ #define TX_HDCP_CONFIG3_DDC_I2C_BUS_CLOCK_TIME_DIVIDER GENMASK(7, 0) -+ -+#define TX_HDCP_MODE 0x002F -+ #define TX_HDCP_MODE_CP_DESIRED BIT(7) -+ #define TX_HDCP_MODE_ESS_CONFIG BIT(6) -+ #define TX_HDCP_MODE_SET_AVMUTE BIT(5) -+ #define TX_HDCP_MODE_CLEAR_AVMUTE BIT(4) -+ #define TX_HDCP_MODE_HDCP_1_1 BIT(3) -+ #define TX_HDCP_MODE_VSYNC_HSYNC_FORCED_POLARITY_SELECT BIT(2) -+ #define TX_HDCP_MODE_FORCED_VSYNC_POLARITY BIT(1) -+ #define TX_HDCP_MODE_FORCED_HSYNC_POLARITY BIT(0) -+ -+// Video config, part 1 -+#define TX_VIDEO_ACTIVE_PIXELS_0 0x0030 -+#define TX_VIDEO_ACTIVE_PIXELS_1 0x0031 -+#define TX_VIDEO_FRONT_PIXELS 0x0032 -+#define TX_VIDEO_HSYNC_PIXELS 0x0033 -+#define TX_VIDEO_BACK_PIXELS 0x0034 -+#define TX_VIDEO_ACTIVE_LINES_0 0x0035 -+#define TX_VIDEO_ACTIVE_LINES_1 0x0036 -+#define TX_VIDEO_EOF_LINES 0x0037 -+#define TX_VIDEO_VSYNC_LINES 0x0038 -+#define TX_VIDEO_SOF_LINES 0x0039 -+#define TX_VIDEO_DTV_TIMING 0x003A -+ #define TX_VIDEO_DTV_TIMING_FORCE_DTV_TIMING_AUTO BIT(7) -+ #define TX_VIDEO_DTV_TIMING_FORCE_VIDEO_SCAN BIT(6) -+ #define TX_VIDEO_DTV_TIMING_FORCE_VIDEO_FIELD BIT(5) -+ #define TX_VIDEO_DTV_TIMING_DISABLE_VIC39_CORRECTION BIT(4) -+ -+#define TX_VIDEO_DTV_MODE 0x003B -+ #define TX_VIDEO_DTV_MODE_FORCED_DEFAULT_PHASE BIT(7) -+ #define TX_VIDEO_DTV_MODE_COLOR_DEPTH GENMASK(1, 0) -+ -+#define TX_VIDEO_DTV_FORMAT0 0x003C -+#define TX_VIDEO_DTV_FORMAT1 0x003D -+#define TX_VIDEO_PIXEL_PACK 0x003F -+// video config, part 2 -+#define TX_VIDEO_CSC_COEFF_B0 0x0040 -+#define TX_VIDEO_CSC_COEFF_B1 0x0041 -+#define TX_VIDEO_CSC_COEFF_R0 0x0042 -+#define TX_VIDEO_CSC_COEFF_R1 0x0043 -+#define TX_VIDEO_CSC_COEFF_CB0 0x0044 -+#define TX_VIDEO_CSC_COEFF_CB1 0x0045 -+#define TX_VIDEO_CSC_COEFF_CR0 0x0046 -+#define TX_VIDEO_CSC_COEFF_CR1 0x0047 -+#define TX_VIDEO_DTV_OPTION_L 0x0048 -+ #define TX_VIDEO_DTV_OPTION_L_OUTPUT_COLOR_FORMAT GENMASK(7, 6) -+ #define TX_VIDEO_DTV_OPTION_L_INPUT_COLOR_FORMAT GENMASK(5, 4) -+ #define TX_VIDEO_DTV_OPTION_L_OUTPUT_COLOR_DEPTH GENMASK(3, 2) -+ #define TX_VIDEO_DTV_OPTION_L_INPUT_COLOR_DEPTH GENMASK(1, 0) -+ -+#define TX_VIDEO_DTV_OPTION_H 0x0049 -+ #define TX_VIDEO_DTV_OPTION_H_COLOR_RANGE_16_235 0x0 -+ #define TX_VIDEO_DTV_OPTION_H_COLOR_RANGE_16_240 0x1 -+ #define TX_VIDEO_DTV_OPTION_H_COLOR_RANGE_1_254 0x2 -+ #define TX_VIDEO_DTV_OPTION_H_COLOR_RANGE_0_255 0x3 -+ #define TX_VIDEO_DTV_OPTION_H_OUTPUT_COLOR_RANGE GENMASK(3, 2) -+ #define TX_VIDEO_DTV_OPTION_H_INPUT_COLOR_RANGE GENMASK(1, 0) -+ -+#define TX_VIDEO_DTV_FILTER 0x004A -+#define TX_VIDEO_DTV_DITHER 0x004B -+#define TX_VIDEO_DTV_DEDITHER 0x004C -+#define TX_VIDEO_PROC_CONFIG0 0x004E -+#define TX_VIDEO_PROC_CONFIG1 0x004F -+ -+// Audio config -+#define TX_AUDIO_FORMAT 0x0058 -+ #define TX_AUDIO_FORMAT_SPDIF_OR_I2S BIT(7) -+ #define TX_AUDIO_FORMAT_I2S_2_OR_8_CH BIT(6) -+ #define TX_AUDIO_FORMAT_I2S_FORMAT GENMASK(5, 4) -+ #define TX_AUDIO_FORMAT_BIT_WIDTH_MASK GENMASK(3, 2) -+ #define TX_AUDIO_FORMAT_BIT_WIDTH_16 0x1 -+ #define TX_AUDIO_FORMAT_BIT_WIDTH_20 0x2 -+ #define TX_AUDIO_FORMAT_BIT_WIDTH_24 0x3 -+ #define TX_AUDIO_FORMAT_WS_POLARITY BIT(1) -+ #define TX_AUDIO_FORMAT_I2S_ONE_BIT_OR_I2S BIT(0) -+ #define TX_AUDIO_FORMAT_SPDIF_CHANNEL_STATUS_FROM_DATA_OR_REG BIT(0) -+ -+#define TX_AUDIO_SPDIF 0x0059 -+ #define TX_AUDIO_SPDIF_ENABLE BIT(0) -+#define TX_AUDIO_I2S 0x005A -+ #define TX_AUDIO_I2S_ENABLE BIT(0) -+#define TX_AUDIO_FIFO 0x005B -+ #define TX_AUDIO_FIFO_FIFO_DEPTH_MASK GENMASK(7, 4) -+ #define TX_AUDIO_FIFO_FIFO_DEPTH_512 0x4 -+ #define TX_AUDIO_FIFO_CRITICAL_THRESHOLD_MASK GENMASK(3, 2) -+ #define TX_AUDIO_FIFO_CRITICAL_THRESHOLD_DEPTH_DIV16 0x2 -+ #define TX_AUDIO_FIFO_NORMAL_THRESHOLD_MASK GENMASK(1, 0) -+ #define TX_AUDIO_FIFO_NORMAL_THRESHOLD_DEPTH_DIV8 0x1 -+#define TX_AUDIO_LIPSYNC 0x005C -+ #define TX_AUDIO_LIPSYNC_NORMALIZED_LIPSYNC_PARAM GENMASK(7, 0) -+#define TX_AUDIO_CONTROL 0x005D -+ #define TX_AUDIO_CONTROL_FORCED_AUDIO_FIFO_CLEAR BIT(7) -+ #define TX_AUDIO_CONTROL_AUTO_AUDIO_FIFO_CLEAR BIT(6) -+ #define TX_AUDIO_CONTROL_AUDIO_PACKET_TYPE_MASK GENMASK(5, 4) -+ #define TX_AUDIO_CONTROL_AUDIO_PACKET_TYPE_AUDIO_SAMPLE_PACKET 0x0 -+ #define TX_AUDIO_CONTROL_AUDIO_PACKET_TYPE_ONE_BIT_AUDIO 0x1 -+ #define TX_AUDIO_CONTROL_AUDIO_PACKET_TYPE_HBR_AUDIO_PACKET 0x2 -+ #define TX_AUDIO_CONTROL_AUDIO_PACKET_TYPE_DST_AUDIO_PACKET 0x3 -+ #define TX_AUDIO_CONTROL_AUDIO_SAMPLE_PACKET_VALID BIT(2) -+ #define TX_AUDIO_CONTROL_AUDIO_SAMPLE_PACKET_USER BIT(1) -+ #define TX_AUDIO_CONTROL_AUDIO_SAMPLE_PACKET_FLAT BIT(0) -+#define TX_AUDIO_HEADER 0x005E -+ #define TX_AUDIO_HEADER_AUDIO_SAMPLE_PACKET_HEADER_LAYOUT1 BIT(7) -+ #define TX_AUDIO_HEADER_SET_NORMAL_DOUBLE_IN_DST_PACKET_HEADER BIT(6) -+#define TX_AUDIO_SAMPLE 0x005F -+ #define TX_AUDIO_SAMPLE_CHANNEL_VALID GENMASK(7, 0) -+#define TX_AUDIO_VALID 0x0060 -+#define TX_AUDIO_USER 0x0061 -+#define TX_AUDIO_PACK 0x0062 -+ #define TX_AUDIO_PACK_AUDIO_SAMPLE_PACKETS_ENABLE BIT(0) -+#define TX_AUDIO_CONTROL_MORE 0x0064 -+ #define TX_AUDIO_CONTROL_MORE_ENABLE BIT(0) -+ -+// tmds config -+#define TX_TMDS_MODE 0x0068 -+ #define TX_TMDS_MODE_FORCED_HDMI BIT(7) -+ #define TX_TMDS_MODE_HDMI_CONFIG BIT(6) -+ #define TX_TMDS_MODE_BIT_SWAP BIT(3) -+ #define TX_TMDS_MODE_CHANNEL_SWAP GENMASK(2, 0) -+ -+#define TX_TMDS_CONFIG0 0x006C -+#define TX_TMDS_CONFIG1 0x006D -+ -+// packet config -+#define TX_PACKET_ALLOC_ACTIVE_1 0x0078 -+#define TX_PACKET_ALLOC_ACTIVE_2 0x0079 -+#define TX_PACKET_ALLOC_EOF_1 0x007A -+#define TX_PACKET_ALLOC_EOF_2 0x007B -+#define TX_PACKET_ALLOC_SOF_1 0x007C -+#define TX_PACKET_ALLOC_SOF_2 0x007D -+#define TX_PACKET_CONTROL_1 0x007E -+ #define TX_PACKET_CONTROL_1_FORCE_PACKET_TIMING BIT(7) -+ #define TX_PACKET_CONTROL_1_PACKET_ALLOC_MODE BIT(6) -+ #define TX_PACKET_CONTROL_1_PACKET_START_LATENCY GENMASK(5, 0) -+ -+#define TX_PACKET_CONTROL_2 0x007F -+ #define TX_PACKET_CONTROL_2_AUDIO_REQUEST_DISABLE BIT(3) -+ #define TX_PACKET_CONTROL_2_HORIZONTAL_GC_PACKET_TRANSPORT_EN BIT(1) -+ -+#define TX_CORE_EDID_CONFIG_MORE 0x0080 -+ #define TX_CORE_EDID_CONFIG_MORE_KEEP_EDID_ERROR BIT(1) -+ #define TX_CORE_EDID_CONFIG_MORE_SYS_TRIGGER_CONFIG_SEMI_MANU BIT(0) -+ -+#define TX_CORE_ALLOC_VSYNC_0 0x0081 -+#define TX_CORE_ALLOC_VSYNC_1 0x0082 -+#define TX_CORE_ALLOC_VSYNC_2 0x0083 -+#define TX_MEM_PD_REG0 0x0084 -+ -+// core config -+#define TX_CORE_DATA_CAPTURE_1 0x00F0 -+#define TX_CORE_DATA_CAPTURE_2 0x00F1 -+ #define TX_CORE_DATA_CAPTURE_2_AUDIO_SOURCE_SELECT GENMASK(7, 6) -+ #define TX_CORE_DATA_CAPTURE_2_EXTERNAL_PACKET_ENABLE BIT(5) -+ #define TX_CORE_DATA_CAPTURE_2_INTERNAL_PACKET_ENABLE BIT(4) -+ #define TX_CORE_DATA_CAPTURE_2_AFE_FIFO_SRC_LANE1 GENMASK(3, 2) -+ #define TX_CORE_DATA_CAPTURE_2_AFE_FIFO_SRC_LANE0 GENMASK(1, 0) -+ -+#define TX_CORE_DATA_MONITOR_1 0x00F2 -+ #define TX_CORE_DATA_MONITOR_1_LANE1 BIT(7) -+ #define TX_CORE_DATA_MONITOR_1_SELECT_LANE1 GENMASK(6, 4) -+ #define TX_CORE_DATA_MONITOR_1_LANE0 BIT(3) -+ #define TX_CORE_DATA_MONITOR_1_SELECT_LANE0 GENMASK(2, 0) -+ -+#define TX_CORE_DATA_MONITOR_2 0x00F3 -+ #define TX_CORE_DATA_MONITOR_2_MONITOR_SELECT GENMASK(2, 0) -+ -+#define TX_CORE_CALIB_MODE 0x00F4 -+#define TX_CORE_CALIB_SAMPLE_DELAY 0x00F5 -+#define TX_CORE_CALIB_VALUE_AUTO 0x00F6 -+#define TX_CORE_CALIB_VALUE 0x00F7 -+ -+// system config 4 -+#define TX_SYS4_TX_CKI_DDR 0x00A0 -+#define TX_SYS4_TX_CKO_DDR 0x00A1 -+#define TX_SYS4_RX_CKI_DDR 0x00A2 -+#define TX_SYS4_RX_CKO_DDR 0x00A3 -+#define TX_SYS4_CONNECT_SEL_0 0x00A4 -+#define TX_SYS4_CONNECT_SEL_1 0x00A5 -+ #define TX_SYS4_CONNECT_SEL_1_TX_CONNECT_SEL_UPPER_CHANNEL_DATA BIT(6) -+ -+#define TX_SYS4_CONNECT_SEL_2 0x00A6 -+#define TX_SYS4_CONNECT_SEL_3 0x00A7 -+#define TX_SYS4_CK_INV_VIDEO 0x00A8 -+ #define TX_SYS4_CK_INV_VIDEO_TMDS_CLK_PATTERN BIT(4) -+#define TX_SYS4_CK_INV_AUDIO 0x00A9 -+#define TX_SYS4_CK_INV_AFE 0x00AA -+#define TX_SYS4_CK_INV_CH01 0x00AB -+#define TX_SYS4_CK_INV_CH2 0x00AC -+#define TX_SYS4_CK_CEC 0x00AD -+#define TX_SYS4_CK_SOURCE_1 0x00AE -+#define TX_SYS4_CK_SOURCE_2 0x00AF -+ -+#define TX_IEC60958_SUB1_OFFSET 0x00B0 -+#define TX_IEC60958_SUB2_OFFSET 0x00C8 -+ -+// system config 5 -+#define TX_SYS5_TX_SOFT_RESET_1 0x00E0 -+ #define TX_SYS5_TX_SOFT_RESET_1_TX_PIXEL_RSTN BIT(7) -+ #define TX_SYS5_TX_SOFT_RESET_1_TX_TMDS_RSTN BIT(6) -+ #define TX_SYS5_TX_SOFT_RESET_1_TX_AUDIO_MASTER_RSTN BIT(5) -+ #define TX_SYS5_TX_SOFT_RESET_1_TX_AUDIO_RESAMPLE_RSTN BIT(4) -+ #define TX_SYS5_TX_SOFT_RESET_1_TX_I2S_RESET_RSTN BIT(3) -+ #define TX_SYS5_TX_SOFT_RESET_1_TX_DIG_RESET_N_CH2 BIT(2) -+ #define TX_SYS5_TX_SOFT_RESET_1_TX_DIG_RESET_N_CH1 BIT(1) -+ #define TX_SYS5_TX_SOFT_RESET_1_TX_DIG_RESET_N_CH0 BIT(0) -+ -+#define TX_SYS5_TX_SOFT_RESET_2 0x00E1 -+ #define TX_SYS5_TX_SOFT_RESET_2_HDMI_CH3_RST_IN BIT(7) -+ #define TX_SYS5_TX_SOFT_RESET_2_HDMI_CH2_RST_IN BIT(6) -+ #define TX_SYS5_TX_SOFT_RESET_2_HDMI_CH1_RST_IN BIT(5) -+ #define TX_SYS5_TX_SOFT_RESET_2_HDMI_CH0_RST_IN BIT(4) -+ #define TX_SYS5_TX_SOFT_RESET_2_HDMI_SR_RST BIT(3) -+ #define TX_SYS5_TX_SOFT_RESET_2_TX_DDC_HDCP_RSTN BIT(2) -+ #define TX_SYS5_TX_SOFT_RESET_2_TX_DDC_EDID_RSTN BIT(1) -+ #define TX_SYS5_TX_SOFT_RESET_2_TX_DIG_RESET_N_CH3 BIT(0) -+ -+#define TX_SYS5_RX_SOFT_RESET_1 0x00E2 -+#define TX_SYS5_RX_SOFT_RESET_2 0x00E3 -+#define TX_SYS5_RX_SOFT_RESET_3 0x00E4 -+#define TX_SYS5_SSTL_BIDIR_IN 0x00E5 -+#define TX_SYS5_SSTL_IN 0x00E6 -+#define TX_SYS5_SSTL_DIFF_IN 0x00E7 -+#define TX_SYS5_FIFO_CONFIG 0x00E8 -+ #define TX_SYS5_FIFO_CONFIG_AFE_FIFO_CHANNEL2_BYPASS BIT(6) -+ #define TX_SYS5_FIFO_CONFIG_AFE_FIFO_CHANNEL1_BYPASS BIT(5) -+ #define TX_SYS5_FIFO_CONFIG_AFE_FIFO_CHANNEL0_BYPASS BIT(4) -+ #define TX_SYS5_FIFO_CONFIG_CLK_CHANNEL3_OUTPUT_ENABLE BIT(3) -+ #define TX_SYS5_FIFO_CONFIG_AFE_FIFO_CHANNEL2_ENABLE BIT(2) -+ #define TX_SYS5_FIFO_CONFIG_AFE_FIFO_CHANNEL1_ENABLE BIT(1) -+ #define TX_SYS5_FIFO_CONFIG_AFE_FIFO_CHANNEL0_ENABLE BIT(0) -+ -+#define TX_SYS5_FIFO_SAMP01_CFG 0x00E9 -+#define TX_SYS5_FIFO_SAMP23_CFG 0x00EA -+#define TX_SYS5_CONNECT_FIFO_CFG 0x00EB -+#define TX_SYS5_IO_CALIB_CONTROL 0x00EC -+#define TX_SYS5_SSTL_BIDIR_OUT 0x00ED -+#define TX_SYS5_SSTL_OUT 0x00EE -+#define TX_SYS5_SSTL_DIFF_OUT 0x00EF -+ -+// HDCP shadow register -+#define TX_HDCP_SHW_BKSV_0 0x0100 -+#define TX_HDCP_SHW_BKSV_1 0x0101 -+#define TX_HDCP_SHW_BKSV_2 0x0102 -+#define TX_HDCP_SHW_BKSV_3 0x0103 -+#define TX_HDCP_SHW_BKSV_4 0x0104 -+#define TX_HDCP_SHW_RI1_0 0x0108 -+#define TX_HDCP_SHW_RI1_1 0x0109 -+#define TX_HDCP_SHW_PJ1 0x010A -+#define TX_HDCP_SHW_AKSV_0 0x0110 -+#define TX_HDCP_SHW_AKSV_1 0x0111 -+#define TX_HDCP_SHW_AKSV_2 0x0112 -+#define TX_HDCP_SHW_AKSV_3 0x0113 -+#define TX_HDCP_SHW_AKSV_4 0x0114 -+#define TX_HDCP_SHW_AINFO 0x0115 -+#define TX_HDCP_SHW_AN_0 0x0118 -+#define TX_HDCP_SHW_AN_1 0x0119 -+#define TX_HDCP_SHW_AN_2 0x011A -+#define TX_HDCP_SHW_AN_3 0x011B -+#define TX_HDCP_SHW_AN_4 0x011C -+#define TX_HDCP_SHW_AN_5 0x011D -+#define TX_HDCP_SHW_AN_6 0x011E -+#define TX_HDCP_SHW_AN_7 0x011F -+#define TX_HDCP_SHW_V1_H0_0 0x0120 -+#define TX_HDCP_SHW_V1_H0_1 0x0121 -+#define TX_HDCP_SHW_V1_H0_2 0x0122 -+#define TX_HDCP_SHW_V1_H0_3 0x0123 -+#define TX_HDCP_SHW_V1_H1_0 0x0124 -+#define TX_HDCP_SHW_V1_H1_1 0x0125 -+#define TX_HDCP_SHW_V1_H1_2 0x0126 -+#define TX_HDCP_SHW_V1_H1_3 0x0127 -+#define TX_HDCP_SHW_V1_H2_0 0x0128 -+#define TX_HDCP_SHW_V1_H2_1 0x0129 -+#define TX_HDCP_SHW_V1_H2_2 0x012A -+#define TX_HDCP_SHW_V1_H2_3 0x012B -+#define TX_HDCP_SHW_V1_H3_0 0x012C -+#define TX_HDCP_SHW_V1_H3_1 0x012D -+#define TX_HDCP_SHW_V1_H3_2 0x012E -+#define TX_HDCP_SHW_V1_H3_3 0x012F -+#define TX_HDCP_SHW_V1_H4_0 0x0130 -+#define TX_HDCP_SHW_V1_H4_1 0x0131 -+#define TX_HDCP_SHW_V1_H4_2 0x0132 -+#define TX_HDCP_SHW_V1_H4_3 0x0133 -+#define TX_HDCP_SHW_BCAPS 0x0140 -+#define TX_HDCP_SHW_BSTATUS_0 0x0141 -+#define TX_HDCP_SHW_BSTATUS_1 0x0142 -+#define TX_HDCP_SHW_KSV_FIFO 0x0143 -+ -+// system status 0 -+#define TX_SYSST0_CONNECT_FIFO 0x0180 -+#define TX_SYSST0_PLL_MONITOR 0x0181 -+#define TX_SYSST0_AFE_FIFO 0x0182 -+#define TX_SYSST0_ROM_STATUS 0x018F -+ -+// hdcp status -+#define TX_HDCP_ST_AUTHENTICATION 0x0190 -+#define TX_HDCP_ST_FRAME_COUNT 0x0191 -+#define TX_HDCP_ST_STATUS_0 0x0192 -+#define TX_HDCP_ST_STATUS_1 0x0193 -+#define TX_HDCP_ST_STATUS_2 0x0194 -+#define TX_HDCP_ST_STATUS_3 0x0195 -+#define TX_HDCP_ST_EDID_STATUS 0x0196 -+ #define TX_HDCP_ST_EDID_STATUS_SYSTEM_STATUS GENMASK(7, 6) -+ #define TX_HDCP_ST_EDID_STATUS_SYSTEM_STATUS_NO_SINK_ATTACHED 0x0 -+ #define TX_HDCP_ST_EDID_STATUS_SYSTEM_STATUS_READING_EDID 0x1 -+ #define TX_HDCP_ST_EDID_STATUS_SYSTEM_STATUS_DVI_MODE 0x2 -+ #define TX_HDCP_ST_EDID_STATUS_SYSTEM_STATUS_HDMI_MODE 0x3 -+ #define TX_HDCP_ST_EDID_STATUS_EDID_DATA_READY BIT(4) -+ #define TX_HDCP_ST_EDID_STATUS_HPD_STATUS BIT(1) -+ -+#define TX_HDCP_ST_MEM_STATUS 0x0197 -+#define TX_HDCP_ST_ST_MODE 0x019F -+ -+// video status -+#define TX_VIDEO_ST_ACTIVE_PIXELS_1 0x01A0 -+#define TX_VIDEO_ST_ACTIVE_PIXELS_2 0x01A1 -+#define TX_VIDEO_ST_FRONT_PIXELS 0x01A2 -+#define TX_VIDEO_ST_HSYNC_PIXELS 0x01A3 -+#define TX_VIDEO_ST_BACK_PIXELS 0x01A4 -+#define TX_VIDEO_ST_ACTIVE_LINES_1 0x01A5 -+#define TX_VIDEO_ST_ACTIVE_LINES_2 0x01A6 -+#define TX_VIDEO_ST_EOF_LINES 0x01A7 -+#define TX_VIDEO_ST_VSYNC_LINES 0x01A8 -+#define TX_VIDEO_ST_SOF_LINES 0x01A9 -+#define TX_VIDEO_ST_DTV_TIMING 0x01AA -+#define TX_VIDEO_ST_DTV_MODE 0x01AB -+// audio status -+#define TX_VIDEO_ST_AUDIO_STATUS 0x01AC -+#define TX_AFE_STATUS_0 0x01AE -+#define TX_AFE_STATUS_1 0x01AF -+ -+#define TX_IEC60958_ST_SUB1_OFFSET 0x01B0 -+#define TX_IEC60958_ST_SUB2_OFFSET 0x01C8 -+ -+// system status 1 -+#define TX_SYSST1_CALIB_BIT_RESULT_0 0x01E0 -+#define TX_SYSST1_CALIB_BIT_RESULT_1 0x01E1 -+//HDMI_STATUS_OUT[7:0] -+#define TX_HDMI_PHY_READBACK_0 0x01E2 -+//HDMI_COMP_OUT[4] -+//HDMI_STATUS_OUT[11:8] -+#define TX_HDMI_PHY_READBACK_1 0x01E3 -+#define TX_SYSST1_CALIB_BIT_RESULT_4 0x01E4 -+#define TX_SYSST1_CALIB_BIT_RESULT_5 0x01E5 -+#define TX_SYSST1_CALIB_BIT_RESULT_6 0x01E6 -+#define TX_SYSST1_CALIB_BIT_RESULT_7 0x01E7 -+#define TX_SYSST1_CALIB_BUS_RESULT_0 0x01E8 -+#define TX_SYSST1_CALIB_BUS_RESULT_1 0x01E9 -+#define TX_SYSST1_CALIB_BUS_RESULT_2 0x01EA -+#define TX_SYSST1_CALIB_BUS_RESULT_3 0x01EB -+#define TX_SYSST1_CALIB_BUS_RESULT_4 0x01EC -+#define TX_SYSST1_CALIB_BUS_RESULT_5 0x01ED -+#define TX_SYSST1_CALIB_BUS_RESULT_6 0x01EE -+#define TX_SYSST1_CALIB_BUS_RESULT_7 0x01EF -+ -+// Packet status -+#define TX_PACKET_ST_REQUEST_STATUS_1 0x01F0 -+#define TX_PACKET_ST_REQUEST_STATUS_2 0x01F1 -+#define TX_PACKET_ST_REQUEST_MISSED_1 0x01F2 -+#define TX_PACKET_ST_REQUEST_MISSED_2 0x01F3 -+#define TX_PACKET_ST_ENCODE_STATUS_0 0x01F4 -+#define TX_PACKET_ST_ENCODE_STATUS_1 0x01F5 -+#define TX_PACKET_ST_ENCODE_STATUS_2 0x01F6 -+#define TX_PACKET_ST_TIMER_STATUS 0x01F7 -+ -+// tmds status -+#define TX_TMDS_ST_CLOCK_METER_1 0x01F8 -+#define TX_TMDS_ST_CLOCK_METER_2 0x01F9 -+#define TX_TMDS_ST_CLOCK_METER_3 0x01FA -+#define TX_TMDS_ST_TMDS_STATUS_1 0x01FC -+#define TX_TMDS_ST_TMDS_STATUS_2 0x01FD -+#define TX_TMDS_ST_TMDS_STATUS_3 0x01FE -+#define TX_TMDS_ST_TMDS_STATUS_4 0x01FF -+ -+// Packet register -+#define TX_PKT_REG_SPD_INFO_BASE_ADDR 0x0200 -+#define TX_PKT_REG_VEND_INFO_BASE_ADDR 0x0220 -+#define TX_PKT_REG_MPEG_INFO_BASE_ADDR 0x0240 -+#define TX_PKT_REG_AVI_INFO_BASE_ADDR 0x0260 -+#define TX_PKT_REG_AUDIO_INFO_BASE_ADDR 0x0280 -+#define TX_PKT_REG_ACP_INFO_BASE_ADDR 0x02A0 -+#define TX_PKT_REG_ISRC1_BASE_ADDR 0x02C0 -+#define TX_PKT_REG_ISRC2_BASE_ADDR 0x02E0 -+#define TX_PKT_REG_EXCEPT0_BASE_ADDR 0x0300 -+#define TX_PKT_REG_EXCEPT1_BASE_ADDR 0x0320 -+#define TX_PKT_REG_EXCEPT2_BASE_ADDR 0x0340 -+#define TX_PKT_REG_EXCEPT3_BASE_ADDR 0x0360 -+#define TX_PKT_REG_EXCEPT4_BASE_ADDR 0x0380 -+#define TX_PKT_REG_GAMUT_P0_BASE_ADDR 0x03A0 -+#define TX_PKT_REG_GAMUT_P1_1_BASE_ADDR 0x03C0 -+#define TX_PKT_REG_GAMUT_P1_2_BASE_ADDR 0x03E0 -+ -+#define TX_RX_EDID_OFFSET 0x0600 -+ -+/* HDMI OTHER registers */ -+ -+#define HDMI_OTHER_CTRL0 0x8000 -+#define HDMI_OTHER_CTRL1 0x8001 -+ #define HDMI_OTHER_CTRL1_POWER_ON BIT(15) -+ #define HDMI_OTHER_CTRL1_HDMI_AUDIO_CLOCK_ON BIT(13) -+ -+#define HDMI_OTHER_STATUS0 0x8002 -+#define HDMI_OTHER_CTRL2 0x8003 -+#define HDMI_OTHER_INTR_MASKN 0x8004 -+ #define HDMI_OTHER_INTR_MASKN_TX_EDID_INT_RISE BIT(2) -+ #define HDMI_OTHER_INTR_MASKN_TX_HPD_INT_FALL BIT(1) -+ #define HDMI_OTHER_INTR_MASKN_TX_HPD_INT_RISE BIT(0) -+ -+#define HDMI_OTHER_INTR_STAT 0x8005 -+ #define HDMI_OTHER_INTR_STAT_EDID_RISING BIT(2) -+ #define HDMI_OTHER_INTR_STAT_HPD_FALLING BIT(1) -+ #define HDMI_OTHER_INTR_STAT_HPD_RISING BIT(0) -+ -+#define HDMI_OTHER_INTR_STAT_CLR 0x8006 -+ #define HDMI_OTHER_INTR_STAT_CLR_EDID_RISING BIT(2) -+ #define HDMI_OTHER_INTR_STAT_CLR_HPD_FALLING BIT(1) -+ #define HDMI_OTHER_INTR_STAT_CLR_HPD_RISING BIT(0) -+ -+#define HDMI_OTHER_AVI_INTR_MASKN0 0x8008 -+#define HDMI_OTHER_AVI_INTR_MASKN1 0x8009 -+#define HDMI_OTHER_RX_AINFO_INTR_MASKN0 0x800a -+#define HDMI_OTHER_RX_AINFO_INTR_MASKN1 0x800b -+#define HDMI_OTHER_RX_PACKET_INTR_CLR 0x800c -+ -+#endif /* __MESON_TRANSWITCH_HDMI_H__ */ -diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c -index 111111111111..222222222222 100644 ---- a/drivers/gpu/drm/meson/meson_vclk.c -+++ b/drivers/gpu/drm/meson/meson_vclk.c -@@ -732,6 +732,11 @@ meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq) - return MODE_CLOCK_HIGH; - } - -+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) -+ return MODE_OK; -+ - if (meson_hdmi_pll_find_params(priv, freq, &m, &frac, &od)) - return MODE_OK; - -@@ -784,6 +789,11 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq, - return MODE_CLOCK_HIGH; - } - -+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) -+ return MODE_OK; -+ - for (i = 0 ; params[i].pixel_freq ; ++i) { - DRM_DEBUG_DRIVER("i = %d pixel_freq = %d alt = %d\n", - i, params[i].pixel_freq, -@@ -1024,6 +1034,128 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, - regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, VCLK_EN, VCLK_EN); - } - -+static int meson_vclk_set_rate_exclusive(struct meson_drm *priv, -+ enum vpu_bulk_clk_id clk_id, -+ unsigned int rate_khz) -+{ -+ struct clk *clk = priv->vid_clks[clk_id].clk; -+ int ret; -+ -+ ret = clk_set_rate_exclusive(clk, rate_khz * 1000UL); -+ if (ret) -+ return ret; -+ -+ priv->vid_clk_rate_exclusive[clk_id] = true; -+ -+ return 0; -+} -+ -+static void meson_vclk_disable_ccf(struct meson_drm *priv) -+{ -+ unsigned int i; -+ -+ /* allow all clocks to be changed in _enable again */ -+ for (i = 0; i < VPU_VID_CLK_NUM; i++) { -+ if (!priv->vid_clk_rate_exclusive[i]) -+ continue; -+ -+ clk_rate_exclusive_put(priv->vid_clks[i].clk); -+ priv->vid_clk_rate_exclusive[i] = false; -+ } -+ -+ if (priv->clk_dac_enabled) { -+ clk_disable(priv->clk_dac); -+ priv->clk_dac_enabled = false; -+ } -+ -+ if (priv->clk_venc_enabled) { -+ clk_disable(priv->clk_venc); -+ priv->clk_venc_enabled = false; -+ } -+} -+ -+static int meson_vclk_enable_ccf(struct meson_drm *priv, unsigned int target, -+ bool hdmi_use_enci, unsigned int phy_freq, -+ unsigned int dac_freq, unsigned int venc_freq) -+{ -+ enum vpu_bulk_clk_id venc_clk_id, dac_clk_id; -+ int ret; -+ -+ if (target == MESON_VCLK_TARGET_CVBS || hdmi_use_enci) -+ venc_clk_id = VPU_VID_CLK_CTS_ENCI; -+ else -+ venc_clk_id = VPU_VID_CLK_CTS_ENCP; -+ -+ if (target == MESON_VCLK_TARGET_CVBS) -+ dac_clk_id = VPU_VID_CLK_CTS_VDAC0; -+ else -+ dac_clk_id = VPU_VID_CLK_HDMI_TX_PIXEL; -+ -+ /* -+ * The TMDS clock also updates the PLL. Protect the PLL rate so all -+ * following clocks are derived from the PLL setting which matches the -+ * TMDS clock. -+ */ -+ ret = meson_vclk_set_rate_exclusive(priv, VPU_VID_CLK_TMDS, phy_freq); -+ if (ret) { -+ dev_err(priv->dev, "Failed to set TMDS clock to %ukHz: %d\n", -+ phy_freq, ret); -+ goto out_enable_clocks; -+ } -+ -+ /* -+ * The DAC clock may be derived from a parent of the VENC clock so we -+ * must protect the VENC clock from changing it's rate. This works -+ * because the DAC freq can be divided by the VENC clock. -+ */ -+ ret = meson_vclk_set_rate_exclusive(priv, venc_clk_id, venc_freq); -+ if (ret) { -+ dev_warn(priv->dev, -+ "Failed to set VENC clock to %ukHz while TMDS clock is %ukHz: %d\n", -+ venc_freq, phy_freq, ret); -+ goto out_enable_clocks; -+ } -+ -+ priv->clk_venc = priv->vid_clks[venc_clk_id].clk; -+ -+ /* -+ * after changing any of the VID_PLL_* clocks (which can happen when -+ * update the VENC clock rate) we need to assert and then de-assert the -+ * VID_DIVIDER_CNTL_* reset lines. -+ */ -+ reset_control_bulk_assert(VPU_RESET_VID_PLL_NUM, priv->vid_pll_resets); -+ reset_control_bulk_deassert(VPU_RESET_VID_PLL_NUM, priv->vid_pll_resets); -+ -+ ret = meson_vclk_set_rate_exclusive(priv, dac_clk_id, dac_freq); -+ if (ret) { -+ dev_warn(priv->dev, -+ "Failed to set pixel clock to %ukHz while TMDS clock is %ukHz: %d\n", -+ dac_freq, phy_freq, ret); -+ goto out_enable_clocks; -+ } -+ -+ priv->clk_dac = priv->vid_clks[dac_clk_id].clk; -+ -+out_enable_clocks: -+ ret = clk_enable(priv->clk_venc); -+ if (ret) -+ dev_err(priv->dev, -+ "Failed to re-enable the VENC clock at %ukHz: %d\n", -+ venc_freq, ret); -+ else -+ priv->clk_venc_enabled = true; -+ -+ ret = clk_enable(priv->clk_dac); -+ if (ret) -+ dev_err(priv->dev, -+ "Failed to re-enable the pixel clock at %ukHz: %d\n", -+ dac_freq, ret); -+ else -+ priv->clk_dac_enabled = true; -+ -+ return ret; -+} -+ - void meson_vclk_setup(struct meson_drm *priv, unsigned int target, - unsigned int phy_freq, unsigned int vclk_freq, - unsigned int venc_freq, unsigned int dac_freq, -@@ -1034,6 +1166,20 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, - unsigned int hdmi_tx_div; - unsigned int venc_div; - -+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) { -+ /* CVBS video clocks are generated off a 1296MHz base clock */ -+ if (target == MESON_VCLK_TARGET_CVBS) -+ phy_freq = 1296000; -+ -+ dev_err(priv->dev, "%s(target: %u, phy: %u, dac: %u, venc: %u, hdmi_use_enci: %u)\n", __func__, target, phy_freq, dac_freq, venc_freq, hdmi_use_enci); -+ meson_vclk_disable_ccf(priv); -+ meson_vclk_enable_ccf(priv, target, hdmi_use_enci, phy_freq, -+ dac_freq, venc_freq); -+ return; -+ } -+ - if (target == MESON_VCLK_TARGET_CVBS) { - meson_venci_cvbs_clock_config(priv); - return; -diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c -index 111111111111..222222222222 100644 ---- a/drivers/gpu/drm/meson/meson_venc.c -+++ b/drivers/gpu/drm/meson/meson_venc.c -@@ -62,10 +62,6 @@ - - /* HHI Registers */ - #define HHI_GCLK_MPEG2 0x148 /* 0x52 offset in data sheet */ --#define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */ --#define HHI_VDAC_CNTL0_G12A 0x2EC /* 0xbb offset in data sheet */ --#define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */ --#define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbc offset in data sheet */ - #define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 offset in data sheet */ - - struct meson_cvbs_enci_mode meson_cvbs_enci_pal = { -@@ -1957,31 +1953,47 @@ void meson_venc_enable_vsync(struct meson_drm *priv) - writel_relaxed(VENC_INTCTRL_ENCI_LNRST_INT_EN, - priv->io_base + _REG(VENC_INTCTRL)); - } -- regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), BIT(25)); -+ -+ if (priv->intr_clks[0].clk) { -+ if (!priv->intr_clks_enabled) { -+ int ret; -+ -+ ret = clk_bulk_enable(priv->num_intr_clks, -+ priv->intr_clks); -+ if (ret) -+ dev_err(priv->dev, -+ "Failed to enable the interrupt clocks\n"); -+ else -+ priv->intr_clks_enabled = true; -+ } -+ } else { -+ regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), BIT(25)); -+ } - } - - void meson_venc_disable_vsync(struct meson_drm *priv) - { -- regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), 0); -+ if (priv->intr_clks[0].clk) { -+ if (priv->intr_clks_enabled) { -+ clk_bulk_disable(priv->num_intr_clks, -+ priv->intr_clks); -+ priv->intr_clks_enabled = false; -+ } -+ } else { -+ regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), 0); -+ } -+ - writel_relaxed(0, priv->io_base + _REG(VENC_INTCTRL)); - } - - void meson_venc_init(struct meson_drm *priv) - { -- /* Disable CVBS VDAC */ -- if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { -- regmap_write(priv->hhi, HHI_VDAC_CNTL0_G12A, 0); -- regmap_write(priv->hhi, HHI_VDAC_CNTL1_G12A, 8); -- } else { -- regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0); -- regmap_write(priv->hhi, HHI_VDAC_CNTL1, 8); -- } -- - /* Power Down Dacs */ - writel_relaxed(0xff, priv->io_base + _REG(VENC_VDAC_SETTING)); - - /* Disable HDMI PHY */ -- regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0); -+ if (priv->hhi) -+ regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0); - - /* Disable HDMI */ - writel_bits_relaxed(VPU_HDMI_ENCI_DATA_TO_HDMI | -diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c -index 111111111111..222222222222 100644 ---- a/drivers/gpu/drm/meson/meson_viu.c -+++ b/drivers/gpu/drm/meson/meson_viu.c -@@ -448,13 +448,17 @@ void meson_viu_init(struct meson_drm *priv) - writel_relaxed(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT)); - writel_relaxed(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT)); - -- /* Set OSD alpha replace value */ -- writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT, -- 0xff << OSD_REPLACE_SHIFT, -- priv->io_base + _REG(VIU_OSD1_CTRL_STAT2)); -- writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT, -- 0xff << OSD_REPLACE_SHIFT, -- priv->io_base + _REG(VIU_OSD2_CTRL_STAT2)); -+ if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) && -+ !meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) && -+ !meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) { -+ /* Set OSD alpha replace value */ -+ writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT, -+ 0xff << OSD_REPLACE_SHIFT, -+ priv->io_base + _REG(VIU_OSD1_CTRL_STAT2)); -+ writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT, -+ 0xff << OSD_REPLACE_SHIFT, -+ priv->io_base + _REG(VIU_OSD2_CTRL_STAT2)); -+ } - - /* Disable VD1 AFBC */ - /* di_mif0_en=0 mif0_to_vpp_en=0 di_mad_en=0 and afbc vd1 set=0*/ -diff --git a/drivers/phy/amlogic/Kconfig b/drivers/phy/amlogic/Kconfig -index 111111111111..222222222222 100644 ---- a/drivers/phy/amlogic/Kconfig -+++ b/drivers/phy/amlogic/Kconfig -@@ -25,6 +25,16 @@ config PHY_MESON8B_USB2 - Meson8b and GXBB SoCs. - If unsure, say N. - -+config PHY_MESON_CVBS_DAC -+ tristate "Amlogic Meson CVBS DAC PHY driver" -+ depends on ARCH_MESON || COMPILE_TEST -+ depends on OF -+ select MFD_SYSCON -+ help -+ Enable this to support the CVBS DAC (PHY) found in Amlogic -+ Meson SoCs. -+ If unsure, say N. -+ - config PHY_MESON_GXL_USB2 - tristate "Meson GXL and GXM USB2 PHY drivers" - default ARCH_MESON -diff --git a/drivers/phy/amlogic/Makefile b/drivers/phy/amlogic/Makefile -index 111111111111..222222222222 100644 ---- a/drivers/phy/amlogic/Makefile -+++ b/drivers/phy/amlogic/Makefile -@@ -1,6 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0-only - obj-$(CONFIG_PHY_MESON8_HDMI_TX) += phy-meson8-hdmi-tx.o - obj-$(CONFIG_PHY_MESON8B_USB2) += phy-meson8b-usb2.o -+obj-$(CONFIG_PHY_MESON_CVBS_DAC) += phy-meson-cvbs-dac.o - obj-$(CONFIG_PHY_MESON_GXL_USB2) += phy-meson-gxl-usb2.o - obj-$(CONFIG_PHY_MESON_G12A_USB2) += phy-meson-g12a-usb2.o - obj-$(CONFIG_PHY_MESON_G12A_USB3_PCIE) += phy-meson-g12a-usb3-pcie.o -diff --git a/drivers/phy/amlogic/phy-meson-cvbs-dac.c b/drivers/phy/amlogic/phy-meson-cvbs-dac.c -new file mode 100644 -index 000000000000..111111111111 ---- /dev/null -+++ b/drivers/phy/amlogic/phy-meson-cvbs-dac.c -@@ -0,0 +1,375 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Copyright (C) 2016 BayLibre, SAS -+ * Copyright (C) 2021 Martin Blumenstingl -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define HHI_VDAC_CNTL0_MESON8 0x2F4 /* 0xbd offset in data sheet */ -+#define HHI_VDAC_CNTL1_MESON8 0x2F8 /* 0xbe offset in data sheet */ -+ -+#define HHI_VDAC_CNTL0_G12A 0x2EC /* 0xbd offset in data sheet */ -+#define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbe offset in data sheet */ -+ -+enum phy_meson_cvbs_dac_reg { -+ MESON_CDAC_CTRL_RESV1, -+ MESON_CDAC_CTRL_RESV2, -+ MESON_CDAC_VREF_ADJ, -+ MESON_CDAC_RL_ADJ, -+ MESON_CDAC_CLK_PHASE_SEL, -+ MESON_CDAC_DRIVER_ADJ, -+ MESON_CDAC_EXT_VREF_EN, -+ MESON_CDAC_BIAS_C, -+ MESON_VDAC_CNTL0_RESERVED, -+ MESON_CDAC_GSW, -+ MESON_CDAC_PWD, -+ MESON_VDAC_CNTL1_RESERVED, -+ MESON_CVBS_DAC_NUM_REGS -+}; -+ -+struct phy_meson_cvbs_dac_data { -+ const struct reg_field *reg_fields; -+ u8 cdac_ctrl_resv2_enable_val; -+ u8 cdac_vref_adj_enable_val; -+ u8 cdac_rl_adj_enable_val; -+ bool disable_ignore_cdac_pwd; -+ bool needs_cvbs_trimming_nvmem_cell; -+}; -+ -+struct phy_meson_cvbs_dac_priv { -+ struct regmap_field *regs[MESON_CVBS_DAC_NUM_REGS]; -+ const struct phy_meson_cvbs_dac_data *data; -+ u8 cdac_gsw_enable_val; -+}; -+ -+static const struct reg_field phy_meson8_cvbs_dac_reg_fields[] = { -+ [MESON_CDAC_CTRL_RESV1] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 0, 7), -+ [MESON_CDAC_CTRL_RESV2] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 8, 15), -+ [MESON_CDAC_VREF_ADJ] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 16, 20), -+ [MESON_CDAC_RL_ADJ] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 21, 23), -+ [MESON_CDAC_CLK_PHASE_SEL] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 24, 24), -+ [MESON_CDAC_DRIVER_ADJ] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 25, 25), -+ [MESON_CDAC_EXT_VREF_EN] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 26, 26), -+ [MESON_CDAC_BIAS_C] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 27, 27), -+ [MESON_VDAC_CNTL0_RESERVED] = REG_FIELD(HHI_VDAC_CNTL0_MESON8, 28, 31), -+ [MESON_CDAC_GSW] = REG_FIELD(HHI_VDAC_CNTL1_MESON8, 0, 2), -+ [MESON_CDAC_PWD] = REG_FIELD(HHI_VDAC_CNTL1_MESON8, 3, 3), -+ [MESON_VDAC_CNTL1_RESERVED] = REG_FIELD(HHI_VDAC_CNTL1_MESON8, 4, 31), -+}; -+ -+static const struct reg_field phy_meson_g12a_cvbs_dac_reg_fields[] = { -+ [MESON_CDAC_CTRL_RESV1] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 0, 7), -+ [MESON_CDAC_CTRL_RESV2] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 8, 15), -+ [MESON_CDAC_VREF_ADJ] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 16, 20), -+ [MESON_CDAC_RL_ADJ] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 21, 23), -+ [MESON_CDAC_CLK_PHASE_SEL] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 24, 24), -+ [MESON_CDAC_DRIVER_ADJ] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 25, 25), -+ [MESON_CDAC_EXT_VREF_EN] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 26, 26), -+ [MESON_CDAC_BIAS_C] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 27, 27), -+ [MESON_VDAC_CNTL0_RESERVED] = REG_FIELD(HHI_VDAC_CNTL0_G12A, 28, 31), -+ [MESON_CDAC_GSW] = REG_FIELD(HHI_VDAC_CNTL1_G12A, 0, 2), -+ [MESON_CDAC_PWD] = REG_FIELD(HHI_VDAC_CNTL1_G12A, 3, 3), -+ [MESON_VDAC_CNTL1_RESERVED] = REG_FIELD(HHI_VDAC_CNTL1_G12A, 4, 31), -+}; -+ -+static const struct phy_meson_cvbs_dac_data phy_meson8_cvbs_dac_data = { -+ .reg_fields = phy_meson8_cvbs_dac_reg_fields, -+ .cdac_ctrl_resv2_enable_val = 0x0, -+ .cdac_vref_adj_enable_val = 0x0, -+ .cdac_rl_adj_enable_val = 0x0, -+ .disable_ignore_cdac_pwd = false, -+ .needs_cvbs_trimming_nvmem_cell = true, -+}; -+ -+static const struct phy_meson_cvbs_dac_data phy_meson_gxbb_cvbs_dac_data = { -+ .reg_fields = phy_meson8_cvbs_dac_reg_fields, -+ .cdac_ctrl_resv2_enable_val = 0x0, -+ .cdac_vref_adj_enable_val = 0x0, -+ .cdac_rl_adj_enable_val = 0x0, -+ .disable_ignore_cdac_pwd = false, -+ .needs_cvbs_trimming_nvmem_cell = false, -+}; -+ -+static const struct phy_meson_cvbs_dac_data phy_meson_gxl_cvbs_dac_data = { -+ .reg_fields = phy_meson8_cvbs_dac_reg_fields, -+ .cdac_ctrl_resv2_enable_val = 0x0, -+ .cdac_vref_adj_enable_val = 0xf, -+ .cdac_rl_adj_enable_val = 0x0, -+ .disable_ignore_cdac_pwd = false, -+ .needs_cvbs_trimming_nvmem_cell = false, -+}; -+ -+static const struct phy_meson_cvbs_dac_data phy_meson_g12a_cvbs_dac_data = { -+ .reg_fields = phy_meson_g12a_cvbs_dac_reg_fields, -+ .cdac_ctrl_resv2_enable_val = 0x60, -+ .cdac_vref_adj_enable_val = 0x10, -+ .cdac_rl_adj_enable_val = 0x4, -+ .disable_ignore_cdac_pwd = true, -+ .needs_cvbs_trimming_nvmem_cell = false, -+}; -+ -+static int phy_meson_cvbs_dac_power_on(struct phy *phy) -+{ -+ struct phy_meson_cvbs_dac_priv *priv = phy_get_drvdata(phy); -+ -+ regmap_field_write(priv->regs[MESON_CDAC_CTRL_RESV1], 0x1); -+ regmap_field_write(priv->regs[MESON_CDAC_CTRL_RESV2], -+ priv->data->cdac_ctrl_resv2_enable_val); -+ regmap_field_write(priv->regs[MESON_CDAC_VREF_ADJ], -+ priv->data->cdac_vref_adj_enable_val); -+ regmap_field_write(priv->regs[MESON_CDAC_RL_ADJ], -+ priv->data->cdac_rl_adj_enable_val); -+ regmap_field_write(priv->regs[MESON_CDAC_GSW], -+ priv->cdac_gsw_enable_val); -+ regmap_field_write(priv->regs[MESON_CDAC_PWD], 0x0); -+ -+ return 0; -+} -+ -+static int phy_meson_cvbs_dac_power_off(struct phy *phy) -+{ -+ struct phy_meson_cvbs_dac_priv *priv = phy_get_drvdata(phy); -+ -+ regmap_field_write(priv->regs[MESON_CDAC_CTRL_RESV1], 0x0); -+ regmap_field_write(priv->regs[MESON_CDAC_CTRL_RESV2], 0x0); -+ regmap_field_write(priv->regs[MESON_CDAC_VREF_ADJ], 0x0); -+ regmap_field_write(priv->regs[MESON_CDAC_RL_ADJ], 0x0); -+ regmap_field_write(priv->regs[MESON_CDAC_GSW], 0x0); -+ -+ if (priv->data->disable_ignore_cdac_pwd) -+ regmap_field_write(priv->regs[MESON_CDAC_PWD], 0x0); -+ else -+ regmap_field_write(priv->regs[MESON_CDAC_PWD], 0x1); -+ -+ return 0; -+} -+ -+static int phy_meson_cvbs_dac_init(struct phy *phy) -+{ -+ struct phy_meson_cvbs_dac_priv *priv = phy_get_drvdata(phy); -+ -+ regmap_field_write(priv->regs[MESON_CDAC_CLK_PHASE_SEL], 0x0); -+ regmap_field_write(priv->regs[MESON_CDAC_DRIVER_ADJ], 0x0); -+ regmap_field_write(priv->regs[MESON_CDAC_EXT_VREF_EN], 0x0); -+ regmap_field_write(priv->regs[MESON_CDAC_BIAS_C], 0x0); -+ regmap_field_write(priv->regs[MESON_VDAC_CNTL0_RESERVED], 0x0); -+ regmap_field_write(priv->regs[MESON_VDAC_CNTL1_RESERVED], 0x0); -+ -+ return phy_meson_cvbs_dac_power_off(phy); -+} -+ -+static const struct phy_ops phy_meson_cvbs_dac_ops = { -+ .init = phy_meson_cvbs_dac_init, -+ .power_on = phy_meson_cvbs_dac_power_on, -+ .power_off = phy_meson_cvbs_dac_power_off, -+ .owner = THIS_MODULE, -+}; -+ -+static u8 phy_meson_cvbs_trimming_version(u8 trimming1) -+{ -+ if ((trimming1 & 0xf0) == 0xa0) -+ return 5; -+ else if ((trimming1 & 0xf0) == 0x40) -+ return 2; -+ else if ((trimming1 & 0xc0) == 0x80) -+ return 1; -+ else if ((trimming1 & 0xc0) == 0x00) -+ return 0; -+ else -+ return 0xff; -+} -+ -+static int phy_meson_cvbs_read_trimming(struct device *dev, -+ struct phy_meson_cvbs_dac_priv *priv) -+{ -+ struct nvmem_cell *cell; -+ u8 *trimming; -+ size_t len; -+ -+ cell = devm_nvmem_cell_get(dev, "cvbs_trimming"); -+ if (IS_ERR(cell)) -+ return dev_err_probe(dev, PTR_ERR(cell), -+ "Failed to get the 'cvbs_trimming' nvmem-cell\n"); -+ -+ trimming = nvmem_cell_read(cell, &len); -+ if (IS_ERR(trimming)) { -+ /* -+ * TrustZone firmware may block access to the CVBS trimming -+ * data stored in the eFuse. On those devices the trimming data -+ * is stored in the u-boot environment. However, the known -+ * examples of trimming data in the u-boot environment are all -+ * zero. -+ */ -+ dev_dbg(dev, -+ "Failed to read the 'cvbs_trimming' nvmem-cell - falling back to a default value\n"); -+ priv->cdac_gsw_enable_val = 0x0; -+ return 0; -+ } -+ -+ if (len != 2) { -+ kfree(trimming); -+ return dev_err_probe(dev, -EINVAL, -+ "Read the 'cvbs_trimming' nvmem-cell with invalid length\n"); -+ } -+ -+ switch (phy_meson_cvbs_trimming_version(trimming[1])) { -+ case 1: -+ case 2: -+ case 5: -+ priv->cdac_gsw_enable_val = trimming[0] & 0x7; -+ break; -+ default: -+ priv->cdac_gsw_enable_val = 0x0; -+ break; -+ } -+ -+ kfree(trimming); -+ -+ return 0; -+} -+ -+static int phy_meson_cvbs_dac_probe(struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ struct phy_meson_cvbs_dac_priv *priv; -+ struct phy_provider *phy_provider; -+ struct device *dev = &pdev->dev; -+ struct regmap *hhi; -+ struct phy *phy; -+ int ret; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ if (np) { -+ priv->data = device_get_match_data(dev); -+ if (!priv->data) -+ return dev_err_probe(dev, -EINVAL, -+ "Could not find the OF match data\n"); -+ -+ hhi = syscon_node_to_regmap(np->parent); -+ if (IS_ERR(hhi)) -+ return dev_err_probe(dev, PTR_ERR(hhi), -+ "Failed to get the parent syscon\n"); -+ } else { -+ const struct platform_device_id *pdev_id; -+ -+ pdev_id = platform_get_device_id(pdev); -+ if (!pdev_id) -+ return dev_err_probe(dev, -EINVAL, -+ "Failed to find platform device ID\n"); -+ -+ priv->data = (void *)pdev_id->driver_data; -+ if (!priv->data) -+ return dev_err_probe(dev, -EINVAL, -+ "Could not find the platform driver data\n"); -+ -+ hhi = syscon_regmap_lookup_by_compatible("amlogic,meson-gx-hhi-sysctrl"); -+ if (IS_ERR(hhi)) -+ return dev_err_probe(dev, PTR_ERR(hhi), -+ "Failed to get the \"amlogic,meson-gx-hhi-sysctrl\" syscon\n"); -+ } -+ -+ if (priv->data->needs_cvbs_trimming_nvmem_cell) { -+ ret = phy_meson_cvbs_read_trimming(dev, priv); -+ if (ret) -+ return ret; -+ } -+ -+ ret = devm_regmap_field_bulk_alloc(dev, hhi, priv->regs, -+ priv->data->reg_fields, -+ MESON_CVBS_DAC_NUM_REGS); -+ if (ret) -+ return dev_err_probe(dev, ret, -+ "Failed to create regmap fields\n"); -+ -+ phy = devm_phy_create(dev, np, &phy_meson_cvbs_dac_ops); -+ if (IS_ERR(phy)) -+ return PTR_ERR(phy); -+ -+ phy_set_drvdata(phy, priv); -+ -+ if (np) { -+ phy_provider = devm_of_phy_provider_register(dev, -+ of_phy_simple_xlate); -+ ret = PTR_ERR_OR_ZERO(phy_provider); -+ if (ret) -+ return dev_err_probe(dev, ret, -+ "Failed to register PHY provider\n"); -+ } -+ -+ platform_set_drvdata(pdev, phy); -+ -+ return 0; -+} -+ -+static const struct of_device_id phy_meson_cvbs_dac_of_match[] = { -+ { -+ .compatible = "amlogic,meson8-cvbs-dac", -+ .data = &phy_meson8_cvbs_dac_data, -+ }, -+ { -+ .compatible = "amlogic,meson-gxbb-cvbs-dac", -+ .data = &phy_meson_gxbb_cvbs_dac_data, -+ }, -+ { -+ .compatible = "amlogic,meson-gxl-cvbs-dac", -+ .data = &phy_meson_gxl_cvbs_dac_data, -+ }, -+ { -+ .compatible = "amlogic,meson-g12a-cvbs-dac", -+ .data = &phy_meson_g12a_cvbs_dac_data, -+ }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, phy_meson_cvbs_dac_of_match); -+ -+/* -+ * The platform_device_id table is used for backwards compatibility with old -+ * .dtbs which don't have a CVBS DAC node (where the VPU DRM driver registers -+ * this as a platform device. Support for additional SoCs should only be added -+ * to the of_device_id table above. -+ */ -+static const struct platform_device_id phy_meson_cvbs_dac_device_ids[] = { -+ { -+ .name = "meson-gxbb-cvbs-dac", -+ .driver_data = (kernel_ulong_t)&phy_meson_gxbb_cvbs_dac_data, -+ }, -+ { -+ .name = "meson-gxl-cvbs-dac", -+ .driver_data = (kernel_ulong_t)&phy_meson_gxl_cvbs_dac_data, -+ }, -+ { -+ .name = "meson-g12a-cvbs-dac", -+ .driver_data = (kernel_ulong_t)&phy_meson_g12a_cvbs_dac_data, -+ }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(platform, phy_meson_cvbs_dac_device_ids); -+ -+static struct platform_driver phy_meson_cvbs_dac_driver = { -+ .driver = { -+ .name = "phy-meson-cvbs-dac", -+ .of_match_table = phy_meson_cvbs_dac_of_match, -+ }, -+ .id_table = phy_meson_cvbs_dac_device_ids, -+ .probe = phy_meson_cvbs_dac_probe, -+}; -+module_platform_driver(phy_meson_cvbs_dac_driver); -+ -+MODULE_AUTHOR("Martin Blumenstingl "); -+MODULE_DESCRIPTION("Amlogic Meson CVBS DAC driver"); -+MODULE_LICENSE("GPL v2"); --- -Armbian - diff --git a/patch/kernel/archive/meson-6.6/generic-0003-drm-meson-Support-meson-8-8b-hdmi-tx-components.patch b/patch/kernel/archive/meson-6.6/generic-0003-drm-meson-Support-meson-8-8b-hdmi-tx-components.patch deleted file mode 100644 index 8a73fa26c626..000000000000 --- a/patch/kernel/archive/meson-6.6/generic-0003-drm-meson-Support-meson-8-8b-hdmi-tx-components.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: hzy -Date: Fri, 17 Nov 2023 22:54:18 +0800 -Subject: drm/meson: Support meson{8,8b}-hdmi-tx components - -Signed-off-by: hzy ---- - drivers/gpu/drm/meson/meson_drv.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c -index 111111111111..222222222222 100644 ---- a/drivers/gpu/drm/meson/meson_drv.c -+++ b/drivers/gpu/drm/meson/meson_drv.c -@@ -668,6 +668,8 @@ static void meson_drv_shutdown(struct platform_device *pdev) - * private structure for HHI registers. - */ - static const struct of_device_id components_dev_match[] = { -+ { .compatible = "amlogic,meson8-hdmi-tx" }, -+ { .compatible = "amlogic,meson8b-hdmi-tx" }, - { .compatible = "amlogic,meson-gxbb-dw-hdmi" }, - { .compatible = "amlogic,meson-gxl-dw-hdmi" }, - { .compatible = "amlogic,meson-gxm-dw-hdmi" }, --- -Armbian - diff --git a/patch/kernel/archive/meson-6.6/generic-Revert-mmc-core-Set-HS-clock-speed-before-sending-HS-CMD13.patch b/patch/kernel/archive/meson-6.6/generic-Revert-mmc-core-Set-HS-clock-speed-before-sending-HS-CMD13.patch deleted file mode 100644 index 79eb92454818..000000000000 --- a/patch/kernel/archive/meson-6.6/generic-Revert-mmc-core-Set-HS-clock-speed-before-sending-HS-CMD13.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: hzy -Date: Sat, 18 Nov 2023 01:22:04 +0800 -Subject: Revert "mmc: core: Set HS clock speed before sending HS CMD13" - -This reverts commit 4bc31edebde51fcf8ad0794763b8679a7ecb5ec0. ---- - drivers/mmc/core/mmc.c | 23 ++-------- - 1 file changed, 4 insertions(+), 19 deletions(-) - -diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c -index 111111111111..222222222222 100644 ---- a/drivers/mmc/core/mmc.c -+++ b/drivers/mmc/core/mmc.c -@@ -1393,17 +1393,13 @@ static int mmc_select_hs400es(struct mmc_card *card) - goto out_err; - } - -- /* -- * Bump to HS timing and frequency. Some cards don't handle -- * SEND_STATUS reliably at the initial frequency. -- */ - mmc_set_timing(host, MMC_TIMING_MMC_HS); -- mmc_set_bus_speed(card); -- - err = mmc_switch_status(card, true); - if (err) - goto out_err; - -+ mmc_set_clock(host, card->ext_csd.hs_max_dtr); -+ - /* Switch card to DDR with strobe bit */ - val = EXT_CSD_DDR_BUS_WIDTH_8 | EXT_CSD_BUS_WIDTH_STROBE; - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, -@@ -1461,7 +1457,7 @@ static int mmc_select_hs400es(struct mmc_card *card) - static int mmc_select_hs200(struct mmc_card *card) - { - struct mmc_host *host = card->host; -- unsigned int old_timing, old_signal_voltage, old_clock; -+ unsigned int old_timing, old_signal_voltage; - int err = -EINVAL; - u8 val; - -@@ -1492,17 +1488,8 @@ static int mmc_select_hs200(struct mmc_card *card) - false, true, MMC_CMD_RETRIES); - if (err) - goto err; -- -- /* -- * Bump to HS timing and frequency. Some cards don't handle -- * SEND_STATUS reliably at the initial frequency. -- * NB: We can't move to full (HS200) speeds until after we've -- * successfully switched over. -- */ - old_timing = host->ios.timing; -- old_clock = host->ios.clock; - mmc_set_timing(host, MMC_TIMING_MMC_HS200); -- mmc_set_clock(card->host, card->ext_csd.hs_max_dtr); - - /* - * For HS200, CRC errors are not a reliable way to know the -@@ -1515,10 +1502,8 @@ static int mmc_select_hs200(struct mmc_card *card) - * mmc_select_timing() assumes timing has not changed if - * it is a switch error. - */ -- if (err == -EBADMSG) { -- mmc_set_clock(host, old_clock); -+ if (err == -EBADMSG) - mmc_set_timing(host, old_timing); -- } - } - err: - if (err) { --- -Armbian - diff --git a/patch/kernel/archive/meson-6.6/generic-Revert-pwm-meson-modify-and-simplify-calculation-in-.patch b/patch/kernel/archive/meson-6.6/generic-Revert-pwm-meson-modify-and-simplify-calculation-in-.patch deleted file mode 100644 index 848cd3e4d562..000000000000 --- a/patch/kernel/archive/meson-6.6/generic-Revert-pwm-meson-modify-and-simplify-calculation-in-.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: hzy -Date: Sat, 18 Nov 2023 01:22:04 +0800 -Subject: Revert "pwm: meson: modify and simplify calculation in - meson_pwm_get_state" - -This reverts commit 6b9352f3f8a1a35faf0efc1ad1807ee303467796. ---- - drivers/pwm/pwm-meson.c | 14 ++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c -index 111111111111..222222222222 100644 ---- a/drivers/pwm/pwm-meson.c -+++ b/drivers/pwm/pwm-meson.c -@@ -322,8 +322,18 @@ static int meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, - channel->lo = FIELD_GET(PWM_LOW_MASK, value); - channel->hi = FIELD_GET(PWM_HIGH_MASK, value); - -- state->period = meson_pwm_cnt_to_ns(chip, pwm, channel->lo + channel->hi); -- state->duty_cycle = meson_pwm_cnt_to_ns(chip, pwm, channel->hi); -+ if (channel->lo == 0) { -+ state->period = meson_pwm_cnt_to_ns(chip, pwm, channel->hi); -+ state->duty_cycle = state->period; -+ } else if (channel->lo >= channel->hi) { -+ state->period = meson_pwm_cnt_to_ns(chip, pwm, -+ channel->lo + channel->hi); -+ state->duty_cycle = meson_pwm_cnt_to_ns(chip, pwm, -+ channel->hi); -+ } else { -+ state->period = 0; -+ state->duty_cycle = 0; -+ } - - state->polarity = PWM_POLARITY_NORMAL; - --- -Armbian - diff --git a/patch/kernel/archive/meson-6.6/odroidc1-dts-Enable-HDMI.patch b/patch/kernel/archive/meson-6.6/odroidc1-dts-Enable-HDMI.patch deleted file mode 100644 index 6611e274d119..000000000000 --- a/patch/kernel/archive/meson-6.6/odroidc1-dts-Enable-HDMI.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Blumenstingl -Date: Fri, 20 Mar 2020 15:17:51 +0100 -Subject: ARM: dts: meson8b: odroid-c1: enable HDMI for the Odroid-C1 - WiP - -WiP - -Signed-off-by: Martin Blumenstingl ---- - arch/arm/boot/dts/amlogic/meson8b-odroidc1.dts | 59 ++++++++++ - 1 file changed, 59 insertions(+) - -diff --git a/arch/arm/boot/dts/amlogic/meson8b-odroidc1.dts b/arch/arm/boot/dts/amlogic/meson8b-odroidc1.dts -index 111111111111..222222222222 100644 ---- a/arch/arm/boot/dts/amlogic/meson8b-odroidc1.dts -+++ b/arch/arm/boot/dts/amlogic/meson8b-odroidc1.dts -@@ -32,6 +32,17 @@ emmc_pwrseq: emmc-pwrseq { - reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>; - }; - -+ hdmi-connector { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi_connector_in: endpoint { -+ remote-endpoint = <&hdmi_tx_tmds_out>; -+ }; -+ }; -+ }; -+ - leds { - compatible = "gpio-leds"; - led-blue { -@@ -93,6 +104,38 @@ rtc32k_xtal: rtc32k-xtal-clk { - #clock-cells = <0>; - }; - -+ sound { -+ compatible = "amlogic,gx-sound-card"; -+ model = "ODROID-C1"; -+ -+ assigned-clocks = <&clkc CLKID_MPLL0>, -+ <&clkc CLKID_MPLL1>; -+ assigned-clock-rates = <294912000>, -+ <270950400>; -+ -+ dai-link-0 { -+ sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>; -+ }; -+ -+ dai-link-1 { -+ sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>; -+ dai-format = "i2s"; -+ mclk-fs = <256>; -+ -+ codec-0 { -+ sound-dai = <&aiu AIU_HDMI CTRL_I2S>; -+ }; -+ }; -+ -+ dai-link-2 { -+ sound-dai = <&aiu AIU_HDMI CTRL_OUT>; -+ -+ codec-0 { -+ sound-dai = <&hdmi_tx 0>; -+ }; -+ }; -+ }; -+ - vcc_1v8: regulator-vcc-1v8 { - /* - * RICHTEK RT9179 configured for a fixed output voltage of -@@ -187,6 +230,10 @@ vdd_rtc: regulator-vdd-rtc { - }; - }; - -+&aiu { -+ status = "okay"; -+}; -+ - &cpu0 { - cpu-supply = <&vcck>; - }; -@@ -283,6 +330,18 @@ &gpio_ao { - "SYS_LED", "", ""; - }; - -+&hdmi_tx { -+ status = "okay"; -+ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; -+ pinctrl-names = "default"; -+}; -+ -+&hdmi_tx_tmds_port { -+ hdmi_tx_tmds_out: endpoint { -+ remote-endpoint = <&hdmi_connector_in>; -+ }; -+}; -+ - &ir_receiver { - status = "okay"; - pinctrl-0 = <&ir_recv_pins>; --- -Armbian - diff --git a/patch/kernel/archive/meson-6.6/onecloud-0001-add-dts.patch b/patch/kernel/archive/meson-6.6/onecloud-0001-add-dts.patch deleted file mode 100644 index b9d9cc535d1a..000000000000 --- a/patch/kernel/archive/meson-6.6/onecloud-0001-add-dts.patch +++ /dev/null @@ -1,440 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: hzy -Date: Sat, 1 Apr 2023 13:24:42 +0800 -Subject: ARM: dts: meson8b: Add DTS for Xunlei Onecloud - -Signed-off-by: hzy ---- - arch/arm/boot/dts/amlogic/Makefile | 1 + - arch/arm/boot/dts/amlogic/meson8b-onecloud.dts | 410 ++++++++++ - 2 files changed, 411 insertions(+) - -diff --git a/arch/arm/boot/dts/amlogic/Makefile b/arch/arm/boot/dts/amlogic/Makefile -index 111111111111..222222222222 100644 ---- a/arch/arm/boot/dts/amlogic/Makefile -+++ b/arch/arm/boot/dts/amlogic/Makefile -@@ -6,4 +6,5 @@ dtb-$(CONFIG_MACH_MESON8) += \ - meson8b-ec100.dtb \ - meson8b-mxq.dtb \ - meson8b-odroidc1.dtb \ -+ meson8b-onecloud.dtb \ - meson8m2-mxiii-plus.dtb -diff --git a/arch/arm/boot/dts/amlogic/meson8b-onecloud.dts b/arch/arm/boot/dts/amlogic/meson8b-onecloud.dts -new file mode 100644 -index 000000000000..111111111111 ---- /dev/null -+++ b/arch/arm/boot/dts/amlogic/meson8b-onecloud.dts -@@ -0,0 +1,410 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Author: hzy -+ */ -+ -+/dts-v1/; -+ -+#include "meson8b.dtsi" -+#include -+#include -+ -+/ { -+ model = "Xunlei OneCloud"; -+ compatible = "xunlei,onecloud", "amlogic,meson8b"; -+ -+ aliases { -+ serial0 = &uart_AO; -+ mmc0 = &sd_card_slot; -+ mmc1 = &sdhc; -+ }; -+ -+ chosen { -+ stdout-path = "serial0:115200n8"; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0x40000000 0x40000000>; -+ }; -+ -+ emmc_pwrseq: emmc-pwrseq { -+ compatible = "mmc-pwrseq-emmc"; -+ reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>; -+ }; -+ -+ button { -+ // compatible = "gpio-keys-polled"; -+ // poll-interval = <100>; -+ -+ compatible = "gpio-keys"; -+ -+ autorepeat; -+ -+ reset-button { -+ label = "reset"; -+ linux,code = ; -+ -+ // gpios = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_LOW>; -+ -+ interrupt-parent = <&gpio_intc>; -+ interrupts = <5 IRQ_TYPE_LEVEL_LOW>; // GPIOAO 5 -+ }; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ -+ red { -+ label = "onecloud:red:alive"; -+ gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>; -+ -+ default-state = "on"; -+ linux,default-trigger = "default-on"; -+ }; -+ -+ green { -+ label = "onecloud:green:alive"; -+ gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_HIGH>; -+ -+ default-state = "off"; -+ linux,default-trigger = "mmc1"; -+ }; -+ -+ blue { -+ label = "onecloud:blue:alive"; -+ gpios = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_HIGH>; -+ -+ default-state = "off"; -+ linux,default-trigger = "usb-host"; -+ }; -+ }; -+ -+ p12v: regulator-p12v { -+ compatible = "regulator-fixed"; -+ -+ regulator-name = "P12V"; -+ regulator-min-microvolt = <12000000>; -+ regulator-max-microvolt = <12000000>; -+ }; -+ -+ vcc_5v: regulator-vcc-5v { -+ compatible = "regulator-fixed"; -+ -+ regulator-name = "VCC5V"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ -+ vin-supply = <&p12v>; -+ -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ vcc_3v3: regulator-vcc-3v3 { -+ compatible = "regulator-fixed"; -+ -+ regulator-name = "VCC3V3"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ -+ vin-supply = <&p12v>; -+ -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ vcc_1v8: regulator-vcc-1v8 { -+ compatible = "regulator-fixed"; -+ -+ regulator-name = "VCC1V8"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ vin-supply = <&p12v>; -+ -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ vcc_ddr: regulator-vcc-ddr { -+ compatible = "regulator-fixed"; -+ -+ regulator-name = "VCC_DDR"; -+ regulator-min-microvolt = <1500000>; -+ regulator-max-microvolt = <1500000>; -+ -+ vin-supply = <&vcc_3v3>; -+ -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ vcc_core: regulator-vcc-core { -+ compatible = "pwm-regulator"; -+ -+ regulator-name = "VCC_CORE"; -+ -+ // +---------------------------------------------------+ -+ // | The actual mapping in phyical | -+ // +------+--------+--------+--------+--------+--------+ -+ // | | 100% | 60% | 30% | 10% | 0% | -+ // +------+--------+--------+--------+--------+--------+ -+ // | V1.0 | 677mV | 857mV | 992mV | 1082mV | 1127mV | -+ // | V1.3 | 1116mV | 1121mV | 1125mV | 1128mV | 1129mV | -+ // +------+--------+--------+--------+--------+--------+ -+ // -+ // According to meson8b.dtsi, the CPU should be able to -+ // run at 504MHz with 870mV. But this regulator supplies -+ // not only CPU but also GPU. And according to the users' -+ // tests on V1.0, we need such higher voltages. -+ -+ pwms = <&pwm_cd 1 12001 0>; // PWM_D -+ pwm-dutycycle-range = <10 0>; -+ regulator-min-microvolt = <860000>; -+ regulator-max-microvolt = <1140000>; -+ -+ pwm-supply = <&p12v>; -+ -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+}; -+ -+&uart_AO { -+ status = "okay"; -+ pinctrl-0 = <&uart_ao_a_pins>; -+ pinctrl-names = "default"; -+}; -+ -+&pwm_cd { -+ status = "okay"; -+ pinctrl-0 = <&pwm_c1_pins>, <&pwm_d_pins>; -+ pinctrl-names = "default"; -+ clocks = <&xtal>, <&xtal>; -+ clock-names = "clkin0", "clkin1"; -+}; -+ -+&cpu0 { -+ cpu-supply = <&vcc_core>; -+}; -+ -+&saradc { -+ status = "okay"; -+ vref-supply = <&vcc_1v8>; -+}; -+ -+&mali { -+ // commented to allow cpufreq tweaking -+ // mali-supply = <&vcc_core>; -+}; -+ -+&gpio { -+ gpio-line-names = -+ /* 0 */ "WIFI_SDIO_D0 PIN18 (GPIOX_0)", -+ /* 1 */ "WIFI_SDIO_D1 PIN19 (GPIOX_1)", -+ /* 2 */ "WIFI_SDIO_D2 PIN14 (GPIOX_2)", -+ /* 3 */ "WIFI_SDIO_D3 PIN15 (GPIOX_3)", -+ /* 4 */ "WIFI_PCM_DIN PIN27 (GPIOX_4)", -+ /* 5 */ "WIFI_PCM_DOUT PIN25 (GPIOX_5)", -+ /* 6 */ "WIFI_PCM_SYNC PIN28 (GPIOX_6)", -+ /* 7 */ "WIFI_PCM_CLK PIN26 (GPIOX_7)", -+ /* 8 */ "WIFI_SDIO_CLK PIN17_Resistor (GPIOX_8)", -+ /* 9 */ "WIFI_SDIO_CMD PIN16 (GPIOX_9)", -+ /* 10 */ "GPIOX_10", -+ /* 11 */ "WIFI PIN12 (GPIOX_11)", -+ /* 12 */ "WIFI_UART_RX PIN43 (GPIOX_16)", -+ /* 13 */ "WIFI_UART_TX PIN42 (GPIOX_17)", -+ /* 14 */ "WIFI_UART_RTS PIN41_Resistor (GPIOX_18)", -+ /* 15 */ "WIFI_UART_CTS PIN44 (GPIOX_19)", -+ /* 16 */ "WIFI PIN34 (GPIOX_20)", -+ /* 17 */ "WIFI_WAKE PIN13 (GPIOX_21)", -+ -+ /* 18 */ "Resistor_TopOf_LED (GPIOY_0)", -+ /* 19 */ "GPIOY_1", -+ /* 20 */ "GPIOY_3", -+ /* 21 */ "GPIOY_6", -+ /* 22 */ "GPIOY_7", -+ /* 23 */ "GPIOY_8", -+ /* 24 */ "GPIOY_9", -+ /* 25 */ "GPIOY_10", -+ /* 26 */ "GPIOY_11", -+ /* 27 */ "GPIOY_12", -+ /* 28 */ "Left_BottomOf_CPU (GPIOY_13)", -+ /* 29 */ "Right_BottomOf_CPU (GPIOY_14)", -+ -+ /* 30 */ "GPIODV_9 (PWM_C)", -+ /* 31 */ "GPIODV_24", -+ /* 32 */ "GPIODV_25", -+ /* 33 */ "GPIODV_26", -+ /* 34 */ "GPIODV_27", -+ /* 35 */ "VCC_CPU_PWM (GPIODV_28)", -+ /* 36 */ "GPIODV_29", -+ -+ /* 37 */ "HDMI_HPD (GPIOH_0)", -+ /* 38 */ "HDMI_SDA (GPIOH_1)", -+ /* 39 */ "HDMI_SCL (GPIOH_2)", -+ /* 40 */ "ETH_PHY_INTR (GPIOH_3)", -+ /* 41 */ "ETH_PHY_nRST (GPIOH_4)", -+ /* 42 */ "ETH_TXD1 (GPIOH_5)", -+ /* 43 */ "ETH_TXD0 (GPIOH_6)", -+ /* 44 */ "ETH_TXD3 (GPIOH_7)", -+ /* 45 */ "ETH_TXD2 (GPIOH_8)", -+ /* 46 */ "ETH_TX_CLK (GPIOH_9)", -+ -+ /* 47 */ "SDCARD_D1 (CARD_0)", -+ /* 48 */ "SDCARD_D0 (CARD_1)", -+ /* 49 */ "SDCARD_CLK (CARD_2)", -+ /* 50 */ "SDCARD_CMD (CARD_3)", -+ /* 51 */ "SDCARD_D3 (CARD_4)", -+ /* 52 */ "SDCARD_D2 (CARD_5)", -+ /* 53 */ "SDCARD_CD (CARD_6)", -+ -+ /* 54 */ "EMMC_D0 (BOOT_0)", -+ /* 55 */ "EMMC_D1 (BOOT_1)", -+ /* 56 */ "EMMC_D2 (BOOT_2)", -+ /* 57 */ "EMMC_D3 (BOOT_3)", -+ /* 58 */ "EMMC_D4 (BOOT_4)", -+ /* 59 */ "EMMC_D5 (BOOT_5)", -+ /* 60 */ "EMMC_D6 (BOOT_6)", -+ /* 61 */ "EMMC_D7 (BOOT_7)", -+ /* 62 */ "EMMC_CLK (BOOT_8)", -+ /* 63 */ "EMMC_nRST (BOOT_9)", -+ /* 64 */ "EMMC_CMD (BOOT_10)", -+ /* 65 */ "BOOT_11", -+ /* 66 */ "BOOT_12", -+ /* 67 */ "BOOT_13", -+ /* 68 */ "BOOT_14", -+ /* 69 */ "BOOT_15", -+ /* 70 */ "BOOT_16", -+ /* 71 */ "BOOT_17", -+ /* 72 */ "BOOT_18", -+ -+ /* 73 */ "ETH_RXD1 (DIF_0_P)", -+ /* 74 */ "ETH_RXD0 (DIF_0_N)", -+ /* 75 */ "ETH_RX_DV (DIF_1_P)", -+ /* 76 */ "ETH_RX_CLK (DIF_1_N)", -+ /* 77 */ "ETH_RXD3 (DIF_2_P)", -+ /* 78 */ "ETH_RXD2 (DIF_2_N)", -+ /* 79 */ "ETH_TX_EN (DIF_3_P)", -+ /* 80 */ "ETH_REF_CLK (DIF_3_N)", -+ /* 81 */ "ETH_MDC (DIF_4_P)", -+ /* 82 */ "ETH_MDIO_EN (DIF_4_N)"; -+}; -+ -+&gpio_ao { -+ gpio-line-names = -+ /* 0 */ "UART TX (GPIOAO_0)", -+ /* 1 */ "UART RX (GPIOAO_1)", -+ /* 2 */ "RED_LED (GPIOAO_2)", -+ /* 3 */ "GREEN_LED (GPIOAO_3)", -+ /* 4 */ "BLUE_LED (GPIOAO_4)", -+ /* 5 */ "BUTTON (GPIOAO_5)", -+ /* 6 */ "GPIOAO_6", -+ /* 7 */ "IR_IN (GPIOAO_7)", -+ /* 8 */ "GPIOAO_8", -+ /* 9 */ "GPIOAO_9", -+ /* 10 */ "GPIOAO_10", -+ /* 11 */ "GPIOAO_11", -+ /* 12 */ "GPIOAO_12", -+ /* 13 */ "GPIOAO_13", -+ -+ /* 14 */ "GPIO_BSD_EN", -+ /* 15 */ "GPIO_TEST_N"; -+}; -+ -+// eMMC -+&sdhc { -+ status = "okay"; -+ -+ pinctrl-0 = <&sdxc_c_pins>; -+ pinctrl-names = "default"; -+ -+ non-removable; -+ bus-width = <8>; -+ max-frequency = <200000000>; -+ cap-mmc-highspeed; -+ mmc-hs200-1_8v; -+ -+ mmc-pwrseq = <&emmc_pwrseq>; -+ vmmc-supply = <&vcc_3v3>; -+ // vqmmc-supply = <&vcc_3v3>; -+}; -+ -+&sdio { -+ status = "okay"; -+ -+ pinctrl-0 = <&sd_b_pins>; -+ pinctrl-names = "default"; -+ -+ // SD card -+ sd_card_slot: slot@1 { -+ compatible = "mmc-slot"; -+ reg = <1>; -+ status = "okay"; -+ -+ bus-width = <4>; -+ no-sdio; -+ cap-mmc-highspeed; -+ cap-sd-highspeed; -+ disable-wp; -+ -+ cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; -+ -+ vmmc-supply = <&vcc_3v3>; -+ // vqmmc-supply = <&vcc_3v3>; -+ }; -+}; -+ -+ðmac { -+ status = "okay"; -+ -+ pinctrl-0 = <ð_rgmii_pins>; -+ pinctrl-names = "default"; -+ -+ phy-handle = <ð_phy>; -+ phy-mode = "rgmii-rxid"; -+ -+ mdio { -+ compatible = "snps,dwmac-mdio"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ // Realtek RTL8211F (0x001cc916) -+ eth_phy: ethernet-phy@0 { -+ reg = <0>; -+ -+ reset-assert-us = <10000>; -+ reset-deassert-us = <80000>; -+ reset-gpios = <&gpio GPIOH_4 GPIO_ACTIVE_LOW>; -+ -+ interrupt-parent = <&gpio_intc>; -+ interrupts = <17 IRQ_TYPE_LEVEL_LOW>; // GPIOH 3 -+ }; -+ }; -+}; -+ -+&usb0 { -+ status = "okay"; -+ dr_mode = "otg"; -+ usb-role-switch; -+ role-switch-default-mode = "host"; -+}; -+ -+&usb0_phy { -+ status = "okay"; -+}; -+ -+&usb1 { -+ status = "okay"; -+}; -+ -+&usb1_phy { -+ status = "okay"; -+}; -+ -+&ir_receiver { -+ status = "okay"; -+ pinctrl-0 = <&ir_recv_pins>; -+ pinctrl-names = "default"; -+}; --- -Armbian - diff --git a/patch/kernel/archive/meson-6.6/onecloud-0002-dts-Support-HDMI.patch b/patch/kernel/archive/meson-6.6/onecloud-0002-dts-Support-HDMI.patch deleted file mode 100644 index 597a2676b2c1..000000000000 --- a/patch/kernel/archive/meson-6.6/onecloud-0002-dts-Support-HDMI.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: hzy -Date: Sat, 1 Apr 2023 10:26:14 +0800 -Subject: ARM: dts: meson8b: onecloud: Support HDMI - -Signed-off-by: hzy ---- - arch/arm/boot/dts/amlogic/meson8b-onecloud.dts | 58 ++++++++++ - 1 file changed, 58 insertions(+) - -diff --git a/arch/arm/boot/dts/amlogic/meson8b-onecloud.dts b/arch/arm/boot/dts/amlogic/meson8b-onecloud.dts -index 111111111111..222222222222 100644 ---- a/arch/arm/boot/dts/amlogic/meson8b-onecloud.dts -+++ b/arch/arm/boot/dts/amlogic/meson8b-onecloud.dts -@@ -80,6 +80,48 @@ blue { - }; - }; - -+ hdmi-connector { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi_connector_in: endpoint { -+ remote-endpoint = <&hdmi_tx_tmds_out>; -+ }; -+ }; -+ }; -+ -+ sound { -+ compatible = "amlogic,gx-sound-card"; -+ -+ assigned-clocks = <&clkc CLKID_MPLL0>, -+ <&clkc CLKID_MPLL1>; -+ assigned-clock-rates = <294912000>, -+ <270950400>; -+ -+ dai-link-0 { -+ sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>; -+ }; -+ -+ dai-link-1 { -+ sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>; -+ dai-format = "i2s"; -+ mclk-fs = <256>; -+ -+ codec-0 { -+ sound-dai = <&aiu AIU_HDMI CTRL_I2S>; -+ }; -+ }; -+ -+ dai-link-2 { -+ sound-dai = <&aiu AIU_HDMI CTRL_OUT>; -+ -+ codec-0 { -+ sound-dai = <&hdmi_tx 0>; -+ }; -+ }; -+ }; -+ - p12v: regulator-p12v { - compatible = "regulator-fixed"; - -@@ -199,6 +241,10 @@ &mali { - // mali-supply = <&vcc_core>; - }; - -+&aiu { -+ status = "okay"; -+}; -+ - &gpio { - gpio-line-names = - /* 0 */ "WIFI_SDIO_D0 PIN18 (GPIOX_0)", -@@ -403,6 +449,18 @@ &usb1_phy { - status = "okay"; - }; - -+&hdmi_tx { -+ status = "okay"; -+ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; -+ pinctrl-names = "default"; -+}; -+ -+&hdmi_tx_tmds_port { -+ hdmi_tx_tmds_out: endpoint { -+ remote-endpoint = <&hdmi_connector_in>; -+ }; -+}; -+ - &ir_receiver { - status = "okay"; - pinctrl-0 = <&ir_recv_pins>; --- -Armbian - From c739c2589f2f4d6b52f1768883a407c4bf8fa0d1 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino Date: Sun, 9 Feb 2025 19:55:54 +0100 Subject: [PATCH 20/33] rockchip64: disable pl330 patch due to pulseaudio issues --- ...tch => general-pl330-01-fix-periodic-transfers.patch.disabled} | 0 ...pl330-02-add-support-for-interleaved-transfers.patch.disabled} | 0 ...general-pl330-03-fix-data-race-on-tx-transfers.patch.disabled} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename patch/kernel/archive/rockchip64-6.12/{general-pl330-01-fix-periodic-transfers.patch => general-pl330-01-fix-periodic-transfers.patch.disabled} (100%) rename patch/kernel/archive/rockchip64-6.12/{general-pl330-02-add-support-for-interleaved-transfers.patch => general-pl330-02-add-support-for-interleaved-transfers.patch.disabled} (100%) rename patch/kernel/archive/rockchip64-6.12/{general-pl330-03-fix-data-race-on-tx-transfers.patch => general-pl330-03-fix-data-race-on-tx-transfers.patch.disabled} (100%) diff --git a/patch/kernel/archive/rockchip64-6.12/general-pl330-01-fix-periodic-transfers.patch b/patch/kernel/archive/rockchip64-6.12/general-pl330-01-fix-periodic-transfers.patch.disabled similarity index 100% rename from patch/kernel/archive/rockchip64-6.12/general-pl330-01-fix-periodic-transfers.patch rename to patch/kernel/archive/rockchip64-6.12/general-pl330-01-fix-periodic-transfers.patch.disabled diff --git a/patch/kernel/archive/rockchip64-6.12/general-pl330-02-add-support-for-interleaved-transfers.patch b/patch/kernel/archive/rockchip64-6.12/general-pl330-02-add-support-for-interleaved-transfers.patch.disabled similarity index 100% rename from patch/kernel/archive/rockchip64-6.12/general-pl330-02-add-support-for-interleaved-transfers.patch rename to patch/kernel/archive/rockchip64-6.12/general-pl330-02-add-support-for-interleaved-transfers.patch.disabled diff --git a/patch/kernel/archive/rockchip64-6.12/general-pl330-03-fix-data-race-on-tx-transfers.patch b/patch/kernel/archive/rockchip64-6.12/general-pl330-03-fix-data-race-on-tx-transfers.patch.disabled similarity index 100% rename from patch/kernel/archive/rockchip64-6.12/general-pl330-03-fix-data-race-on-tx-transfers.patch rename to patch/kernel/archive/rockchip64-6.12/general-pl330-03-fix-data-race-on-tx-transfers.patch.disabled From a875d1a78d80047d78352688751dcb9bd1bbe6eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 18:46:31 +0000 Subject: [PATCH 21/33] build(deps): bump dtschema from 2024.11 to 2025.2 Bumps [dtschema](https://github.com/devicetree-org/dt-schema) from 2024.11 to 2025.2. - [Release notes](https://github.com/devicetree-org/dt-schema/releases) - [Commits](https://github.com/devicetree-org/dt-schema/compare/v2024.11...v2025.02) --- updated-dependencies: - dependency-name: dtschema dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 406249f59b21..4f9a1ee4929a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,5 +15,5 @@ PyYAML == 6.0.2 # for parsing/writing YAML oras == 0.1.30 # for OCI stuff in mapper-oci-update Jinja2 == 3.1.5 # for templating rich == 13.9.4 # for rich text formatting -dtschema == 2024.11 # for checking dts files and dt bindings +dtschema == 2025.2 # for checking dts files and dt bindings yamllint == 1.35.1 # for checking dts files and dt bindings From 9f8f9f51ba7134f7e46f2ef3643af712787f1f48 Mon Sep 17 00:00:00 2001 From: Martin Schmiedel Date: Mon, 10 Feb 2025 12:26:22 +0100 Subject: [PATCH 22/33] IMX8: update patches to fix upstream changes - while at it rewrite-uboot-patches Signed-off-by: Martin Schmiedel --- config/sources/families/imx8m.conf | 1 - .../0001-tqma8-enable-distro-boot.patch | 72 +++++++++---------- .../0002-tqma8mpxl-enable-distro-boot.patch | 26 +++---- ..._atf_imx8mp.sh-add-script-for-imx8mp.patch | 15 ++-- 4 files changed, 55 insertions(+), 59 deletions(-) diff --git a/config/sources/families/imx8m.conf b/config/sources/families/imx8m.conf index 953784068990..4804cf1666ec 100644 --- a/config/sources/families/imx8m.conf +++ b/config/sources/families/imx8m.conf @@ -24,7 +24,6 @@ case $BOARD in ATFBRANCH="branch:TQM-lf_v2.10" BOOTSOURCE='https://github.com/tq-systems/u-boot-tqmaxx.git' # u-boot mainlining is hard and has low-priority BOOTBRANCH='branch:TQMa8-v2020.04_imx_5.4.70_2.3.0' - BOOTBRANCH='commit:673acba389cfe6c9e8639e8009fc9403492f5061' BOOTPATCHDIR="u-boot-tqma" # could be removed when distro boot patches are integrated ;; esac diff --git a/patch/u-boot/u-boot-tqma/0001-tqma8-enable-distro-boot.patch b/patch/u-boot/u-boot-tqma/0001-tqma8-enable-distro-boot.patch index fd36114a2b78..d8321efe912a 100644 --- a/patch/u-boot/u-boot-tqma/0001-tqma8-enable-distro-boot.patch +++ b/patch/u-boot/u-boot-tqma/0001-tqma8-enable-distro-boot.patch @@ -1,14 +1,14 @@ -From e04dcf9f512273afd43b014db110e5823a5869e6 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Martin Schmiedel Date: Mon, 9 Oct 2023 09:50:48 +0200 -Subject: [PATCH] tqma8: enable distro boot +Subject: tqma8: enable distro boot Signed-off-by: Martin Schmiedel --- board/tqc/common/Kconfig | 4 + board/tqc/common/Makefile | 1 + board/tqc/common/tqc_bb.h | 6 + - board/tqc/common/tqc_distro.c | 37 +++ + board/tqc/common/tqc_distro.c | 37 ++ board/tqc/tqma8mpxl/tqma8mpxl.c | 5 +- board/tqc/tqma8mx/tqma8mx.c | 5 +- board/tqc/tqma8mxml/tqma8mxml.c | 5 +- @@ -23,17 +23,14 @@ Signed-off-by: Martin Schmiedel configs/tqma8mxml_4gb_mba8mx_mmc_defconfig | 1 - configs/tqma8mxnl_1gb_mba8mx_defconfig | 1 - configs/tqma8mxnl_1gb_mba8mx_mfg_defconfig | 1 - - doc/board/tq/examples/boot-legacy.cmd | 26 ++ + doc/board/tq/examples/boot-legacy.cmd | 26 + include/configs/tqma8mxml-mba8mx.h | 11 +- - include/configs/tqma8mxml.h | 256 ++++---------------- - include/environment/tq/boot.h | 21 ++ + include/configs/tqma8mxml.h | 256 ++-------- + include/environment/tq/boot.h | 21 + 22 files changed, 167 insertions(+), 221 deletions(-) - create mode 100644 board/tqc/common/tqc_distro.c - create mode 100644 doc/board/tq/examples/boot-legacy.cmd - create mode 100644 include/environment/tq/boot.h diff --git a/board/tqc/common/Kconfig b/board/tqc/common/Kconfig -index 7f60d0b686..a34a2cf300 100644 +index 111111111111..222222222222 100644 --- a/board/tqc/common/Kconfig +++ b/board/tqc/common/Kconfig @@ -16,6 +16,10 @@ config TQC_ENVLOC @@ -48,7 +45,7 @@ index 7f60d0b686..a34a2cf300 100644 bool diff --git a/board/tqc/common/Makefile b/board/tqc/common/Makefile -index 1640cc9cd2..1d04d94aad 100644 +index 111111111111..222222222222 100644 --- a/board/tqc/common/Makefile +++ b/board/tqc/common/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_TQC_EMMC) += tqc_emmc.o @@ -60,7 +57,7 @@ index 1640cc9cd2..1d04d94aad 100644 obj-$(CONFIG_TQC_VARD) += tq_som_features.o obj-$(CONFIG_TQC_SPI_NOR) += tqc_spi_nor.o diff --git a/board/tqc/common/tqc_bb.h b/board/tqc/common/tqc_bb.h -index a6dfc1ab97..e9e1415eb3 100644 +index 111111111111..222222222222 100644 --- a/board/tqc/common/tqc_bb.h +++ b/board/tqc/common/tqc_bb.h @@ -64,4 +64,10 @@ int tqc_pcf85063_set_clkout(int bus, int address, uint8_t clkout); @@ -76,7 +73,7 @@ index a6dfc1ab97..e9e1415eb3 100644 #endif diff --git a/board/tqc/common/tqc_distro.c b/board/tqc/common/tqc_distro.c new file mode 100644 -index 0000000000..fc525e24c6 +index 000000000000..111111111111 --- /dev/null +++ b/board/tqc/common/tqc_distro.c @@ -0,0 +1,37 @@ @@ -118,7 +115,7 @@ index 0000000000..fc525e24c6 + env_set("boot_targets", boot_devtype); +} diff --git a/board/tqc/tqma8mpxl/tqma8mpxl.c b/board/tqc/tqma8mpxl/tqma8mpxl.c -index bc34c07e84..9077c6cea1 100644 +index 111111111111..222222222222 100644 --- a/board/tqc/tqma8mpxl/tqma8mpxl.c +++ b/board/tqc/tqma8mpxl/tqma8mpxl.c @@ -294,9 +294,12 @@ int board_late_init(void) @@ -136,7 +133,7 @@ index bc34c07e84..9077c6cea1 100644 return 0; diff --git a/board/tqc/tqma8mx/tqma8mx.c b/board/tqc/tqma8mx/tqma8mx.c -index 25748d4901..8fcd38b5eb 100644 +index 111111111111..222222222222 100644 --- a/board/tqc/tqma8mx/tqma8mx.c +++ b/board/tqc/tqma8mx/tqma8mx.c @@ -219,9 +219,12 @@ int board_late_init(void) @@ -154,10 +151,10 @@ index 25748d4901..8fcd38b5eb 100644 } diff --git a/board/tqc/tqma8mxml/tqma8mxml.c b/board/tqc/tqma8mxml/tqma8mxml.c -index 18c04aded2..1ff4dbea4f 100644 +index 111111111111..222222222222 100644 --- a/board/tqc/tqma8mxml/tqma8mxml.c +++ b/board/tqc/tqma8mxml/tqma8mxml.c -@@ -223,9 +223,12 @@ int board_late_init(void) +@@ -179,9 +179,12 @@ int board_late_init(void) #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG env_set("board_name", tqc_bb_get_boardname()); @@ -172,7 +169,7 @@ index 18c04aded2..1ff4dbea4f 100644 } diff --git a/configs/tqma8mxml_1gb_mba8mx_fspi_defconfig b/configs/tqma8mxml_1gb_mba8mx_fspi_defconfig -index 141b273a4e..a8bab81a07 100644 +index 111111111111..222222222222 100644 --- a/configs/tqma8mxml_1gb_mba8mx_fspi_defconfig +++ b/configs/tqma8mxml_1gb_mba8mx_fspi_defconfig @@ -8,7 +8,6 @@ CONFIG_TQMA8MXX_BOOT_FSPI=y @@ -184,7 +181,7 @@ index 141b273a4e..a8bab81a07 100644 CONFIG_ARCH_MISC_INIT=y CONFIG_SPL_SEPARATE_BSS=y diff --git a/configs/tqma8mxml_1gb_mba8mx_mfg_defconfig b/configs/tqma8mxml_1gb_mba8mx_mfg_defconfig -index b28dc1cc97..6f7773658e 100644 +index 111111111111..222222222222 100644 --- a/configs/tqma8mxml_1gb_mba8mx_mfg_defconfig +++ b/configs/tqma8mxml_1gb_mba8mx_mfg_defconfig @@ -9,7 +9,6 @@ CONFIG_TQMA8MXX_BOOT_SDCARD=y @@ -196,7 +193,7 @@ index b28dc1cc97..6f7773658e 100644 CONFIG_ARCH_MISC_INIT=y CONFIG_SPL_SEPARATE_BSS=y diff --git a/configs/tqma8mxml_1gb_mba8mx_mmc_defconfig b/configs/tqma8mxml_1gb_mba8mx_mmc_defconfig -index db8c138a52..0b38d87709 100644 +index 111111111111..222222222222 100644 --- a/configs/tqma8mxml_1gb_mba8mx_mmc_defconfig +++ b/configs/tqma8mxml_1gb_mba8mx_mmc_defconfig @@ -8,7 +8,6 @@ CONFIG_TQMA8MXX_BOOT_SDCARD=y @@ -208,7 +205,7 @@ index db8c138a52..0b38d87709 100644 CONFIG_ARCH_MISC_INIT=y CONFIG_SPL_SEPARATE_BSS=y diff --git a/configs/tqma8mxml_2gb_mba8mx_fspi_defconfig b/configs/tqma8mxml_2gb_mba8mx_fspi_defconfig -index 1c558ac3d9..748c35a7ba 100644 +index 111111111111..222222222222 100644 --- a/configs/tqma8mxml_2gb_mba8mx_fspi_defconfig +++ b/configs/tqma8mxml_2gb_mba8mx_fspi_defconfig @@ -7,7 +7,6 @@ CONFIG_TQMA8MXX_BOOT_FSPI=y @@ -220,7 +217,7 @@ index 1c558ac3d9..748c35a7ba 100644 CONFIG_ARCH_MISC_INIT=y CONFIG_SPL_SEPARATE_BSS=y diff --git a/configs/tqma8mxml_2gb_mba8mx_mfg_defconfig b/configs/tqma8mxml_2gb_mba8mx_mfg_defconfig -index e0d6c02086..ef248cfeca 100644 +index 111111111111..222222222222 100644 --- a/configs/tqma8mxml_2gb_mba8mx_mfg_defconfig +++ b/configs/tqma8mxml_2gb_mba8mx_mfg_defconfig @@ -8,7 +8,6 @@ CONFIG_TQMA8MXX_BOOT_SDCARD=y @@ -232,7 +229,7 @@ index e0d6c02086..ef248cfeca 100644 CONFIG_ARCH_MISC_INIT=y CONFIG_SPL_SEPARATE_BSS=y diff --git a/configs/tqma8mxml_2gb_mba8mx_mmc_defconfig b/configs/tqma8mxml_2gb_mba8mx_mmc_defconfig -index 0c9a6cf97b..e27bcfc8fa 100644 +index 111111111111..222222222222 100644 --- a/configs/tqma8mxml_2gb_mba8mx_mmc_defconfig +++ b/configs/tqma8mxml_2gb_mba8mx_mmc_defconfig @@ -7,7 +7,6 @@ CONFIG_TQMA8MXX_BOOT_SDCARD=y @@ -244,7 +241,7 @@ index 0c9a6cf97b..e27bcfc8fa 100644 CONFIG_ARCH_MISC_INIT=y CONFIG_SPL_SEPARATE_BSS=y diff --git a/configs/tqma8mxml_4gb_mba8mx_fspi_defconfig b/configs/tqma8mxml_4gb_mba8mx_fspi_defconfig -index 3267f99fbe..bc6ff38907 100644 +index 111111111111..222222222222 100644 --- a/configs/tqma8mxml_4gb_mba8mx_fspi_defconfig +++ b/configs/tqma8mxml_4gb_mba8mx_fspi_defconfig @@ -8,7 +8,6 @@ CONFIG_TQMA8MXX_BOOT_FSPI=y @@ -256,7 +253,7 @@ index 3267f99fbe..bc6ff38907 100644 CONFIG_ARCH_MISC_INIT=y CONFIG_SPL_SEPARATE_BSS=y diff --git a/configs/tqma8mxml_4gb_mba8mx_mfg_defconfig b/configs/tqma8mxml_4gb_mba8mx_mfg_defconfig -index 4b47cff2cf..1e256fc462 100644 +index 111111111111..222222222222 100644 --- a/configs/tqma8mxml_4gb_mba8mx_mfg_defconfig +++ b/configs/tqma8mxml_4gb_mba8mx_mfg_defconfig @@ -9,7 +9,6 @@ CONFIG_TQMA8MXX_BOOT_SDCARD=y @@ -268,7 +265,7 @@ index 4b47cff2cf..1e256fc462 100644 CONFIG_ARCH_MISC_INIT=y CONFIG_SPL_SEPARATE_BSS=y diff --git a/configs/tqma8mxml_4gb_mba8mx_mmc_defconfig b/configs/tqma8mxml_4gb_mba8mx_mmc_defconfig -index 94855ceb6a..27fa14119a 100644 +index 111111111111..222222222222 100644 --- a/configs/tqma8mxml_4gb_mba8mx_mmc_defconfig +++ b/configs/tqma8mxml_4gb_mba8mx_mmc_defconfig @@ -8,7 +8,6 @@ CONFIG_TQMA8MXX_BOOT_SDCARD=y @@ -280,7 +277,7 @@ index 94855ceb6a..27fa14119a 100644 CONFIG_ARCH_MISC_INIT=y CONFIG_SPL_SEPARATE_BSS=y diff --git a/configs/tqma8mxnl_1gb_mba8mx_defconfig b/configs/tqma8mxnl_1gb_mba8mx_defconfig -index 97f510ec2a..4a0c36d5a7 100644 +index 111111111111..222222222222 100644 --- a/configs/tqma8mxnl_1gb_mba8mx_defconfig +++ b/configs/tqma8mxnl_1gb_mba8mx_defconfig @@ -6,7 +6,6 @@ CONFIG_TARGET_TQMA8MXNL=y @@ -292,7 +289,7 @@ index 97f510ec2a..4a0c36d5a7 100644 CONFIG_ARCH_MISC_INIT=y CONFIG_SPL_SEPARATE_BSS=y diff --git a/configs/tqma8mxnl_1gb_mba8mx_mfg_defconfig b/configs/tqma8mxnl_1gb_mba8mx_mfg_defconfig -index 34c68bbd1f..7f93b46dc1 100644 +index 111111111111..222222222222 100644 --- a/configs/tqma8mxnl_1gb_mba8mx_mfg_defconfig +++ b/configs/tqma8mxnl_1gb_mba8mx_mfg_defconfig @@ -7,7 +7,6 @@ CONFIG_TQMA8MXX_MFG_SUPPORT=y @@ -305,7 +302,7 @@ index 34c68bbd1f..7f93b46dc1 100644 CONFIG_SPL_SEPARATE_BSS=y diff --git a/doc/board/tq/examples/boot-legacy.cmd b/doc/board/tq/examples/boot-legacy.cmd new file mode 100644 -index 0000000000..63445aadaa +index 000000000000..111111111111 --- /dev/null +++ b/doc/board/tq/examples/boot-legacy.cmd @@ -0,0 +1,26 @@ @@ -336,7 +333,7 @@ index 0000000000..63445aadaa +load "${devtype}" "${devnum}:${bootpart}" "${fdt_addr_r}" "${fdtfile}" || exit 1 +${boottype} "${loadaddr}" - "${fdt_addr_r}" diff --git a/include/configs/tqma8mxml-mba8mx.h b/include/configs/tqma8mxml-mba8mx.h -index 1dac176bc3..62fff364bf 100644 +index 111111111111..222222222222 100644 --- a/include/configs/tqma8mxml-mba8mx.h +++ b/include/configs/tqma8mxml-mba8mx.h @@ -14,9 +14,12 @@ @@ -357,7 +354,7 @@ index 1dac176bc3..62fff364bf 100644 #endif /* __TQMA8MXML_MBA8MX_H */ diff --git a/include/configs/tqma8mxml.h b/include/configs/tqma8mxml.h -index 647b177cb3..f850ad7a12 100644 +index 111111111111..222222222222 100644 --- a/include/configs/tqma8mxml.h +++ b/include/configs/tqma8mxml.h @@ -10,7 +10,8 @@ @@ -633,14 +630,15 @@ index 647b177cb3..f850ad7a12 100644 /* Size of malloc() pool */ #define CONFIG_SYS_MALLOC_LEN SZ_64M -@@ -389,16 +245,10 @@ - #error - #endif +@@ -391,17 +247,11 @@ + + #include "tqma8-shared-env.h" -#define CONFIG_EXTRA_ENV_SETTINGS \ ++#define CONFIG_EXTRA_ENV_SETTINGS \ + TQMA8_SHARED_ENV_SETTINGS \ - TQMA8MXML_CM_ENV_SETTINGS \ - TQMA8MX_MODULE_ENV_SETTINGS \ -+#define CONFIG_EXTRA_ENV_SETTINGS \ + TQ_BOOT_ENV_SETTINGS \ + BOOTENV \ + TQMA8MX_MODULE_ENV_SETTINGS \ @@ -656,7 +654,7 @@ index 647b177cb3..f850ad7a12 100644 #endif /* __TQMA8MXML_H */ diff --git a/include/environment/tq/boot.h b/include/environment/tq/boot.h new file mode 100644 -index 0000000000..f940bea14d +index 000000000000..111111111111 --- /dev/null +++ b/include/environment/tq/boot.h @@ -0,0 +1,21 @@ @@ -682,5 +680,5 @@ index 0000000000..f940bea14d + +#endif /* __TQ_BOOT_H */ -- -2.34.1 +Armbian diff --git a/patch/u-boot/u-boot-tqma/0002-tqma8mpxl-enable-distro-boot.patch b/patch/u-boot/u-boot-tqma/0002-tqma8mpxl-enable-distro-boot.patch index 9c033a4a3626..ae0d50c9f04d 100644 --- a/patch/u-boot/u-boot-tqma/0002-tqma8mpxl-enable-distro-boot.patch +++ b/patch/u-boot/u-boot-tqma/0002-tqma8mpxl-enable-distro-boot.patch @@ -1,19 +1,19 @@ -From 34ee47ccf7b67d01e9b44cd6e32a9b109424343c Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Martin Schmiedel Date: Mon, 9 Oct 2023 09:50:48 +0200 -Subject: [PATCH] tqma8mpxl: enable distro boot +Subject: tqma8mpxl: enable distro boot Signed-off-by: Martin Schmiedel --- - .../tqma8mpxl_multi_mba8mp_ras314_defconfig | 3 +- - configs/tqma8mpxl_multi_mba8mpxl_defconfig | 2 +- - include/configs/tqma8mpxl-mba8mp-ras314.h | 8 +- - include/configs/tqma8mpxl-mba8mpxl.h | 8 +- - include/configs/tqma8mpxl.h | 227 ++---------------- + configs/tqma8mpxl_multi_mba8mp_ras314_defconfig | 3 +- + configs/tqma8mpxl_multi_mba8mpxl_defconfig | 2 +- + include/configs/tqma8mpxl-mba8mp-ras314.h | 8 +- + include/configs/tqma8mpxl-mba8mpxl.h | 8 +- + include/configs/tqma8mpxl.h | 227 +--------- 5 files changed, 40 insertions(+), 208 deletions(-) diff --git a/configs/tqma8mpxl_multi_mba8mp_ras314_defconfig b/configs/tqma8mpxl_multi_mba8mp_ras314_defconfig -index 0cd4aee354..2b84636312 100644 +index 111111111111..222222222222 100644 --- a/configs/tqma8mpxl_multi_mba8mp_ras314_defconfig +++ b/configs/tqma8mpxl_multi_mba8mp_ras314_defconfig @@ -15,7 +15,6 @@ CONFIG_FIT_SIGNATURE=y @@ -35,7 +35,7 @@ index 0cd4aee354..2b84636312 100644 CONFIG_LMB_MAX_REGIONS=16 +CONFIG_CMD_IMPORTENV=y diff --git a/configs/tqma8mpxl_multi_mba8mpxl_defconfig b/configs/tqma8mpxl_multi_mba8mpxl_defconfig -index d020405a6b..db20a5c897 100644 +index 111111111111..222222222222 100644 --- a/configs/tqma8mpxl_multi_mba8mpxl_defconfig +++ b/configs/tqma8mpxl_multi_mba8mpxl_defconfig @@ -14,7 +14,6 @@ CONFIG_FIT_SIGNATURE=y @@ -52,7 +52,7 @@ index d020405a6b..db20a5c897 100644 CONFIG_LMB_MAX_REGIONS=16 +CONFIG_CMD_IMPORTENV=y diff --git a/include/configs/tqma8mpxl-mba8mp-ras314.h b/include/configs/tqma8mpxl-mba8mp-ras314.h -index 9a38680c83..7eef5bedff 100644 +index 111111111111..222222222222 100644 --- a/include/configs/tqma8mpxl-mba8mp-ras314.h +++ b/include/configs/tqma8mpxl-mba8mp-ras314.h @@ -27,6 +27,12 @@ @@ -70,7 +70,7 @@ index 9a38680c83..7eef5bedff 100644 #endif /* __TQMA8MPXL_MBA8MPRAS314_H */ diff --git a/include/configs/tqma8mpxl-mba8mpxl.h b/include/configs/tqma8mpxl-mba8mpxl.h -index f652a02eba..351c13ad94 100644 +index 111111111111..222222222222 100644 --- a/include/configs/tqma8mpxl-mba8mpxl.h +++ b/include/configs/tqma8mpxl-mba8mpxl.h @@ -27,6 +27,12 @@ @@ -88,7 +88,7 @@ index f652a02eba..351c13ad94 100644 #endif /* __TQMA8MPXL_MBA8MPXL_H */ diff --git a/include/configs/tqma8mpxl.h b/include/configs/tqma8mpxl.h -index 6e832128db..4a31298461 100644 +index 111111111111..222222222222 100644 --- a/include/configs/tqma8mpxl.h +++ b/include/configs/tqma8mpxl.h @@ -10,10 +10,12 @@ @@ -361,5 +361,5 @@ index 6e832128db..4a31298461 100644 - #endif /* __TQMA8MPXL_H */ -- -2.34.1 +Armbian diff --git a/patch/u-boot/u-boot-tqma/0003-imx-mkimage_fit_atf_imx8mp.sh-add-script-for-imx8mp.patch b/patch/u-boot/u-boot-tqma/0003-imx-mkimage_fit_atf_imx8mp.sh-add-script-for-imx8mp.patch index a84b79232858..10d0e59a03ed 100644 --- a/patch/u-boot/u-boot-tqma/0003-imx-mkimage_fit_atf_imx8mp.sh-add-script-for-imx8mp.patch +++ b/patch/u-boot/u-boot-tqma/0003-imx-mkimage_fit_atf_imx8mp.sh-add-script-for-imx8mp.patch @@ -1,20 +1,19 @@ -From 55a5f1cb804eba8065c8f959d71f334d7dc57eab Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Martin Schmiedel Date: Mon, 22 Jul 2024 07:48:26 +0200 -Subject: [PATCH] imx: mkimage_fit_atf_imx8mp.sh: add script for imx8mp +Subject: imx: mkimage_fit_atf_imx8mp.sh: add script for imx8mp If Varibles can not be exported this script set default value for ATF_LOAD_ADDR Signed-off-by: Martin Schmiedel --- Makefile | 2 + - arch/arm/mach-imx/mkimage_fit_atf_imx8mp.sh | 139 ++++++++++++++++++++ + arch/arm/mach-imx/mkimage_fit_atf_imx8mp.sh | 139 ++++++++++ board/tqc/tqma8mpxl/Kconfig | 3 + 3 files changed, 144 insertions(+) - create mode 100755 arch/arm/mach-imx/mkimage_fit_atf_imx8mp.sh diff --git a/Makefile b/Makefile -index 312bb794c3..2d65bebd95 100644 +index 111111111111..222222222222 100644 --- a/Makefile +++ b/Makefile @@ -1281,6 +1281,8 @@ ifneq ($(CONFIG_SPL_FIT_GENERATOR),"") @@ -28,7 +27,7 @@ index 312bb794c3..2d65bebd95 100644 U_BOOT_ITS_DEPS += u-boot diff --git a/arch/arm/mach-imx/mkimage_fit_atf_imx8mp.sh b/arch/arm/mach-imx/mkimage_fit_atf_imx8mp.sh new file mode 100755 -index 0000000000..25031ce710 +index 000000000000..111111111111 --- /dev/null +++ b/arch/arm/mach-imx/mkimage_fit_atf_imx8mp.sh @@ -0,0 +1,139 @@ @@ -172,7 +171,7 @@ index 0000000000..25031ce710 +}; +__ITS_EOF diff --git a/board/tqc/tqma8mpxl/Kconfig b/board/tqc/tqma8mpxl/Kconfig -index 19e5d5030f..a8bd61246f 100644 +index 111111111111..222222222222 100644 --- a/board/tqc/tqma8mpxl/Kconfig +++ b/board/tqc/tqma8mpxl/Kconfig @@ -15,6 +15,9 @@ config SPL_TEXT_BASE @@ -186,5 +185,5 @@ index 19e5d5030f..a8bd61246f 100644 bool default y -- -2.34.1 +Armbian From 04873d47de7dadd956668f559f26e67e9aec4537 Mon Sep 17 00:00:00 2001 From: Martin Schmiedel Date: Mon, 10 Feb 2025 12:36:54 +0100 Subject: [PATCH 23/33] MBa8MPxL-RAS314: fix firmware file in root folder - wget and cp lead to remaining file in root - use mv instead Signed-off-by: Martin Schmiedel --- config/boards/mba8mpxl-ras314.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/boards/mba8mpxl-ras314.conf b/config/boards/mba8mpxl-ras314.conf index 99b9429bfcce..78058c0ad902 100644 --- a/config/boards/mba8mpxl-ras314.conf +++ b/config/boards/mba8mpxl-ras314.conf @@ -19,7 +19,7 @@ function post_family_tweaks_bsp__mba8mpxl-ras314() { wget https://github.com/nxp-imx/imx-firmware/raw/lf-6.6.3_1.0.0/nxp/FwImage_8997/pcieuart8997_combo_v4.bin run_host_command_logged mkdir -pv --mode=755 "$destination/lib/firmware/" || exit_with_error "Unable to mkdir firmware" run_host_command_logged mkdir -v --mode=775 "$destination/lib/firmware/mrvl/" || exit_with_error "Unable to mkdir mrvl" - run_host_command_logged cp -Pv "pcieuart8997_combo_v4.bin" "$destination/lib/firmware/mrvl/" || exit_with_error "Unable to copy mrvl firmware" + run_host_command_logged mv -v "pcieuart8997_combo_v4.bin" "$destination/lib/firmware/mrvl/" || exit_with_error "Unable to copy mrvl firmware" # Add udev rule to delay btnxpuart loading cat <<- NXP_UDEV_RULE > "${destination}"/etc/udev/rules.d/10-nxp-bluetooth-delay.rules From ec2544e005b717b906a014d43f63c1f54b252ea3 Mon Sep 17 00:00:00 2001 From: Igor Pecovnik Date: Sun, 9 Feb 2025 21:08:38 +0100 Subject: [PATCH 24/33] Bugfix: Remove directories from sha files --- lib/functions/image/compress-checksum.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/functions/image/compress-checksum.sh b/lib/functions/image/compress-checksum.sh index f103d960be74..824092e2b254 100644 --- a/lib/functions/image/compress-checksum.sh +++ b/lib/functions/image/compress-checksum.sh @@ -45,7 +45,8 @@ function output_images_compress_and_checksum() { if [[ $COMPRESS_OUTPUTIMAGE == *sha* ]]; then display_alert "SHA256 calculating" "${uncompressed_file_basename}${compression_type}" "info" - sha256sum -b "${uncompressed_file}${compression_type}" > "${uncompressed_file}${compression_type}".sha + # awk manipulation is needed to get rid of temporal folder path from SHA signature + sha256sum -b "${uncompressed_file}${compression_type}" | awk '{split($2, a, "/"); print $1, a[length(a)]}' > "${uncompressed_file}${compression_type}".sha fi done From d048673c004f99c715b88ac517736f802c28d572 Mon Sep 17 00:00:00 2001 From: amazingfate Date: Sat, 1 Feb 2025 23:08:24 +0800 Subject: [PATCH 25/33] u-boot-radxa-rk35xx: bump to next-dev-v2024.10 --- config/sources/families/rk35xx.conf | 2 +- config/sources/families/rockchip-rk3588.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/sources/families/rk35xx.conf b/config/sources/families/rk35xx.conf index 968a9b1df001..64441c7c30e4 100644 --- a/config/sources/families/rk35xx.conf +++ b/config/sources/families/rk35xx.conf @@ -10,7 +10,7 @@ source "${BASH_SOURCE%/*}/include/rockchip64_common.inc" BOOTSOURCE='https://github.com/radxa/u-boot.git' -BOOTBRANCH='branch:next-dev-v2024.03' # Always use same version as rk3588, they share a patch dir +BOOTBRANCH='branch:next-dev-v2024.10' # Always use same version as rk3588, they share a patch dir BOOTPATCHDIR="legacy/u-boot-radxa-rk35xx" OVERLAY_PREFIX='rk35xx' diff --git a/config/sources/families/rockchip-rk3588.conf b/config/sources/families/rockchip-rk3588.conf index dd6b239bed19..ae99b4bac37b 100644 --- a/config/sources/families/rockchip-rk3588.conf +++ b/config/sources/families/rockchip-rk3588.conf @@ -10,7 +10,7 @@ source "${BASH_SOURCE%/*}/include/rockchip64_common.inc" BOOTSOURCE='https://github.com/radxa/u-boot.git' -BOOTBRANCH='branch:next-dev-v2024.03' # Always use same version as rk35xx, they share a patch dir +BOOTBRANCH='branch:next-dev-v2024.10' # Always use same version as rk35xx, they share a patch dir BOOTPATCHDIR="legacy/u-boot-radxa-rk35xx" OVERLAY_PREFIX='rockchip-rk3588' From 540249279619ba0972f5e66e7a3b76ab47721f3a Mon Sep 17 00:00:00 2001 From: amazingfate Date: Sun, 2 Feb 2025 00:04:23 +0800 Subject: [PATCH 26/33] merge u-boot-armsom-rk3576 to u-boot-radxa-rk35xx --- config/boards/armsom-cm5-io.csc | 4 -- config/boards/armsom-cm5-rpi-cm4-io.csc | 4 -- config/boards/armsom-sige5.csc | 4 -- .../0000.patching_config.yaml | 5 -- ...he-error-that-the-command-source-fai.patch | 26 -------- ...stent-return-type-of-command_process.patch | 35 ---------- ...assing-of-BL31-location-via-variable.patch | 65 ------------------- .../defconfig/armsom-cm5-io-rk3576_defconfig | 0 .../armsom-cm5-rpi-cm4-io-rk3576_defconfig | 0 .../defconfig/armsom-sige5-rk3576_defconfig | 0 .../dt/rk3576-armsom-cm5-io.dts | 0 .../dt/rk3576-armsom-sige5.dts | 0 ...assing-of-BL32-location-via-variable.patch | 0 13 files changed, 143 deletions(-) delete mode 100644 patch/u-boot/legacy/u-boot-armsom-rk3576/0000.patching_config.yaml delete mode 100644 patch/u-boot/legacy/u-boot-armsom-rk3576/0001-cmd-source-fix-the-error-that-the-command-source-fai.patch delete mode 100644 patch/u-boot/legacy/u-boot-armsom-rk3576/0002-cmd-inconsistent-return-type-of-command_process.patch delete mode 100644 patch/u-boot/legacy/u-boot-armsom-rk3576/rockchip-allow-passing-of-BL31-location-via-variable.patch rename patch/u-boot/legacy/{u-boot-armsom-rk3576 => u-boot-radxa-rk35xx}/defconfig/armsom-cm5-io-rk3576_defconfig (100%) rename patch/u-boot/legacy/{u-boot-armsom-rk3576 => u-boot-radxa-rk35xx}/defconfig/armsom-cm5-rpi-cm4-io-rk3576_defconfig (100%) rename patch/u-boot/legacy/{u-boot-armsom-rk3576 => u-boot-radxa-rk35xx}/defconfig/armsom-sige5-rk3576_defconfig (100%) rename patch/u-boot/legacy/{u-boot-armsom-rk3576 => u-boot-radxa-rk35xx}/dt/rk3576-armsom-cm5-io.dts (100%) rename patch/u-boot/legacy/{u-boot-armsom-rk3576 => u-boot-radxa-rk35xx}/dt/rk3576-armsom-sige5.dts (100%) rename patch/u-boot/legacy/{u-boot-armsom-rk3576 => u-boot-radxa-rk35xx}/rockchip-allow-passing-of-BL32-location-via-variable.patch (100%) diff --git a/config/boards/armsom-cm5-io.csc b/config/boards/armsom-cm5-io.csc index 2c1dd8e922ee..ec704cd4438f 100644 --- a/config/boards/armsom-cm5-io.csc +++ b/config/boards/armsom-cm5-io.csc @@ -13,10 +13,6 @@ BOARD_MAINTAINER="" function post_family_config_branch_vendor__armsom-cm5-io_use_vendor_uboot() { display_alert "$BOARD" "vendor u-boot overrides for $BOARD / $BRANCH" "info" - declare -g BOOTSOURCE="https://github.com/ArmSoM/u-boot.git" - declare -g BOOTBRANCH="tag:rk3576-6.1-rk3.1" - declare -g BOOTPATCHDIR="legacy/u-boot-armsom-rk3576" - declare -g BOOTDIR="u-boot-${BOARD}" declare -g UBOOT_TARGET_MAP="BL31=$RKBIN_DIR/$BL31_BLOB TEE=$RKBIN_DIR/$BL32_BLOB spl/u-boot-spl.bin u-boot.dtb u-boot.itb;;idbloader.img u-boot.itb" } diff --git a/config/boards/armsom-cm5-rpi-cm4-io.csc b/config/boards/armsom-cm5-rpi-cm4-io.csc index ea33136b97ec..d130455a00e7 100644 --- a/config/boards/armsom-cm5-rpi-cm4-io.csc +++ b/config/boards/armsom-cm5-rpi-cm4-io.csc @@ -13,10 +13,6 @@ BOARD_MAINTAINER="" function post_family_config_branch_vendor__armsom-cm5-rpi-cm4-io_use_vendor_uboot() { display_alert "$BOARD" "vendor u-boot overrides for $BOARD / $BRANCH" "info" - declare -g BOOTSOURCE="https://github.com/ArmSoM/u-boot.git" - declare -g BOOTBRANCH="tag:rk3576-6.1-rk3.1" - declare -g BOOTPATCHDIR="legacy/u-boot-armsom-rk3576" - declare -g BOOTDIR="u-boot-${BOARD}" declare -g UBOOT_TARGET_MAP="BL31=$RKBIN_DIR/$BL31_BLOB TEE=$RKBIN_DIR/$BL32_BLOB spl/u-boot-spl.bin u-boot.dtb u-boot.itb;;idbloader.img u-boot.itb" } diff --git a/config/boards/armsom-sige5.csc b/config/boards/armsom-sige5.csc index 9aea68a3c443..370f88a0f184 100644 --- a/config/boards/armsom-sige5.csc +++ b/config/boards/armsom-sige5.csc @@ -13,10 +13,6 @@ BOARD_MAINTAINER="" function post_family_config_branch_vendor__armsom-sige7_use_vendor_uboot() { display_alert "$BOARD" "vendor u-boot overrides for $BOARD / $BRANCH" "info" - declare -g BOOTSOURCE="https://github.com/ArmSoM/u-boot.git" - declare -g BOOTBRANCH="tag:rk3576-6.1-rk3.1" - declare -g BOOTPATCHDIR="legacy/u-boot-armsom-rk3576" - declare -g BOOTDIR="u-boot-${BOARD}" declare -g UBOOT_TARGET_MAP="BL31=$RKBIN_DIR/$BL31_BLOB TEE=$RKBIN_DIR/$BL32_BLOB spl/u-boot-spl.bin u-boot.dtb u-boot.itb;;idbloader.img u-boot.itb" } diff --git a/patch/u-boot/legacy/u-boot-armsom-rk3576/0000.patching_config.yaml b/patch/u-boot/legacy/u-boot-armsom-rk3576/0000.patching_config.yaml deleted file mode 100644 index 719cf56a8c70..000000000000 --- a/patch/u-boot/legacy/u-boot-armsom-rk3576/0000.patching_config.yaml +++ /dev/null @@ -1,5 +0,0 @@ -config: - - overlay-directories: - - { source: "defconfig", target: "configs" } # copies all files in defconfig dir to the configs/ dir in the u-boot source tree - - { source: "dt", target: "arch/arm/dts" } # copies all files in dt dir to the arch/arm/dts dir in the u-boot source tree diff --git a/patch/u-boot/legacy/u-boot-armsom-rk3576/0001-cmd-source-fix-the-error-that-the-command-source-fai.patch b/patch/u-boot/legacy/u-boot-armsom-rk3576/0001-cmd-source-fix-the-error-that-the-command-source-fai.patch deleted file mode 100644 index c3c313e294ef..000000000000 --- a/patch/u-boot/legacy/u-boot-armsom-rk3576/0001-cmd-source-fix-the-error-that-the-command-source-fai.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Stephen -Date: Mon, 8 Nov 2021 14:30:00 +0800 -Subject: cmd: source: fix the error that the command source failed to execute - -Signed-off-by: Stephen ---- - cmd/source.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/cmd/source.c b/cmd/source.c -index 111111111111..222222222222 100644 ---- a/cmd/source.c -+++ b/cmd/source.c -@@ -87,7 +87,7 @@ source (ulong addr, const char *fit_uname) - * past the zero-terminated sequence of image lengths to get - * to the actual image data - */ -- while (*data++ != IMAGE_PARAM_INVAL); -+ while (*data++); - break; - #endif - #if defined(CONFIG_FIT) --- -Armbian - diff --git a/patch/u-boot/legacy/u-boot-armsom-rk3576/0002-cmd-inconsistent-return-type-of-command_process.patch b/patch/u-boot/legacy/u-boot-armsom-rk3576/0002-cmd-inconsistent-return-type-of-command_process.patch deleted file mode 100644 index 0c2469f1c092..000000000000 --- a/patch/u-boot/legacy/u-boot-armsom-rk3576/0002-cmd-inconsistent-return-type-of-command_process.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Heinrich Schuchardt -Date: Mon, 1 Aug 2022 15:17:49 +0200 -Subject: cmd: inconsistent return type of command_process() - -The declarations in the header and in the implementation must match. - -Reported-by: Sergei Antonov -Signed-off-by: Heinrich Schuchardt -Reviewed-by: Simon Glass ---- - include/command.h | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/include/command.h b/include/command.h -index 111111111111..222222222222 100644 ---- a/include/command.h -+++ b/include/command.h -@@ -137,10 +137,10 @@ enum command_ret_t { - * is left unchanged. - * @param ticks If ticks is not null, this function set it to the - * number of ticks the command took to complete. -- * @return 0 if the command succeeded, 1 if it failed -+ * @return 0 if command succeeded, else non-zero (CMD_RET_...) - */ --int cmd_process(int flag, int argc, char * const argv[], -- int *repeatable, unsigned long *ticks); -+enum command_ret_t cmd_process(int flag, int argc, char *const argv[], -+ int *repeatable, unsigned long *ticks); - - void fixup_cmdtable(cmd_tbl_t *cmdtp, int size); - --- -Armbian - diff --git a/patch/u-boot/legacy/u-boot-armsom-rk3576/rockchip-allow-passing-of-BL31-location-via-variable.patch b/patch/u-boot/legacy/u-boot-armsom-rk3576/rockchip-allow-passing-of-BL31-location-via-variable.patch deleted file mode 100644 index c9ff83eb2e31..000000000000 --- a/patch/u-boot/legacy/u-boot-armsom-rk3576/rockchip-allow-passing-of-BL31-location-via-variable.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Stephen Chen -Date: Tue, 21 Mar 2023 16:11:34 +0800 -Subject: rockchip: allow passing of BL31 location via variable - -Source link: https://github.com/piter75/armbian-build/blob/rock-3a-bring-up/patch/u-boot/u-boot-rk356x/general-configurable-bl31-path.patch - -Signed-off-by: Stephen Chen ---- - arch/arm/mach-rockchip/decode_bl31.py | 12 ++++++++- - arch/arm/mach-rockchip/make_fit_atf.py | 13 +++++++++- - 2 files changed, 23 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/mach-rockchip/decode_bl31.py b/arch/arm/mach-rockchip/decode_bl31.py -index 301bd153753..42fa32d23d2 100755 ---- a/arch/arm/mach-rockchip/decode_bl31.py -+++ b/arch/arm/mach-rockchip/decode_bl31.py -@@ -41,7 +41,17 @@ def generate_atf_binary(bl31_file_name): - atf.write(data) - - def main(): -- bl31_elf="./bl31.elf" -+ if "BL31" in os.environ: -+ bl31_elf=os.getenv("BL31"); -+ elif os.path.isfile("./bl31.elf"): -+ bl31_elf = "./bl31.elf" -+ else: -+ os.system("echo 'int main(){}' > bl31.c") -+ os.system("${CROSS_COMPILE}gcc -c bl31.c -o bl31.elf") -+ bl31_elf = "./bl31.elf" -+ logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG) -+ logging.warning(' BL31 file bl31.elf NOT found, resulting binary is non-functional') -+ logging.warning(' Please read Building section in doc/README.rockchip') - generate_atf_binary(bl31_elf); - - if __name__ == "__main__": -diff --git a/arch/arm/mach-rockchip/make_fit_atf.py b/arch/arm/mach-rockchip/make_fit_atf.py -index 27b6ef75970..fac8d6f1219 100755 ---- a/arch/arm/mach-rockchip/make_fit_atf.py -+++ b/arch/arm/mach-rockchip/make_fit_atf.py -@@ -212,9 +212,20 @@ def get_bl31_segments_info(bl31_file_name): - - def main(): - uboot_elf="./u-boot" -- bl31_elf="./bl31.elf" - FIT_ITS=sys.stdout - -+ if "BL31" in os.environ: -+ bl31_elf=os.getenv("BL31"); -+ elif os.path.isfile("./bl31.elf"): -+ bl31_elf = "./bl31.elf" -+ else: -+ os.system("echo 'int main(){}' > bl31.c") -+ os.system("${CROSS_COMPILE}gcc -c bl31.c -o bl31.elf") -+ bl31_elf = "./bl31.elf" -+ logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG) -+ logging.warning(' BL31 file bl31.elf NOT found, resulting binary is non-functional') -+ logging.warning(' Please read Building section in doc/README.rockchip') -+ - opts, args = getopt.getopt(sys.argv[1:], "o:u:b:h") - for opt, val in opts: - if opt == "-o": --- -Armbian - diff --git a/patch/u-boot/legacy/u-boot-armsom-rk3576/defconfig/armsom-cm5-io-rk3576_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-cm5-io-rk3576_defconfig similarity index 100% rename from patch/u-boot/legacy/u-boot-armsom-rk3576/defconfig/armsom-cm5-io-rk3576_defconfig rename to patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-cm5-io-rk3576_defconfig diff --git a/patch/u-boot/legacy/u-boot-armsom-rk3576/defconfig/armsom-cm5-rpi-cm4-io-rk3576_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-cm5-rpi-cm4-io-rk3576_defconfig similarity index 100% rename from patch/u-boot/legacy/u-boot-armsom-rk3576/defconfig/armsom-cm5-rpi-cm4-io-rk3576_defconfig rename to patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-cm5-rpi-cm4-io-rk3576_defconfig diff --git a/patch/u-boot/legacy/u-boot-armsom-rk3576/defconfig/armsom-sige5-rk3576_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-sige5-rk3576_defconfig similarity index 100% rename from patch/u-boot/legacy/u-boot-armsom-rk3576/defconfig/armsom-sige5-rk3576_defconfig rename to patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-sige5-rk3576_defconfig diff --git a/patch/u-boot/legacy/u-boot-armsom-rk3576/dt/rk3576-armsom-cm5-io.dts b/patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3576-armsom-cm5-io.dts similarity index 100% rename from patch/u-boot/legacy/u-boot-armsom-rk3576/dt/rk3576-armsom-cm5-io.dts rename to patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3576-armsom-cm5-io.dts diff --git a/patch/u-boot/legacy/u-boot-armsom-rk3576/dt/rk3576-armsom-sige5.dts b/patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3576-armsom-sige5.dts similarity index 100% rename from patch/u-boot/legacy/u-boot-armsom-rk3576/dt/rk3576-armsom-sige5.dts rename to patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3576-armsom-sige5.dts diff --git a/patch/u-boot/legacy/u-boot-armsom-rk3576/rockchip-allow-passing-of-BL32-location-via-variable.patch b/patch/u-boot/legacy/u-boot-radxa-rk35xx/rockchip-allow-passing-of-BL32-location-via-variable.patch similarity index 100% rename from patch/u-boot/legacy/u-boot-armsom-rk3576/rockchip-allow-passing-of-BL32-location-via-variable.patch rename to patch/u-boot/legacy/u-boot-radxa-rk35xx/rockchip-allow-passing-of-BL32-location-via-variable.patch From c81f89ca90f80483c7d33e0677c0faa3bccebe36 Mon Sep 17 00:00:00 2001 From: amazingfate Date: Sun, 2 Feb 2025 14:16:37 +0800 Subject: [PATCH 27/33] u-boot-radxa-rk35xx: disable optee Follow change from radxa 738cda44532c324e07296c95751e3083fa95f282. Change with command: sed -i "/CONFIG_OPTEE/d" patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/* --- .../defconfig/armsom-aim7-io-rk3588_defconfig | 2 -- .../defconfig/armsom-cm5-io-rk3576_defconfig | 2 -- .../defconfig/armsom-cm5-rpi-cm4-io-rk3576_defconfig | 2 -- .../defconfig/armsom-sige3-rk3568_defconfig | 2 -- .../defconfig/armsom-sige5-rk3576_defconfig | 2 -- .../defconfig/armsom-sige7-rk3588_defconfig | 2 -- .../u-boot-radxa-rk35xx/defconfig/armsom-w3-rk3588_defconfig | 2 -- .../u-boot-radxa-rk35xx/defconfig/hinlink_rk3528_defconfig | 2 -- .../defconfig/mixtile-edge2-rk3568_defconfig | 2 -- .../u-boot-radxa-rk35xx/defconfig/nanopi-r6s-rk3588s_defconfig | 3 --- .../defconfig/orangepi-5-max-rk3588_defconfig | 2 -- .../defconfig/orangepi-5-plus-rk3588_defconfig | 2 -- .../u-boot-radxa-rk35xx/defconfig/orangepi-5-rk3588s_defconfig | 2 -- .../defconfig/orangepi-5-sata-rk3588s_defconfig | 2 -- .../defconfig/orangepi-5b-rk3588s_defconfig | 2 -- .../u-boot-radxa-rk35xx/defconfig/radxa_e20c_rk3528_defconfig | 2 -- .../defconfig/retro-lite-cm5-rk3588s_defconfig | 2 -- .../u-boot-radxa-rk35xx/defconfig/rk3588-cyber-aib_defconfig | 2 -- 18 files changed, 37 deletions(-) diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-aim7-io-rk3588_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-aim7-io-rk3588_defconfig index 97642e9f4fa5..76c4c84c27c8 100644 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-aim7-io-rk3588_defconfig +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-aim7-io-rk3588_defconfig @@ -210,5 +210,3 @@ CONFIG_AVB_LIBAVB_AB=y CONFIG_AVB_LIBAVB_ATX=y CONFIG_AVB_LIBAVB_USER=y CONFIG_RK_AVB_LIBAVB_USER=y -CONFIG_OPTEE_CLIENT=y -CONFIG_OPTEE_V2=y diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-cm5-io-rk3576_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-cm5-io-rk3576_defconfig index fa69a379cf38..5ee20156ada6 100644 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-cm5-io-rk3576_defconfig +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-cm5-io-rk3576_defconfig @@ -217,7 +217,5 @@ CONFIG_AVB_LIBAVB_AB=y CONFIG_AVB_LIBAVB_ATX=y CONFIG_AVB_LIBAVB_USER=y CONFIG_RK_AVB_LIBAVB_USER=y -CONFIG_OPTEE_CLIENT=y -CONFIG_OPTEE_V2=y CONFIG_ROCKCHIP_EARLY_DISTRO_DTB=y CONFIG_ROCKCHIP_EARLY_DISTRO_DTB_PATH="/boot/dtb/rockchip/rk3576-armsom-cm5-io.dtb" diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-cm5-rpi-cm4-io-rk3576_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-cm5-rpi-cm4-io-rk3576_defconfig index d2205afdfb2f..d6724380552f 100644 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-cm5-rpi-cm4-io-rk3576_defconfig +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-cm5-rpi-cm4-io-rk3576_defconfig @@ -217,7 +217,5 @@ CONFIG_AVB_LIBAVB_AB=y CONFIG_AVB_LIBAVB_ATX=y CONFIG_AVB_LIBAVB_USER=y CONFIG_RK_AVB_LIBAVB_USER=y -CONFIG_OPTEE_CLIENT=y -CONFIG_OPTEE_V2=y CONFIG_ROCKCHIP_EARLY_DISTRO_DTB=y CONFIG_ROCKCHIP_EARLY_DISTRO_DTB_PATH="/boot/dtb/rockchip/rk3576-armsom-cm5-rpi-cm4-io.dtb" diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-sige3-rk3568_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-sige3-rk3568_defconfig index 12569e57d556..65ee0a00bcfb 100644 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-sige3-rk3568_defconfig +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-sige3-rk3568_defconfig @@ -229,8 +229,6 @@ CONFIG_AVB_LIBAVB_AB=y CONFIG_AVB_LIBAVB_ATX=y CONFIG_AVB_LIBAVB_USER=y CONFIG_RK_AVB_LIBAVB_USER=y -CONFIG_OPTEE_CLIENT=y -CONFIG_OPTEE_V2=y CONFIG_CMD_CHARGE_DISPLAY=y CONFIG_DM_CHARGE_DISPLAY=y CONFIG_CMD_PMIC=y diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-sige5-rk3576_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-sige5-rk3576_defconfig index 73125b562a72..e6ab7fffa007 100644 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-sige5-rk3576_defconfig +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-sige5-rk3576_defconfig @@ -217,7 +217,5 @@ CONFIG_AVB_LIBAVB_AB=y CONFIG_AVB_LIBAVB_ATX=y CONFIG_AVB_LIBAVB_USER=y CONFIG_RK_AVB_LIBAVB_USER=y -CONFIG_OPTEE_CLIENT=y -CONFIG_OPTEE_V2=y CONFIG_ROCKCHIP_EARLY_DISTRO_DTB=y CONFIG_ROCKCHIP_EARLY_DISTRO_DTB_PATH="/boot/dtb/rockchip/rk3576-armsom-sige5.dtb" diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-sige7-rk3588_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-sige7-rk3588_defconfig index 41fc8c029c67..54c242d7bfb2 100644 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-sige7-rk3588_defconfig +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-sige7-rk3588_defconfig @@ -217,7 +217,5 @@ CONFIG_AVB_LIBAVB_AB=y CONFIG_AVB_LIBAVB_ATX=y CONFIG_AVB_LIBAVB_USER=y CONFIG_RK_AVB_LIBAVB_USER=y -CONFIG_OPTEE_CLIENT=y -CONFIG_OPTEE_V2=y CONFIG_CMD_CHARGE_DISPLAY=y CONFIG_DM_CHARGE_DISPLAY=y diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-w3-rk3588_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-w3-rk3588_defconfig index e22682f5beef..9f1ae340b219 100644 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-w3-rk3588_defconfig +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-w3-rk3588_defconfig @@ -212,5 +212,3 @@ CONFIG_AVB_LIBAVB_AB=y CONFIG_AVB_LIBAVB_ATX=y CONFIG_AVB_LIBAVB_USER=y CONFIG_RK_AVB_LIBAVB_USER=y -CONFIG_OPTEE_CLIENT=y -CONFIG_OPTEE_V2=y diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/hinlink_rk3528_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/hinlink_rk3528_defconfig index 7e174b3be20a..b37bc5fa7f77 100644 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/hinlink_rk3528_defconfig +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/hinlink_rk3528_defconfig @@ -191,5 +191,3 @@ CONFIG_AVB_LIBAVB_AB=y CONFIG_AVB_LIBAVB_ATX=y CONFIG_AVB_LIBAVB_USER=y CONFIG_RK_AVB_LIBAVB_USER=y -#CONFIG_OPTEE_CLIENT=y -#CONFIG_OPTEE_V2=y diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/mixtile-edge2-rk3568_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/mixtile-edge2-rk3568_defconfig index 175ccb7dc6ee..824220dc12ec 100644 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/mixtile-edge2-rk3568_defconfig +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/mixtile-edge2-rk3568_defconfig @@ -229,8 +229,6 @@ CONFIG_AVB_LIBAVB_AB=y CONFIG_AVB_LIBAVB_ATX=y CONFIG_AVB_LIBAVB_USER=y CONFIG_RK_AVB_LIBAVB_USER=y -CONFIG_OPTEE_CLIENT=y -CONFIG_OPTEE_V2=y CONFIG_CMD_CHARGE_DISPLAY=y CONFIG_DM_CHARGE_DISPLAY=y CONFIG_CMD_PMIC=y diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/nanopi-r6s-rk3588s_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/nanopi-r6s-rk3588s_defconfig index 19bae5562928..a7a81de9d28b 100644 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/nanopi-r6s-rk3588s_defconfig +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/nanopi-r6s-rk3588s_defconfig @@ -212,6 +212,3 @@ CONFIG_AVB_LIBAVB_AB=y CONFIG_AVB_LIBAVB_ATX=y CONFIG_AVB_LIBAVB_USER=y CONFIG_RK_AVB_LIBAVB_USER=y -CONFIG_OPTEE_CLIENT=y -CONFIG_OPTEE_V2=y -CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION=y diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5-max-rk3588_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5-max-rk3588_defconfig index 5de721791c2b..f336897338e2 100644 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5-max-rk3588_defconfig +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5-max-rk3588_defconfig @@ -251,5 +251,3 @@ CONFIG_LIBATA=y CONFIG_SCSI_AHCI=y CONFIG_SCSI=y CONFIG_MTD_BLK_U_BOOT_OFFS=0x400 -CONFIG_OPTEE_CLIENT=y -CONFIG_OPTEE_V2=y diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5-plus-rk3588_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5-plus-rk3588_defconfig index 1d221c7efb1b..3a139c2643a7 100644 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5-plus-rk3588_defconfig +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5-plus-rk3588_defconfig @@ -251,5 +251,3 @@ CONFIG_LIBATA=y CONFIG_SCSI_AHCI=y CONFIG_SCSI=y CONFIG_MTD_BLK_U_BOOT_OFFS=0x400 -CONFIG_OPTEE_CLIENT=y -CONFIG_OPTEE_V2=y diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5-rk3588s_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5-rk3588s_defconfig index c7e5e86fc4ce..580456ff6c55 100644 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5-rk3588s_defconfig +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5-rk3588s_defconfig @@ -250,5 +250,3 @@ CONFIG_LIBATA=y CONFIG_SCSI_AHCI=y CONFIG_SCSI=y CONFIG_MTD_BLK_U_BOOT_OFFS=0x400 -CONFIG_OPTEE_CLIENT=y -CONFIG_OPTEE_V2=y diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5-sata-rk3588s_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5-sata-rk3588s_defconfig index 5374c4cb113e..1ef1426e17f0 100644 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5-sata-rk3588s_defconfig +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5-sata-rk3588s_defconfig @@ -250,5 +250,3 @@ CONFIG_LIBATA=y CONFIG_SCSI_AHCI=y CONFIG_SCSI=y CONFIG_MTD_BLK_U_BOOT_OFFS=0x400 -CONFIG_OPTEE_CLIENT=y -CONFIG_OPTEE_V2=y diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5b-rk3588s_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5b-rk3588s_defconfig index dd2c9457fb7c..6df9d0dfd85e 100644 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5b-rk3588s_defconfig +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/orangepi-5b-rk3588s_defconfig @@ -250,5 +250,3 @@ CONFIG_LIBATA=y CONFIG_SCSI_AHCI=y CONFIG_SCSI=y CONFIG_MTD_BLK_U_BOOT_OFFS=0x400 -CONFIG_OPTEE_CLIENT=y -CONFIG_OPTEE_V2=y diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/radxa_e20c_rk3528_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/radxa_e20c_rk3528_defconfig index c9eb2dc349df..bd55defa9c91 100644 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/radxa_e20c_rk3528_defconfig +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/radxa_e20c_rk3528_defconfig @@ -198,5 +198,3 @@ CONFIG_AVB_LIBAVB_AB=y CONFIG_AVB_LIBAVB_ATX=y CONFIG_AVB_LIBAVB_USER=y CONFIG_RK_AVB_LIBAVB_USER=y -CONFIG_OPTEE_CLIENT=y -CONFIG_OPTEE_V2=y diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/retro-lite-cm5-rk3588s_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/retro-lite-cm5-rk3588s_defconfig index 14342294775c..d536aa5eebcd 100644 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/retro-lite-cm5-rk3588s_defconfig +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/retro-lite-cm5-rk3588s_defconfig @@ -218,5 +218,3 @@ CONFIG_AVB_LIBAVB_AB=y CONFIG_AVB_LIBAVB_ATX=y CONFIG_AVB_LIBAVB_USER=y CONFIG_RK_AVB_LIBAVB_USER=y -CONFIG_OPTEE_CLIENT=y -CONFIG_OPTEE_V2=y diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/rk3588-cyber-aib_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/rk3588-cyber-aib_defconfig index 3266131385ed..cf8434b1caa3 100644 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/rk3588-cyber-aib_defconfig +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/rk3588-cyber-aib_defconfig @@ -210,5 +210,3 @@ CONFIG_AVB_LIBAVB_AB=y CONFIG_AVB_LIBAVB_ATX=y CONFIG_AVB_LIBAVB_USER=y CONFIG_RK_AVB_LIBAVB_USER=y -CONFIG_OPTEE_CLIENT=y -CONFIG_OPTEE_V2=y From 83e5675fb416b3101e28f14e36e31a451fe34543 Mon Sep 17 00:00:00 2001 From: amazingfate Date: Sun, 2 Feb 2025 15:32:24 +0800 Subject: [PATCH 28/33] rk3576: remove unnecessary BL32 from uboot --- config/boards/armsom-cm5-io.csc | 6 ------ config/boards/armsom-cm5-rpi-cm4-io.csc | 6 ------ config/boards/armsom-sige5.csc | 6 ------ .../sources/families/include/rockchip64_common.inc | 1 - ...llow-passing-of-BL32-location-via-variable.patch | 13 ------------- 5 files changed, 32 deletions(-) delete mode 100644 patch/u-boot/legacy/u-boot-radxa-rk35xx/rockchip-allow-passing-of-BL32-location-via-variable.patch diff --git a/config/boards/armsom-cm5-io.csc b/config/boards/armsom-cm5-io.csc index ec704cd4438f..5b955641c960 100644 --- a/config/boards/armsom-cm5-io.csc +++ b/config/boards/armsom-cm5-io.csc @@ -10,12 +10,6 @@ BOOT_SCENARIO="spl-blobs" IMAGE_PARTITION_TABLE="gpt" BOARD_MAINTAINER="" -function post_family_config_branch_vendor__armsom-cm5-io_use_vendor_uboot() { - display_alert "$BOARD" "vendor u-boot overrides for $BOARD / $BRANCH" "info" - - declare -g UBOOT_TARGET_MAP="BL31=$RKBIN_DIR/$BL31_BLOB TEE=$RKBIN_DIR/$BL32_BLOB spl/u-boot-spl.bin u-boot.dtb u-boot.itb;;idbloader.img u-boot.itb" -} - function post_family_tweaks__armsom-cm5-io_naming_audios() { display_alert "$BOARD" "Renaming armsom-cm5 audios" "info" diff --git a/config/boards/armsom-cm5-rpi-cm4-io.csc b/config/boards/armsom-cm5-rpi-cm4-io.csc index d130455a00e7..e462fc94a1b2 100644 --- a/config/boards/armsom-cm5-rpi-cm4-io.csc +++ b/config/boards/armsom-cm5-rpi-cm4-io.csc @@ -10,12 +10,6 @@ BOOT_SCENARIO="spl-blobs" IMAGE_PARTITION_TABLE="gpt" BOARD_MAINTAINER="" -function post_family_config_branch_vendor__armsom-cm5-rpi-cm4-io_use_vendor_uboot() { - display_alert "$BOARD" "vendor u-boot overrides for $BOARD / $BRANCH" "info" - - declare -g UBOOT_TARGET_MAP="BL31=$RKBIN_DIR/$BL31_BLOB TEE=$RKBIN_DIR/$BL32_BLOB spl/u-boot-spl.bin u-boot.dtb u-boot.itb;;idbloader.img u-boot.itb" -} - function post_family_tweaks__armsom-cm5-rpi-cm4-io_naming_audios() { display_alert "$BOARD" "Renaming armsom-cm5-rpi-cm4-io audios" "info" diff --git a/config/boards/armsom-sige5.csc b/config/boards/armsom-sige5.csc index 370f88a0f184..629028fa2b24 100644 --- a/config/boards/armsom-sige5.csc +++ b/config/boards/armsom-sige5.csc @@ -10,12 +10,6 @@ BOOT_SCENARIO="spl-blobs" IMAGE_PARTITION_TABLE="gpt" BOARD_MAINTAINER="" -function post_family_config_branch_vendor__armsom-sige7_use_vendor_uboot() { - display_alert "$BOARD" "vendor u-boot overrides for $BOARD / $BRANCH" "info" - - declare -g UBOOT_TARGET_MAP="BL31=$RKBIN_DIR/$BL31_BLOB TEE=$RKBIN_DIR/$BL32_BLOB spl/u-boot-spl.bin u-boot.dtb u-boot.itb;;idbloader.img u-boot.itb" -} - function post_family_tweaks__armsom-sige7_naming_audios() { display_alert "$BOARD" "Renaming armsom-sige7 audios" "info" diff --git a/config/sources/families/include/rockchip64_common.inc b/config/sources/families/include/rockchip64_common.inc index b35a6418914d..b669a6280efc 100644 --- a/config/sources/families/include/rockchip64_common.inc +++ b/config/sources/families/include/rockchip64_common.inc @@ -139,7 +139,6 @@ case "$BOOT_SOC" in BOOT_SCENARIO="${BOOT_SCENARIO:=spl-blobs}" DDR_BLOB="${DDR_BLOB:-"rk35/rk3576_ddr_lp4_2112MHz_lp5_2736MHz_v1.03.bin"}" BL31_BLOB="${BL31_BLOB:-"rk35/rk3576_bl31_v1.04.elf"}" - BL32_BLOB="${BL32_BLOB:-"rk35/rk3576_bl32_v1.01.bin"}" ;; rk3588) #CPUMAX undefined? diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/rockchip-allow-passing-of-BL32-location-via-variable.patch b/patch/u-boot/legacy/u-boot-radxa-rk35xx/rockchip-allow-passing-of-BL32-location-via-variable.patch deleted file mode 100644 index 1adbcac91748..000000000000 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/rockchip-allow-passing-of-BL32-location-via-variable.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/arch/arm/mach-rockchip/fit_nodes.sh b/arch/arm/mach-rockchip/fit_nodes.sh -index 9639a06e1c..ceee0ccc20 100755 ---- a/arch/arm/mach-rockchip/fit_nodes.sh -+++ b/arch/arm/mach-rockchip/fit_nodes.sh -@@ -180,7 +180,7 @@ function gen_bl32_node() - fi - fi - -- TEE="tee.bin" -+ TEE="${TEE:=tee.bin}" - echo " optee { - description = \"OP-TEE\"; - data = /incbin/(\"${TEE}${SUFFIX}\"); From d9b7000ea5f3bc41bd8e8bd0ef2a93298f3a46f0 Mon Sep 17 00:00:00 2001 From: amazingfate Date: Sun, 2 Feb 2025 15:21:40 +0800 Subject: [PATCH 29/33] armsom-sige5: add pd negotiation support to uboot --- .../add-u-boot-pd-negotiation-support.patch | 41 +++++++++++++++++++ .../defconfig/armsom-sige5-rk3576_defconfig | 3 ++ 2 files changed, 44 insertions(+) create mode 100644 patch/u-boot/legacy/u-boot-radxa-rk35xx/board_armsom-sige5/add-u-boot-pd-negotiation-support.patch diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/board_armsom-sige5/add-u-boot-pd-negotiation-support.patch b/patch/u-boot/legacy/u-boot-radxa-rk35xx/board_armsom-sige5/add-u-boot-pd-negotiation-support.patch new file mode 100644 index 000000000000..f4092b29ee57 --- /dev/null +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/board_armsom-sige5/add-u-boot-pd-negotiation-support.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: amazingfate +Date: Thu, 2 May 2024 01:45:23 +0800 +Subject: add u-boot pd negotiation support + +--- + drivers/power/power_delivery/tcpm.c | 4 ++-- + include/configs/rk3576_common.h | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/power/power_delivery/tcpm.c b/drivers/power/power_delivery/tcpm.c +index 22334c6230c4..1b94a401836a 100644 +--- a/drivers/power/power_delivery/tcpm.c ++++ b/drivers/power/power_delivery/tcpm.c +@@ -1390,8 +1390,8 @@ static void tcpm_pd_rx_handler(struct tcpm_port *port, + */ + if (!!(le16_to_cpu(msg->header) & PD_HEADER_DATA_ROLE) == + (port->data_role == TYPEC_HOST)) { +- printf("Data role mismatch, initiating error recovery\n"); +- tcpm_set_state(port, ERROR_RECOVERY, 0); ++ printf("Data role mismatch, hard resetting...\n"); ++ tcpm_set_state(port, HARD_RESET_SEND, 0); + } else { + if (cnt) + tcpm_pd_data_request(port, msg); +diff --git a/include/configs/rk3576_common.h b/include/configs/rk3576_common.h +index 549a2583c3ad..448ae2ec6ef0 100644 +--- a/include/configs/rk3576_common.h ++++ b/include/configs/rk3576_common.h +@@ -96,7 +96,7 @@ + #define CONFIG_USB_OHCI_NEW + #define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 1 + +-#define CONFIG_PREBOOT ++#define CONFIG_PREBOOT "charge_pd" + #define CONFIG_LIB_HW_RAND + + #endif +-- +Armbian + diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-sige5-rk3576_defconfig b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-sige5-rk3576_defconfig index e6ab7fffa007..96d9b13f00b1 100644 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-sige5-rk3576_defconfig +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/defconfig/armsom-sige5-rk3576_defconfig @@ -219,3 +219,6 @@ CONFIG_AVB_LIBAVB_USER=y CONFIG_RK_AVB_LIBAVB_USER=y CONFIG_ROCKCHIP_EARLY_DISTRO_DTB=y CONFIG_ROCKCHIP_EARLY_DISTRO_DTB_PATH="/boot/dtb/rockchip/rk3576-armsom-sige5.dtb" +CONFIG_CMD_CHARGE_DISPLAY=y +CONFIG_CMD_PMIC=y +CONFIG_CMD_REGULATOR=y From 06852a04a5e6d7515cf10fd4009d399e0908361b Mon Sep 17 00:00:00 2001 From: amazingfate Date: Tue, 11 Feb 2025 09:51:54 +0800 Subject: [PATCH 30/33] retro-lite-cm5: fix for latest radxa uboot --- .../legacy/u-boot-radxa-rk35xx/dt/rk3588s-retro-lite-cm5.dts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3588s-retro-lite-cm5.dts b/patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3588s-retro-lite-cm5.dts index 0e9c435159c2..92df7f285c96 100644 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3588s-retro-lite-cm5.dts +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/dt/rk3588s-retro-lite-cm5.dts @@ -5,7 +5,9 @@ */ /dts-v1/; -#include "rk3588s-radxa-cm5.dtsi" +#include "rk3588.dtsi" +#include "rk3588-u-boot.dtsi" +#include / { model = "Retro Lite CM5"; From 6ecc0b7e22518145f2607f7192815a97b945839e Mon Sep 17 00:00:00 2001 From: amazingfate Date: Tue, 11 Feb 2025 09:58:56 +0800 Subject: [PATCH 31/33] fxblox-rk1: add missing patch for latest radxa uboot --- .../0001-add-rk3588-fxblox-rk1-board.patch | 468 ++++++++++++++++++ 1 file changed, 468 insertions(+) create mode 100644 patch/u-boot/legacy/u-boot-radxa-rk35xx/0001-add-rk3588-fxblox-rk1-board.patch diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/0001-add-rk3588-fxblox-rk1-board.patch b/patch/u-boot/legacy/u-boot-radxa-rk35xx/0001-add-rk3588-fxblox-rk1-board.patch new file mode 100644 index 000000000000..2abd6653eeb7 --- /dev/null +++ b/patch/u-boot/legacy/u-boot-radxa-rk35xx/0001-add-rk3588-fxblox-rk1-board.patch @@ -0,0 +1,468 @@ +From 357924fe8fc6c7654aa39565785d8731f0750501 Mon Sep 17 00:00:00 2001 +From: mahdichi +Date: Fri, 25 Oct 2024 10:02:53 -0400 +Subject: [PATCH] add rk3588 fxblox-rk1 board + +Link: https://github.com/radxa/u-boot/pull/104 + +Signed-off-by: mahdichi +--- + arch/arm/dts/rk3588-fxblox-rk1.dts | 220 ++++++++++++++++++++++++++++ + configs/fxblox-rk1-rk3588_defconfig | 218 +++++++++++++++++++++++++++ + 2 files changed, 438 insertions(+) + create mode 100644 arch/arm/dts/rk3588-fxblox-rk1.dts + create mode 100644 configs/fxblox-rk1-rk3588_defconfig + +diff --git a/arch/arm/dts/rk3588-fxblox-rk1.dts b/arch/arm/dts/rk3588-fxblox-rk1.dts +new file mode 100644 +index 0000000000..ac598edd8c +--- /dev/null ++++ b/arch/arm/dts/rk3588-fxblox-rk1.dts +@@ -0,0 +1,220 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2021 Rockchip Electronics Co., Ltd ++ * ++ */ ++ ++/dts-v1/; ++#include "rk3588.dtsi" ++#include "rk3588-u-boot.dtsi" ++#include ++ ++/ { ++ model = "FxBlox RK1"; ++ compatible = "Functionland,fxblox-rk1", "rockchip,rk3588"; ++ ++ chosen { ++ stdout-path = &uart2; ++ u-boot,spl-boot-order = &spi_nor, &sdmmc, &sdhci, &spi_nand; ++ }; ++ ++ vcc12v_dcin: vcc12v-dcin { ++ u-boot,dm-pre-reloc; ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc12v_dcin"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ }; ++ ++ vcc5v0_sys: vcc5v0-sys { ++ u-boot,dm-pre-reloc; ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc12v_dcin>; ++ }; ++ ++ vcc3v3_pcie30: vcc3v3-pcie30 { ++ u-boot,dm-pre-reloc; ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_pcie30"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ enable-active-high; ++ gpio = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>; ++ regulator-boot-on; ++ regulator-always-on; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ vcc5v0_host: vcc5v0-host-regulator { ++ u-boot,dm-pre-reloc; ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_host"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ enable-active-high; ++ gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_HIGH>; ++ regulator-boot-on; ++ regulator-always-on; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc5v0_host_en>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ vbus5v0_typec: vbus5v0-typec { ++ u-boot,dm-pre-reloc; ++ compatible = "regulator-fixed"; ++ regulator-name = "vbus5v0_typec"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ enable-active-high; ++ gpio = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>; ++ regulator-boot-on; ++ regulator-always-on; ++ vin-supply = <&vcc5v0_sys>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&typec5v_pwren>; ++ }; ++ ++ led_red_reg: led-red-reg { ++ u-boot,dm-pre-reloc; ++ compatible = "regulator-fixed"; ++ regulator-name = "led_red_reg"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ enable-active-high; ++ gpio = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>; ++ regulator-boot-on; ++ regulator-always-on; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gpio_led_red>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ led_blue_reg: led-blue-reg { ++ u-boot,dm-pre-reloc; ++ compatible = "regulator-fixed"; ++ regulator-name = "led_blue_reg"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ enable-active-high; ++ gpio = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>; ++ regulator-boot-on; ++ regulator-always-on; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gpio_led_blue>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++}; ++ ++&pcie3x4 { ++ u-boot,dm-pre-reloc; ++ reset-gpios = <&gpio0 RK_PD0 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++}; ++ ++&pcie30phy { ++ u-boot,dm-pre-reloc; ++ status = "okay"; ++}; ++ ++&usb2phy2_grf { ++ u-boot,dm-pre-reloc; ++ status = "okay"; ++ phy-supply = <&vcc5v0_host>; ++}; ++ ++&u2phy2 { ++ u-boot,dm-pre-reloc; ++ status = "okay"; ++ phy-supply = <&vcc5v0_host>; ++}; ++ ++&u2phy2_host { ++ u-boot,dm-pre-reloc; ++ status = "okay"; ++ phy-supply = <&vcc5v0_host>; ++}; ++ ++&usb_host0_ehci { ++ u-boot,dm-pre-reloc; ++ status = "okay"; ++ vbus-supply= <&vbus5v0_typec>; ++}; ++ ++&usb_host0_ohci { ++ u-boot,dm-pre-reloc; ++ vbus-supply= <&vbus5v0_typec>; ++ status = "okay"; ++}; ++ ++&usb2phy0_grf { ++ u-boot,dm-pre-reloc; ++ status = "okay"; ++ phy-supply = <&vbus5v0_typec>; ++}; ++ ++&u2phy0 { ++ u-boot,dm-pre-reloc; ++ status = "okay"; ++ phy-supply = <&vbus5v0_typec>; ++}; ++ ++&u2phy0_otg { ++ u-boot,dm-pre-reloc; ++ status = "okay"; ++ phy-supply = <&vbus5v0_typec>; ++}; ++ ++&usbdp_phy0 { ++ u-boot,dm-pre-reloc; ++ status = "disable"; ++ phy-supply = <&vbus5v0_typec>; ++}; ++ ++&usbdrd3_0 { ++ u-boot,dm-pre-reloc; ++ vbus-supply= <&vbus5v0_typec>; ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3_0 { ++ u-boot,dm-pre-reloc; ++ dr_mode = "host"; ++ vbus-supply= <&vbus5v0_typec>; ++ status = "okay"; ++}; ++ ++&pinctrl { ++ usb { ++ u-boot,dm-pre-reloc; ++ vcc5v0_host_en: vcc5v0-host-en { ++ u-boot,dm-pre-reloc; ++ rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb-typec { ++ u-boot,dm-pre-reloc; ++ typec5v_pwren: typec5v-pwren { ++ u-boot,dm-pre-reloc; ++ rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ gpio_led { ++ gpio_led_red: gpio-led-red { ++ rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ gpio_led_blue: gpio-led-blue { ++ rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; +diff --git a/configs/fxblox-rk1-rk3588_defconfig b/configs/fxblox-rk1-rk3588_defconfig +new file mode 100644 +index 0000000000..da7dd82034 +--- /dev/null ++++ b/configs/fxblox-rk1-rk3588_defconfig +@@ -0,0 +1,218 @@ ++CONFIG_ARM=y ++CONFIG_ARM_CPU_SUSPEND=y ++CONFIG_ARCH_ROCKCHIP=y ++CONFIG_SPL_GPIO_SUPPORT=y ++CONFIG_SPL_LIBCOMMON_SUPPORT=y ++CONFIG_SPL_LIBGENERIC_SUPPORT=y ++CONFIG_SYS_MALLOC_F_LEN=0x80000 ++CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-rockchip/make_fit_atf.sh" ++CONFIG_ROCKCHIP_RK3588=y ++CONFIG_ROCKCHIP_BOOTDEV="mmc 0" ++CONFIG_ROCKCHIP_FIT_IMAGE=y ++CONFIG_ROCKCHIP_HWID_DTB=y ++CONFIG_ROCKCHIP_VENDOR_PARTITION=y ++CONFIG_USING_KERNEL_DTB_V2=y ++CONFIG_ROCKCHIP_FIT_IMAGE_PACK=y ++CONFIG_ROCKCHIP_NEW_IDB=y ++CONFIG_ROCKCHIP_EMMC_IOMUX=y ++CONFIG_LOADER_INI="RK3588MINIALL.ini" ++CONFIG_TRUST_INI="RK3588TRUST.ini" ++CONFIG_SPL_SERIAL_SUPPORT=y ++CONFIG_SPL_DRIVERS_MISC_SUPPORT=y ++CONFIG_TARGET_EVB_RK3588=y ++CONFIG_SPL_LIBDISK_SUPPORT=y ++CONFIG_SPL_SPI_FLASH_SUPPORT=y ++CONFIG_SPL_SPI_SUPPORT=y ++CONFIG_DEFAULT_DEVICE_TREE="rk3588-fxblox-rk1" ++CONFIG_DEBUG_UART=y ++CONFIG_FIT=y ++CONFIG_FIT_IMAGE_POST_PROCESS=y ++CONFIG_FIT_HW_CRYPTO=y ++CONFIG_SPL_LOAD_FIT=y ++CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y ++CONFIG_SPL_FIT_HW_CRYPTO=y ++# CONFIG_SPL_SYS_DCACHE_OFF is not set ++CONFIG_BOOTDELAY=1 ++# CONFIG_DISABLE_CONSOLE=y ++# CONFIG_SYS_CONSOLE_INFO_QUIET=y ++# CONFIG_DISPLAY_CPUINFO is not set ++CONFIG_ANDROID_BOOTLOADER=y ++CONFIG_ANDROID_AVB=y ++CONFIG_ANDROID_BOOT_IMAGE_HASH=y ++CONFIG_SPL_BOARD_INIT=y ++# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set ++# CONFIG_SPL_LEGACY_IMAGE_SUPPORT is not set ++CONFIG_SPL_SEPARATE_BSS=y ++CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y ++CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=0x1 ++CONFIG_SPL_MMC_WRITE=y ++CONFIG_SPL_MTD_SUPPORT=y ++CONFIG_SPL_ATF=y ++CONFIG_FASTBOOT_BUF_ADDR=0xc00800 ++CONFIG_FASTBOOT_BUF_SIZE=0x04000000 ++CONFIG_FASTBOOT_FLASH=y ++CONFIG_FASTBOOT_FLASH_MMC_DEV=0 ++CONFIG_CMD_BOOTZ=y ++CONFIG_CMD_DTIMG=y ++# CONFIG_CMD_ELF is not set ++# CONFIG_CMD_IMI is not set ++# CONFIG_CMD_IMLS is not set ++# CONFIG_CMD_XIMG is not set ++# CONFIG_CMD_LZMADEC is not set ++# CONFIG_CMD_UNZIP is not set ++# CONFIG_CMD_FLASH is not set ++# CONFIG_CMD_FPGA is not set ++CONFIG_CMD_GPT=y ++# CONFIG_CMD_LOADB is not set ++# CONFIG_CMD_LOADS is not set ++CONFIG_CMD_BOOT_ANDROID=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_PCI=y ++CONFIG_CMD_SF=y ++CONFIG_CMD_SPI=y ++CONFIG_CMD_USB=y ++CONFIG_CMD_USB_MASS_STORAGE=y ++# CONFIG_CMD_ITEST is not set ++# CONFIG_CMD_SETEXPR is not set ++CONFIG_CMD_TFTPPUT=y ++CONFIG_CMD_TFTP_BOOTM=y ++CONFIG_CMD_TFTP_FLASH=y ++# CONFIG_CMD_MISC is not set ++CONFIG_CMD_MTD_BLK=y ++# CONFIG_SPL_DOS_PARTITION is not set ++# CONFIG_ISO_PARTITION is not set ++CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64 ++CONFIG_SPL_OF_CONTROL=y ++CONFIG_SPL_DTB_MINIMUM=y ++CONFIG_OF_LIVE=y ++CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" ++# CONFIG_NET_TFTP_VARS is not set ++CONFIG_REGMAP=y ++CONFIG_SPL_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_SPL_SYSCON=y ++# CONFIG_SARADC_ROCKCHIP is not set ++CONFIG_SARADC_ROCKCHIP_V2=y ++CONFIG_CLK=y ++CONFIG_SPL_CLK=y ++CONFIG_CLK_SCMI=y ++CONFIG_SPL_CLK_SCMI=y ++CONFIG_DM_CRYPTO=y ++CONFIG_SPL_DM_CRYPTO=y ++CONFIG_ROCKCHIP_CRYPTO_V2=y ++CONFIG_SPL_ROCKCHIP_CRYPTO_V2=y ++CONFIG_DM_RNG=y ++CONFIG_RNG_ROCKCHIP=y ++CONFIG_SCMI_FIRMWARE=y ++CONFIG_SPL_SCMI_FIRMWARE=y ++CONFIG_ROCKCHIP_GPIO=y ++CONFIG_ROCKCHIP_GPIO_V2=y ++CONFIG_SYS_I2C_ROCKCHIP=y ++CONFIG_DM_KEY=y ++CONFIG_ADC_KEY=y ++CONFIG_MISC=y ++CONFIG_SPL_MISC=y ++CONFIG_MISC_DECOMPRESS=y ++CONFIG_SPL_MISC_DECOMPRESS=y ++CONFIG_ROCKCHIP_OTP=y ++CONFIG_ROCKCHIP_HW_DECOMPRESS=y ++CONFIG_SPL_ROCKCHIP_HW_DECOMPRESS=y ++CONFIG_SPL_ROCKCHIP_SECURE_OTP=y ++CONFIG_MMC_DW=y ++CONFIG_MMC_DW_ROCKCHIP=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_SDMA=y ++CONFIG_MMC_SDHCI_ROCKCHIP=y ++CONFIG_MTD=y ++CONFIG_MTD_BLK=y ++CONFIG_MTD_DEVICE=y ++CONFIG_NAND=y ++CONFIG_MTD_SPI_NAND=y ++CONFIG_SPI_FLASH=y ++CONFIG_SF_DEFAULT_SPEED=80000000 ++CONFIG_SPI_FLASH_EON=y ++CONFIG_SPI_FLASH_GIGADEVICE=y ++CONFIG_SPI_FLASH_MACRONIX=y ++CONFIG_SPI_FLASH_SST=y ++CONFIG_SPI_FLASH_WINBOND=y ++CONFIG_SPI_FLASH_XMC=y ++CONFIG_SPI_FLASH_XTX=y ++CONFIG_SPI_FLASH_MTD=y ++CONFIG_DM_ETH=y ++CONFIG_DM_ETH_PHY=y ++CONFIG_DWC_ETH_QOS=y ++CONFIG_GMAC_ROCKCHIP=y ++CONFIG_NVME=y ++CONFIG_PCI=y ++CONFIG_DM_PCI=y ++CONFIG_DM_PCI_COMPAT=y ++CONFIG_PCIE_DW_ROCKCHIP=y ++CONFIG_PHY_ROCKCHIP_INNO_USB2=y ++CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX=y ++CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y ++CONFIG_PINCTRL=y ++CONFIG_SPL_PINCTRL=y ++CONFIG_DM_PMIC=y ++CONFIG_PMIC_SPI_RK8XX=y ++CONFIG_REGULATOR_PWM=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_DM_REGULATOR_GPIO=y ++CONFIG_REGULATOR_RK860X=y ++CONFIG_REGULATOR_RK806=y ++CONFIG_PWM_ROCKCHIP=y ++CONFIG_RAM=y ++CONFIG_SPL_RAM=y ++CONFIG_TPL_RAM=y ++CONFIG_ROCKCHIP_SDRAM_COMMON=y ++CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE=0 ++CONFIG_DM_RESET=y ++CONFIG_SPL_DM_RESET=y ++CONFIG_SPL_RESET_ROCKCHIP=y ++CONFIG_BAUDRATE=1500000 ++CONFIG_DEBUG_UART_BASE=0xFEB50000 ++CONFIG_DEBUG_UART_CLOCK=24000000 ++CONFIG_DEBUG_UART_SHIFT=2 ++CONFIG_ROCKCHIP_SPI=y ++CONFIG_ROCKCHIP_SFC=y ++CONFIG_SYSRESET=y ++CONFIG_USB=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_DWC3=y ++CONFIG_USB_XHCI_PCI=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_GENERIC=y ++CONFIG_USB_OHCI_HCD=y ++CONFIG_USB_OHCI_GENERIC=y ++CONFIG_USB_DWC3=y ++CONFIG_USB_DWC3_GADGET=y ++CONFIG_USB_DWC3_GENERIC=y ++CONFIG_USB_STORAGE=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_GADGET_MANUFACTURER="Rockchip" ++CONFIG_USB_GADGET_VENDOR_NUM=0x2207 ++CONFIG_USB_GADGET_PRODUCT_NUM=0x350a ++CONFIG_USB_GADGET_DOWNLOAD=y ++CONFIG_DM_VIDEO=y ++CONFIG_DISPLAY=y ++CONFIG_DRM_ROCKCHIP=y ++CONFIG_DRM_ROCKCHIP_DW_MIPI_DSI2=y ++CONFIG_DRM_ROCKCHIP_ANALOGIX_DP=y ++CONFIG_DRM_ROCKCHIP_SAMSUNG_MIPI_DCPHY=y ++CONFIG_USE_TINY_PRINTF=y ++CONFIG_LIB_RAND=y ++CONFIG_SPL_TINY_MEMSET=y ++CONFIG_RSA=y ++CONFIG_SPL_RSA=y ++CONFIG_RSA_N_SIZE=0x200 ++CONFIG_RSA_E_SIZE=0x10 ++CONFIG_RSA_C_SIZE=0x20 ++CONFIG_LZ4=y ++CONFIG_ERRNO_STR=y ++# CONFIG_EFI_LOADER is not set ++CONFIG_AVB_LIBAVB=y ++CONFIG_AVB_LIBAVB_AB=y ++CONFIG_AVB_LIBAVB_ATX=y ++CONFIG_AVB_LIBAVB_USER=y ++CONFIG_RK_AVB_LIBAVB_USER=y ++CONFIG_OPTEE_CLIENT=y ++CONFIG_OPTEE_V2=y +-- +2.43.0 + From 3851e940bff59309d5d6c18f175a69fb0d966cda Mon Sep 17 00:00:00 2001 From: Igor Pecovnik Date: Tue, 11 Feb 2025 13:28:50 +0100 Subject: [PATCH 32/33] Cosmetical: switch edge and current kernel order, so that current shows as primary When using TUI, this is important. --- config/boards/armsom-sige7.csc | 2 +- config/boards/bananapim7.conf | 2 +- config/boards/cm3588-nas.csc | 2 +- config/boards/indiedroid-nova.csc | 2 +- config/boards/khadas-edge2.conf | 2 +- config/boards/nanopct6-lts.conf | 2 +- config/boards/nanopct6.conf | 2 +- config/boards/nanopi-m6.conf | 2 +- config/boards/nanopi-r6c.csc | 2 +- config/boards/nanopi-r6s.conf | 2 +- config/boards/orangepi5-plus.conf | 2 +- config/boards/orangepi5.conf | 2 +- config/boards/radxa-e25.csc | 2 +- config/boards/rock-3a.conf | 2 +- config/boards/rock-5a.conf | 2 +- config/boards/rock-5b.conf | 2 +- config/boards/station-m2.csc | 2 +- config/boards/turing-rk1.csc | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/config/boards/armsom-sige7.csc b/config/boards/armsom-sige7.csc index 0a9ac06fc8c5..908b0d7f7c4f 100644 --- a/config/boards/armsom-sige7.csc +++ b/config/boards/armsom-sige7.csc @@ -3,7 +3,7 @@ BOARD_NAME="ArmSoM Sige7" BOARDFAMILY="rockchip-rk3588" BOARD_MAINTAINER="" BOOTCONFIG="armsom-sige7-rk3588_defconfig" -KERNEL_TARGET="edge,current,vendor" +KERNEL_TARGET="current,edge,vendor" FULL_DESKTOP="yes" BOOT_LOGO="desktop" BOOT_FDT_FILE="rockchip/rk3588-armsom-sige7.dtb" diff --git a/config/boards/bananapim7.conf b/config/boards/bananapim7.conf index 42f188f445ae..e3043386f627 100644 --- a/config/boards/bananapim7.conf +++ b/config/boards/bananapim7.conf @@ -3,6 +3,6 @@ BOARD_NAME="Banana Pi M7" BOARD_MAINTAINER="amazingfate" BOOT_FDT_FILE="rockchip/rk3588-bananapi-m7.dtb" # Those are included in armsom-sige7.csc, but this file is parsed directly by the JSON matrix generator and thus those need to be in here -KERNEL_TARGET="edge,current,vendor" +KERNEL_TARGET="current,edge,vendor" KERNEL_TEST_TARGET="vendor,current" BOARDFAMILY="rockchip-rk3588" diff --git a/config/boards/cm3588-nas.csc b/config/boards/cm3588-nas.csc index 2226389831ed..1876111ff0b7 100644 --- a/config/boards/cm3588-nas.csc +++ b/config/boards/cm3588-nas.csc @@ -4,7 +4,7 @@ BOARDFAMILY="rockchip-rk3588" BOARD_MAINTAINER="ColorfulRhino" BOOTCONFIG="cm3588-nas-rk3588_defconfig" # Mainline defconfig, enables booting from NVMe BOOT_SOC="rk3588" -KERNEL_TARGET="edge,current,vendor" +KERNEL_TARGET="current,edge,vendor" FULL_DESKTOP="yes" BOOT_LOGO="desktop" IMAGE_PARTITION_TABLE="gpt" diff --git a/config/boards/indiedroid-nova.csc b/config/boards/indiedroid-nova.csc index fbd90036df12..1b2e1b8050f0 100644 --- a/config/boards/indiedroid-nova.csc +++ b/config/boards/indiedroid-nova.csc @@ -4,7 +4,7 @@ declare -g BOARD_MAINTAINER="lanefu" declare -g BOARDFAMILY="rockchip-rk3588" declare -g BOOTCONFIG="indiedroid_defconfig" # vendor name, not standard, see hook below, set BOOT_SOC below to compensate declare -g BOOT_SOC="rk3588" -declare -g KERNEL_TARGET="edge,current,vendor" +declare -g KERNEL_TARGET="current,edge,vendor" declare -g FULL_DESKTOP="yes" declare -g BOOT_LOGO="desktop" declare -g BOOT_FDT_FILE="rockchip/rk3588s-indiedroid-nova.dtb" diff --git a/config/boards/khadas-edge2.conf b/config/boards/khadas-edge2.conf index bb9fccfd63fe..d64f74aca554 100644 --- a/config/boards/khadas-edge2.conf +++ b/config/boards/khadas-edge2.conf @@ -3,7 +3,7 @@ declare -g BOARD_NAME="Khadas Edge2" declare -g BOARDFAMILY="rockchip-rk3588" declare -g BOARD_MAINTAINER="efectn" declare -g BOOT_SOC="rk3588" # Just to avoid errors in rockchip64_commmon -declare -g KERNEL_TARGET="edge,current,vendor" +declare -g KERNEL_TARGET="current,edge,vendor" declare -g KERNEL_TEST_TARGET="vendor,current" declare -g IMAGE_PARTITION_TABLE="gpt" declare -g KERNEL_UPGRADE_FREEZE="vendor-rk35xx@24.8.1" diff --git a/config/boards/nanopct6-lts.conf b/config/boards/nanopct6-lts.conf index b216d281ec51..d4b8f12e8583 100644 --- a/config/boards/nanopct6-lts.conf +++ b/config/boards/nanopct6-lts.conf @@ -5,5 +5,5 @@ BOARD_NAME="NanoPC T6 LTS" BOARDFAMILY="rockchip-rk3588" BOARD_MAINTAINER="SuperKali Tonymac32" BOOT_FDT_FILE="rockchip/rk3588-nanopc-t6-lts.dtb" # As opposed to "rockchip/rk3588-nanopc-t6.dtb" for the non-LTS version -KERNEL_TARGET="edge,current,vendor" +KERNEL_TARGET="current,edge,vendor" KERNEL_TEST_TARGET="vendor,current" diff --git a/config/boards/nanopct6.conf b/config/boards/nanopct6.conf index aff6802de595..9e17d2bd0915 100644 --- a/config/boards/nanopct6.conf +++ b/config/boards/nanopct6.conf @@ -4,7 +4,7 @@ BOARDFAMILY="rockchip-rk3588" BOARD_MAINTAINER="SuperKali Tonymac32" BOOTCONFIG="nanopc_t6_defconfig" # vendor name, not standard, see hook below, set BOOT_SOC below to compensate BOOT_SOC="rk3588" -KERNEL_TARGET="edge,current,vendor" +KERNEL_TARGET="current,edge,vendor" KERNEL_TEST_TARGET="vendor,current" FULL_DESKTOP="yes" BOOT_LOGO="desktop" diff --git a/config/boards/nanopi-m6.conf b/config/boards/nanopi-m6.conf index fbd7b97285fa..abf93a6f629f 100644 --- a/config/boards/nanopi-m6.conf +++ b/config/boards/nanopi-m6.conf @@ -4,7 +4,7 @@ BOARDFAMILY="rockchip-rk3588" BOARD_MAINTAINER="efectn" BOOTCONFIG="nanopi-m6-rk3588s_defconfig" # vendor name, not standard, see hook below, set BOOT_SOC below to compensate BOOT_SOC="rk3588" -KERNEL_TARGET="edge,current,vendor" +KERNEL_TARGET="current,edge,vendor" KERNEL_TEST_TARGET="vendor,current" FULL_DESKTOP="yes" BOOT_LOGO="desktop" diff --git a/config/boards/nanopi-r6c.csc b/config/boards/nanopi-r6c.csc index 3be3d7e36ee7..aa1f20f7247f 100644 --- a/config/boards/nanopi-r6c.csc +++ b/config/boards/nanopi-r6c.csc @@ -4,7 +4,7 @@ BOARDFAMILY="rockchip-rk3588" BOARD_MAINTAINER="ColorfulRhino" BOOTCONFIG="nanopi-r6c-rk3588s_defconfig" # Mainline defconfig, enables booting from NVMe BOOT_SOC="rk3588" -KERNEL_TARGET="edge,current,vendor" +KERNEL_TARGET="current,edge,vendor" FULL_DESKTOP="yes" BOOT_LOGO="desktop" IMAGE_PARTITION_TABLE="gpt" diff --git a/config/boards/nanopi-r6s.conf b/config/boards/nanopi-r6s.conf index c8fde5a4e305..71eef1820ef4 100644 --- a/config/boards/nanopi-r6s.conf +++ b/config/boards/nanopi-r6s.conf @@ -4,7 +4,7 @@ BOARDFAMILY="rockchip-rk3588" BOARD_MAINTAINER="efectn" BOOTCONFIG="nanopi-r6s-rk3588s_defconfig" # Mainline defconfig BOOT_SOC="rk3588" -KERNEL_TARGET="edge,current,vendor" +KERNEL_TARGET="current,edge,vendor" KERNEL_TEST_TARGET="vendor,current" FULL_DESKTOP="yes" BOOT_LOGO="desktop" diff --git a/config/boards/orangepi5-plus.conf b/config/boards/orangepi5-plus.conf index 141e6153d49f..f2aa79cb14a3 100644 --- a/config/boards/orangepi5-plus.conf +++ b/config/boards/orangepi5-plus.conf @@ -4,7 +4,7 @@ BOARDFAMILY="rockchip-rk3588" BOARD_MAINTAINER="alexl83" BOOTCONFIG="orangepi-5-plus-rk3588_defconfig" # vendor name, not standard, see hook below, set BOOT_SOC below to compensate BOOT_SOC="rk3588" -KERNEL_TARGET="edge,current,vendor" +KERNEL_TARGET="current,edge,vendor" KERNEL_TEST_TARGET="vendor,current" FULL_DESKTOP="yes" BOOT_LOGO="desktop" diff --git a/config/boards/orangepi5.conf b/config/boards/orangepi5.conf index f67170646f7e..c49518be0ad3 100644 --- a/config/boards/orangepi5.conf +++ b/config/boards/orangepi5.conf @@ -5,7 +5,7 @@ BOARD_MAINTAINER="efectn" BOOTCONFIG="orangepi-5-rk3588s_defconfig" # vendor name, not standard, see hook below, set BOOT_SOC below to compensate BOOTCONFIG_SATA="orangepi-5-sata-rk3588s_defconfig" BOOT_SOC="rk3588" -KERNEL_TARGET="edge,current,vendor" +KERNEL_TARGET="current,edge,vendor" KERNEL_TEST_TARGET="vendor,current" FULL_DESKTOP="yes" BOOT_LOGO="desktop" diff --git a/config/boards/radxa-e25.csc b/config/boards/radxa-e25.csc index 7ad93fe811d0..4fda6bb92ebc 100644 --- a/config/boards/radxa-e25.csc +++ b/config/boards/radxa-e25.csc @@ -3,7 +3,7 @@ BOARD_NAME="Radxa E25" BOARDFAMILY="rk35xx" BOARD_MAINTAINER="krachlatte" BOOTCONFIG="radxa-e25-rk3568_defconfig" -KERNEL_TARGET="edge,current,vendor" +KERNEL_TARGET="current,edge,vendor" KERNEL_TEST_TARGET="current" FULL_DESKTOP="yes" BOOT_LOGO="desktop" diff --git a/config/boards/rock-3a.conf b/config/boards/rock-3a.conf index 368b6fa2f6c6..59d3556133d4 100644 --- a/config/boards/rock-3a.conf +++ b/config/boards/rock-3a.conf @@ -4,7 +4,7 @@ BOARDFAMILY="rk35xx" BOARD_MAINTAINER="ZazaBR amazingfate catalinii vamzii" BOOTCONFIG="rock-3a-rk3568_defconfig" BOOTCONFIG_SATA="rock-3a-sata-rk3568_defconfig" -KERNEL_TARGET="edge,current,vendor" +KERNEL_TARGET="current,edge,vendor" KERNEL_TEST_TARGET="current" FULL_DESKTOP="yes" BOOT_LOGO="desktop" diff --git a/config/boards/rock-5a.conf b/config/boards/rock-5a.conf index 0047cd7ed33e..648b6bbd6c4a 100644 --- a/config/boards/rock-5a.conf +++ b/config/boards/rock-5a.conf @@ -3,7 +3,7 @@ BOARD_NAME="Rock 5A" BOARDFAMILY="rockchip-rk3588" BOARD_MAINTAINER="amazingfate" BOOTCONFIG="rock-5a-rk3588s_defconfig" -KERNEL_TARGET="edge,current,vendor" +KERNEL_TARGET="current,edge,vendor" KERNEL_TEST_TARGET="vendor,current" FULL_DESKTOP="yes" BOOT_LOGO="desktop" diff --git a/config/boards/rock-5b.conf b/config/boards/rock-5b.conf index e961d1568f5d..46da1f0c2d46 100644 --- a/config/boards/rock-5b.conf +++ b/config/boards/rock-5b.conf @@ -3,7 +3,7 @@ BOARD_NAME="Rock 5B" BOARDFAMILY="rockchip-rk3588" BOARD_MAINTAINER="amazingfate linhz0hz" BOOTCONFIG="rock-5b-rk3588_defconfig" -KERNEL_TARGET="edge,current,vendor" +KERNEL_TARGET="current,edge,vendor" KERNEL_TEST_TARGET="vendor,current" FULL_DESKTOP="yes" BOOT_LOGO="desktop" diff --git a/config/boards/station-m2.csc b/config/boards/station-m2.csc index b3f9630ea6fa..fb41692032f0 100644 --- a/config/boards/station-m2.csc +++ b/config/boards/station-m2.csc @@ -3,7 +3,7 @@ BOARD_NAME="Station M2" BOARDFAMILY="rk35xx" BOARD_MAINTAINER="" BOOTCONFIG="station-m2-rk3566_defconfig" -KERNEL_TARGET="edge,current,vendor" +KERNEL_TARGET="current,edge,vendor" KERNEL_TEST_TARGET="current" FULL_DESKTOP="yes" BOOT_LOGO="desktop" diff --git a/config/boards/turing-rk1.csc b/config/boards/turing-rk1.csc index 8339e9acbe6d..e264c734922f 100644 --- a/config/boards/turing-rk1.csc +++ b/config/boards/turing-rk1.csc @@ -4,7 +4,7 @@ BOARDFAMILY="rockchip-rk3588" BOARD_MAINTAINER="" BOOTCONFIG="turing-rk1-rk3588_defconfig" BOOT_SOC="rk3588" -KERNEL_TARGET="edge,current,vendor" +KERNEL_TARGET="current,edge,vendor" KERNEL_TEST_TARGET="vendor,current" FULL_DESKTOP="yes" BOOT_LOGO="desktop" From 65faeba83e4fab32ac3af35625e6df45396e61bb Mon Sep 17 00:00:00 2001 From: amazingfate Date: Wed, 12 Feb 2025 00:05:20 +0800 Subject: [PATCH 33/33] Revert "fxblox-rk1: add missing patch for latest radxa uboot" This reverts commit 6ecc0b7e22518145f2607f7192815a97b945839e. --- .../0001-add-rk3588-fxblox-rk1-board.patch | 468 ------------------ 1 file changed, 468 deletions(-) delete mode 100644 patch/u-boot/legacy/u-boot-radxa-rk35xx/0001-add-rk3588-fxblox-rk1-board.patch diff --git a/patch/u-boot/legacy/u-boot-radxa-rk35xx/0001-add-rk3588-fxblox-rk1-board.patch b/patch/u-boot/legacy/u-boot-radxa-rk35xx/0001-add-rk3588-fxblox-rk1-board.patch deleted file mode 100644 index 2abd6653eeb7..000000000000 --- a/patch/u-boot/legacy/u-boot-radxa-rk35xx/0001-add-rk3588-fxblox-rk1-board.patch +++ /dev/null @@ -1,468 +0,0 @@ -From 357924fe8fc6c7654aa39565785d8731f0750501 Mon Sep 17 00:00:00 2001 -From: mahdichi -Date: Fri, 25 Oct 2024 10:02:53 -0400 -Subject: [PATCH] add rk3588 fxblox-rk1 board - -Link: https://github.com/radxa/u-boot/pull/104 - -Signed-off-by: mahdichi ---- - arch/arm/dts/rk3588-fxblox-rk1.dts | 220 ++++++++++++++++++++++++++++ - configs/fxblox-rk1-rk3588_defconfig | 218 +++++++++++++++++++++++++++ - 2 files changed, 438 insertions(+) - create mode 100644 arch/arm/dts/rk3588-fxblox-rk1.dts - create mode 100644 configs/fxblox-rk1-rk3588_defconfig - -diff --git a/arch/arm/dts/rk3588-fxblox-rk1.dts b/arch/arm/dts/rk3588-fxblox-rk1.dts -new file mode 100644 -index 0000000000..ac598edd8c ---- /dev/null -+++ b/arch/arm/dts/rk3588-fxblox-rk1.dts -@@ -0,0 +1,220 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd -+ * -+ */ -+ -+/dts-v1/; -+#include "rk3588.dtsi" -+#include "rk3588-u-boot.dtsi" -+#include -+ -+/ { -+ model = "FxBlox RK1"; -+ compatible = "Functionland,fxblox-rk1", "rockchip,rk3588"; -+ -+ chosen { -+ stdout-path = &uart2; -+ u-boot,spl-boot-order = &spi_nor, &sdmmc, &sdhci, &spi_nand; -+ }; -+ -+ vcc12v_dcin: vcc12v-dcin { -+ u-boot,dm-pre-reloc; -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc12v_dcin"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <12000000>; -+ regulator-max-microvolt = <12000000>; -+ }; -+ -+ vcc5v0_sys: vcc5v0-sys { -+ u-boot,dm-pre-reloc; -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_sys"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ vin-supply = <&vcc12v_dcin>; -+ }; -+ -+ vcc3v3_pcie30: vcc3v3-pcie30 { -+ u-boot,dm-pre-reloc; -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc3v3_pcie30"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ enable-active-high; -+ gpio = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>; -+ regulator-boot-on; -+ regulator-always-on; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ vcc5v0_host: vcc5v0-host-regulator { -+ u-boot,dm-pre-reloc; -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc5v0_host"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ enable-active-high; -+ gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_HIGH>; -+ regulator-boot-on; -+ regulator-always-on; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vcc5v0_host_en>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ vbus5v0_typec: vbus5v0-typec { -+ u-boot,dm-pre-reloc; -+ compatible = "regulator-fixed"; -+ regulator-name = "vbus5v0_typec"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ enable-active-high; -+ gpio = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>; -+ regulator-boot-on; -+ regulator-always-on; -+ vin-supply = <&vcc5v0_sys>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&typec5v_pwren>; -+ }; -+ -+ led_red_reg: led-red-reg { -+ u-boot,dm-pre-reloc; -+ compatible = "regulator-fixed"; -+ regulator-name = "led_red_reg"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ enable-active-high; -+ gpio = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>; -+ regulator-boot-on; -+ regulator-always-on; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&gpio_led_red>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+ -+ led_blue_reg: led-blue-reg { -+ u-boot,dm-pre-reloc; -+ compatible = "regulator-fixed"; -+ regulator-name = "led_blue_reg"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ enable-active-high; -+ gpio = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>; -+ regulator-boot-on; -+ regulator-always-on; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&gpio_led_blue>; -+ vin-supply = <&vcc5v0_sys>; -+ }; -+}; -+ -+&pcie3x4 { -+ u-boot,dm-pre-reloc; -+ reset-gpios = <&gpio0 RK_PD0 GPIO_ACTIVE_HIGH>; -+ status = "okay"; -+}; -+ -+&pcie30phy { -+ u-boot,dm-pre-reloc; -+ status = "okay"; -+}; -+ -+&usb2phy2_grf { -+ u-boot,dm-pre-reloc; -+ status = "okay"; -+ phy-supply = <&vcc5v0_host>; -+}; -+ -+&u2phy2 { -+ u-boot,dm-pre-reloc; -+ status = "okay"; -+ phy-supply = <&vcc5v0_host>; -+}; -+ -+&u2phy2_host { -+ u-boot,dm-pre-reloc; -+ status = "okay"; -+ phy-supply = <&vcc5v0_host>; -+}; -+ -+&usb_host0_ehci { -+ u-boot,dm-pre-reloc; -+ status = "okay"; -+ vbus-supply= <&vbus5v0_typec>; -+}; -+ -+&usb_host0_ohci { -+ u-boot,dm-pre-reloc; -+ vbus-supply= <&vbus5v0_typec>; -+ status = "okay"; -+}; -+ -+&usb2phy0_grf { -+ u-boot,dm-pre-reloc; -+ status = "okay"; -+ phy-supply = <&vbus5v0_typec>; -+}; -+ -+&u2phy0 { -+ u-boot,dm-pre-reloc; -+ status = "okay"; -+ phy-supply = <&vbus5v0_typec>; -+}; -+ -+&u2phy0_otg { -+ u-boot,dm-pre-reloc; -+ status = "okay"; -+ phy-supply = <&vbus5v0_typec>; -+}; -+ -+&usbdp_phy0 { -+ u-boot,dm-pre-reloc; -+ status = "disable"; -+ phy-supply = <&vbus5v0_typec>; -+}; -+ -+&usbdrd3_0 { -+ u-boot,dm-pre-reloc; -+ vbus-supply= <&vbus5v0_typec>; -+ status = "okay"; -+}; -+ -+&usbdrd_dwc3_0 { -+ u-boot,dm-pre-reloc; -+ dr_mode = "host"; -+ vbus-supply= <&vbus5v0_typec>; -+ status = "okay"; -+}; -+ -+&pinctrl { -+ usb { -+ u-boot,dm-pre-reloc; -+ vcc5v0_host_en: vcc5v0-host-en { -+ u-boot,dm-pre-reloc; -+ rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ usb-typec { -+ u-boot,dm-pre-reloc; -+ typec5v_pwren: typec5v-pwren { -+ u-boot,dm-pre-reloc; -+ rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ gpio_led { -+ gpio_led_red: gpio-led-red { -+ rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ gpio_led_blue: gpio-led-blue { -+ rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+}; -diff --git a/configs/fxblox-rk1-rk3588_defconfig b/configs/fxblox-rk1-rk3588_defconfig -new file mode 100644 -index 0000000000..da7dd82034 ---- /dev/null -+++ b/configs/fxblox-rk1-rk3588_defconfig -@@ -0,0 +1,218 @@ -+CONFIG_ARM=y -+CONFIG_ARM_CPU_SUSPEND=y -+CONFIG_ARCH_ROCKCHIP=y -+CONFIG_SPL_GPIO_SUPPORT=y -+CONFIG_SPL_LIBCOMMON_SUPPORT=y -+CONFIG_SPL_LIBGENERIC_SUPPORT=y -+CONFIG_SYS_MALLOC_F_LEN=0x80000 -+CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-rockchip/make_fit_atf.sh" -+CONFIG_ROCKCHIP_RK3588=y -+CONFIG_ROCKCHIP_BOOTDEV="mmc 0" -+CONFIG_ROCKCHIP_FIT_IMAGE=y -+CONFIG_ROCKCHIP_HWID_DTB=y -+CONFIG_ROCKCHIP_VENDOR_PARTITION=y -+CONFIG_USING_KERNEL_DTB_V2=y -+CONFIG_ROCKCHIP_FIT_IMAGE_PACK=y -+CONFIG_ROCKCHIP_NEW_IDB=y -+CONFIG_ROCKCHIP_EMMC_IOMUX=y -+CONFIG_LOADER_INI="RK3588MINIALL.ini" -+CONFIG_TRUST_INI="RK3588TRUST.ini" -+CONFIG_SPL_SERIAL_SUPPORT=y -+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y -+CONFIG_TARGET_EVB_RK3588=y -+CONFIG_SPL_LIBDISK_SUPPORT=y -+CONFIG_SPL_SPI_FLASH_SUPPORT=y -+CONFIG_SPL_SPI_SUPPORT=y -+CONFIG_DEFAULT_DEVICE_TREE="rk3588-fxblox-rk1" -+CONFIG_DEBUG_UART=y -+CONFIG_FIT=y -+CONFIG_FIT_IMAGE_POST_PROCESS=y -+CONFIG_FIT_HW_CRYPTO=y -+CONFIG_SPL_LOAD_FIT=y -+CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y -+CONFIG_SPL_FIT_HW_CRYPTO=y -+# CONFIG_SPL_SYS_DCACHE_OFF is not set -+CONFIG_BOOTDELAY=1 -+# CONFIG_DISABLE_CONSOLE=y -+# CONFIG_SYS_CONSOLE_INFO_QUIET=y -+# CONFIG_DISPLAY_CPUINFO is not set -+CONFIG_ANDROID_BOOTLOADER=y -+CONFIG_ANDROID_AVB=y -+CONFIG_ANDROID_BOOT_IMAGE_HASH=y -+CONFIG_SPL_BOARD_INIT=y -+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set -+# CONFIG_SPL_LEGACY_IMAGE_SUPPORT is not set -+CONFIG_SPL_SEPARATE_BSS=y -+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y -+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=0x1 -+CONFIG_SPL_MMC_WRITE=y -+CONFIG_SPL_MTD_SUPPORT=y -+CONFIG_SPL_ATF=y -+CONFIG_FASTBOOT_BUF_ADDR=0xc00800 -+CONFIG_FASTBOOT_BUF_SIZE=0x04000000 -+CONFIG_FASTBOOT_FLASH=y -+CONFIG_FASTBOOT_FLASH_MMC_DEV=0 -+CONFIG_CMD_BOOTZ=y -+CONFIG_CMD_DTIMG=y -+# CONFIG_CMD_ELF is not set -+# CONFIG_CMD_IMI is not set -+# CONFIG_CMD_IMLS is not set -+# CONFIG_CMD_XIMG is not set -+# CONFIG_CMD_LZMADEC is not set -+# CONFIG_CMD_UNZIP is not set -+# CONFIG_CMD_FLASH is not set -+# CONFIG_CMD_FPGA is not set -+CONFIG_CMD_GPT=y -+# CONFIG_CMD_LOADB is not set -+# CONFIG_CMD_LOADS is not set -+CONFIG_CMD_BOOT_ANDROID=y -+CONFIG_CMD_MMC=y -+CONFIG_CMD_PCI=y -+CONFIG_CMD_SF=y -+CONFIG_CMD_SPI=y -+CONFIG_CMD_USB=y -+CONFIG_CMD_USB_MASS_STORAGE=y -+# CONFIG_CMD_ITEST is not set -+# CONFIG_CMD_SETEXPR is not set -+CONFIG_CMD_TFTPPUT=y -+CONFIG_CMD_TFTP_BOOTM=y -+CONFIG_CMD_TFTP_FLASH=y -+# CONFIG_CMD_MISC is not set -+CONFIG_CMD_MTD_BLK=y -+# CONFIG_SPL_DOS_PARTITION is not set -+# CONFIG_ISO_PARTITION is not set -+CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64 -+CONFIG_SPL_OF_CONTROL=y -+CONFIG_SPL_DTB_MINIMUM=y -+CONFIG_OF_LIVE=y -+CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" -+# CONFIG_NET_TFTP_VARS is not set -+CONFIG_REGMAP=y -+CONFIG_SPL_REGMAP=y -+CONFIG_SYSCON=y -+CONFIG_SPL_SYSCON=y -+# CONFIG_SARADC_ROCKCHIP is not set -+CONFIG_SARADC_ROCKCHIP_V2=y -+CONFIG_CLK=y -+CONFIG_SPL_CLK=y -+CONFIG_CLK_SCMI=y -+CONFIG_SPL_CLK_SCMI=y -+CONFIG_DM_CRYPTO=y -+CONFIG_SPL_DM_CRYPTO=y -+CONFIG_ROCKCHIP_CRYPTO_V2=y -+CONFIG_SPL_ROCKCHIP_CRYPTO_V2=y -+CONFIG_DM_RNG=y -+CONFIG_RNG_ROCKCHIP=y -+CONFIG_SCMI_FIRMWARE=y -+CONFIG_SPL_SCMI_FIRMWARE=y -+CONFIG_ROCKCHIP_GPIO=y -+CONFIG_ROCKCHIP_GPIO_V2=y -+CONFIG_SYS_I2C_ROCKCHIP=y -+CONFIG_DM_KEY=y -+CONFIG_ADC_KEY=y -+CONFIG_MISC=y -+CONFIG_SPL_MISC=y -+CONFIG_MISC_DECOMPRESS=y -+CONFIG_SPL_MISC_DECOMPRESS=y -+CONFIG_ROCKCHIP_OTP=y -+CONFIG_ROCKCHIP_HW_DECOMPRESS=y -+CONFIG_SPL_ROCKCHIP_HW_DECOMPRESS=y -+CONFIG_SPL_ROCKCHIP_SECURE_OTP=y -+CONFIG_MMC_DW=y -+CONFIG_MMC_DW_ROCKCHIP=y -+CONFIG_MMC_SDHCI=y -+CONFIG_MMC_SDHCI_SDMA=y -+CONFIG_MMC_SDHCI_ROCKCHIP=y -+CONFIG_MTD=y -+CONFIG_MTD_BLK=y -+CONFIG_MTD_DEVICE=y -+CONFIG_NAND=y -+CONFIG_MTD_SPI_NAND=y -+CONFIG_SPI_FLASH=y -+CONFIG_SF_DEFAULT_SPEED=80000000 -+CONFIG_SPI_FLASH_EON=y -+CONFIG_SPI_FLASH_GIGADEVICE=y -+CONFIG_SPI_FLASH_MACRONIX=y -+CONFIG_SPI_FLASH_SST=y -+CONFIG_SPI_FLASH_WINBOND=y -+CONFIG_SPI_FLASH_XMC=y -+CONFIG_SPI_FLASH_XTX=y -+CONFIG_SPI_FLASH_MTD=y -+CONFIG_DM_ETH=y -+CONFIG_DM_ETH_PHY=y -+CONFIG_DWC_ETH_QOS=y -+CONFIG_GMAC_ROCKCHIP=y -+CONFIG_NVME=y -+CONFIG_PCI=y -+CONFIG_DM_PCI=y -+CONFIG_DM_PCI_COMPAT=y -+CONFIG_PCIE_DW_ROCKCHIP=y -+CONFIG_PHY_ROCKCHIP_INNO_USB2=y -+CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX=y -+CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y -+CONFIG_PINCTRL=y -+CONFIG_SPL_PINCTRL=y -+CONFIG_DM_PMIC=y -+CONFIG_PMIC_SPI_RK8XX=y -+CONFIG_REGULATOR_PWM=y -+CONFIG_DM_REGULATOR_FIXED=y -+CONFIG_DM_REGULATOR_GPIO=y -+CONFIG_REGULATOR_RK860X=y -+CONFIG_REGULATOR_RK806=y -+CONFIG_PWM_ROCKCHIP=y -+CONFIG_RAM=y -+CONFIG_SPL_RAM=y -+CONFIG_TPL_RAM=y -+CONFIG_ROCKCHIP_SDRAM_COMMON=y -+CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE=0 -+CONFIG_DM_RESET=y -+CONFIG_SPL_DM_RESET=y -+CONFIG_SPL_RESET_ROCKCHIP=y -+CONFIG_BAUDRATE=1500000 -+CONFIG_DEBUG_UART_BASE=0xFEB50000 -+CONFIG_DEBUG_UART_CLOCK=24000000 -+CONFIG_DEBUG_UART_SHIFT=2 -+CONFIG_ROCKCHIP_SPI=y -+CONFIG_ROCKCHIP_SFC=y -+CONFIG_SYSRESET=y -+CONFIG_USB=y -+CONFIG_USB_XHCI_HCD=y -+CONFIG_USB_XHCI_DWC3=y -+CONFIG_USB_XHCI_PCI=y -+CONFIG_USB_EHCI_HCD=y -+CONFIG_USB_EHCI_GENERIC=y -+CONFIG_USB_OHCI_HCD=y -+CONFIG_USB_OHCI_GENERIC=y -+CONFIG_USB_DWC3=y -+CONFIG_USB_DWC3_GADGET=y -+CONFIG_USB_DWC3_GENERIC=y -+CONFIG_USB_STORAGE=y -+CONFIG_USB_GADGET=y -+CONFIG_USB_GADGET_MANUFACTURER="Rockchip" -+CONFIG_USB_GADGET_VENDOR_NUM=0x2207 -+CONFIG_USB_GADGET_PRODUCT_NUM=0x350a -+CONFIG_USB_GADGET_DOWNLOAD=y -+CONFIG_DM_VIDEO=y -+CONFIG_DISPLAY=y -+CONFIG_DRM_ROCKCHIP=y -+CONFIG_DRM_ROCKCHIP_DW_MIPI_DSI2=y -+CONFIG_DRM_ROCKCHIP_ANALOGIX_DP=y -+CONFIG_DRM_ROCKCHIP_SAMSUNG_MIPI_DCPHY=y -+CONFIG_USE_TINY_PRINTF=y -+CONFIG_LIB_RAND=y -+CONFIG_SPL_TINY_MEMSET=y -+CONFIG_RSA=y -+CONFIG_SPL_RSA=y -+CONFIG_RSA_N_SIZE=0x200 -+CONFIG_RSA_E_SIZE=0x10 -+CONFIG_RSA_C_SIZE=0x20 -+CONFIG_LZ4=y -+CONFIG_ERRNO_STR=y -+# CONFIG_EFI_LOADER is not set -+CONFIG_AVB_LIBAVB=y -+CONFIG_AVB_LIBAVB_AB=y -+CONFIG_AVB_LIBAVB_ATX=y -+CONFIG_AVB_LIBAVB_USER=y -+CONFIG_RK_AVB_LIBAVB_USER=y -+CONFIG_OPTEE_CLIENT=y -+CONFIG_OPTEE_V2=y --- -2.43.0 -