From 8c9322b4ed50ed9ecca6bbae63662e151ffdd3c2 Mon Sep 17 00:00:00 2001 From: Fi3w0 <98111375+Fi3w0@users.noreply.github.com> Date: Thu, 8 Oct 2026 03:43:01 +0200 Subject: [PATCH] Update custom kernel to CachyOS 7.2.9-2 (fiw-nyx-v1.2) and add Ryzen tuning - Kernel snapshot: CachyOS 7.2.9-2 patch, name -2-fiw-nyx-v1.2; later 7.2.x point releases reuse the patch, next series masked from snapshot.json - Fiw's Ryzen preset: sysctl tuning (max_map_count, dirty bytes, BBR + fq) - tidewm list gains mpvpaper; grim moves to dev --- docs/setup.md | 7 + lib/rice.py | 7 +- optional/kernel/config.d/99-name.config | 4 +- optional/kernel/guard | 19 +- ...2.7-1.patch => 0100-cachyos-7.2.9-2.patch} | 8149 +++++++++-------- optional/kernel/snapshot.json | 11 +- optional/tuning/70-fiw-performance.conf | 22 + optional/tuning/bbr.conf | 2 + packages/dev.list | 1 + packages/tidewm.list | 2 +- 10 files changed, 4444 insertions(+), 3780 deletions(-) rename optional/kernel/patches/{0100-cachyos-7.2.7-1.patch => 0100-cachyos-7.2.9-2.patch} (96%) create mode 100644 optional/tuning/70-fiw-performance.conf create mode 100644 optional/tuning/bbr.conf diff --git a/docs/setup.md b/docs/setup.md index 578cc6a..14e3290 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -73,6 +73,13 @@ Custom kernel installs with NVIDIA also check its modules against the selected custom kernel and binary fallback. Missing or outdated modules are compiled for each, and failures appear in the package report. +The custom kernel snapshot is CachyOS 7.2.9-2 (`7.2.9-2-fiw-nyx-v1.2`). Newer +7.2.x point releases reuse that patch and config; the next series stays masked +until the snapshot is updated. Fiw's Ryzen preset also installs +`/etc/sysctl.d/70-fiw-dots-performance.conf` (CachyOS-style memory/network +values, `vm.max_map_count` for Proton games, TCP BBR with fq) and loads +`tcp_bbr`. No extra packages are needed for either. + Read-only resolution and an export are available separately: ```sh diff --git a/lib/rice.py b/lib/rice.py index 0bd4784..f2e799d 100644 --- a/lib/rice.py +++ b/lib/rice.py @@ -353,7 +353,12 @@ def root_files(selection, repo_location=None): result['etc/kernel/config.d/' + src.name] = src.read_text() result['etc/portage/package.accept_keywords/fiw-dots-kernel'] = 'sys-kernel/gentoo-kernel ~amd64\nsys-kernel/gentoo-kernel-bin ~amd64\nvirtual/dist-kernel ~amd64\n' result['etc/portage/env/sys-kernel/gentoo-kernel'] = (REPO / 'optional/kernel/guard').read_text() - result['etc/portage/package.mask/fiw-dots-custom-kernel'] = '# Tested custom-kernel snapshot; update snapshot and patch explicitly.\n>sys-kernel/gentoo-kernel-7.2.8\n' + # Point releases of the tested series reuse the patch (see guard); a new series needs a new snapshot. + major, minor = json.loads((REPO / 'optional/kernel/snapshot.json').read_text())['patch_kernel'].split('.')[:2] + result['etc/portage/package.mask/fiw-dots-custom-kernel'] = '# Tested custom-kernel series; update snapshot and patch for the next one.\n>=sys-kernel/gentoo-kernel-' + major + '.' + str(int(minor) + 1) + '\n' + if selection['profile'] == 'fiw-ryzen': + result['etc/sysctl.d/70-fiw-dots-performance.conf'] = (REPO / 'optional/tuning/70-fiw-performance.conf').read_text() + result['etc/modules-load.d/fiw-dots-bbr.conf'] = (REPO / 'optional/tuning/bbr.conf').read_text() if selection['bootloader'] != 'keep': result['etc/portage/package.use/fiw-dots-boot'] = ('sys-kernel/installkernel systemd dracut -grub -uki -ukify -ugrd -efistub -refind -systemd-boot\n') if selection['bootloader'] == 'grub': diff --git a/optional/kernel/config.d/99-name.config b/optional/kernel/config.d/99-name.config index 5dce444..8d8d15a 100644 --- a/optional/kernel/config.d/99-name.config +++ b/optional/kernel/config.d/99-name.config @@ -1,5 +1,5 @@ # uname -r → --fiw-nyx-v # e.g. 7.2.7-1-fiw-nyx-v1.1. fiw-cachy-patch updates the cachyos release number; # bump v by hand when you change your own tweaks. -# History: v1 = "-1-fiwzen-v1" (first build), v1.1 = renamed to fiw-nyx. -CONFIG_LOCALVERSION="-1-fiw-nyx-v1.1" +# History: v1 = "-1-fiwzen-v1" (first build), v1.1 = renamed to fiw-nyx. v1.2 = 2026-10-08 rebuild (7.2.9-2). +CONFIG_LOCALVERSION="-2-fiw-nyx-v1.2" diff --git a/optional/kernel/guard b/optional/kernel/guard index 2eaebdd..547a859 100644 --- a/optional/kernel/guard +++ b/optional/kernel/guard @@ -3,14 +3,17 @@ export KBUILD_BUILD_USER=fiw export KBUILD_BUILD_HOST=gentoo -# The CachyOS patch is a diff against exactly one kernel version. Refuse to build -# any other version until scripts/fiw-cachy-patch has regenerated it. -# Versions the current patch is known to apply to (space separated). -# 2026-09-26: CachyOS has no 7.2.8 yet; the 7.2.7-1 patch applies to 7.2.8 (3 hunks -# with fuzz, checked by hand: only context shifted by 7.2.8's APX lines). -FIW_CACHY_PV="7.2.7 7.2.8" +# Version the CachyOS patch in /etc/portage/patches was generated for. +# fiw-cachy-patch rewrites this line (the postsync hook runs it when CachyOS +# has a release for a new gentoo-kernel). A newer point release in the same +# series (7.2.x) reuses the existing patch and config.d unchanged; if the patch +# no longer applies, the build stops and the installed kernels stay as they are. +FIW_CACHY_PV=7.2.9 pre_src_prepare() { - if [[ " ${FIW_CACHY_PV} " != *" ${PV} "* ]]; then - die "CachyOS patch is for ${FIW_CACHY_PV}, not ${PV}. Run: fiw-cachy-patch ${PV}" + [[ ${PV} == "${FIW_CACHY_PV}" ]] && return + if [[ ${PV%.*} != "${FIW_CACHY_PV%.*}" ]]; then + die "CachyOS patch is for ${FIW_CACHY_PV}; ${PV} is a new series. Run: fiw-cachy-patch ${PV}" fi + ewarn "No CachyOS patch for ${PV} yet: reusing the ${FIW_CACHY_PV} patch and config." + ewarn "Fallbacks if it misbehaves: gentoo-kernel-bin entry, or CachyOS." } diff --git a/optional/kernel/patches/0100-cachyos-7.2.7-1.patch b/optional/kernel/patches/0100-cachyos-7.2.9-2.patch similarity index 96% rename from optional/kernel/patches/0100-cachyos-7.2.7-1.patch rename to optional/kernel/patches/0100-cachyos-7.2.9-2.patch index 34b9a3b..d73c37c 100644 --- a/optional/kernel/patches/0100-cachyos-7.2.7-1.patch +++ b/optional/kernel/patches/0100-cachyos-7.2.9-2.patch @@ -1,6 +1,94 @@ +diff -ruN --no-dereference -x .git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +--- a/Documentation/admin-guide/kernel-parameters.txt 2026-10-07 05:21:40.768534597 +0200 ++++ b/Documentation/admin-guide/kernel-parameters.txt 2026-10-03 14:48:53.000000000 +0200 +@@ -2487,6 +2487,9 @@ + disable + Do not enable intel_pstate as the default + scaling driver for the supported processors ++ enable ++ Enable intel_pstate in-case "disable" was passed ++ previously in the kernel boot parameters + active + Use intel_pstate driver to bypass the scaling + governors layer of cpufreq and provides it own +@@ -5026,6 +5029,15 @@ + nomsi [MSI] If the PCI_MSI kernel config parameter is + enabled, this kernel boot option can be used to + disable the use of MSI interrupts system-wide. ++ pcie_acs_override = ++ [PCIE] Override missing PCIe ACS support for: ++ downstream ++ All downstream ports - full ACS capabilities ++ multfunction ++ All multifunction devices - multifunction ACS subset ++ id:nnnn:nnnn ++ Specfic device - full ACS capabilities ++ Specified as vid:did (vendor/device ID) in hex + noioapicquirk [APIC] Disable all boot interrupt quirks. + Safety option to keep boot IRQs enabled. This + should never be necessary. +@@ -7906,6 +7918,8 @@ + obtained from HW or FW using either an MSR or CPUID(0x15). + Warn if the difference is more than 500 ppm. + [x86] watchdog: Enforce the clocksource watchdog on TSC ++ [x86] directsync: attempt to sync the tsc via direct ++ writes if MSR_IA32_TSC_ADJUST isn't available + + tsc_early_khz= [X86,EARLY] Skip early TSC calibration and use the given + value instead. Useful when the early TSC frequency discovery +diff -ruN --no-dereference -x .git a/Documentation/admin-guide/pm/amd-pstate.rst b/Documentation/admin-guide/pm/amd-pstate.rst +--- a/Documentation/admin-guide/pm/amd-pstate.rst 2026-08-16 23:32:26.000000000 +0200 ++++ b/Documentation/admin-guide/pm/amd-pstate.rst 2026-10-03 14:48:53.000000000 +0200 +@@ -372,6 +372,22 @@ + Attempting to manually write to the ``energy_performance_preference`` sysfs + file will fail when ``dynamic_epp`` is enabled. + ++Energy performance preference boosting ++====================================== ++On MSR-based systems running in the ``active mode``, the driver can optionally ++bias the energy performance preference of a recently-busy CPU toward ++performance while leaving all other CPUs at the policy value. C0 residency is ++sampled at most every 10 ms; while a CPU has been at least 50% busy within the ++last 300 ms, the EPP field of its CPPC request is set to ``performance`` (0). ++The policy value is restored once 300 ms pass without a busy sample. ++ ++This behavior is disabled by default. It can be enabled with the module ++parameter ``amd_pstate.epp_boost=1`` on the kernel command line, or at runtime ++by writing ``1`` to ``/sys/module/amd_pstate/parameters/epp_boost``. The ++mechanism only runs while the parameter is enabled and has no overhead when ++disabled. It has no effect in the ``passive`` and ``guided`` modes or on ++shared-memory (non-MSR) systems. ++ + ``amd-pstate`` vs ``acpi-cpufreq`` + ====================================== + +diff -ruN --no-dereference -x .git a/Makefile b/Makefile +--- a/Makefile 2026-10-07 05:21:40.774623869 +0200 ++++ b/Makefile 2026-10-03 14:48:53.000000000 +0200 +@@ -932,11 +932,20 @@ + ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE + KBUILD_CFLAGS += -O2 + KBUILD_RUSTFLAGS += -Copt-level=2 ++else ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE_O3 ++KBUILD_CFLAGS += -O3 ++KBUILD_RUSTFLAGS += -Copt-level=3 + else ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE + KBUILD_CFLAGS += -Os + KBUILD_RUSTFLAGS += -Copt-level=s + endif + ++# Perform swing modulo scheduling immediately before the first scheduling pass. ++# This pass looks at innermost loops and reorders their instructions by ++# overlapping different iterations. ++KBUILD_CFLAGS += $(call cc-option,-fmodulo-sched -fmodulo-sched-allow-regmoves -fivopts) ++KBUILD_CFLAGS += $(call cc-option,-mllvm -enable-pipeliner) ++ + # Always set `debug-assertions` and `overflow-checks` because their default + # depends on `opt-level` and `debug-assertions`, respectively. + KBUILD_RUSTFLAGS += -Cdebug-assertions=$(if $(CONFIG_RUST_DEBUG_ASSERTIONS),y,n) diff -ruN --no-dereference -x .git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h ---- a/arch/arm/include/asm/mmu_context.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/arch/arm/include/asm/mmu_context.h 2026-09-23 12:56:16.000000000 +0200 +--- a/arch/arm/include/asm/mmu_context.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/arch/arm/include/asm/mmu_context.h 2026-10-03 14:48:53.000000000 +0200 @@ -80,7 +80,7 @@ #ifndef MODULE #define finish_arch_post_lock_switch \ @@ -11,8 +99,8 @@ diff -ruN --no-dereference -x .git a/arch/arm/include/asm/mmu_context.h b/arch/a struct mm_struct *mm = current->mm; diff -ruN --no-dereference -x .git a/arch/riscv/include/asm/sync_core.h b/arch/riscv/include/asm/sync_core.h ---- a/arch/riscv/include/asm/sync_core.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/arch/riscv/include/asm/sync_core.h 2026-09-23 12:56:16.000000000 +0200 +--- a/arch/riscv/include/asm/sync_core.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/arch/riscv/include/asm/sync_core.h 2026-10-03 14:48:53.000000000 +0200 @@ -6,7 +6,7 @@ * RISC-V implements return to user-space through an xRET instruction, * which is not core serializing. @@ -23,8 +111,8 @@ diff -ruN --no-dereference -x .git a/arch/riscv/include/asm/sync_core.h b/arch/r asm volatile ("fence.i" ::: "memory"); } diff -ruN --no-dereference -x .git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h ---- a/arch/s390/include/asm/mmu_context.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/arch/s390/include/asm/mmu_context.h 2026-09-23 12:56:16.000000000 +0200 +--- a/arch/s390/include/asm/mmu_context.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/arch/s390/include/asm/mmu_context.h 2026-10-03 14:48:53.000000000 +0200 @@ -93,7 +93,7 @@ } @@ -35,8 +123,8 @@ diff -ruN --no-dereference -x .git a/arch/s390/include/asm/mmu_context.h b/arch/ struct task_struct *tsk = current; struct mm_struct *mm = tsk->mm; diff -ruN --no-dereference -x .git a/arch/sparc/include/asm/mmu_context_64.h b/arch/sparc/include/asm/mmu_context_64.h ---- a/arch/sparc/include/asm/mmu_context_64.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/arch/sparc/include/asm/mmu_context_64.h 2026-09-23 12:56:16.000000000 +0200 +--- a/arch/sparc/include/asm/mmu_context_64.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/arch/sparc/include/asm/mmu_context_64.h 2026-10-03 14:48:53.000000000 +0200 @@ -160,7 +160,7 @@ } @@ -46,70 +134,13 @@ diff -ruN --no-dereference -x .git a/arch/sparc/include/asm/mmu_context_64.h b/a { /* Restore the state of MCDPER register for the new process * just switched to. -diff -ruN --no-dereference -x .git a/arch/x86/include/asm/sync_core.h b/arch/x86/include/asm/sync_core.h ---- a/arch/x86/include/asm/sync_core.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/arch/x86/include/asm/sync_core.h 2026-09-23 12:56:16.000000000 +0200 -@@ -93,7 +93,7 @@ - * to user-mode. x86 implements return to user-space through sysexit, - * sysrel, and sysretq, which are not core serializing. - */ --static inline void sync_core_before_usermode(void) -+static __always_inline void sync_core_before_usermode(void) - { - /* With PTI, we unconditionally serialize before running user code. */ - if (static_cpu_has(X86_FEATURE_PTI)) -diff -ruN --no-dereference -x .git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h ---- a/arch/x86/include/asm/tlbflush.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/arch/x86/include/asm/tlbflush.h 2026-09-23 12:56:16.000000000 +0200 -@@ -4,6 +4,7 @@ - - #include - #include -+#include - #include - - #include -@@ -212,6 +213,12 @@ - extern void initialize_tlbstate_and_flush(void); - - /* -+ * Keep stack-allocated flush_tlb_info cacheline aligned, but cap the -+ * alignment to avoid excessive stack usage on large-cacheline systems. -+ */ -+#define FLUSH_TLB_INFO_ALIGN MIN(SMP_CACHE_BYTES, 64) -+ -+/* - * TLB flushing: - * - * - flush_tlb_all() flushes all processes TLBs -@@ -249,7 +256,7 @@ - u8 stride_shift; - u8 freed_tables; - u8 trim_cpumask; --}; -+} __aligned(FLUSH_TLB_INFO_ALIGN); - - void flush_tlb_local(void); - void flush_tlb_one_user(unsigned long addr); -diff -ruN --no-dereference -x .git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h ---- a/arch/x86/include/asm/tsc.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/arch/x86/include/asm/tsc.h 2026-09-23 12:56:16.000000000 +0200 -@@ -93,6 +93,7 @@ - extern unsigned long long native_sched_clock_from_tsc(u64 tsc); - - extern int tsc_clocksource_reliable; -+extern int tsc_allow_direct_sync; - extern bool tsc_async_resets; - - /* diff -ruN --no-dereference -x .git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu ---- a/arch/x86/Kconfig.cpu 2026-09-21 15:09:00.000000000 +0200 -+++ b/arch/x86/Kconfig.cpu 2026-09-23 12:56:16.000000000 +0200 -@@ -204,6 +204,11 @@ - # usage warnings that only appear wth '-march=native'. - depends on CC_IS_GCC || CLANG_VERSION >= 190100 +--- a/arch/x86/Kconfig.cpu 2026-10-07 05:21:40.842225539 +0200 ++++ b/arch/x86/Kconfig.cpu 2026-10-03 14:48:53.000000000 +0200 +@@ -214,6 +214,10 @@ + def_bool (RUSTC_VERSION >= 108800 && RUSTC_LLVM_MAJOR_VERSION >= 23) || \ + RUSTC_VERSION >= 109300 -+ +choice + prompt "x86_64 Compiler Build Optimization" + default GENERIC_CPU @@ -117,7 +148,7 @@ diff -ruN --no-dereference -x .git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu config X86_NATIVE_CPU bool "Build and optimize for local/native CPU" depends on X86_64 -@@ -218,6 +223,47 @@ +@@ -229,6 +233,47 @@ If unsure, say N. @@ -165,9 +196,116 @@ diff -ruN --no-dereference -x .git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu config X86_GENERIC bool "Generic x86 support" depends on X86_32 +diff -ruN --no-dereference -x .git a/arch/x86/Makefile b/arch/x86/Makefile +--- a/arch/x86/Makefile 2026-10-07 05:21:40.842340618 +0200 ++++ b/arch/x86/Makefile 2026-10-03 14:48:53.000000000 +0200 +@@ -167,10 +167,22 @@ + + # generate_rust_target.rs handles Rust APX gating. + KBUILD_RUSTFLAGS += -Ctarget-cpu=native +-else ++endif ++ ++ifdef CONFIG_MZEN4 ++ KBUILD_CFLAGS += -march=znver4 ++ KBUILD_RUSTFLAGS += -Ctarget-cpu=znver4 ++endif ++ ++ifdef CONFIG_GENERIC_CPU ++ifeq ($(CONFIG_X86_64_VERSION),1) + KBUILD_CFLAGS += -march=x86-64 -mtune=generic + KBUILD_RUSTFLAGS += -Ctarget-cpu=x86-64 -Ztune-cpu=generic +-endif ++else ++ KBUILD_CFLAGS +=-march=x86-64-v$(CONFIG_X86_64_VERSION) ++ KBUILD_RUSTFLAGS += -Ctarget-cpu=x86-64-v$(CONFIG_X86_64_VERSION) ++endif # CONFIG_X86_64_VERSION ++endif # CONFIG_GENERIC_CPU + + KBUILD_CFLAGS += -mno-red-zone + KBUILD_CFLAGS += -mcmodel=kernel +diff -ruN --no-dereference -x .git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h +--- a/arch/x86/include/asm/pci.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/arch/x86/include/asm/pci.h 2026-10-03 14:48:53.000000000 +0200 +@@ -26,6 +26,7 @@ + #if IS_ENABLED(CONFIG_VMD) + struct pci_dev *vmd_dev; /* VMD Device if in Intel VMD domain */ + #endif ++ struct pci_dev *nvme_remap_dev; /* AHCI Device if NVME remapped bus */ + }; + + extern int pci_routeirq; +@@ -69,6 +70,11 @@ + #define is_vmd(bus) false + #endif /* CONFIG_VMD */ + ++static inline bool is_nvme_remap(struct pci_bus *bus) ++{ ++ return to_pci_sysdata(bus)->nvme_remap_dev != NULL; ++} ++ + /* Can be used to override the logic in pci_scan_bus for skipping + already-configured bus numbers - to be used for buggy BIOSes + or architectures with incomplete PCI setup by the loader */ +diff -ruN --no-dereference -x .git a/arch/x86/include/asm/sync_core.h b/arch/x86/include/asm/sync_core.h +--- a/arch/x86/include/asm/sync_core.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/arch/x86/include/asm/sync_core.h 2026-10-03 14:48:53.000000000 +0200 +@@ -93,7 +93,7 @@ + * to user-mode. x86 implements return to user-space through sysexit, + * sysrel, and sysretq, which are not core serializing. + */ +-static inline void sync_core_before_usermode(void) ++static __always_inline void sync_core_before_usermode(void) + { + /* With PTI, we unconditionally serialize before running user code. */ + if (static_cpu_has(X86_FEATURE_PTI)) +diff -ruN --no-dereference -x .git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h +--- a/arch/x86/include/asm/tlbflush.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/arch/x86/include/asm/tlbflush.h 2026-10-03 14:48:53.000000000 +0200 +@@ -4,6 +4,7 @@ + + #include + #include ++#include + #include + + #include +@@ -212,6 +213,12 @@ + extern void initialize_tlbstate_and_flush(void); + + /* ++ * Keep stack-allocated flush_tlb_info cacheline aligned, but cap the ++ * alignment to avoid excessive stack usage on large-cacheline systems. ++ */ ++#define FLUSH_TLB_INFO_ALIGN MIN(SMP_CACHE_BYTES, 64) ++ ++/* + * TLB flushing: + * + * - flush_tlb_all() flushes all processes TLBs +@@ -249,7 +256,7 @@ + u8 stride_shift; + u8 freed_tables; + u8 trim_cpumask; +-}; ++} __aligned(FLUSH_TLB_INFO_ALIGN); + + void flush_tlb_local(void); + void flush_tlb_one_user(unsigned long addr); +diff -ruN --no-dereference -x .git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h +--- a/arch/x86/include/asm/tsc.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/arch/x86/include/asm/tsc.h 2026-10-03 14:48:53.000000000 +0200 +@@ -93,6 +93,7 @@ + extern unsigned long long native_sched_clock_from_tsc(u64 tsc); + + extern int tsc_clocksource_reliable; ++extern int tsc_allow_direct_sync; + extern bool tsc_async_resets; + + /* diff -ruN --no-dereference -x .git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c ---- a/arch/x86/kernel/acpi/sleep.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/arch/x86/kernel/acpi/sleep.c 2026-09-23 12:56:16.000000000 +0200 +--- a/arch/x86/kernel/acpi/sleep.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/arch/x86/kernel/acpi/sleep.c 2026-10-03 14:48:53.000000000 +0200 @@ -104,6 +104,15 @@ header->pmode_misc_en_high)) header->pmode_behavior |= @@ -185,8 +323,8 @@ diff -ruN --no-dereference -x .git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/ker header->real_magic = 0x12345678; diff -ruN --no-dereference -x .git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c ---- a/arch/x86/kernel/cpu/amd.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/arch/x86/kernel/cpu/amd.c 2026-09-23 12:56:16.000000000 +0200 +--- a/arch/x86/kernel/cpu/amd.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/arch/x86/kernel/cpu/amd.c 2026-10-03 14:48:53.000000000 +0200 @@ -1042,11 +1042,8 @@ static void init_amd_zen5(struct cpuinfo_x86 *c) @@ -202,8 +340,8 @@ diff -ruN --no-dereference -x .git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel static void init_amd(struct cpuinfo_x86 *c) diff -ruN --no-dereference -x .git a/arch/x86/kernel/cpu/bus_lock.c b/arch/x86/kernel/cpu/bus_lock.c ---- a/arch/x86/kernel/cpu/bus_lock.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/arch/x86/kernel/cpu/bus_lock.c 2026-09-23 12:56:16.000000000 +0200 +--- a/arch/x86/kernel/cpu/bus_lock.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/arch/x86/kernel/cpu/bus_lock.c 2026-10-03 14:48:53.000000000 +0200 @@ -47,7 +47,11 @@ static struct ratelimit_state bld_ratelimit; @@ -217,8 +355,8 @@ diff -ruN --no-dereference -x .git a/arch/x86/kernel/cpu/bus_lock.c b/arch/x86/k #ifdef CONFIG_PROC_SYSCTL diff -ruN --no-dereference -x .git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c ---- a/arch/x86/kernel/kvm.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/arch/x86/kernel/kvm.c 2026-09-23 12:56:16.000000000 +0200 +--- a/arch/x86/kernel/kvm.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/arch/x86/kernel/kvm.c 2026-10-03 14:48:53.000000000 +0200 @@ -663,8 +663,10 @@ u8 state; int cpu; @@ -232,8 +370,8 @@ diff -ruN --no-dereference -x .git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm /* * We have to call flush only on online vCPUs. And diff -ruN --no-dereference -x .git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c ---- a/arch/x86/kernel/smpboot.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/arch/x86/kernel/smpboot.c 2026-09-23 12:56:16.000000000 +0200 +--- a/arch/x86/kernel/smpboot.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/arch/x86/kernel/smpboot.c 2026-10-03 14:48:53.000000000 +0200 @@ -61,6 +61,7 @@ #include #include @@ -260,8 +398,8 @@ diff -ruN --no-dereference -x .git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel nmi_selftest(); impress_friends(); diff -ruN --no-dereference -x .git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c ---- a/arch/x86/kernel/tsc.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/arch/x86/kernel/tsc.c 2026-09-23 12:56:16.000000000 +0200 +--- a/arch/x86/kernel/tsc.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/arch/x86/kernel/tsc.c 2026-10-03 14:48:53.000000000 +0200 @@ -52,6 +52,7 @@ static DEFINE_STATIC_KEY_FALSE_RO(__use_tsc); @@ -280,8 +418,8 @@ diff -ruN --no-dereference -x .git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc } __setup("tsc=", tsc_setup); diff -ruN --no-dereference -x .git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c ---- a/arch/x86/kernel/tsc_sync.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/arch/x86/kernel/tsc_sync.c 2026-09-23 12:56:16.000000000 +0200 +--- a/arch/x86/kernel/tsc_sync.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/arch/x86/kernel/tsc_sync.c 2026-10-03 14:48:53.000000000 +0200 @@ -34,6 +34,8 @@ static DEFINE_PER_CPU(struct tsc_adjust, tsc_adjust); static struct timer_list tsc_sync_check_timer; @@ -376,37 +514,9 @@ diff -ruN --no-dereference -x .git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kerne goto retry; } -diff -ruN --no-dereference -x .git a/arch/x86/Makefile b/arch/x86/Makefile ---- a/arch/x86/Makefile 2026-09-21 15:09:00.000000000 +0200 -+++ b/arch/x86/Makefile 2026-09-23 12:56:16.000000000 +0200 -@@ -162,10 +162,22 @@ - ifdef CONFIG_X86_NATIVE_CPU - KBUILD_CFLAGS += -march=native - KBUILD_RUSTFLAGS += -Ctarget-cpu=native --else -+endif -+ -+ifdef CONFIG_MZEN4 -+ KBUILD_CFLAGS += -march=znver4 -+ KBUILD_RUSTFLAGS += -Ctarget-cpu=znver4 -+endif -+ -+ifdef CONFIG_GENERIC_CPU -+ifeq ($(CONFIG_X86_64_VERSION),1) - KBUILD_CFLAGS += -march=x86-64 -mtune=generic - KBUILD_RUSTFLAGS += -Ctarget-cpu=x86-64 -Ztune-cpu=generic --endif -+else -+ KBUILD_CFLAGS +=-march=x86-64-v$(CONFIG_X86_64_VERSION) -+ KBUILD_RUSTFLAGS += -Ctarget-cpu=x86-64-v$(CONFIG_X86_64_VERSION) -+endif # CONFIG_X86_64_VERSION -+endif # CONFIG_GENERIC_CPU - - KBUILD_CFLAGS += -mno-red-zone - KBUILD_CFLAGS += -mcmodel=kernel diff -ruN --no-dereference -x .git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c ---- a/arch/x86/mm/tlb.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/arch/x86/mm/tlb.c 2026-09-23 12:56:16.000000000 +0200 +--- a/arch/x86/mm/tlb.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/arch/x86/mm/tlb.c 2026-10-03 14:48:53.000000000 +0200 @@ -1373,35 +1373,19 @@ */ unsigned long tlb_single_page_flush_ceiling __read_mostly = 33; @@ -586,9 +696,49 @@ diff -ruN --no-dereference -x .git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c } /* +diff -ruN --no-dereference -x .git a/arch/x86/pci/common.c b/arch/x86/pci/common.c +--- a/arch/x86/pci/common.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/arch/x86/pci/common.c 2026-10-03 14:48:53.000000000 +0200 +@@ -723,12 +723,15 @@ + return 0; + } + +-#if IS_ENABLED(CONFIG_VMD) + struct pci_dev *pci_real_dma_dev(struct pci_dev *dev) + { ++#if IS_ENABLED(CONFIG_VMD) + if (is_vmd(dev->bus)) + return to_pci_sysdata(dev->bus)->vmd_dev; ++#endif ++ ++ if (is_nvme_remap(dev->bus)) ++ return to_pci_sysdata(dev->bus)->nvme_remap_dev; + + return dev; + } +-#endif +diff -ruN --no-dereference -x .git a/arch/x86/realmode/rm/wakeup.h b/arch/x86/realmode/rm/wakeup.h +--- a/arch/x86/realmode/rm/wakeup.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/arch/x86/realmode/rm/wakeup.h 2026-10-03 14:48:53.000000000 +0200 +@@ -23,6 +23,8 @@ + u64 pmode_gdt; + u32 pmode_misc_en_low; /* Protected mode MISC_ENABLE */ + u32 pmode_misc_en_high; ++ u32 pmode_tsc_low; ++ u32 pmode_tsc_high; + u32 pmode_behavior; /* Wakeup routine behavior flags */ + u32 realmode_flags; + u32 real_magic; +@@ -39,5 +41,6 @@ + #define WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE 0 + #define WAKEUP_BEHAVIOR_RESTORE_CR4 1 + #define WAKEUP_BEHAVIOR_RESTORE_EFER 2 ++#define WAKEUP_BEHAVIOR_RESTORE_TSC 3 + + #endif /* ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H */ diff -ruN --no-dereference -x .git a/arch/x86/realmode/rm/wakeup_asm.S b/arch/x86/realmode/rm/wakeup_asm.S ---- a/arch/x86/realmode/rm/wakeup_asm.S 2026-09-21 15:09:00.000000000 +0200 -+++ b/arch/x86/realmode/rm/wakeup_asm.S 2026-09-23 12:56:16.000000000 +0200 +--- a/arch/x86/realmode/rm/wakeup_asm.S 2026-08-16 23:32:26.000000000 +0200 ++++ b/arch/x86/realmode/rm/wakeup_asm.S 2026-10-03 14:48:53.000000000 +0200 @@ -27,6 +27,7 @@ pmode_efer: .quad 0 /* Saved EFER */ pmode_gdt: .quad 0 @@ -615,28 +765,55 @@ diff -ruN --no-dereference -x .git a/arch/x86/realmode/rm/wakeup_asm.S b/arch/x8 /* Do any other stuff... */ #ifndef CONFIG_64BIT -diff -ruN --no-dereference -x .git a/arch/x86/realmode/rm/wakeup.h b/arch/x86/realmode/rm/wakeup.h ---- a/arch/x86/realmode/rm/wakeup.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/arch/x86/realmode/rm/wakeup.h 2026-09-23 12:56:16.000000000 +0200 -@@ -23,6 +23,8 @@ - u64 pmode_gdt; - u32 pmode_misc_en_low; /* Protected mode MISC_ENABLE */ - u32 pmode_misc_en_high; -+ u32 pmode_tsc_low; -+ u32 pmode_tsc_high; - u32 pmode_behavior; /* Wakeup routine behavior flags */ - u32 realmode_flags; - u32 real_magic; -@@ -39,5 +41,6 @@ - #define WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE 0 - #define WAKEUP_BEHAVIOR_RESTORE_CR4 1 - #define WAKEUP_BEHAVIOR_RESTORE_EFER 2 -+#define WAKEUP_BEHAVIOR_RESTORE_TSC 3 +diff -ruN --no-dereference -x .git a/block/Kconfig.iosched b/block/Kconfig.iosched +--- a/block/Kconfig.iosched 2026-08-16 23:32:26.000000000 +0200 ++++ b/block/Kconfig.iosched 2026-10-03 14:48:53.000000000 +0200 +@@ -16,6 +16,20 @@ + synchronous writes, it will self-tune queue depths to achieve that + goal. - #endif /* ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H */ ++config MQ_IOSCHED_ADIOS ++ tristate "Adaptive Deadline I/O scheduler" ++ default m ++ help ++ The Adaptive Deadline I/O Scheduler (ADIOS) is a multi-queue I/O ++ scheduler with learning-based adaptive latency control. ++ ++config MQ_IOSCHED_DEFAULT_ADIOS ++ bool "Enable ADIOS I/O scheduler as default MQ I/O scheduler" ++ depends on MQ_IOSCHED_ADIOS=y ++ default n ++ help ++ Enable the ADIOS I/O scheduler as the default scheduler for MQ I/O. ++ + config IOSCHED_BFQ + tristate "BFQ I/O scheduler" + select BLK_ICQ +diff -ruN --no-dereference -x .git a/block/Makefile b/block/Makefile +--- a/block/Makefile 2026-08-16 23:32:26.000000000 +0200 ++++ b/block/Makefile 2026-10-03 14:48:53.000000000 +0200 +@@ -25,6 +25,7 @@ + obj-$(CONFIG_BLK_CGROUP_IOCOST) += blk-iocost.o + obj-$(CONFIG_MQ_IOSCHED_DEADLINE) += mq-deadline.o + obj-$(CONFIG_MQ_IOSCHED_KYBER) += kyber-iosched.o ++obj-$(CONFIG_MQ_IOSCHED_ADIOS) += adios.o + bfq-y := bfq-iosched.o bfq-wf2q.o bfq-cgroup.o + obj-$(CONFIG_IOSCHED_BFQ) += bfq.o + +@@ -39,3 +40,10 @@ + blk-crypto-sysfs.o + obj-$(CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK) += blk-crypto-fallback.o + obj-$(CONFIG_BLOCK_HOLDER_DEPRECATED) += holder.o ++ ++all: ++ make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules ++ ++clean: ++ make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean ++ diff -ruN --no-dereference -x .git a/block/adios.c b/block/adios.c --- a/block/adios.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/block/adios.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/block/adios.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,1981 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -2621,8 +2798,8 @@ diff -ruN --no-dereference -x .git a/block/adios.c b/block/adios.c +MODULE_DESCRIPTION(ADIOS_PROGNAME); \ No newline at end of file diff -ruN --no-dereference -x .git a/block/elevator.c b/block/elevator.c ---- a/block/elevator.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/block/elevator.c 2026-09-23 12:56:16.000000000 +0200 +--- a/block/elevator.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/block/elevator.c 2026-10-03 14:48:53.000000000 +0200 @@ -740,6 +740,19 @@ if (q->tag_set->flags & BLK_MQ_F_NO_SCHED_BY_DEFAULT) return; @@ -2661,119 +2838,9 @@ diff -ruN --no-dereference -x .git a/block/elevator.c b/block/elevator.c elevator_put(ctx.type); } -diff -ruN --no-dereference -x .git a/block/Kconfig.iosched b/block/Kconfig.iosched ---- a/block/Kconfig.iosched 2026-09-21 15:09:00.000000000 +0200 -+++ b/block/Kconfig.iosched 2026-09-23 12:56:16.000000000 +0200 -@@ -16,6 +16,20 @@ - synchronous writes, it will self-tune queue depths to achieve that - goal. - -+config MQ_IOSCHED_ADIOS -+ tristate "Adaptive Deadline I/O scheduler" -+ default m -+ help -+ The Adaptive Deadline I/O Scheduler (ADIOS) is a multi-queue I/O -+ scheduler with learning-based adaptive latency control. -+ -+config MQ_IOSCHED_DEFAULT_ADIOS -+ bool "Enable ADIOS I/O scheduler as default MQ I/O scheduler" -+ depends on MQ_IOSCHED_ADIOS=y -+ default n -+ help -+ Enable the ADIOS I/O scheduler as the default scheduler for MQ I/O. -+ - config IOSCHED_BFQ - tristate "BFQ I/O scheduler" - select BLK_ICQ -diff -ruN --no-dereference -x .git a/block/Makefile b/block/Makefile ---- a/block/Makefile 2026-09-21 15:09:00.000000000 +0200 -+++ b/block/Makefile 2026-09-23 12:56:16.000000000 +0200 -@@ -25,6 +25,7 @@ - obj-$(CONFIG_BLK_CGROUP_IOCOST) += blk-iocost.o - obj-$(CONFIG_MQ_IOSCHED_DEADLINE) += mq-deadline.o - obj-$(CONFIG_MQ_IOSCHED_KYBER) += kyber-iosched.o -+obj-$(CONFIG_MQ_IOSCHED_ADIOS) += adios.o - bfq-y := bfq-iosched.o bfq-wf2q.o bfq-cgroup.o - obj-$(CONFIG_IOSCHED_BFQ) += bfq.o - -@@ -39,3 +40,10 @@ - blk-crypto-sysfs.o - obj-$(CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK) += blk-crypto-fallback.o - obj-$(CONFIG_BLOCK_HOLDER_DEPRECATED) += holder.o -+ -+all: -+ make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules -+ -+clean: -+ make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean -+ -diff -ruN --no-dereference -x .git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt ---- a/Documentation/admin-guide/kernel-parameters.txt 2026-09-21 15:09:00.000000000 +0200 -+++ b/Documentation/admin-guide/kernel-parameters.txt 2026-09-23 12:56:16.000000000 +0200 -@@ -2487,6 +2487,9 @@ - disable - Do not enable intel_pstate as the default - scaling driver for the supported processors -+ enable -+ Enable intel_pstate in-case "disable" was passed -+ previously in the kernel boot parameters - active - Use intel_pstate driver to bypass the scaling - governors layer of cpufreq and provides it own -@@ -5026,6 +5029,15 @@ - nomsi [MSI] If the PCI_MSI kernel config parameter is - enabled, this kernel boot option can be used to - disable the use of MSI interrupts system-wide. -+ pcie_acs_override = -+ [PCIE] Override missing PCIe ACS support for: -+ downstream -+ All downstream ports - full ACS capabilities -+ multfunction -+ All multifunction devices - multifunction ACS subset -+ id:nnnn:nnnn -+ Specfic device - full ACS capabilities -+ Specified as vid:did (vendor/device ID) in hex - noioapicquirk [APIC] Disable all boot interrupt quirks. - Safety option to keep boot IRQs enabled. This - should never be necessary. -@@ -7906,6 +7918,8 @@ - obtained from HW or FW using either an MSR or CPUID(0x15). - Warn if the difference is more than 500 ppm. - [x86] watchdog: Enforce the clocksource watchdog on TSC -+ [x86] directsync: attempt to sync the tsc via direct -+ writes if MSR_IA32_TSC_ADJUST isn't available - - tsc_early_khz= [X86,EARLY] Skip early TSC calibration and use the given - value instead. Useful when the early TSC frequency discovery -diff -ruN --no-dereference -x .git a/Documentation/admin-guide/pm/amd-pstate.rst b/Documentation/admin-guide/pm/amd-pstate.rst ---- a/Documentation/admin-guide/pm/amd-pstate.rst 2026-09-21 15:09:00.000000000 +0200 -+++ b/Documentation/admin-guide/pm/amd-pstate.rst 2026-09-23 12:56:16.000000000 +0200 -@@ -372,6 +372,22 @@ - Attempting to manually write to the ``energy_performance_preference`` sysfs - file will fail when ``dynamic_epp`` is enabled. - -+Energy performance preference boosting -+====================================== -+On MSR-based systems running in the ``active mode``, the driver can optionally -+bias the energy performance preference of a recently-busy CPU toward -+performance while leaving all other CPUs at the policy value. C0 residency is -+sampled at most every 10 ms; while a CPU has been at least 50% busy within the -+last 300 ms, the EPP field of its CPPC request is set to ``performance`` (0). -+The policy value is restored once 300 ms pass without a busy sample. -+ -+This behavior is disabled by default. It can be enabled with the module -+parameter ``amd_pstate.epp_boost=1`` on the kernel command line, or at runtime -+by writing ``1`` to ``/sys/module/amd_pstate/parameters/epp_boost``. The -+mechanism only runs while the parameter is enabled and has no overhead when -+disabled. It has no effect in the ``passive`` and ``guided`` modes or on -+shared-memory (non-MSR) systems. -+ - ``amd-pstate`` vs ``acpi-cpufreq`` - ====================================== - diff -ruN --no-dereference -x .git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c ---- a/drivers/acpi/processor_idle.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/acpi/processor_idle.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/acpi/processor_idle.c 2026-10-07 05:21:40.870219273 +0200 ++++ b/drivers/acpi/processor_idle.c 2026-10-03 14:48:53.000000000 +0200 @@ -1441,6 +1441,19 @@ if (disabled_by_idle_boot_param()) return; @@ -2795,8 +2862,8 @@ diff -ruN --no-dereference -x .git a/drivers/acpi/processor_idle.c b/drivers/acp pr->flags.power_setup_done = 1; diff -ruN --no-dereference -x .git a/drivers/acpi/scan.c b/drivers/acpi/scan.c ---- a/drivers/acpi/scan.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/acpi/scan.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/acpi/scan.c 2026-10-07 05:21:40.870618691 +0200 ++++ b/drivers/acpi/scan.c 2026-10-03 14:48:53.000000000 +0200 @@ -1757,6 +1757,7 @@ * by the drivers/platform/x86/serial-multi-instantiate.c driver, which * knows which client device id to use for each resource. @@ -2814,8 +2881,8 @@ diff -ruN --no-dereference -x .git a/drivers/acpi/scan.c b/drivers/acpi/scan.c /* Non-conforming _HID for Cirrus Logic already released */ {"CLSA0100", }, diff -ruN --no-dereference -x .git a/drivers/acpi/x86/apple.c b/drivers/acpi/x86/apple.c ---- a/drivers/acpi/x86/apple.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/acpi/x86/apple.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/acpi/x86/apple.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/acpi/x86/apple.c 2026-10-03 14:48:53.000000000 +0200 @@ -6,7 +6,13 @@ #include @@ -2959,10 +3026,65 @@ diff -ruN --no-dereference -x .git a/drivers/acpi/x86/apple.c b/drivers/acpi/x86 +} +late_initcall(apple_t2_cpu_pm_init); +#endif +diff -ruN --no-dereference -x .git a/drivers/ata/ahci.c b/drivers/ata/ahci.c +--- a/drivers/ata/ahci.c 2026-10-07 05:21:40.871192130 +0200 ++++ b/drivers/ata/ahci.c 2026-10-03 14:48:53.000000000 +0200 +@@ -2659,7 +2659,7 @@ + return IRQ_RETVAL(rc); + } + +-static void ahci_remap_check(struct pci_dev *pdev, int bar, ++static int ahci_remap_check(struct pci_dev *pdev, int bar, + struct ahci_host_priv *hpriv) + { + int i; +@@ -2672,7 +2672,7 @@ + pci_resource_len(pdev, bar) < SZ_512K || + bar != AHCI_PCI_BAR_STANDARD || + !(readl(hpriv->mmio + AHCI_VSCAP) & 1)) +- return; ++ return 0; + + cap = readq(hpriv->mmio + AHCI_REMAP_CAP); + for (i = 0; i < AHCI_MAX_REMAP; i++) { +@@ -2687,18 +2687,11 @@ + } + + if (!hpriv->remapped_nvme) +- return; ++ return 0; + +- dev_warn(&pdev->dev, "Found %u remapped NVMe devices.\n", +- hpriv->remapped_nvme); +- dev_warn(&pdev->dev, +- "Switch your BIOS from RAID to AHCI mode to use them.\n"); +- +- /* +- * Don't rely on the msi-x capability in the remap case, +- * share the legacy interrupt across ahci and remapped devices. +- */ +- hpriv->flags |= AHCI_HFLAG_NO_MSI; ++ /* Abort probe, allowing intel-nvme-remap to step in when available */ ++ dev_info(&pdev->dev, "Device will be handled by intel-nvme-remap.\n"); ++ return -ENODEV; + } + + static int ahci_get_irq_vector(struct ata_host *host, int port) +@@ -2988,7 +2981,9 @@ + return rc; + + /* detect remapped nvme devices */ +- ahci_remap_check(pdev, ahci_pci_bar, hpriv); ++ rc = ahci_remap_check(pdev, ahci_pci_bar, hpriv); ++ if (rc) ++ return rc; + + sysfs_add_file_to_group(&pdev->dev.kobj, + &dev_attr_remapped_nvme.attr, diff -ruN --no-dereference -x .git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c ---- a/drivers/bluetooth/btusb.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/bluetooth/btusb.c 2026-09-23 12:56:16.000000000 +0200 -@@ -568,6 +568,8 @@ +--- a/drivers/bluetooth/btusb.c 2026-10-07 05:21:40.879573544 +0200 ++++ b/drivers/bluetooth/btusb.c 2026-10-03 14:48:53.000000000 +0200 +@@ -585,6 +585,8 @@ BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x13d3, 0x3612), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, @@ -2971,7 +3093,7 @@ diff -ruN --no-dereference -x .git a/drivers/bluetooth/btusb.c b/drivers/bluetoo { USB_DEVICE(0x0489, 0xe122), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, -@@ -696,6 +698,8 @@ +@@ -713,6 +715,8 @@ { USB_DEVICE(0x13d3, 0x3596), .driver_info = BTUSB_MEDIATEK | BTUSB_WIDEBAND_SPEECH }, /* MediaTek MT7922 Bluetooth devices */ @@ -2981,8 +3103,8 @@ diff -ruN --no-dereference -x .git a/drivers/bluetooth/btusb.c b/drivers/bluetoo BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x13d3, 0x3610), .driver_info = BTUSB_MEDIATEK | diff -ruN --no-dereference -x .git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c ---- a/drivers/cpufreq/amd-pstate.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/cpufreq/amd-pstate.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/cpufreq/amd-pstate.c 2026-10-07 05:21:40.897356410 +0200 ++++ b/drivers/cpufreq/amd-pstate.c 2026-10-03 14:48:53.000000000 +0200 @@ -27,6 +27,7 @@ #include #include @@ -3322,8 +3444,8 @@ diff -ruN --no-dereference -x .git a/drivers/cpufreq/amd-pstate.c b/drivers/cpuf static struct cpufreq_driver amd_pstate_driver = { diff -ruN --no-dereference -x .git a/drivers/cpufreq/amd-pstate.h b/drivers/cpufreq/amd-pstate.h ---- a/drivers/cpufreq/amd-pstate.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/cpufreq/amd-pstate.h 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/cpufreq/amd-pstate.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/cpufreq/amd-pstate.h 2026-10-03 14:48:53.000000000 +0200 @@ -10,6 +10,7 @@ #include @@ -3374,8 +3496,8 @@ diff -ruN --no-dereference -x .git a/drivers/cpufreq/amd-pstate.h b/drivers/cpuf /* diff -ruN --no-dereference -x .git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c ---- a/drivers/cpufreq/intel_pstate.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/cpufreq/intel_pstate.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/cpufreq/intel_pstate.c 2026-10-07 05:21:40.898663602 +0200 ++++ b/drivers/cpufreq/intel_pstate.c 2026-10-03 14:48:53.000000000 +0200 @@ -3927,6 +3927,8 @@ if (!strcmp(str, "disable")) @@ -3385,9 +3507,20 @@ diff -ruN --no-dereference -x .git a/drivers/cpufreq/intel_pstate.c b/drivers/cp else if (!strcmp(str, "active")) default_driver = &intel_pstate; else if (!strcmp(str, "passive")) +diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 2026-10-07 05:21:40.919669507 +0200 ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h 2026-10-03 14:48:53.000000000 +0200 +@@ -161,6 +161,7 @@ + */ + extern int amdgpu_modeset; + extern unsigned int amdgpu_vram_limit; ++extern int amdgpu_ignore_min_pcap; + extern int amdgpu_vis_vram_limit; + extern int amdgpu_gart_size; + extern int amdgpu_gtt_size; diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 2026-10-07 05:21:40.921790445 +0200 ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 2026-10-03 14:48:53.000000000 +0200 @@ -150,6 +150,7 @@ }; @@ -3422,20 +3555,9 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/d if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA || (pdev->class >> 8) == PCI_CLASS_DISPLAY_OTHER) { if (drm_firmware_drivers_only() && amdgpu_modeset == -1) -diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h 2026-09-23 12:56:16.000000000 +0200 -@@ -161,6 +161,7 @@ - */ - extern int amdgpu_modeset; - extern unsigned int amdgpu_vram_limit; -+extern int amdgpu_ignore_min_pcap; - extern int amdgpu_vis_vram_limit; - extern int amdgpu_gart_size; - extern int amdgpu_gtt_size; diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c ---- a/drivers/gpu/drm/amd/amdgpu/vi.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/amdgpu/vi.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/amd/amdgpu/vi.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/amd/amdgpu/vi.c 2026-10-03 14:48:53.000000000 +0200 @@ -1407,10 +1407,30 @@ return (nak_r + nak_g); } @@ -3467,9 +3589,23 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/g if (adev->flags & AMD_IS_APU) return false; +diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig +--- a/drivers/gpu/drm/amd/display/Kconfig 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/amd/display/Kconfig 2026-10-03 14:48:53.000000000 +0200 +@@ -68,4 +68,10 @@ + For more information on KUnit and unit tests in general, please + refer to the KUnit documentation in Documentation/dev-tools/kunit/. + ++config AMD_PRIVATE_COLOR ++ bool "Enable KMS color management by AMD for AMD" ++ default n ++ help ++ This option extends the KMS color management API with AMD driver-specific properties to enhance the color management support on AMD Steam Deck. ++ + endmenu diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 2026-10-07 05:21:40.930553474 +0200 ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 2026-10-03 14:48:53.000000000 +0200 @@ -2255,6 +2255,9 @@ if (amdgpu_dc_debug_mask & DC_SKIP_DETECTION_LT) adev->dm.dc->debug.skip_detection_link_training = true; @@ -3489,7 +3625,29 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp if (amdgpu_dm_create_color_properties(adev)) return -ENOMEM; #endif -@@ -7115,6 +7118,11 @@ +@@ -7015,16 +7018,11 @@ + timing_out->v_border_top = 0; + timing_out->v_border_bottom = 0; + /* TODO: un-hardcode */ +- if (drm_mode_is_420_only(info, mode_in) +- && (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A || +- stream->signal == SIGNAL_TYPE_HDMI_FRL) +- && aconnector +- && aconnector->force_yuv_pixel_format == PIXEL_ENCODING_YCBCR420) +- timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420; +- else if (drm_mode_is_420_also(info, mode_in) +- && aconnector +- && (aconnector->force_yuv_pixel_format == PIXEL_ENCODING_YCBCR420 +- || aconnector->force_yuv420_output)) ++ if (drm_mode_is_420_only(info, mode_in) || ++ (aconnector && ++ (aconnector->force_yuv_pixel_format == PIXEL_ENCODING_YCBCR420 || ++ aconnector->force_yuv420_output) && ++ drm_mode_is_420_also(info, mode_in))) + timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420; + else if ((connector->display_info.color_formats & BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR422)) + && aconnector +@@ -7115,6 +7113,11 @@ stream->output_color_space = get_output_color_space(timing_out, connector_state); stream->content_type = get_output_content_type(connector_state); @@ -3501,7 +3659,7 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp } static void fill_audio_info(struct audio_info *audio_info, -@@ -7635,6 +7643,7 @@ +@@ -7635,6 +7638,7 @@ struct drm_display_mode mode; struct drm_display_mode saved_mode; struct drm_display_mode *freesync_mode = NULL; @@ -3509,7 +3667,7 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp bool native_mode_found = false; bool recalculate_timing = false; bool scale = dm_state->scaling != RMX_OFF; -@@ -7726,6 +7735,16 @@ +@@ -7726,6 +7730,16 @@ } } @@ -3526,7 +3684,7 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp if (recalculate_timing) drm_mode_set_crtcinfo(&saved_mode, 0); -@@ -7772,7 +7791,7 @@ +@@ -7772,7 +7786,7 @@ if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A || stream->signal == SIGNAL_TYPE_HDMI_FRL) @@ -3535,7 +3693,7 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT || stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST || -@@ -10065,7 +10084,11 @@ +@@ -10065,7 +10079,11 @@ aconn = (struct amdgpu_dm_connector *)new_stream->dm_stream_context; @@ -3548,7 +3706,7 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp pack_sdp_v1_3 = aconn->pack_sdp_v1_3; if (aconn->vsdb_info.amd_vsdb_version == 1) -@@ -10151,6 +10174,10 @@ +@@ -10151,6 +10169,10 @@ VRR_STATE_ACTIVE_VARIABLE : VRR_STATE_INACTIVE; } @@ -3559,7 +3717,7 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp } else { config.state = VRR_STATE_UNSUPPORTED; } -@@ -13890,7 +13917,7 @@ +@@ -13892,7 +13914,7 @@ return ret; } @@ -3568,7 +3726,7 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp const struct edid *edid) { u8 *edid_ext = NULL; -@@ -13923,8 +13950,8 @@ +@@ -13925,8 +13947,8 @@ max_vfreq = edid_ext[j+10]; if (max_vfreq && min_vfreq) { @@ -3579,7 +3737,7 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp return; } -@@ -13944,13 +13971,13 @@ +@@ -13946,13 +13968,13 @@ return connector->display_info.amd_vsdb.version != 0; } @@ -3595,7 +3753,7 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp /*----- drm_find_cea_extension() -----*/ /* No EDID or EDID extensions */ -@@ -13971,9 +13998,101 @@ +@@ -13973,9 +13995,101 @@ if (edid_ext[0] != CEA_EXT) return -ENODEV; @@ -3606,8 +3764,7 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp + *vsdb_info = vsdb_local; + return false; +} - -- return valid_vsdb_found ? i : -ENODEV; ++ +static bool is_aconn_range_invalid(const struct amdgpu_dm_connector *aconn) +{ + return aconn->min_vfreq == 0 || aconn->max_vfreq == 0; @@ -3693,13 +3850,14 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp + + if (vsdb->min_refresh_rate_hz == 0) + return; -+ + +- return valid_vsdb_found ? i : -ENODEV; + if (vsdb->min_refresh_rate_hz < aconn->min_vfreq) + aconn->min_vfreq = vsdb->min_refresh_rate_hz; } /** -@@ -13994,16 +14113,19 @@ +@@ -13996,16 +14110,19 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector, const struct drm_edid *drm_edid, bool do_mccs) { @@ -3721,7 +3879,7 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp if (!connector->state) { drm_err(adev_to_drm(adev), "%s - Connector has no state", __func__); -@@ -14031,71 +14153,67 @@ +@@ -14033,71 +14150,67 @@ if (!adev->dm.freesync_module || !dc_supports_vrr(sink->ctx->dce_version)) goto update; @@ -3843,7 +4001,7 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp } /* Handle MCCS */ -@@ -14113,6 +14231,11 @@ +@@ -14115,6 +14228,11 @@ if (dm_con_state) dm_con_state->freesync_capable = freesync_capable; @@ -3856,8 +4014,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp amdgpu_dm_connector->dc_link->replay_settings.config.replay_supported) { amdgpu_dm_connector->dc_link->replay_settings.config.replay_supported = false; diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 2026-10-07 05:21:40.931732242 +0200 ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 2026-10-03 14:48:53.000000000 +0200 @@ -187,7 +187,7 @@ } EXPORT_IF_KUNIT(amdgpu_dm_fixpt_from_s3132); @@ -3868,9 +4026,9 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp * * AMD driver supports pre-defined mathematical functions for transferring diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c 2026-09-23 12:56:16.000000000 +0200 -@@ -483,7 +483,7 @@ +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c 2026-10-07 05:21:40.932013025 +0200 ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c 2026-10-03 14:48:53.000000000 +0200 +@@ -484,7 +484,7 @@ } #endif @@ -3879,7 +4037,7 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp /** * dm_crtc_additional_color_mgmt - enable additional color properties * @crtc: DRM CRTC -@@ -565,7 +565,7 @@ +@@ -566,7 +566,7 @@ #if defined(CONFIG_DEBUG_FS) .late_register = amdgpu_dm_crtc_late_register, #endif @@ -3888,7 +4046,7 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp .atomic_set_property = amdgpu_dm_atomic_crtc_set_property, .atomic_get_property = amdgpu_dm_atomic_crtc_get_property, #endif -@@ -791,7 +791,7 @@ +@@ -792,7 +792,7 @@ drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LEGACY_LUT_ENTRIES); @@ -3898,8 +4056,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp #endif return 0; diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c 2026-10-07 05:21:40.932856968 +0200 ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c 2026-10-03 14:48:53.000000000 +0200 @@ -194,7 +194,12 @@ edid_caps->display_name, AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS); @@ -3914,7 +4072,7 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp if (edid_caps->edid_hdmi) { edid_caps->qs_bit = connector->display_info.rgb_quant_range_selectable; -@@ -1576,42 +1581,42 @@ +@@ -1577,42 +1582,42 @@ // TODO } @@ -3978,7 +4136,7 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp } bool dm_helpers_is_fullscreen(struct dc_context *ctx, struct dc_stream_state *stream) -@@ -1715,7 +1720,7 @@ +@@ -1716,7 +1721,7 @@ if (dc_is_dp_signal(link->connector_signal)) { if ((dpcd_caps->dpcd_rev.raw >= DPCD_REV_14) && (dpcd_caps->dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER) && @@ -3988,8 +4146,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp mccs_op = true; diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 2026-10-07 05:21:40.933427701 +0200 ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 2026-10-03 14:48:53.000000000 +0200 @@ -1628,7 +1628,7 @@ drm_atomic_helper_plane_destroy_state(plane, state); } @@ -4023,8 +4181,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp } - diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h ---- a/drivers/gpu/drm/amd/display/dc/dc.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/display/dc/dc.h 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/amd/display/dc/dc.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/amd/display/dc/dc.h 2026-10-03 14:48:53.000000000 +0200 @@ -1117,6 +1117,7 @@ bool scl_reset_length10; bool hdmi20_disable; @@ -4034,8 +4192,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/dc/dc.h b/drive uint8_t force_odm_combine; //bit vector based on otg inst diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h ---- a/drivers/gpu/drm/amd/display/dc/dc_types.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/amd/display/dc/dc_types.h 2026-10-07 05:21:40.934369429 +0200 ++++ b/drivers/gpu/drm/amd/display/dc/dc_types.h 2026-10-03 14:48:53.000000000 +0200 @@ -222,9 +222,14 @@ uint32_t max_tmds_clk_mhz; @@ -4053,8 +4211,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/dc/dc_types.h b bool hdr_supported; bool rr_capable; diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h b/drivers/gpu/drm/amd/display/dc/dm_helpers.h ---- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h 2026-10-03 14:48:53.000000000 +0200 @@ -231,10 +231,10 @@ const struct dc_link *link, struct set_config_cmd_payload *payload, @@ -4068,8 +4226,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h bool dm_helpers_is_hdr_on(struct dc_context *ctx, struct dc_stream_state *stream); diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/dc/dml/dsc/qp_tables.h b/drivers/gpu/drm/amd/display/dc/dml/dsc/qp_tables.h ---- a/drivers/gpu/drm/amd/display/dc/dml/dsc/qp_tables.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/display/dc/dml/dsc/qp_tables.h 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/amd/display/dc/dml/dsc/qp_tables.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/amd/display/dc/dml/dsc/qp_tables.h 2026-10-03 14:48:53.000000000 +0200 @@ -63,7 +63,7 @@ { 6.5, { 4, 6, 7, 8, 8, 8, 9, 10, 11, 11, 12, 12, 12, 13, 15} }, { 7, { 4, 5, 7, 7, 8, 8, 8, 9, 10, 11, 11, 12, 12, 13, 14} }, @@ -4089,8 +4247,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/dc/dml/dsc/qp_t { 9, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 12} }, { 9.5, { 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 12} }, diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c ---- a/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c 2026-10-03 14:48:53.000000000 +0200 @@ -123,7 +123,7 @@ *p++ = (int)((bpp <= 12) ? (-8) : ((bpp >= 15) ? (-6) : (-8 + dsc_roundf((bpp - 12) * (2 / 3.0))))); *p++ = (int)((bpp <= 12) ? (-10) : ((bpp >= 15) ? (-8) : (-10 + dsc_roundf((bpp - 12) * (2 / 3.0))))); @@ -4106,8 +4264,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_c } - diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/include/ddc_service_types.h b/drivers/gpu/drm/amd/display/include/ddc_service_types.h ---- a/drivers/gpu/drm/amd/display/include/ddc_service_types.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/display/include/ddc_service_types.h 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/amd/display/include/ddc_service_types.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/amd/display/include/ddc_service_types.h 2026-10-03 14:48:53.000000000 +0200 @@ -37,6 +37,7 @@ #define DP_BRANCH_DEVICE_ID_001CF8 0x001CF8 #define DP_BRANCH_DEVICE_ID_0060AD 0x0060AD @@ -4116,23 +4274,9 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/include/ddc_ser #define DP_BRANCH_HW_REV_10 0x10 #define DP_BRANCH_HW_REV_20 0x20 -diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig ---- a/drivers/gpu/drm/amd/display/Kconfig 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/display/Kconfig 2026-09-23 12:56:16.000000000 +0200 -@@ -68,4 +68,10 @@ - For more information on KUnit and unit tests in general, please - refer to the KUnit documentation in Documentation/dev-tools/kunit/. - -+config AMD_PRIVATE_COLOR -+ bool "Enable KMS color management by AMD for AMD" -+ default n -+ help -+ This option extends the KMS color management API with AMD driver-specific properties to enhance the color management support on AMD Steam Deck. -+ - endmenu diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c ---- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c 2026-10-03 14:48:53.000000000 +0200 @@ -27,6 +27,7 @@ #include "dc.h" #include "mod_freesync.h" @@ -4152,8 +4296,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/modules/freesyn build_vrr_infopacket_v3(stream->signal, vrr, app_tf, infopacket, stream->freesync_on_desktop); break; diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h b/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h ---- a/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h 2026-10-03 14:48:53.000000000 +0200 @@ -34,6 +34,8 @@ struct dc_info_packet; struct mod_vrr_params; @@ -4175,8 +4319,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/modules/inc/mod AS_SDP_VER_0 = 0x0, AS_SDP_VER_1 = 0x1, diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet_types.h b/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet_types.h ---- a/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet_types.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet_types.h 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet_types.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet_types.h 2026-10-03 14:48:53.000000000 +0200 @@ -29,9 +29,10 @@ enum adaptive_sync_type { ADAPTIVE_SYNC_TYPE_NONE = 0, @@ -4191,8 +4335,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/modules/inc/mod #endif /* MOD_INFO_PACKET_TYPES_H_ */ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c ---- a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c 2026-10-03 14:48:53.000000000 +0200 @@ -48,6 +48,7 @@ vsc_packet_rev7 = 7, }; @@ -4437,8 +4581,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/display/modules/info_pa break; } diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h ---- a/drivers/gpu/drm/amd/include/amd_shared.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/include/amd_shared.h 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/amd/include/amd_shared.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/amd/include/amd_shared.h 2026-10-03 14:48:53.000000000 +0200 @@ -416,6 +416,12 @@ * @DC_SKIP_DETECTION_LT: (0x200000) If set, skip detection link training */ @@ -4453,8 +4597,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/include/amd_shared.h b/ enum amd_dpm_forced_level; diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c ---- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c 2026-10-03 14:48:53.000000000 +0200 @@ -3410,6 +3410,9 @@ struct device_attribute *attr, char *buf) @@ -4466,8 +4610,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/driver } diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c ---- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c 2026-10-03 14:48:53.000000000 +0200 @@ -3001,7 +3001,10 @@ *limit = smu->max_power_limit; break; @@ -4490,8 +4634,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b "New power limit (%d) is out of range [%d,%d]\n", limit, smu->min_power_limit, smu->max_power_limit); diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c ---- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c 2026-10-03 14:48:53.000000000 +0200 @@ -674,6 +674,22 @@ int ret = 0; uint32_t feature_mask[2]; @@ -4516,8 +4660,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_ feature->feature_num < SMU_FEATURE_NUM_DEFAULT) { ret = -EINVAL; diff -ruN --no-dereference -x .git a/drivers/gpu/drm/drm_displayid_internal.h b/drivers/gpu/drm/drm_displayid_internal.h ---- a/drivers/gpu/drm/drm_displayid_internal.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/drm_displayid_internal.h 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/drm_displayid_internal.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/drm_displayid_internal.h 2026-10-03 14:48:53.000000000 +0200 @@ -67,6 +67,7 @@ #define DATA_BLOCK_2_TILED_DISPLAY_TOPOLOGY 0x28 #define DATA_BLOCK_2_CONTAINER_ID 0x29 @@ -4572,8 +4716,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/drm_displayid_internal.h b/ /* diff -ruN --no-dereference -x .git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c ---- a/drivers/gpu/drm/drm_edid.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/drm_edid.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/drm_edid.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/drm_edid.c 2026-10-03 14:48:53.000000000 +0200 @@ -45,6 +45,7 @@ #include #include @@ -4938,8 +5082,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/dr /* extended blocks are not supported yet */ if (timing_size != 6) diff -ruN --no-dereference -x .git a/drivers/gpu/drm/gud/gud_connector.c b/drivers/gpu/drm/gud/gud_connector.c ---- a/drivers/gpu/drm/gud/gud_connector.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/gud/gud_connector.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/gud/gud_connector.c 2026-10-07 05:21:40.940041990 +0200 ++++ b/drivers/gpu/drm/gud/gud_connector.c 2026-10-03 14:48:53.000000000 +0200 @@ -399,11 +399,8 @@ for (i = 0; i < num_modes; i++) { char *mode = &buf[i * GUD_CONNECTOR_TV_MODE_NAME_LEN]; @@ -4955,8 +5099,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/gud/gud_connector.c b/drive } diff -ruN --no-dereference -x .git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c ---- a/drivers/gpu/drm/i915/display/intel_ddi.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/i915/display/intel_ddi.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/i915/display/intel_ddi.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/i915/display/intel_ddi.c 2026-10-03 14:48:53.000000000 +0200 @@ -4940,6 +4940,9 @@ if (dig_port->ddi_a_4_lanes) return false; @@ -4968,8 +5112,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/i915/display/intel_ddi.c b/ * supported configuration */ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c ---- a/drivers/gpu/drm/i915/display/intel_fbdev.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/i915/display/intel_fbdev.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/i915/display/intel_fbdev.c 2026-10-03 14:48:53.000000000 +0200 @@ -280,10 +280,10 @@ ifbdev->fb = NULL; @@ -4985,8 +5129,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/i915/display/intel_fbdev.c fb->base.width, fb->base.height, sizes->fb_width, sizes->fb_height); diff -ruN --no-dereference -x .git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c ---- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c 2026-10-03 14:48:53.000000000 +0200 @@ -97,6 +97,7 @@ might_sleep(); intel_td_flush(display); @@ -4996,8 +5140,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/i915/display/intel_frontbuf intel_fbc_flush(display, frontbuffer_bits, origin); } diff -ruN --no-dereference -x .git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c ---- a/drivers/gpu/drm/i915/display/intel_psr.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/i915/display/intel_psr.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/i915/display/intel_psr.c 2026-10-07 05:21:40.941328413 +0200 ++++ b/drivers/gpu/drm/i915/display/intel_psr.c 2026-10-03 14:48:53.000000000 +0200 @@ -714,8 +714,14 @@ * To support PSR version 02h and PSR version 03h without * Y-coordinate requirement panels we would need to enable @@ -5037,7 +5181,7 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/i915/display/intel_psr.c b/ tgl_psr2_disable_dc3co(intel_dp); unlock: mutex_unlock(&intel_dp->psr.lock); -@@ -4706,3 +4721,30 @@ +@@ -4721,3 +4736,30 @@ return (pr_support & DP_PANEL_REPLAY_SUPPORT) && !(pr_cap & DP_PANEL_REPLAY_ASYNC_VIDEO_TIMING_NOT_SUPPORTED_IN_PR); } @@ -5069,8 +5213,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/i915/display/intel_psr.c b/ + } +} diff -ruN --no-dereference -x .git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h ---- a/drivers/gpu/drm/i915/display/intel_psr.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/i915/display/intel_psr.h 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/i915/display/intel_psr.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/i915/display/intel_psr.h 2026-10-03 14:48:53.000000000 +0200 @@ -40,6 +40,7 @@ void intel_psr_invalidate(struct intel_display *display, unsigned frontbuffer_bits, @@ -5080,8 +5224,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/i915/display/intel_psr.h b/ unsigned frontbuffer_bits, enum fb_op_origin origin); diff -ruN --no-dereference -x .git a/drivers/gpu/drm/i915/display/intel_quirks.c b/drivers/gpu/drm/i915/display/intel_quirks.c ---- a/drivers/gpu/drm/i915/display/intel_quirks.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/i915/display/intel_quirks.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/i915/display/intel_quirks.c 2026-10-07 05:21:40.941479770 +0200 ++++ b/drivers/gpu/drm/i915/display/intel_quirks.c 2026-10-03 14:48:53.000000000 +0200 @@ -66,6 +66,18 @@ drm_info(display->drm, "Applying Increase DDI Disabled quirk\n"); } @@ -5101,7 +5245,7 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/i915/display/intel_quirks.c static void quirk_no_pps_backlight_power_hook(struct intel_display *display) { intel_set_quirk(display, QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK); -@@ -259,6 +271,9 @@ +@@ -262,6 +274,9 @@ /* Xiaomi Book Pro 14 2026 */ { 0xb081, 0x1d72, 0x2424, quirk_disable_psr2 }, @@ -5112,8 +5256,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/i915/display/intel_quirks.c static const struct intel_dpcd_quirk intel_dpcd_quirks[] = { diff -ruN --no-dereference -x .git a/drivers/gpu/drm/i915/display/intel_quirks.h b/drivers/gpu/drm/i915/display/intel_quirks.h ---- a/drivers/gpu/drm/i915/display/intel_quirks.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/i915/display/intel_quirks.h 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/i915/display/intel_quirks.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/i915/display/intel_quirks.h 2026-10-03 14:48:53.000000000 +0200 @@ -23,6 +23,7 @@ QUIRK_EDP_LIMIT_RATE_HBR2, QUIRK_DISABLE_EDP_PANEL_REPLAY, @@ -5123,8 +5267,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/i915/display/intel_quirks.h void intel_init_quirks(struct intel_display *display); diff -ruN --no-dereference -x .git a/drivers/gpu/drm/i915/gt/intel_rc6.c b/drivers/gpu/drm/i915/gt/intel_rc6.c ---- a/drivers/gpu/drm/i915/gt/intel_rc6.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/i915/gt/intel_rc6.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/i915/gt/intel_rc6.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/i915/gt/intel_rc6.c 2026-10-03 14:48:53.000000000 +0200 @@ -2,9 +2,9 @@ /* * Copyright © 2019 Intel Corporation @@ -5155,8 +5299,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/i915/gt/intel_rc6.c b/drive return false; diff -ruN --no-dereference -x .git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c ---- a/drivers/gpu/drm/nouveau/nouveau_ttm.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/nouveau/nouveau_ttm.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c 2026-10-03 14:48:53.000000000 +0200 @@ -188,6 +188,11 @@ man->func = &nouveau_vram_manager; @@ -5170,8 +5314,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/dri drm->gem.vram_available >> PAGE_SHIFT); ttm_set_driver_manager(&drm->ttm.bdev, TTM_PL_VRAM, man); diff -ruN --no-dereference -x .git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c ---- a/drivers/gpu/drm/ttm/ttm_bo.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/ttm/ttm_bo.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/ttm/ttm_bo.c 2026-10-07 05:21:40.949498045 +0200 ++++ b/drivers/gpu/drm/ttm/ttm_bo.c 2026-10-03 14:48:53.000000000 +0200 @@ -488,6 +488,118 @@ return ret; } @@ -5478,8 +5622,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/ ret = ttm_bo_add_pipelined_eviction_fences(bo, man, ctx->no_wait_gpu); diff -ruN --no-dereference -x .git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c ---- a/drivers/gpu/drm/ttm/ttm_resource.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/ttm/ttm_resource.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/ttm/ttm_resource.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/ttm/ttm_resource.c 2026-10-03 14:48:53.000000000 +0200 @@ -386,33 +386,52 @@ } EXPORT_SYMBOL(ttm_resource_fini); @@ -5550,8 +5694,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/ttm/ttm_resource.c b/driver spin_lock(&bo->bdev->lru_lock); ttm_resource_add_bulk_move(*res_ptr, bo); diff -ruN --no-dereference -x .git a/drivers/gpu/drm/xe/display/xe_display_bo.c b/drivers/gpu/drm/xe/display/xe_display_bo.c ---- a/drivers/gpu/drm/xe/display/xe_display_bo.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/drm/xe/display/xe_display_bo.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/drm/xe/display/xe_display_bo.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/drm/xe/display/xe_display_bo.c 2026-10-03 14:48:53.000000000 +0200 @@ -147,33 +147,12 @@ struct xe_device *xe = to_xe_device(drm); struct xe_bo *obj; @@ -5593,8 +5737,8 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/drm/xe/display/xe_display_bo.c drm_err(&xe->drm, "failed to allocate framebuffer (%pe)\n", obj); return ERR_PTR(-ENOMEM); diff -ruN --no-dereference -x .git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c ---- a/drivers/gpu/vga/vga_switcheroo.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/gpu/vga/vga_switcheroo.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/gpu/vga/vga_switcheroo.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/gpu/vga/vga_switcheroo.c 2026-10-03 14:48:53.000000000 +0200 @@ -31,6 +31,7 @@ #define pr_fmt(fmt) "vga_switcheroo: " fmt @@ -5618,9 +5762,74 @@ diff -ruN --no-dereference -x .git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/ return true; } +diff -ruN --no-dereference -x .git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +--- a/drivers/hid/Kconfig 2026-10-07 05:21:40.953344198 +0200 ++++ b/drivers/hid/Kconfig 2026-10-03 14:48:53.000000000 +0200 +@@ -743,7 +743,8 @@ + Support for the Apple Magic Mouse/Trackpad multi-touch. + + Say Y here if you want support for the multi-touch features of the +- Apple Wireless "Magic" Mouse and the Apple Wireless "Magic" Trackpad. ++ Apple Wireless "Magic" Mouse, the Apple Wireless "Magic" Trackpad and ++ force touch Trackpads in Macbooks starting from 2015. + + config HID_MALTRON + tristate "Maltron L90 keyboard" +@@ -1495,4 +1496,8 @@ + + source "drivers/hid/usbhid/Kconfig" + ++source "drivers/hid/spi-hid/Kconfig" ++ ++source "drivers/hid/dockchannel-hid/Kconfig" ++ + endif # HID_SUPPORT +diff -ruN --no-dereference -x .git a/drivers/hid/Makefile b/drivers/hid/Makefile +--- a/drivers/hid/Makefile 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/hid/Makefile 2026-10-03 14:48:53.000000000 +0200 +@@ -179,6 +179,12 @@ + + obj-$(CONFIG_AMD_SFH_HID) += amd-sfh-hid/ + ++obj-$(CONFIG_HID_DOCKCHANNEL) += dockchannel-hid/ ++ ++obj-$(CONFIG_SPI_HID_APPLE_CORE) += spi-hid/ ++ ++obj-$(CONFIG_HID_DOCKCHANNEL) += dockchannel-hid/ ++ + obj-$(CONFIG_SURFACE_HID_CORE) += surface-hid/ + + obj-$(CONFIG_INTEL_THC_HID) += intel-thc-hid/ +diff -ruN --no-dereference -x .git a/drivers/hid/dockchannel-hid/Kconfig b/drivers/hid/dockchannel-hid/Kconfig +--- a/drivers/hid/dockchannel-hid/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ b/drivers/hid/dockchannel-hid/Kconfig 2026-10-03 14:48:53.000000000 +0200 +@@ -0,0 +1,13 @@ ++# SPDX-License-Identifier: GPL-2.0-only OR MIT ++menu "DockChannel HID support" ++ depends on APPLE_DOCKCHANNEL ++ ++config HID_DOCKCHANNEL ++ tristate "HID over DockChannel transport layer for Apple Silicon SoCs" ++ depends on APPLE_DOCKCHANNEL && INPUT && OF && HID ++ help ++ Say Y here if you use an M2 or later Apple Silicon based laptop. ++ The keyboard and touchpad are HID based devices connected via the ++ proprietary DockChannel interface. ++ ++endmenu +diff -ruN --no-dereference -x .git a/drivers/hid/dockchannel-hid/Makefile b/drivers/hid/dockchannel-hid/Makefile +--- a/drivers/hid/dockchannel-hid/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ b/drivers/hid/dockchannel-hid/Makefile 2026-10-03 14:48:53.000000000 +0200 +@@ -0,0 +1,6 @@ ++# SPDX-License-Identifier: GPL-2.0-only OR MIT ++# ++# Makefile for DockChannel HID transport drivers ++# ++ ++obj-$(CONFIG_HID_DOCKCHANNEL) += dockchannel-hid.o diff -ruN --no-dereference -x .git a/drivers/hid/dockchannel-hid/dockchannel-hid.c b/drivers/hid/dockchannel-hid/dockchannel-hid.c --- a/drivers/hid/dockchannel-hid/dockchannel-hid.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/hid/dockchannel-hid/dockchannel-hid.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/hid/dockchannel-hid/dockchannel-hid.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,1213 @@ +/* + * SPDX-License-Identifier: GPL-2.0 OR MIT @@ -6835,36 +7044,9 @@ diff -ruN --no-dereference -x .git a/drivers/hid/dockchannel-hid/dockchannel-hid +MODULE_DESCRIPTION("Apple DockChannel HID transport driver"); +MODULE_AUTHOR("Hector Martin "); +MODULE_LICENSE("Dual MIT/GPL"); -diff -ruN --no-dereference -x .git a/drivers/hid/dockchannel-hid/Kconfig b/drivers/hid/dockchannel-hid/Kconfig ---- a/drivers/hid/dockchannel-hid/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/hid/dockchannel-hid/Kconfig 2026-09-23 12:56:16.000000000 +0200 -@@ -0,0 +1,13 @@ -+# SPDX-License-Identifier: GPL-2.0-only OR MIT -+menu "DockChannel HID support" -+ depends on APPLE_DOCKCHANNEL -+ -+config HID_DOCKCHANNEL -+ tristate "HID over DockChannel transport layer for Apple Silicon SoCs" -+ depends on APPLE_DOCKCHANNEL && INPUT && OF && HID -+ help -+ Say Y here if you use an M2 or later Apple Silicon based laptop. -+ The keyboard and touchpad are HID based devices connected via the -+ proprietary DockChannel interface. -+ -+endmenu -diff -ruN --no-dereference -x .git a/drivers/hid/dockchannel-hid/Makefile b/drivers/hid/dockchannel-hid/Makefile ---- a/drivers/hid/dockchannel-hid/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/hid/dockchannel-hid/Makefile 2026-09-23 12:56:16.000000000 +0200 -@@ -0,0 +1,6 @@ -+# SPDX-License-Identifier: GPL-2.0-only OR MIT -+# -+# Makefile for DockChannel HID transport drivers -+# -+ -+obj-$(CONFIG_HID_DOCKCHANNEL) += dockchannel-hid.o diff -ruN --no-dereference -x .git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c ---- a/drivers/hid/hid-apple.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/hid/hid-apple.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/hid/hid-apple.c 2026-10-07 05:21:40.953665689 +0200 ++++ b/drivers/hid/hid-apple.c 2026-10-03 14:48:53.000000000 +0200 @@ -30,7 +30,7 @@ #include "hid-ids.h" @@ -7037,8 +7219,8 @@ diff -ruN --no-dereference -x .git a/drivers/hid/hid-apple.c b/drivers/hid/hid-a .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY }, { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024), diff -ruN --no-dereference -x .git a/drivers/hid/hid-appletb-kbd.c b/drivers/hid/hid-appletb-kbd.c ---- a/drivers/hid/hid-appletb-kbd.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/hid/hid-appletb-kbd.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/hid/hid-appletb-kbd.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/hid/hid-appletb-kbd.c 2026-10-03 14:48:53.000000000 +0200 @@ -56,6 +56,12 @@ module_param_named(idle_timeout, appletb_tb_idle_timeout, int, 0644); MODULE_PARM_DESC(idle_timeout, "Idle timeout in sec"); @@ -7130,8 +7312,8 @@ diff -ruN --no-dereference -x .git a/drivers/hid/hid-appletb-kbd.c b/drivers/hid } } diff -ruN --no-dereference -x .git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c ---- a/drivers/hid/hid-asus.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/hid/hid-asus.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/hid/hid-asus.c 2026-10-07 05:21:40.953754036 +0200 ++++ b/drivers/hid/hid-asus.c 2026-10-03 14:48:53.000000000 +0200 @@ -1480,12 +1480,14 @@ return ret; } @@ -7154,8 +7336,8 @@ diff -ruN --no-dereference -x .git a/drivers/hid/hid-asus.c b/drivers/hid/hid-as } diff -ruN --no-dereference -x .git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c ---- a/drivers/hid/hid-core.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/hid/hid-core.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/hid/hid-core.c 2026-10-07 05:21:40.953949908 +0200 ++++ b/drivers/hid/hid-core.c 2026-10-03 14:48:53.000000000 +0200 @@ -477,7 +477,10 @@ case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: @@ -7182,8 +7364,8 @@ diff -ruN --no-dereference -x .git a/drivers/hid/hid-core.c b/drivers/hid/hid-co bus = "VIRTUAL"; break; diff -ruN --no-dereference -x .git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h ---- a/drivers/hid/hid-ids.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/hid/hid-ids.h 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/hid/hid-ids.h 2026-10-07 05:21:40.954372120 +0200 ++++ b/drivers/hid/hid-ids.h 2026-10-03 14:48:53.000000000 +0200 @@ -96,6 +96,8 @@ #define USB_VENDOR_ID_APPLE 0x05ac @@ -7209,8 +7391,8 @@ diff -ruN --no-dereference -x .git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids #define USB_VENDOR_ID_ASETEK 0x2433 #define USB_DEVICE_ID_ASETEK_INVICTA 0xf300 diff -ruN --no-dereference -x .git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c ---- a/drivers/hid/hid-magicmouse.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/hid/hid-magicmouse.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/hid/hid-magicmouse.c 2026-10-07 05:21:40.954947252 +0200 ++++ b/drivers/hid/hid-magicmouse.c 2026-10-03 14:48:53.000000000 +0200 @@ -60,8 +60,14 @@ #define MOUSE_REPORT_ID 0x29 #define MOUSE2_REPORT_ID 0x12 @@ -8145,47 +8327,9 @@ diff -ruN --no-dereference -x .git a/drivers/hid/hid-magicmouse.c b/drivers/hid/ { } }; MODULE_DEVICE_TABLE(hid, magic_mice); -diff -ruN --no-dereference -x .git a/drivers/hid/Kconfig b/drivers/hid/Kconfig ---- a/drivers/hid/Kconfig 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/hid/Kconfig 2026-09-23 12:56:16.000000000 +0200 -@@ -743,7 +743,8 @@ - Support for the Apple Magic Mouse/Trackpad multi-touch. - - Say Y here if you want support for the multi-touch features of the -- Apple Wireless "Magic" Mouse and the Apple Wireless "Magic" Trackpad. -+ Apple Wireless "Magic" Mouse, the Apple Wireless "Magic" Trackpad and -+ force touch Trackpads in Macbooks starting from 2015. - - config HID_MALTRON - tristate "Maltron L90 keyboard" -@@ -1495,4 +1496,8 @@ - - source "drivers/hid/usbhid/Kconfig" - -+source "drivers/hid/spi-hid/Kconfig" -+ -+source "drivers/hid/dockchannel-hid/Kconfig" -+ - endif # HID_SUPPORT -diff -ruN --no-dereference -x .git a/drivers/hid/Makefile b/drivers/hid/Makefile ---- a/drivers/hid/Makefile 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/hid/Makefile 2026-09-23 12:56:16.000000000 +0200 -@@ -179,6 +179,12 @@ - - obj-$(CONFIG_AMD_SFH_HID) += amd-sfh-hid/ - -+obj-$(CONFIG_HID_DOCKCHANNEL) += dockchannel-hid/ -+ -+obj-$(CONFIG_SPI_HID_APPLE_CORE) += spi-hid/ -+ -+obj-$(CONFIG_HID_DOCKCHANNEL) += dockchannel-hid/ -+ - obj-$(CONFIG_SURFACE_HID_CORE) += surface-hid/ - - obj-$(CONFIG_INTEL_THC_HID) += intel-thc-hid/ diff -ruN --no-dereference -x .git a/drivers/hid/spi-hid/Kconfig b/drivers/hid/spi-hid/Kconfig --- a/drivers/hid/spi-hid/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/hid/spi-hid/Kconfig 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/hid/spi-hid/Kconfig 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: GPL-2.0-only +menu "SPI HID support" @@ -8213,7 +8357,7 @@ diff -ruN --no-dereference -x .git a/drivers/hid/spi-hid/Kconfig b/drivers/hid/s + select CRC16 diff -ruN --no-dereference -x .git a/drivers/hid/spi-hid/Makefile b/drivers/hid/spi-hid/Makefile --- a/drivers/hid/spi-hid/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/hid/spi-hid/Makefile 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/hid/spi-hid/Makefile 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0-only +# @@ -8227,7 +8371,7 @@ diff -ruN --no-dereference -x .git a/drivers/hid/spi-hid/Makefile b/drivers/hid/ +obj-$(CONFIG_SPI_HID_APPLE_OF) += spi-hid-apple-of.o diff -ruN --no-dereference -x .git a/drivers/hid/spi-hid/spi-hid-apple-core.c b/drivers/hid/spi-hid/spi-hid-apple-core.c --- a/drivers/hid/spi-hid/spi-hid-apple-core.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/hid/spi-hid/spi-hid-apple-core.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/hid/spi-hid/spi-hid-apple-core.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,1194 @@ +/* + * SPDX-License-Identifier: GPL-2.0 @@ -9423,48 +9567,9 @@ diff -ruN --no-dereference -x .git a/drivers/hid/spi-hid/spi-hid-apple-core.c b/ +MODULE_DESCRIPTION("Apple SPI HID transport driver"); +MODULE_AUTHOR("Janne Grunau "); +MODULE_LICENSE("GPL"); -diff -ruN --no-dereference -x .git a/drivers/hid/spi-hid/spi-hid-apple.h b/drivers/hid/spi-hid/spi-hid-apple.h ---- a/drivers/hid/spi-hid/spi-hid-apple.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/hid/spi-hid/spi-hid-apple.h 2026-09-23 12:56:16.000000000 +0200 -@@ -0,0 +1,35 @@ -+/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ -+ -+#ifndef SPI_HID_APPLE_H -+#define SPI_HID_APPLE_H -+ -+#include -+#include -+ -+/** -+ * struct spihid_apple_ops - Ops to control the device from the core driver. -+ * -+ * @power_on: reset and power the device on. -+ * @power_off: power the device off. -+ * @enable_irq: enable irq or ACPI gpe. -+ * @disable_irq: disable irq or ACPI gpe. -+ */ -+ -+struct spihid_apple_ops { -+ int (*power_on)(struct spihid_apple_ops *ops); -+ int (*power_off)(struct spihid_apple_ops *ops); -+ int (*enable_irq)(struct spihid_apple_ops *ops); -+ int (*disable_irq)(struct spihid_apple_ops *ops); -+ int (*enable_irq_wake)(struct spihid_apple_ops *ops); -+ int (*disable_irq_wake)(struct spihid_apple_ops *ops); -+}; -+ -+irqreturn_t spihid_apple_core_irq(int irq, void *data); -+ -+int spihid_apple_core_probe(struct spi_device *spi, struct spihid_apple_ops *ops); -+void spihid_apple_core_remove(struct spi_device *spi); -+void spihid_apple_core_shutdown(struct spi_device *spi); -+ -+extern const struct dev_pm_ops spihid_apple_core_pm; -+ -+#endif /* SPI_HID_APPLE_H */ diff -ruN --no-dereference -x .git a/drivers/hid/spi-hid/spi-hid-apple-of.c b/drivers/hid/spi-hid/spi-hid-apple-of.c --- a/drivers/hid/spi-hid/spi-hid-apple-of.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/hid/spi-hid/spi-hid-apple-of.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/hid/spi-hid/spi-hid-apple-of.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,153 @@ +/* + * SPDX-License-Identifier: GPL-2.0 @@ -9619,29 +9724,79 @@ diff -ruN --no-dereference -x .git a/drivers/hid/spi-hid/spi-hid-apple-of.c b/dr +MODULE_DESCRIPTION("Apple SPI HID transport driver for OpenFirmware systems"); +MODULE_AUTHOR("Janne Grunau "); +MODULE_LICENSE("GPL"); -diff -ruN --no-dereference -x .git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c ---- a/drivers/hwmon/applesmc.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/hwmon/applesmc.c 2026-09-23 12:56:16.000000000 +0200 -@@ -17,6 +17,7 @@ +diff -ruN --no-dereference -x .git a/drivers/hid/spi-hid/spi-hid-apple.h b/drivers/hid/spi-hid/spi-hid-apple.h +--- a/drivers/hid/spi-hid/spi-hid-apple.h 1970-01-01 01:00:00.000000000 +0100 ++++ b/drivers/hid/spi-hid/spi-hid-apple.h 2026-10-03 14:48:53.000000000 +0200 +@@ -0,0 +1,35 @@ ++/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ ++ ++#ifndef SPI_HID_APPLE_H ++#define SPI_HID_APPLE_H ++ ++#include ++#include ++ ++/** ++ * struct spihid_apple_ops - Ops to control the device from the core driver. ++ * ++ * @power_on: reset and power the device on. ++ * @power_off: power the device off. ++ * @enable_irq: enable irq or ACPI gpe. ++ * @disable_irq: disable irq or ACPI gpe. ++ */ ++ ++struct spihid_apple_ops { ++ int (*power_on)(struct spihid_apple_ops *ops); ++ int (*power_off)(struct spihid_apple_ops *ops); ++ int (*enable_irq)(struct spihid_apple_ops *ops); ++ int (*disable_irq)(struct spihid_apple_ops *ops); ++ int (*enable_irq_wake)(struct spihid_apple_ops *ops); ++ int (*disable_irq_wake)(struct spihid_apple_ops *ops); ++}; ++ ++irqreturn_t spihid_apple_core_irq(int irq, void *data); ++ ++int spihid_apple_core_probe(struct spi_device *spi, struct spihid_apple_ops *ops); ++void spihid_apple_core_remove(struct spi_device *spi); ++void spihid_apple_core_shutdown(struct spi_device *spi); ++ ++extern const struct dev_pm_ops spihid_apple_core_pm; ++ ++#endif /* SPI_HID_APPLE_H */ +diff -ruN --no-dereference -x .git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig +--- a/drivers/hwmon/Kconfig 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/hwmon/Kconfig 2026-10-03 14:48:53.000000000 +0200 +@@ -388,6 +388,16 @@ + Say Y here if you have an applicable laptop and want to experience + the awesome power of applesmc. - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -+#include - #include - #include - #include -@@ -1316,7 +1317,7 @@ - { - int ret; - -- if (!dmi_check_system(applesmc_whitelist)) { -+ if (!dmi_check_system(applesmc_whitelist) || dmi_check_system(t2_mac_tbl)) { - pr_warn("supported laptop not found!\n"); - ret = -ENODEV; - goto out; ++config SENSORS_APPLESMC_T2 ++ tristate "Apple SMC for T2 Macbooks" ++ depends on INPUT && X86 ++ select NEW_LEDS ++ select LEDS_CLASS ++ help ++ Duplicate of the applesmc driver patched of T2 Macbooks. A separate ++ driver is provided instead of patching the available one because of ++ incompatibilies with non-T2 Macbooks. ++ + config SENSORS_ARCTIC_FAN_CONTROLLER + tristate "ARCTIC Fan Controller" + depends on USB_HID +diff -ruN --no-dereference -x .git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile +--- a/drivers/hwmon/Makefile 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/hwmon/Makefile 2026-10-03 14:48:53.000000000 +0200 +@@ -48,6 +48,7 @@ + obj-$(CONFIG_SENSORS_ADT7475) += adt7475.o + obj-$(CONFIG_SENSORS_AHT10) += aht10.o + obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o ++obj-$(CONFIG_SENSORS_APPLESMC_T2) += applesmc-t2.o + obj-$(CONFIG_SENSORS_AQUACOMPUTER_D5NEXT) += aquacomputer_d5next.o + obj-$(CONFIG_SENSORS_ARCTIC_FAN_CONTROLLER) += arctic_fan_controller.o + obj-$(CONFIG_SENSORS_ARM_SCMI) += scmi-hwmon.o diff -ruN --no-dereference -x .git a/drivers/hwmon/applesmc-t2.c b/drivers/hwmon/applesmc-t2.c --- a/drivers/hwmon/applesmc-t2.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/hwmon/applesmc-t2.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/hwmon/applesmc-t2.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,1917 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* @@ -11560,40 +11715,29 @@ diff -ruN --no-dereference -x .git a/drivers/hwmon/applesmc-t2.c b/drivers/hwmon +MODULE_DESCRIPTION("Apple SMC"); +MODULE_LICENSE("GPL v2"); +MODULE_DEVICE_TABLE(dmi, t2_mac_tbl); -diff -ruN --no-dereference -x .git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig ---- a/drivers/hwmon/Kconfig 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/hwmon/Kconfig 2026-09-23 12:56:16.000000000 +0200 -@@ -388,6 +388,16 @@ - Say Y here if you have an applicable laptop and want to experience - the awesome power of applesmc. +diff -ruN --no-dereference -x .git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +--- a/drivers/hwmon/applesmc.c 2026-10-07 05:21:40.957905108 +0200 ++++ b/drivers/hwmon/applesmc.c 2026-10-03 14:48:53.000000000 +0200 +@@ -17,6 +17,7 @@ -+config SENSORS_APPLESMC_T2 -+ tristate "Apple SMC for T2 Macbooks" -+ depends on INPUT && X86 -+ select NEW_LEDS -+ select LEDS_CLASS -+ help -+ Duplicate of the applesmc driver patched of T2 Macbooks. A separate -+ driver is provided instead of patching the available one because of -+ incompatibilies with non-T2 Macbooks. -+ - config SENSORS_ARCTIC_FAN_CONTROLLER - tristate "ARCTIC Fan Controller" - depends on USB_HID -diff -ruN --no-dereference -x .git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile ---- a/drivers/hwmon/Makefile 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/hwmon/Makefile 2026-09-23 12:56:16.000000000 +0200 -@@ -48,6 +48,7 @@ - obj-$(CONFIG_SENSORS_ADT7475) += adt7475.o - obj-$(CONFIG_SENSORS_AHT10) += aht10.o - obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o -+obj-$(CONFIG_SENSORS_APPLESMC_T2) += applesmc-t2.o - obj-$(CONFIG_SENSORS_AQUACOMPUTER_D5NEXT) += aquacomputer_d5next.o - obj-$(CONFIG_SENSORS_ARCTIC_FAN_CONTROLLER) += arctic_fan_controller.o - obj-$(CONFIG_SENSORS_ARM_SCMI) += scmi-hwmon.o + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + ++#include + #include + #include + #include +@@ -1316,7 +1317,7 @@ + { + int ret; + +- if (!dmi_check_system(applesmc_whitelist)) { ++ if (!dmi_check_system(applesmc_whitelist) || dmi_check_system(t2_mac_tbl)) { + pr_warn("supported laptop not found!\n"); + ret = -ENODEV; + goto out; diff -ruN --no-dereference -x .git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c ---- a/drivers/i2c/i2c-core-acpi.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/i2c/i2c-core-acpi.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/i2c/i2c-core-acpi.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/i2c/i2c-core-acpi.c 2026-10-03 14:48:53.000000000 +0200 @@ -373,6 +373,7 @@ * the device works without issues on Windows at what is expected to be * a 400KHz frequency. The root cause of the issue is not known. @@ -11603,8 +11747,8 @@ diff -ruN --no-dereference -x .git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i { "ELAN0678", 0 }, { "ELAN06FA", 0 }, diff -ruN --no-dereference -x .git a/drivers/input/evdev.c b/drivers/input/evdev.c ---- a/drivers/input/evdev.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/input/evdev.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/input/evdev.c 2026-10-07 05:21:40.970240380 +0200 ++++ b/drivers/input/evdev.c 2026-10-03 14:48:53.000000000 +0200 @@ -47,6 +47,7 @@ struct fasync_struct *fasync; struct evdev *evdev; @@ -11666,8 +11810,8 @@ diff -ruN --no-dereference -x .git a/drivers/input/evdev.c b/drivers/input/evdev } diff -ruN --no-dereference -x .git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig ---- a/drivers/media/v4l2-core/Kconfig 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/media/v4l2-core/Kconfig 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/media/v4l2-core/Kconfig 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/media/v4l2-core/Kconfig 2026-10-03 14:48:53.000000000 +0200 @@ -40,6 +40,11 @@ config V4L2_JPEG_HELPER tristate @@ -11681,8 +11825,8 @@ diff -ruN --no-dereference -x .git a/drivers/media/v4l2-core/Kconfig b/drivers/m config V4L2_H264 tristate diff -ruN --no-dereference -x .git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile ---- a/drivers/media/v4l2-core/Makefile 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/media/v4l2-core/Makefile 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/media/v4l2-core/Makefile 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/media/v4l2-core/Makefile 2026-10-03 14:48:53.000000000 +0200 @@ -34,5 +34,7 @@ obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o obj-$(CONFIG_V4L2_VP9) += v4l2-vp9.o @@ -11693,7 +11837,7 @@ diff -ruN --no-dereference -x .git a/drivers/media/v4l2-core/Makefile b/drivers/ obj-$(CONFIG_VIDEO_DEV) += v4l2-dv-timings.o videodev.o diff -ruN --no-dereference -x .git a/drivers/media/v4l2-core/v4l2loopback.c b/drivers/media/v4l2-core/v4l2loopback.c --- a/drivers/media/v4l2-core/v4l2loopback.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/media/v4l2-core/v4l2loopback.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/media/v4l2-core/v4l2loopback.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,3375 @@ +/* -*- c-file-style: "linux" -*- */ +/* @@ -15070,9 +15214,121 @@ diff -ruN --no-dereference -x .git a/drivers/media/v4l2-core/v4l2loopback.c b/dr + +module_init(v4l2loopback_init_module); +module_exit(v4l2loopback_cleanup_module); +diff -ruN --no-dereference -x .git a/drivers/media/v4l2-core/v4l2loopback.h b/drivers/media/v4l2-core/v4l2loopback.h +--- a/drivers/media/v4l2-core/v4l2loopback.h 1970-01-01 01:00:00.000000000 +0100 ++++ b/drivers/media/v4l2-core/v4l2loopback.h 2026-10-03 14:48:53.000000000 +0200 +@@ -0,0 +1,108 @@ ++/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ ++/* ++ * v4l2loopback.h ++ * ++ * Written by IOhannes m zmölnig, 7/1/20. ++ * ++ * Copyright 2020 by IOhannes m zmölnig. Redistribution of this file is ++ * permitted under the GNU General Public License. ++ */ ++#ifndef _V4L2LOOPBACK_H ++#define _V4L2LOOPBACK_H ++ ++#define V4L2LOOPBACK_VERSION_MAJOR 0 ++#define V4L2LOOPBACK_VERSION_MINOR 15 ++#define V4L2LOOPBACK_VERSION_BUGFIX 4 ++ ++/* /dev/v4l2loopback interface */ ++ ++struct v4l2_loopback_config { ++ /** ++ * the device-number (/dev/video) ++ * V4L2LOOPBACK_CTL_ADD: ++ * setting this to a value<0, will allocate an available one ++ * if nr>=0 and the device already exists, the ioctl will EEXIST ++ * if output_nr and capture_nr are the same, only a single device will be created ++ * NOTE: currently split-devices (where output_nr and capture_nr differ) ++ * are not implemented yet. ++ * until then, requesting different device-IDs will result in EINVAL. ++ * ++ * V4L2LOOPBACK_CTL_QUERY: ++ * either both output_nr and capture_nr must refer to the same loopback, ++ * or one (and only one) of them must be -1 ++ * ++ */ ++ __s32 output_nr; ++ __s32 unused; /*capture_nr;*/ ++ ++ /** ++ * a nice name for your device ++ * if (*card_label)==0, an automatic name is assigned ++ */ ++ char card_label[32]; ++ ++ /** ++ * allowed frame size ++ * if too low, default values are used ++ */ ++ __u32 min_width; ++ __u32 max_width; ++ __u32 min_height; ++ __u32 max_height; ++ ++ /** ++ * number of buffers to allocate for the queue ++ * if set to <=0, default values are used ++ */ ++ __s32 max_buffers; ++ ++ /** ++ * how many consumers are allowed to open this device concurrently ++ * if set to <=0, default values are used ++ */ ++ __s32 max_openers; ++ ++ /** ++ * set the debugging level for this device ++ */ ++ __s32 debug; ++ ++ /** ++ * whether to announce OUTPUT/CAPTURE capabilities exclusively ++ * for this device or not ++ * (!exclusive_caps) ++ * NOTE: this is going to be removed once separate output/capture ++ * devices are implemented ++ */ ++ __s32 announce_all_caps; ++}; ++ ++#define V4L2LOOPBACK_CTL_IOCTLMAGIC '~' ++ ++/* a pointer to an (unsigned int) that - on success - will hold ++ * the version code of the v4l2loopback module ++ * as returned by KERNEL_VERSION(MAJOR, MINOR, BUGFIX) ++ */ ++#define V4L2LOOPBACK_CTL_VERSION _IOR(V4L2LOOPBACK_CTL_IOCTLMAGIC, 0, __u32) ++ ++/* a pointer to a (struct v4l2_loopback_config) that has all values you wish to impose on the ++ * to-be-created device set. ++ * if the ptr is NULL, a new device is created with default values at the driver's discretion. ++ * ++ * returns the device_nr of the OUTPUT device (which can be used with V4L2LOOPBACK_CTL_QUERY, ++ * to get more information on the device) ++ */ ++#define V4L2LOOPBACK_CTL_ADD \ ++ _IOW(V4L2LOOPBACK_CTL_IOCTLMAGIC, 1, struct v4l2_loopback_config) ++ ++/* the device-number (either CAPTURE or OUTPUT) associated with the loopback-device */ ++#define V4L2LOOPBACK_CTL_REMOVE _IOW(V4L2LOOPBACK_CTL_IOCTLMAGIC, 2, __u32) ++ ++/* a pointer to a (struct v4l2_loopback_config) that has output_nr and/or capture_nr set ++ * (the two values must either refer to video-devices associated with the same loopback device ++ * or exactly one of them must be <0 ++ */ ++#define V4L2LOOPBACK_CTL_QUERY \ ++ _IOWR(V4L2LOOPBACK_CTL_IOCTLMAGIC, 3, struct v4l2_loopback_config) ++ ++#endif /* _V4L2LOOPBACK_H */ diff -ruN --no-dereference -x .git a/drivers/media/v4l2-core/v4l2loopback_formats.h b/drivers/media/v4l2-core/v4l2loopback_formats.h --- a/drivers/media/v4l2-core/v4l2loopback_formats.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/media/v4l2-core/v4l2loopback_formats.h 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/media/v4l2-core/v4l2loopback_formats.h 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,445 @@ +static const struct v4l2l_format formats[] = { +#ifndef V4L2_PIX_FMT_VP9 @@ -15519,121 +15775,27 @@ diff -ruN --no-dereference -x .git a/drivers/media/v4l2-core/v4l2loopback_format + }, +#endif /* V4L2_PIX_FMT_HEVC */ +}; -diff -ruN --no-dereference -x .git a/drivers/media/v4l2-core/v4l2loopback.h b/drivers/media/v4l2-core/v4l2loopback.h ---- a/drivers/media/v4l2-core/v4l2loopback.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/media/v4l2-core/v4l2loopback.h 2026-09-23 12:56:16.000000000 +0200 -@@ -0,0 +1,108 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ -+/* -+ * v4l2loopback.h -+ * -+ * Written by IOhannes m zmölnig, 7/1/20. -+ * -+ * Copyright 2020 by IOhannes m zmölnig. Redistribution of this file is -+ * permitted under the GNU General Public License. -+ */ -+#ifndef _V4L2LOOPBACK_H -+#define _V4L2LOOPBACK_H -+ -+#define V4L2LOOPBACK_VERSION_MAJOR 0 -+#define V4L2LOOPBACK_VERSION_MINOR 15 -+#define V4L2LOOPBACK_VERSION_BUGFIX 4 -+ -+/* /dev/v4l2loopback interface */ -+ -+struct v4l2_loopback_config { -+ /** -+ * the device-number (/dev/video) -+ * V4L2LOOPBACK_CTL_ADD: -+ * setting this to a value<0, will allocate an available one -+ * if nr>=0 and the device already exists, the ioctl will EEXIST -+ * if output_nr and capture_nr are the same, only a single device will be created -+ * NOTE: currently split-devices (where output_nr and capture_nr differ) -+ * are not implemented yet. -+ * until then, requesting different device-IDs will result in EINVAL. -+ * -+ * V4L2LOOPBACK_CTL_QUERY: -+ * either both output_nr and capture_nr must refer to the same loopback, -+ * or one (and only one) of them must be -1 -+ * -+ */ -+ __s32 output_nr; -+ __s32 unused; /*capture_nr;*/ -+ -+ /** -+ * a nice name for your device -+ * if (*card_label)==0, an automatic name is assigned -+ */ -+ char card_label[32]; -+ -+ /** -+ * allowed frame size -+ * if too low, default values are used -+ */ -+ __u32 min_width; -+ __u32 max_width; -+ __u32 min_height; -+ __u32 max_height; -+ -+ /** -+ * number of buffers to allocate for the queue -+ * if set to <=0, default values are used -+ */ -+ __s32 max_buffers; -+ -+ /** -+ * how many consumers are allowed to open this device concurrently -+ * if set to <=0, default values are used -+ */ -+ __s32 max_openers; -+ -+ /** -+ * set the debugging level for this device -+ */ -+ __s32 debug; -+ -+ /** -+ * whether to announce OUTPUT/CAPTURE capabilities exclusively -+ * for this device or not -+ * (!exclusive_caps) -+ * NOTE: this is going to be removed once separate output/capture -+ * devices are implemented -+ */ -+ __s32 announce_all_caps; -+}; -+ -+#define V4L2LOOPBACK_CTL_IOCTLMAGIC '~' -+ -+/* a pointer to an (unsigned int) that - on success - will hold -+ * the version code of the v4l2loopback module -+ * as returned by KERNEL_VERSION(MAJOR, MINOR, BUGFIX) -+ */ -+#define V4L2LOOPBACK_CTL_VERSION _IOR(V4L2LOOPBACK_CTL_IOCTLMAGIC, 0, __u32) -+ -+/* a pointer to a (struct v4l2_loopback_config) that has all values you wish to impose on the -+ * to-be-created device set. -+ * if the ptr is NULL, a new device is created with default values at the driver's discretion. -+ * -+ * returns the device_nr of the OUTPUT device (which can be used with V4L2LOOPBACK_CTL_QUERY, -+ * to get more information on the device) -+ */ -+#define V4L2LOOPBACK_CTL_ADD \ -+ _IOW(V4L2LOOPBACK_CTL_IOCTLMAGIC, 1, struct v4l2_loopback_config) -+ -+/* the device-number (either CAPTURE or OUTPUT) associated with the loopback-device */ -+#define V4L2LOOPBACK_CTL_REMOVE _IOW(V4L2LOOPBACK_CTL_IOCTLMAGIC, 2, __u32) -+ -+/* a pointer to a (struct v4l2_loopback_config) that has output_nr and/or capture_nr set -+ * (the two values must either refer to video-devices associated with the same loopback device -+ * or exactly one of them must be <0 -+ */ -+#define V4L2LOOPBACK_CTL_QUERY \ -+ _IOWR(V4L2LOOPBACK_CTL_IOCTLMAGIC, 3, struct v4l2_loopback_config) -+ -+#endif /* _V4L2LOOPBACK_H */ +diff -ruN --no-dereference -x .git a/drivers/net/wireguard/queueing.h b/drivers/net/wireguard/queueing.h +--- a/drivers/net/wireguard/queueing.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/net/wireguard/queueing.h 2026-10-03 14:48:53.000000000 +0200 +@@ -78,12 +78,14 @@ + u8 l4_hash = skb->l4_hash; + u8 sw_hash = skb->sw_hash; + u32 hash = skb->hash; ++ u8 tstamp_type = skb->tstamp_type; + skb_scrub_packet(skb, true); + memset(&skb->headers, 0, sizeof(skb->headers)); + if (encapsulating) { + skb->l4_hash = l4_hash; + skb->sw_hash = sw_hash; + skb->hash = hash; ++ skb->tstamp_type = tstamp_type; + } + skb->queue_mapping = 0; + skb->nohdr = 0; diff -ruN --no-dereference -x .git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c ---- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c 2026-10-03 14:48:53.000000000 +0200 @@ -516,6 +516,10 @@ u32 link_id = u32_get_bits(info->control.flags, IEEE80211_TX_CTRL_MLO_LINK); @@ -15646,8 +15808,8 @@ diff -ruN --no-dereference -x .git a/drivers/net/wireless/intel/iwlwifi/mld/mac8 * so the FW can't translate the MLD addr to the link addr. Do it here */ diff -ruN --no-dereference -x .git a/drivers/net/wireless/intel/iwlwifi/mld/tx.c b/drivers/net/wireless/intel/iwlwifi/mld/tx.c ---- a/drivers/net/wireless/intel/iwlwifi/mld/tx.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/net/wireless/intel/iwlwifi/mld/tx.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/net/wireless/intel/iwlwifi/mld/tx.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/net/wireless/intel/iwlwifi/mld/tx.c 2026-10-03 14:48:53.000000000 +0200 @@ -987,6 +987,9 @@ struct sk_buff *skb = NULL; u8 zero_addr[ETH_ALEN] = {}; @@ -15658,9 +15820,492 @@ diff -ruN --no-dereference -x .git a/drivers/net/wireless/intel/iwlwifi/mld/tx.c /* * Don't transmit during firmware restart. The firmware is dead, * so iwl_trans_tx() would return -EIO for each frame. Avoid the +diff -ruN --no-dereference -x .git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile +--- a/drivers/pci/controller/Makefile 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/pci/controller/Makefile 2026-10-03 14:48:53.000000000 +0200 +@@ -1,4 +1,10 @@ + # SPDX-License-Identifier: GPL-2.0 ++ifdef CONFIG_X86_64 ++ifdef CONFIG_SATA_AHCI ++obj-y += intel-nvme-remap.o ++endif ++endif ++ + obj-$(CONFIG_PCIE_CADENCE) += cadence/ + obj-$(CONFIG_PCI_FTPCI100) += pci-ftpci100.o + obj-$(CONFIG_PCI_IXP4XX) += pci-ixp4xx.o +diff -ruN --no-dereference -x .git a/drivers/pci/controller/intel-nvme-remap.c b/drivers/pci/controller/intel-nvme-remap.c +--- a/drivers/pci/controller/intel-nvme-remap.c 1970-01-01 01:00:00.000000000 +0100 ++++ b/drivers/pci/controller/intel-nvme-remap.c 2026-10-03 14:48:53.000000000 +0200 +@@ -0,0 +1,465 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Intel remapped NVMe device support. ++ * ++ * Copyright (c) 2019 Endless Mobile, Inc. ++ * Author: Daniel Drake ++ * ++ * Some products ship by default with the SATA controller in "RAID" or ++ * "Intel RST Premium With Intel Optane System Acceleration" mode. Under this ++ * mode, which we refer to as "remapped NVMe" mode, any installed NVMe ++ * devices disappear from the PCI bus, and instead their I/O memory becomes ++ * available within the AHCI device BARs. ++ * ++ * This scheme is understood to be a way of avoiding usage of the standard ++ * Windows NVMe driver under that OS, instead mandating usage of Intel's ++ * driver instead, which has better power management, and presumably offers ++ * some RAID/disk-caching solutions too. ++ * ++ * Here in this driver, we support the remapped NVMe mode by claiming the ++ * AHCI device and creating a fake PCIe root port. On the new bus, the ++ * original AHCI device is exposed with only minor tweaks. Then, fake PCI ++ * devices corresponding to the remapped NVMe devices are created. The usual ++ * ahci and nvme drivers are then expected to bind to these devices and ++ * operate as normal. ++ * ++ * The PCI configuration space for the NVMe devices is completely ++ * unavailable, so we fake a minimal one and hope for the best. ++ * ++ * Interrupts are shared between the AHCI and NVMe devices. For simplicity, ++ * we only support the legacy interrupt here, although MSI support ++ * could potentially be added later. ++ */ ++ ++#define MODULE_NAME "intel-nvme-remap" ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define AHCI_PCI_BAR_STANDARD 5 ++ ++struct nvme_remap_dev { ++ struct pci_dev *dev; /* AHCI device */ ++ struct pci_bus *bus; /* our fake PCI bus */ ++ struct pci_sysdata sysdata; ++ int irq_base; /* our fake interrupts */ ++ ++ /* ++ * When we detect an all-ones write to a BAR register, this flag ++ * is set, so that we return the BAR size on the next read (a ++ * standard PCI behaviour). ++ * This includes the assumption that an all-ones BAR write is ++ * immediately followed by a read of the same register. ++ */ ++ bool bar_sizing; ++ ++ /* ++ * Resources copied from the AHCI device, to be regarded as ++ * resources on our fake bus. ++ */ ++ struct resource ahci_resources[PCI_NUM_RESOURCES]; ++ ++ /* Resources corresponding to the NVMe devices. */ ++ struct resource remapped_dev_mem[AHCI_MAX_REMAP]; ++ ++ /* Number of remapped NVMe devices found. */ ++ int num_remapped_devices; ++}; ++ ++static inline struct nvme_remap_dev *nrdev_from_bus(struct pci_bus *bus) ++{ ++ return container_of(bus->sysdata, struct nvme_remap_dev, sysdata); ++} ++ ++ ++/******** PCI configuration space **********/ ++ ++/* ++ * Helper macros for tweaking returned contents of PCI configuration space. ++ * ++ * value contains len bytes of data read from reg. ++ * If fixup_reg is included in that range, fix up the contents of that ++ * register to fixed_value. ++ */ ++#define NR_FIX8(fixup_reg, fixed_value) do { \ ++ if (reg <= fixup_reg && fixup_reg < reg + len) \ ++ ((u8 *) value)[fixup_reg - reg] = (u8) (fixed_value); \ ++ } while (0) ++ ++#define NR_FIX16(fixup_reg, fixed_value) do { \ ++ NR_FIX8(fixup_reg, fixed_value); \ ++ NR_FIX8(fixup_reg + 1, fixed_value >> 8); \ ++ } while (0) ++ ++#define NR_FIX24(fixup_reg, fixed_value) do { \ ++ NR_FIX8(fixup_reg, fixed_value); \ ++ NR_FIX8(fixup_reg + 1, fixed_value >> 8); \ ++ NR_FIX8(fixup_reg + 2, fixed_value >> 16); \ ++ } while (0) ++ ++#define NR_FIX32(fixup_reg, fixed_value) do { \ ++ NR_FIX16(fixup_reg, (u16) fixed_value); \ ++ NR_FIX16(fixup_reg + 2, fixed_value >> 16); \ ++ } while (0) ++ ++/* ++ * Read PCI config space of the slot 0 (AHCI) device. ++ * We pass through the read request to the underlying device, but ++ * tweak the results in some cases. ++ */ ++static int nvme_remap_pci_read_slot0(struct pci_bus *bus, int reg, ++ int len, u32 *value) ++{ ++ struct nvme_remap_dev *nrdev = nrdev_from_bus(bus); ++ struct pci_bus *ahci_dev_bus = nrdev->dev->bus; ++ int ret; ++ ++ ret = ahci_dev_bus->ops->read(ahci_dev_bus, nrdev->dev->devfn, ++ reg, len, value); ++ if (ret) ++ return ret; ++ ++ /* ++ * Adjust the device class, to prevent this driver from attempting to ++ * additionally probe the device we're simulating here. ++ */ ++ NR_FIX24(PCI_CLASS_PROG, PCI_CLASS_STORAGE_SATA_AHCI); ++ ++ /* ++ * Unset interrupt pin, otherwise ACPI tries to find routing ++ * info for our virtual IRQ, fails, and complains. ++ */ ++ NR_FIX8(PCI_INTERRUPT_PIN, 0); ++ ++ /* ++ * Truncate the AHCI BAR to not include the region that covers the ++ * hidden devices. This will cause the ahci driver to successfully ++ * probe th new device (instead of handing it over to this driver). ++ */ ++ if (nrdev->bar_sizing) { ++ NR_FIX32(PCI_BASE_ADDRESS_5, ~(SZ_16K - 1)); ++ nrdev->bar_sizing = false; ++ } ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++/* ++ * Read PCI config space of a remapped device. ++ * Since the original PCI config space is inaccessible, we provide a minimal, ++ * fake config space instead. ++ */ ++static int nvme_remap_pci_read_remapped(struct pci_bus *bus, unsigned int port, ++ int reg, int len, u32 *value) ++{ ++ struct nvme_remap_dev *nrdev = nrdev_from_bus(bus); ++ struct resource *remapped_mem; ++ ++ if (port > nrdev->num_remapped_devices) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ ++ *value = 0; ++ remapped_mem = &nrdev->remapped_dev_mem[port - 1]; ++ ++ /* Set a Vendor ID, otherwise Linux assumes no device is present */ ++ NR_FIX16(PCI_VENDOR_ID, PCI_VENDOR_ID_INTEL); ++ ++ /* Always appear on & bus mastering */ ++ NR_FIX16(PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); ++ ++ /* Set class so that nvme driver probes us */ ++ NR_FIX24(PCI_CLASS_PROG, PCI_CLASS_STORAGE_EXPRESS); ++ ++ if (nrdev->bar_sizing) { ++ NR_FIX32(PCI_BASE_ADDRESS_0, ++ ~(resource_size(remapped_mem) - 1)); ++ nrdev->bar_sizing = false; ++ } else { ++ resource_size_t mem_start = remapped_mem->start; ++ ++ mem_start |= PCI_BASE_ADDRESS_MEM_TYPE_64; ++ NR_FIX32(PCI_BASE_ADDRESS_0, mem_start); ++ mem_start >>= 32; ++ NR_FIX32(PCI_BASE_ADDRESS_1, mem_start); ++ } ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++/* Read PCI configuration space. */ ++static int nvme_remap_pci_read(struct pci_bus *bus, unsigned int devfn, ++ int reg, int len, u32 *value) ++{ ++ if (PCI_SLOT(devfn) == 0) ++ return nvme_remap_pci_read_slot0(bus, reg, len, value); ++ else ++ return nvme_remap_pci_read_remapped(bus, PCI_SLOT(devfn), ++ reg, len, value); ++} ++ ++/* ++ * Write PCI config space of the slot 0 (AHCI) device. ++ * Apart from the special case of BAR sizing, we disable all writes. ++ * Otherwise, the ahci driver could make changes (e.g. unset PCI bus master) ++ * that would affect the operation of the NVMe devices. ++ */ ++static int nvme_remap_pci_write_slot0(struct pci_bus *bus, int reg, ++ int len, u32 value) ++{ ++ struct nvme_remap_dev *nrdev = nrdev_from_bus(bus); ++ struct pci_bus *ahci_dev_bus = nrdev->dev->bus; ++ ++ if (reg >= PCI_BASE_ADDRESS_0 && reg <= PCI_BASE_ADDRESS_5) { ++ /* ++ * Writing all-ones to a BAR means that the size of the ++ * memory region is being checked. Flag this so that we can ++ * reply with an appropriate size on the next read. ++ */ ++ if (value == ~0) ++ nrdev->bar_sizing = true; ++ ++ return ahci_dev_bus->ops->write(ahci_dev_bus, ++ nrdev->dev->devfn, ++ reg, len, value); ++ } ++ ++ return PCIBIOS_SET_FAILED; ++} ++ ++/* ++ * Write PCI config space of a remapped device. ++ * Since the original PCI config space is inaccessible, we reject all ++ * writes, except for the special case of BAR probing. ++ */ ++static int nvme_remap_pci_write_remapped(struct pci_bus *bus, ++ unsigned int port, ++ int reg, int len, u32 value) ++{ ++ struct nvme_remap_dev *nrdev = nrdev_from_bus(bus); ++ ++ if (port > nrdev->num_remapped_devices) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ ++ /* ++ * Writing all-ones to a BAR means that the size of the memory ++ * region is being checked. Flag this so that we can reply with ++ * an appropriate size on the next read. ++ */ ++ if (value == ~0 && reg >= PCI_BASE_ADDRESS_0 ++ && reg <= PCI_BASE_ADDRESS_5) { ++ nrdev->bar_sizing = true; ++ return PCIBIOS_SUCCESSFUL; ++ } ++ ++ return PCIBIOS_SET_FAILED; ++} ++ ++/* Write PCI configuration space. */ ++static int nvme_remap_pci_write(struct pci_bus *bus, unsigned int devfn, ++ int reg, int len, u32 value) ++{ ++ if (PCI_SLOT(devfn) == 0) ++ return nvme_remap_pci_write_slot0(bus, reg, len, value); ++ else ++ return nvme_remap_pci_write_remapped(bus, PCI_SLOT(devfn), ++ reg, len, value); ++} ++ ++static struct pci_ops nvme_remap_pci_ops = { ++ .read = nvme_remap_pci_read, ++ .write = nvme_remap_pci_write, ++}; ++ ++ ++/******** Initialization & exit **********/ ++ ++/* ++ * Find a PCI domain ID to use for our fake bus. ++ * Start at 0x10000 to not clash with ACPI _SEG domains (16 bits). ++ */ ++static int find_free_domain(void) ++{ ++ int domain = 0xffff; ++ struct pci_bus *bus = NULL; ++ ++ while ((bus = pci_find_next_bus(bus)) != NULL) ++ domain = max_t(int, domain, pci_domain_nr(bus)); ++ ++ return domain + 1; ++} ++ ++static int find_remapped_devices(struct nvme_remap_dev *nrdev, ++ struct list_head *resources) ++{ ++ void __iomem *mmio; ++ int i, count = 0; ++ u32 cap; ++ ++ mmio = pcim_iomap(nrdev->dev, AHCI_PCI_BAR_STANDARD, ++ pci_resource_len(nrdev->dev, ++ AHCI_PCI_BAR_STANDARD)); ++ if (!mmio) ++ return -ENODEV; ++ ++ /* Check if this device might have remapped nvme devices. */ ++ if (pci_resource_len(nrdev->dev, AHCI_PCI_BAR_STANDARD) < SZ_512K || ++ !(readl(mmio + AHCI_VSCAP) & 1)) ++ return -ENODEV; ++ ++ cap = readq(mmio + AHCI_REMAP_CAP); ++ for (i = AHCI_MAX_REMAP-1; i >= 0; i--) { ++ struct resource *remapped_mem; ++ ++ if ((cap & (1 << i)) == 0) ++ continue; ++ if (readl(mmio + ahci_remap_dcc(i)) ++ != PCI_CLASS_STORAGE_EXPRESS) ++ continue; ++ ++ /* We've found a remapped device */ ++ remapped_mem = &nrdev->remapped_dev_mem[count++]; ++ remapped_mem->start = ++ pci_resource_start(nrdev->dev, AHCI_PCI_BAR_STANDARD) ++ + ahci_remap_base(i); ++ remapped_mem->end = remapped_mem->start ++ + AHCI_REMAP_N_SIZE - 1; ++ remapped_mem->flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED; ++ pci_add_resource(resources, remapped_mem); ++ } ++ ++ pcim_iounmap(nrdev->dev, mmio); ++ ++ if (count == 0) ++ return -ENODEV; ++ ++ nrdev->num_remapped_devices = count; ++ dev_info(&nrdev->dev->dev, "Found %d remapped NVMe devices\n", ++ nrdev->num_remapped_devices); ++ return 0; ++} ++ ++static void nvme_remap_remove_root_bus(void *data) ++{ ++ struct pci_bus *bus = data; ++ ++ pci_stop_root_bus(bus); ++ pci_remove_root_bus(bus); ++} ++ ++static int nvme_remap_probe(struct pci_dev *dev, ++ const struct pci_device_id *id) ++{ ++ struct nvme_remap_dev *nrdev; ++ LIST_HEAD(resources); ++ int i; ++ int ret; ++ struct pci_dev *child; ++ ++ nrdev = devm_kzalloc(&dev->dev, sizeof(*nrdev), GFP_KERNEL); ++ if (!nrdev) ++ return -ENOMEM; ++ ++ nrdev->sysdata.domain = find_free_domain(); ++ nrdev->sysdata.nvme_remap_dev = dev; ++ nrdev->dev = dev; ++ pci_set_drvdata(dev, nrdev); ++ ++ ret = pcim_enable_device(dev); ++ if (ret < 0) ++ return ret; ++ ++ pci_set_master(dev); ++ ++ ret = find_remapped_devices(nrdev, &resources); ++ if (ret) ++ return ret; ++ ++ /* Add resources from the original AHCI device */ ++ for (i = 0; i < PCI_NUM_RESOURCES; i++) { ++ struct resource *res = &dev->resource[i]; ++ ++ if (res->start) { ++ struct resource *nr_res = &nrdev->ahci_resources[i]; ++ ++ nr_res->start = res->start; ++ nr_res->end = res->end; ++ nr_res->flags = res->flags; ++ pci_add_resource(&resources, nr_res); ++ } ++ } ++ ++ /* Create virtual interrupts */ ++ nrdev->irq_base = devm_irq_alloc_descs(&dev->dev, -1, 0, ++ nrdev->num_remapped_devices + 1, ++ 0); ++ if (nrdev->irq_base < 0) ++ return nrdev->irq_base; ++ ++ /* Create and populate PCI bus */ ++ nrdev->bus = pci_create_root_bus(&dev->dev, 0, &nvme_remap_pci_ops, ++ &nrdev->sysdata, &resources); ++ if (!nrdev->bus) ++ return -ENODEV; ++ ++ if (devm_add_action_or_reset(&dev->dev, nvme_remap_remove_root_bus, ++ nrdev->bus)) ++ return -ENOMEM; ++ ++ /* We don't support sharing MSI interrupts between these devices */ ++ nrdev->bus->bus_flags |= PCI_BUS_FLAGS_NO_MSI; ++ ++ pci_scan_child_bus(nrdev->bus); ++ ++ list_for_each_entry(child, &nrdev->bus->devices, bus_list) { ++ /* ++ * Prevent PCI core from trying to move memory BARs around. ++ * The hidden NVMe devices are at fixed locations. ++ */ ++ for (i = 0; i < PCI_NUM_RESOURCES; i++) { ++ struct resource *res = &child->resource[i]; ++ ++ if (res->flags & IORESOURCE_MEM) ++ res->flags |= IORESOURCE_PCI_FIXED; ++ } ++ ++ /* Share the legacy IRQ between all devices */ ++ child->irq = dev->irq; ++ } ++ ++ pci_assign_unassigned_bus_resources(nrdev->bus); ++ pci_bus_add_devices(nrdev->bus); ++ ++ return 0; ++} ++ ++static const struct pci_device_id nvme_remap_ids[] = { ++ /* ++ * Match all Intel RAID controllers. ++ * ++ * There's overlap here with the set of devices detected by the ahci ++ * driver, but ahci will only successfully probe when there ++ * *aren't* any remapped NVMe devices, and this driver will only ++ * successfully probe when there *are* remapped NVMe devices that ++ * need handling. ++ */ ++ { ++ PCI_VDEVICE(INTEL, PCI_ANY_ID), ++ .class = PCI_CLASS_STORAGE_RAID << 8, ++ .class_mask = 0xffffff00, ++ }, ++ {0,} ++}; ++MODULE_DEVICE_TABLE(pci, nvme_remap_ids); ++ ++static struct pci_driver nvme_remap_drv = { ++ .name = MODULE_NAME, ++ .id_table = nvme_remap_ids, ++ .probe = nvme_remap_probe, ++}; ++module_pci_driver(nvme_remap_drv); ++ ++MODULE_AUTHOR("Daniel Drake "); ++MODULE_LICENSE("GPL v2"); diff -ruN --no-dereference -x .git a/drivers/pci/quirks.c b/drivers/pci/quirks.c ---- a/drivers/pci/quirks.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/pci/quirks.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/pci/quirks.c 2026-10-07 05:21:41.042696267 +0200 ++++ b/drivers/pci/quirks.c 2026-10-03 14:48:53.000000000 +0200 @@ -3747,6 +3747,106 @@ dev->dev_flags |= PCI_DEV_FLAGS_NO_BUS_RESET; } @@ -15777,8 +16422,8 @@ diff -ruN --no-dereference -x .git a/drivers/pci/quirks.c b/drivers/pci/quirks.c }; diff -ruN --no-dereference -x .git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c ---- a/drivers/pci/vgaarb.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/pci/vgaarb.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/pci/vgaarb.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/pci/vgaarb.c 2026-10-03 14:48:53.000000000 +0200 @@ -143,6 +143,7 @@ pci_dev_put(vga_default); vga_default = pci_dev_get(pdev); @@ -15788,8 +16433,8 @@ diff -ruN --no-dereference -x .git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c /** * vga_remove_vgacon - deactivate VGA console diff -ruN --no-dereference -x .git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c ---- a/drivers/platform/x86/apple-gmux.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/platform/x86/apple-gmux.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/platform/x86/apple-gmux.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/platform/x86/apple-gmux.c 2026-10-03 14:48:53.000000000 +0200 @@ -21,6 +21,7 @@ #include #include @@ -15830,8 +16475,8 @@ diff -ruN --no-dereference -x .git a/drivers/platform/x86/apple-gmux.c b/drivers * Retina MacBook Pros cannot switch the panel's AUX separately * and need eDP pre-calibration. They are distinguishable from diff -ruN --no-dereference -x .git a/drivers/platform/x86/serial-multi-instantiate.c b/drivers/platform/x86/serial-multi-instantiate.c ---- a/drivers/platform/x86/serial-multi-instantiate.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/platform/x86/serial-multi-instantiate.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/platform/x86/serial-multi-instantiate.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/platform/x86/serial-multi-instantiate.c 2026-10-03 14:48:53.000000000 +0200 @@ -307,6 +307,15 @@ smi_devs_unregister(smi); } @@ -15881,8 +16526,8 @@ diff -ruN --no-dereference -x .git a/drivers/platform/x86/serial-multi-instantia /* Non-conforming _HID for Cirrus Logic already released */ { "CLSA0100", (unsigned long)&cs35l41_hda }, diff -ruN --no-dereference -x .git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig ---- a/drivers/scsi/Kconfig 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/scsi/Kconfig 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/scsi/Kconfig 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/scsi/Kconfig 2026-10-03 14:48:53.000000000 +0200 @@ -1522,4 +1522,6 @@ source "drivers/scsi/device_handler/Kconfig" @@ -15891,8 +16536,8 @@ diff -ruN --no-dereference -x .git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig + endmenu diff -ruN --no-dereference -x .git a/drivers/scsi/Makefile b/drivers/scsi/Makefile ---- a/drivers/scsi/Makefile 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/scsi/Makefile 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/scsi/Makefile 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/scsi/Makefile 2026-10-03 14:48:53.000000000 +0200 @@ -152,6 +152,7 @@ obj-$(CONFIG_SCSI_ENCLOSURE) += ses.o @@ -15903,7 +16548,7 @@ diff -ruN --no-dereference -x .git a/drivers/scsi/Makefile b/drivers/scsi/Makefi obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o diff -ruN --no-dereference -x .git a/drivers/scsi/vhba/Kconfig b/drivers/scsi/vhba/Kconfig --- a/drivers/scsi/vhba/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/scsi/vhba/Kconfig 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/scsi/vhba/Kconfig 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,9 @@ +config VHBA + tristate "Virtual (SCSI) Host Bus Adapter" @@ -15916,7 +16561,7 @@ diff -ruN --no-dereference -x .git a/drivers/scsi/vhba/Kconfig b/drivers/scsi/vh + will be called vhba. diff -ruN --no-dereference -x .git a/drivers/scsi/vhba/Makefile b/drivers/scsi/vhba/Makefile --- a/drivers/scsi/vhba/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/scsi/vhba/Makefile 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/scsi/vhba/Makefile 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,4 @@ +VHBA_VERSION := 20250329 + @@ -15924,7 +16569,7 @@ diff -ruN --no-dereference -x .git a/drivers/scsi/vhba/Makefile b/drivers/scsi/v +ccflags-y := -DVHBA_VERSION=\"$(VHBA_VERSION)\" -Werror diff -ruN --no-dereference -x .git a/drivers/scsi/vhba/vhba.c b/drivers/scsi/vhba/vhba.c --- a/drivers/scsi/vhba/vhba.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/scsi/vhba/vhba.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/scsi/vhba/vhba.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,1132 @@ +/* + * vhba.c @@ -17058,9 +17703,69 @@ diff -ruN --no-dereference -x .git a/drivers/scsi/vhba/vhba.c b/drivers/scsi/vhb +module_init(vhba_init); +module_exit(vhba_exit); + +diff -ruN --no-dereference -x .git a/drivers/soc/apple/Kconfig b/drivers/soc/apple/Kconfig +--- a/drivers/soc/apple/Kconfig 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/soc/apple/Kconfig 2026-10-03 14:48:53.000000000 +0200 +@@ -4,6 +4,15 @@ + + menu "Apple SoC drivers" + ++config APPLE_DOCKCHANNEL ++ tristate "Apple DockChannel FIFO" ++ depends on ARCH_APPLE || COMPILE_TEST ++ help ++ DockChannel is a simple FIFO used on Apple SoCs for debug and inter-processor ++ communications. ++ ++ Say 'y' here if you have an Apple SoC. ++ + config APPLE_MAILBOX + tristate "Apple SoC mailboxes" + depends on PM +@@ -28,6 +37,19 @@ + + Say 'y' here if you have an Apple SoC. + ++config APPLE_RTKIT_HELPER ++ tristate "Apple Generic RTKit helper co-processor" ++ depends on APPLE_RTKIT ++ depends on ARCH_APPLE || COMPILE_TEST ++ help ++ Apple SoCs such as the M1 come with various co-processors running ++ their proprietary RTKit operating system. This option enables support ++ for a generic co-processor that does not implement any additional ++ in-band communications. It can be used for testing purposes, or for ++ coprocessors such as MTP that communicate over a different interface. ++ ++ Say 'y' here if you have an Apple SoC. ++ + config APPLE_SART + tristate "Apple SART DMA address filter" + depends on ARCH_APPLE || COMPILE_TEST +diff -ruN --no-dereference -x .git a/drivers/soc/apple/Makefile b/drivers/soc/apple/Makefile +--- a/drivers/soc/apple/Makefile 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/soc/apple/Makefile 2026-10-03 14:48:53.000000000 +0200 +@@ -1,11 +1,17 @@ + # SPDX-License-Identifier: GPL-2.0-only + ++obj-$(CONFIG_APPLE_DOCKCHANNEL) += apple-dockchannel.o ++apple-dockchannel-y = dockchannel.o ++ + obj-$(CONFIG_APPLE_MAILBOX) += apple-mailbox.o + apple-mailbox-y = mailbox.o + + obj-$(CONFIG_APPLE_RTKIT) += apple-rtkit.o + apple-rtkit-y = rtkit.o rtkit-crashlog.o + ++obj-$(CONFIG_APPLE_RTKIT_HELPER) += apple-rtkit-helper.o ++apple-rtkit-helper-y = rtkit-helper.o ++ + obj-$(CONFIG_APPLE_SART) += apple-sart.o + apple-sart-y = sart.o + diff -ruN --no-dereference -x .git a/drivers/soc/apple/dockchannel.c b/drivers/soc/apple/dockchannel.c --- a/drivers/soc/apple/dockchannel.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/soc/apple/dockchannel.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/soc/apple/dockchannel.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,404 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* @@ -17466,69 +18171,9 @@ diff -ruN --no-dereference -x .git a/drivers/soc/apple/dockchannel.c b/drivers/s +MODULE_AUTHOR("Hector Martin "); +MODULE_LICENSE("Dual MIT/GPL"); +MODULE_DESCRIPTION("Apple DockChannel driver"); -diff -ruN --no-dereference -x .git a/drivers/soc/apple/Kconfig b/drivers/soc/apple/Kconfig ---- a/drivers/soc/apple/Kconfig 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/soc/apple/Kconfig 2026-09-23 12:56:16.000000000 +0200 -@@ -4,6 +4,15 @@ - - menu "Apple SoC drivers" - -+config APPLE_DOCKCHANNEL -+ tristate "Apple DockChannel FIFO" -+ depends on ARCH_APPLE || COMPILE_TEST -+ help -+ DockChannel is a simple FIFO used on Apple SoCs for debug and inter-processor -+ communications. -+ -+ Say 'y' here if you have an Apple SoC. -+ - config APPLE_MAILBOX - tristate "Apple SoC mailboxes" - depends on PM -@@ -28,6 +37,19 @@ - - Say 'y' here if you have an Apple SoC. - -+config APPLE_RTKIT_HELPER -+ tristate "Apple Generic RTKit helper co-processor" -+ depends on APPLE_RTKIT -+ depends on ARCH_APPLE || COMPILE_TEST -+ help -+ Apple SoCs such as the M1 come with various co-processors running -+ their proprietary RTKit operating system. This option enables support -+ for a generic co-processor that does not implement any additional -+ in-band communications. It can be used for testing purposes, or for -+ coprocessors such as MTP that communicate over a different interface. -+ -+ Say 'y' here if you have an Apple SoC. -+ - config APPLE_SART - tristate "Apple SART DMA address filter" - depends on ARCH_APPLE || COMPILE_TEST -diff -ruN --no-dereference -x .git a/drivers/soc/apple/Makefile b/drivers/soc/apple/Makefile ---- a/drivers/soc/apple/Makefile 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/soc/apple/Makefile 2026-09-23 12:56:16.000000000 +0200 -@@ -1,11 +1,17 @@ - # SPDX-License-Identifier: GPL-2.0-only - -+obj-$(CONFIG_APPLE_DOCKCHANNEL) += apple-dockchannel.o -+apple-dockchannel-y = dockchannel.o -+ - obj-$(CONFIG_APPLE_MAILBOX) += apple-mailbox.o - apple-mailbox-y = mailbox.o - - obj-$(CONFIG_APPLE_RTKIT) += apple-rtkit.o - apple-rtkit-y = rtkit.o rtkit-crashlog.o - -+obj-$(CONFIG_APPLE_RTKIT_HELPER) += apple-rtkit-helper.o -+apple-rtkit-helper-y = rtkit-helper.o -+ - obj-$(CONFIG_APPLE_SART) += apple-sart.o - apple-sart-y = sart.o - diff -ruN --no-dereference -x .git a/drivers/soc/apple/rtkit-helper.c b/drivers/soc/apple/rtkit-helper.c --- a/drivers/soc/apple/rtkit-helper.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/soc/apple/rtkit-helper.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/soc/apple/rtkit-helper.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* @@ -17682,8 +18327,8 @@ diff -ruN --no-dereference -x .git a/drivers/soc/apple/rtkit-helper.c b/drivers/ +MODULE_LICENSE("Dual MIT/GPL"); +MODULE_DESCRIPTION("Apple RTKit helper driver"); diff -ruN --no-dereference -x .git a/drivers/staging/Kconfig b/drivers/staging/Kconfig ---- a/drivers/staging/Kconfig 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/staging/Kconfig 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/staging/Kconfig 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/staging/Kconfig 2026-10-03 14:48:53.000000000 +0200 @@ -48,4 +48,6 @@ source "drivers/staging/vme_user/Kconfig" @@ -17692,8 +18337,8 @@ diff -ruN --no-dereference -x .git a/drivers/staging/Kconfig b/drivers/staging/K + endif # STAGING diff -ruN --no-dereference -x .git a/drivers/staging/Makefile b/drivers/staging/Makefile ---- a/drivers/staging/Makefile 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/staging/Makefile 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/staging/Makefile 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/staging/Makefile 2026-10-03 14:48:53.000000000 +0200 @@ -13,3 +13,4 @@ obj-$(CONFIG_GREYBUS) += greybus/ obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/ @@ -17701,7 +18346,7 @@ diff -ruN --no-dereference -x .git a/drivers/staging/Makefile b/drivers/staging/ +obj-$(CONFIG_T2BCE_CORE) += t2bce/ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/Kconfig b/drivers/staging/t2bce/Kconfig --- a/drivers/staging/t2bce/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/Kconfig 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/Kconfig 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,40 @@ +# SPDX-License-Identifier: GPL-2.0-only +menu "Apple T2 Buffer Copy Engine support" @@ -17745,16 +18390,27 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/Kconfig b/drivers/sta +endmenu diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/Makefile b/drivers/staging/t2bce/Makefile --- a/drivers/staging/t2bce/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/Makefile 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/Makefile 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_T2BCE_DMA) += t2bce_dma/ +obj-$(CONFIG_T2BCE_CORE) += t2bce_core/ +obj-$(CONFIG_T2BCE_VHCI) += t2bce_vhci/ +obj-$(CONFIG_T2BCE_AUDIO) += t2bce_audio/ +diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_audio/Makefile b/drivers/staging/t2bce/t2bce_audio/Makefile +--- a/drivers/staging/t2bce/t2bce_audio/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ b/drivers/staging/t2bce/t2bce_audio/Makefile 2026-10-03 14:48:53.000000000 +0200 +@@ -0,0 +1,7 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++obj-$(CONFIG_T2BCE_AUDIO) += t2bce_audio.o ++t2bce_audio-y := audio.o protocol.o protocol_bce.o pcm.o ++ ++ccflags-y += -DWITHOUT_NVME_PATCH ++ccflags-y += -I$(src) ++ccflags-y += -I$(src)/../t2bce_core/include diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_audio/audio.c b/drivers/staging/t2bce/t2bce_audio/audio.c --- a/drivers/staging/t2bce/t2bce_audio/audio.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_audio/audio.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/t2bce_audio/audio.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,930 @@ +#include +#include @@ -18688,7 +19344,7 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_audio/audio.c b +module_exit(t2audio_module_exit); diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_audio/audio.h b/drivers/staging/t2bce/t2bce_audio/audio.h --- a/drivers/staging/t2bce/t2bce_audio/audio.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_audio/audio.h 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/t2bce_audio/audio.h 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,148 @@ +#ifndef T2AUDIO_H +#define T2AUDIO_H @@ -18840,7 +19496,7 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_audio/audio.h b +#endif //T2AUDIO_H diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_audio/description.h b/drivers/staging/t2bce/t2bce_audio/description.h --- a/drivers/staging/t2bce/t2bce_audio/description.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_audio/description.h 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/t2bce_audio/description.h 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,42 @@ +#ifndef T2AUDIO_DESCRIPTION_H +#define T2AUDIO_DESCRIPTION_H @@ -18884,20 +19540,9 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_audio/descripti +} + +#endif //T2AUDIO_DESCRIPTION_H -diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_audio/Makefile b/drivers/staging/t2bce/t2bce_audio/Makefile ---- a/drivers/staging/t2bce/t2bce_audio/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_audio/Makefile 2026-09-23 12:56:16.000000000 +0200 -@@ -0,0 +1,7 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+obj-$(CONFIG_T2BCE_AUDIO) += t2bce_audio.o -+t2bce_audio-y := audio.o protocol.o protocol_bce.o pcm.o -+ -+ccflags-y += -DWITHOUT_NVME_PATCH -+ccflags-y += -I$(src) -+ccflags-y += -I$(src)/../t2bce_core/include diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_audio/pcm.c b/drivers/staging/t2bce/t2bce_audio/pcm.c --- a/drivers/staging/t2bce/t2bce_audio/pcm.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_audio/pcm.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/t2bce_audio/pcm.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,520 @@ +#include "pcm.h" +#include "audio.h" @@ -19421,7 +20066,7 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_audio/pcm.c b/d +} diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_audio/pcm.h b/drivers/staging/t2bce/t2bce_audio/pcm.h --- a/drivers/staging/t2bce/t2bce_audio/pcm.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_audio/pcm.h 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/t2bce_audio/pcm.h 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,17 @@ +#ifndef T2AUDIO_PCM_H +#define T2AUDIO_PCM_H @@ -19440,349 +20085,9 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_audio/pcm.h b/d + u64 update_seed, s64 clock_offset_ns, bool clock_ready); + +#endif //T2AUDIO_PCM_H -diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_audio/protocol_bce.c b/drivers/staging/t2bce/t2bce_audio/protocol_bce.c ---- a/drivers/staging/t2bce/t2bce_audio/protocol_bce.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_audio/protocol_bce.c 2026-09-23 12:56:16.000000000 +0200 -@@ -0,0 +1,260 @@ -+#include "protocol_bce.h" -+ -+#include "audio.h" -+#include -+ -+static void t2audio_bce_out_queue_completion(struct t2bce_core_queue_sq *sq); -+static void t2audio_bce_in_queue_completion(struct t2bce_core_queue_sq *sq); -+static int t2audio_bce_queue_init(struct t2audio_device *dev, struct t2audio_bce_queue *q, const char *name, -+ enum dma_data_direction direction, t2bce_core_sq_completion cfn); -+void t2audio_bce_in_queue_submit_pending(struct t2audio_bce_queue *q, size_t count); -+static void t2audio_deferred_msg_work(struct work_struct *ws); -+ -+int t2audio_bce_init(struct t2audio_device *dev) -+{ -+ int status; -+ struct t2audio_bce *bce = &dev->bcem; -+ bce->cq = t2bce_core_create_cq(dev->bce, 0x80); -+ spin_lock_init(&bce->spinlock); -+ if (!bce->cq) -+ return -EINVAL; -+ if ((status = t2audio_bce_queue_init(dev, &bce->qout, "com.apple.BridgeAudio.IntelToARM", DMA_TO_DEVICE, -+ t2audio_bce_out_queue_completion))) { -+ return status; -+ } -+ if ((status = t2audio_bce_queue_init(dev, &bce->qin, "com.apple.BridgeAudio.ARMToIntel", DMA_FROM_DEVICE, -+ t2audio_bce_in_queue_completion))) { -+ return status; -+ } -+ t2audio_bce_in_queue_submit_pending(&bce->qin, bce->qin.el_count); -+ return 0; -+} -+ -+int t2audio_bce_queue_init(struct t2audio_device *dev, struct t2audio_bce_queue *q, const char *name, -+ enum dma_data_direction direction, t2bce_core_sq_completion cfn) -+{ -+ q->cq = dev->bcem.cq; -+ q->el_size = T2AUDIO_BCE_QUEUE_ELEMENT_SIZE; -+ q->el_count = T2AUDIO_BCE_QUEUE_ELEMENT_COUNT; -+ /* Allocate one extra SQ slot because the BCE ring always keeps one entry empty. */ -+ q->sq = t2bce_core_create_sq(dev->bce, q->cq, name, (u32) (q->el_count + 1), direction, cfn, dev); -+ if (!q->sq) -+ return -EINVAL; -+ -+ q->data = dma_alloc_coherent(t2bce_core_client_dma_dev(dev->bce), q->el_size * q->el_count, &q->dma_addr, GFP_KERNEL); -+ if (!q->data) { -+ t2bce_core_destroy_sq(dev->bce, q->sq); -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+static void t2audio_send_create_tag(struct t2audio_bce *b, int *tagn, char tag[4]) -+{ -+ b->tag_num = (b->tag_num + 1) % T2AUDIO_BCE_QUEUE_TAG_COUNT; -+ *tagn = b->tag_num; -+ tag[0] = 'S'; -+ tag[1] = '0' + b->tag_num / 100; -+ tag[2] = '0' + (b->tag_num / 10) % 10; -+ tag[3] = '0' + b->tag_num % 10; -+} -+ -+int __t2audio_send_prepare(struct t2audio_bce *b, struct t2audio_send_ctx *ctx, char *tag) -+{ -+ int status; -+ size_t index; -+ void *dptr; -+ struct t2audio_msg_header *header; -+ if ((status = t2bce_core_reserve_submission(b->qout.sq, &ctx->timeout))) -+ return status; -+ spin_lock_irqsave(&b->spinlock, ctx->irq_flags); -+ index = b->qout.data_tail; -+ dptr = (u8 *) b->qout.data + index * b->qout.el_size; -+ ctx->msg.data = dptr; -+ header = dptr; -+ if (tag) -+ *((u32 *) header->tag) = *((u32 *) tag); -+ else -+ t2audio_send_create_tag(b, &ctx->tag_n, header->tag); -+ return 0; -+} -+ -+void __t2audio_send(struct t2audio_bce *b, struct t2audio_send_ctx *ctx) -+{ -+#ifdef DEBUG -+ pr_debug("t2bce_audio: Sending command data\n"); -+ print_hex_dump(KERN_DEBUG, "t2bce_audio:OUT ", DUMP_PREFIX_NONE, 32, 1, ctx->msg.data, ctx->msg.size, true); -+#endif -+ t2bce_core_set_next_submission_single(b->qout.sq, -+ b->qout.dma_addr + (dma_addr_t) (ctx->msg.data - b->qout.data), ctx->msg.size); -+ t2bce_core_submit_to_device(b->qout.sq); -+ b->qout.data_tail = (b->qout.data_tail + 1) % b->qout.el_count; -+ spin_unlock_irqrestore(&b->spinlock, ctx->irq_flags); -+} -+ -+int __t2audio_send_cmd_sync(struct t2audio_bce *b, struct t2audio_send_ctx *ctx, struct t2audio_msg *reply) -+{ -+ struct t2audio_bce_queue_entry ent; -+ DECLARE_COMPLETION_ONSTACK(cmpl); -+ ent.msg = reply; -+ ent.cmpl = &cmpl; -+ b->pending_entries[ctx->tag_n] = &ent; -+ __t2audio_send(b, ctx); /* drops b->spinlock */ -+ ctx->timeout = wait_for_completion_timeout(&cmpl, ctx->timeout); -+ if (ctx->timeout == 0) { -+ /* -+ * Timed-out replies may still arrive later; remove the waiter before -+ * returning so a stale reply cannot complete a reused stack object. -+ */ -+ spin_lock_irqsave(&b->spinlock, ctx->irq_flags); -+ if (b->pending_entries[ctx->tag_n] == &ent) -+ b->pending_entries[ctx->tag_n] = NULL; -+ spin_unlock_irqrestore(&b->spinlock, ctx->irq_flags); -+ return -ETIMEDOUT; -+ } -+ return 0; -+} -+ -+static void t2audio_handle_reply(struct t2audio_bce *b, struct t2audio_msg *reply) -+{ -+ const char *tag; -+ int tagn; -+ unsigned long irq_flags; -+ char tag_zero[5]; -+ struct t2audio_bce_queue_entry *entry; -+ -+ tag = ((struct t2audio_msg_header *) reply->data)->tag; -+ if (tag[0] != 'S') { -+ pr_err("t2bce_audio: unexpected reply tag: %.4s\n", tag); -+ return; -+ } -+ *((u32 *) tag_zero) = *((u32 *) tag); -+ tag_zero[4] = 0; -+ if (kstrtoint(&tag_zero[1], 10, &tagn)) { -+ pr_err("t2bce_audio: reply tag parse failed: %.4s\n", tag); -+ return; -+ } -+ -+ spin_lock_irqsave(&b->spinlock, irq_flags); -+ entry = b->pending_entries[tagn]; -+ if (entry) { -+ if (reply->size < entry->msg->size) -+ entry->msg->size = reply->size; -+ memcpy(entry->msg->data, reply->data, entry->msg->size); -+ complete(entry->cmpl); -+ -+ b->pending_entries[tagn] = NULL; -+ } else { -+ pr_warn_ratelimited("t2bce_audio: stale reply without queued command tag=%.4s\n", tag); -+ } -+ spin_unlock_irqrestore(&b->spinlock, irq_flags); -+} -+ -+static void t2audio_bce_out_queue_completion(struct t2bce_core_queue_sq *sq) -+{ -+ while (t2bce_core_next_completion(sq)) { -+ t2bce_core_notify_submission_complete(sq); -+ } -+} -+ -+static void t2audio_bce_in_queue_handle_msg(struct t2audio_device *a, struct t2audio_msg *msg); -+ -+static void t2audio_deferred_msg_work(struct work_struct *ws) -+{ -+ struct t2audio_deferred_msg *work = container_of(ws, struct t2audio_deferred_msg, ws); -+ struct t2audio_msg_header *header = work->msg.data; -+ -+ if (header->type == T2AUDIO_MSG_TYPE_COMMAND) -+ t2audio_handle_command(work->a, &work->msg); -+ else if (header->type == T2AUDIO_MSG_TYPE_NOTIFICATION) -+ t2audio_handle_notification(work->a, &work->msg); -+ -+ kfree(work->msg.data); -+ kfree(work); -+} -+ -+static void t2audio_bce_in_queue_completion(struct t2bce_core_queue_sq *sq) -+{ -+ struct t2audio_msg msg; -+ struct t2audio_device *dev = t2bce_core_queue_sq_userdata(sq); -+ struct t2audio_bce_queue *q = &dev->bcem.qin; -+ struct t2bce_core_sq_completion_data *c; -+ size_t cnt = 0; -+ -+ mb(); -+ while ((c = t2bce_core_next_completion(sq))) { -+ msg.data = (u8 *) q->data + q->data_head * q->el_size; -+ msg.size = c->data_size; -+#ifdef DEBUG -+ pr_debug("t2bce_audio: Received command data %llx\n", c->data_size); -+ print_hex_dump(KERN_DEBUG, "t2bce_audio:IN ", DUMP_PREFIX_NONE, 32, 1, msg.data, min(msg.size, 128UL), true); -+#endif -+ t2audio_bce_in_queue_handle_msg(dev, &msg); -+ -+ q->data_head = (q->data_head + 1) % q->el_count; -+ -+ t2bce_core_notify_submission_complete(sq); -+ ++cnt; -+ } -+ t2audio_bce_in_queue_submit_pending(q, cnt); -+} -+ -+static void t2audio_bce_in_queue_handle_msg(struct t2audio_device *a, struct t2audio_msg *msg) -+{ -+ struct t2audio_msg_header *header = (struct t2audio_msg_header *) msg->data; -+ struct t2audio_deferred_msg *work; -+ -+ if (msg->size < sizeof(struct t2audio_msg_header)) { -+ pr_err("t2bce_audio: Msg size smaller than header (%lx)", msg->size); -+ return; -+ } -+ if (header->type == T2AUDIO_MSG_TYPE_RESPONSE) { -+ t2audio_handle_reply(&a->bcem, msg); -+ return; -+ } -+ -+ work = kzalloc(sizeof(*work), GFP_ATOMIC); -+ if (!work) { -+ pr_err("t2bce_audio: Failed to allocate deferred message work\n"); -+ return; -+ } -+ -+ work->msg.data = kmemdup(msg->data, msg->size, GFP_ATOMIC); -+ if (!work->msg.data) { -+ kfree(work); -+ pr_err("t2bce_audio: Failed to copy deferred message\n"); -+ return; -+ } -+ -+ work->a = a; -+ work->msg.size = msg->size; -+ INIT_WORK(&work->ws, t2audio_deferred_msg_work); -+ schedule_work(&work->ws); -+} -+ -+void t2audio_bce_in_queue_submit_pending(struct t2audio_bce_queue *q, size_t count) -+{ -+ while (count--) { -+ if (t2bce_core_reserve_submission(q->sq, NULL)) { -+ pr_err("t2bce_audio: Failed to reserve an event queue submission\n"); -+ break; -+ } -+ t2bce_core_set_next_submission_single(q->sq, -+ q->dma_addr + (dma_addr_t) (q->data_tail * q->el_size), q->el_size); -+ q->data_tail = (q->data_tail + 1) % q->el_count; -+ } -+ t2bce_core_submit_to_device(q->sq); -+} -+ -+struct t2audio_msg t2audio_reply_alloc(void) -+{ -+ struct t2audio_msg ret; -+ ret.size = T2AUDIO_BCE_QUEUE_ELEMENT_SIZE; -+ ret.data = kmalloc(ret.size, GFP_KERNEL); -+ return ret; -+} -+ -+void t2audio_reply_free(struct t2audio_msg *reply) -+{ -+ kfree(reply->data); -+} -diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_audio/protocol_bce.h b/drivers/staging/t2bce/t2bce_audio/protocol_bce.h ---- a/drivers/staging/t2bce/t2bce_audio/protocol_bce.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_audio/protocol_bce.h 2026-09-23 12:56:16.000000000 +0200 -@@ -0,0 +1,72 @@ -+#ifndef T2AUDIO_PROTOCOL_BCE_H -+#define T2AUDIO_PROTOCOL_BCE_H -+ -+#include "protocol.h" -+#include "t2bce_core_transport.h" -+ -+#define T2AUDIO_BCE_QUEUE_ELEMENT_SIZE 0x1000 -+#define T2AUDIO_BCE_QUEUE_ELEMENT_COUNT 20 -+ -+#define T2AUDIO_BCE_QUEUE_TAG_COUNT 1000 -+ -+struct t2audio_device; -+ -+struct t2audio_bce_queue_entry { -+ struct t2audio_msg *msg; -+ struct completion *cmpl; -+}; -+struct t2audio_bce_queue { -+ struct t2bce_core_queue_cq *cq; -+ struct t2bce_core_queue_sq *sq; -+ void *data; -+ dma_addr_t dma_addr; -+ size_t data_head, data_tail; -+ size_t el_size, el_count; -+}; -+struct t2audio_bce { -+ struct t2bce_core_queue_cq *cq; -+ struct t2audio_bce_queue qin; -+ struct t2audio_bce_queue qout; -+ int tag_num; -+ struct t2audio_bce_queue_entry *pending_entries[T2AUDIO_BCE_QUEUE_TAG_COUNT]; -+ struct spinlock spinlock; -+}; -+ -+struct t2audio_send_ctx { -+ int status; -+ int tag_n; -+ unsigned long irq_flags; -+ struct t2audio_msg msg; -+ unsigned long timeout; -+}; -+ -+int t2audio_bce_init(struct t2audio_device *dev); -+int __t2audio_send_prepare(struct t2audio_bce *b, struct t2audio_send_ctx *ctx, char *tag); -+void __t2audio_send(struct t2audio_bce *b, struct t2audio_send_ctx *ctx); -+int __t2audio_send_cmd_sync(struct t2audio_bce *b, struct t2audio_send_ctx *ctx, struct t2audio_msg *reply); -+ -+#define t2audio_send_with_tag(a, ctx, tag, tout, fn, ...) ({ \ -+ (ctx)->timeout = msecs_to_jiffies(tout); \ -+ (ctx)->status = __t2audio_send_prepare(&(a)->bcem, (ctx), (tag)); \ -+ if (!(ctx)->status) { \ -+ fn(&(ctx)->msg, ##__VA_ARGS__); \ -+ __t2audio_send(&(a)->bcem, (ctx)); \ -+ } \ -+ (ctx)->status; \ -+}) -+#define t2audio_send(a, ctx, tout, fn, ...) t2audio_send_with_tag(a, ctx, NULL, tout, fn, ##__VA_ARGS__) -+ -+#define t2audio_send_cmd_sync(a, ctx, reply, tout, fn, ...) ({ \ -+ (ctx)->timeout = msecs_to_jiffies(tout); \ -+ (ctx)->status = __t2audio_send_prepare(&(a)->bcem, (ctx), NULL); \ -+ if (!(ctx)->status) { \ -+ fn(&(ctx)->msg, ##__VA_ARGS__); \ -+ (ctx)->status = __t2audio_send_cmd_sync(&(a)->bcem, (ctx), (reply)); \ -+ } \ -+ (ctx)->status; \ -+}) -+ -+struct t2audio_msg t2audio_reply_alloc(void); -+void t2audio_reply_free(struct t2audio_msg *reply); -+ -+#endif //T2AUDIO_PROTOCOL_BCE_H diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_audio/protocol.c b/drivers/staging/t2bce/t2bce_audio/protocol.c --- a/drivers/staging/t2bce/t2bce_audio/protocol.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_audio/protocol.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/t2bce_audio/protocol.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,347 @@ +#include "protocol.h" +#include "protocol_bce.h" @@ -20134,7 +20439,7 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_audio/protocol. \ No newline at end of file diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_audio/protocol.h b/drivers/staging/t2bce/t2bce_audio/protocol.h --- a/drivers/staging/t2bce/t2bce_audio/protocol.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_audio/protocol.h 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/t2bce_audio/protocol.h 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,147 @@ +#ifndef T2AUDIO_PROTOCOL_H +#define T2AUDIO_PROTOCOL_H @@ -20283,9 +20588,360 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_audio/protocol. + + +#endif //T2AUDIO_PROTOCOL_H +diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_audio/protocol_bce.c b/drivers/staging/t2bce/t2bce_audio/protocol_bce.c +--- a/drivers/staging/t2bce/t2bce_audio/protocol_bce.c 1970-01-01 01:00:00.000000000 +0100 ++++ b/drivers/staging/t2bce/t2bce_audio/protocol_bce.c 2026-10-03 14:48:53.000000000 +0200 +@@ -0,0 +1,260 @@ ++#include "protocol_bce.h" ++ ++#include "audio.h" ++#include ++ ++static void t2audio_bce_out_queue_completion(struct t2bce_core_queue_sq *sq); ++static void t2audio_bce_in_queue_completion(struct t2bce_core_queue_sq *sq); ++static int t2audio_bce_queue_init(struct t2audio_device *dev, struct t2audio_bce_queue *q, const char *name, ++ enum dma_data_direction direction, t2bce_core_sq_completion cfn); ++void t2audio_bce_in_queue_submit_pending(struct t2audio_bce_queue *q, size_t count); ++static void t2audio_deferred_msg_work(struct work_struct *ws); ++ ++int t2audio_bce_init(struct t2audio_device *dev) ++{ ++ int status; ++ struct t2audio_bce *bce = &dev->bcem; ++ bce->cq = t2bce_core_create_cq(dev->bce, 0x80); ++ spin_lock_init(&bce->spinlock); ++ if (!bce->cq) ++ return -EINVAL; ++ if ((status = t2audio_bce_queue_init(dev, &bce->qout, "com.apple.BridgeAudio.IntelToARM", DMA_TO_DEVICE, ++ t2audio_bce_out_queue_completion))) { ++ return status; ++ } ++ if ((status = t2audio_bce_queue_init(dev, &bce->qin, "com.apple.BridgeAudio.ARMToIntel", DMA_FROM_DEVICE, ++ t2audio_bce_in_queue_completion))) { ++ return status; ++ } ++ t2audio_bce_in_queue_submit_pending(&bce->qin, bce->qin.el_count); ++ return 0; ++} ++ ++int t2audio_bce_queue_init(struct t2audio_device *dev, struct t2audio_bce_queue *q, const char *name, ++ enum dma_data_direction direction, t2bce_core_sq_completion cfn) ++{ ++ q->cq = dev->bcem.cq; ++ q->el_size = T2AUDIO_BCE_QUEUE_ELEMENT_SIZE; ++ q->el_count = T2AUDIO_BCE_QUEUE_ELEMENT_COUNT; ++ /* Allocate one extra SQ slot because the BCE ring always keeps one entry empty. */ ++ q->sq = t2bce_core_create_sq(dev->bce, q->cq, name, (u32) (q->el_count + 1), direction, cfn, dev); ++ if (!q->sq) ++ return -EINVAL; ++ ++ q->data = dma_alloc_coherent(t2bce_core_client_dma_dev(dev->bce), q->el_size * q->el_count, &q->dma_addr, GFP_KERNEL); ++ if (!q->data) { ++ t2bce_core_destroy_sq(dev->bce, q->sq); ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static void t2audio_send_create_tag(struct t2audio_bce *b, int *tagn, char tag[4]) ++{ ++ b->tag_num = (b->tag_num + 1) % T2AUDIO_BCE_QUEUE_TAG_COUNT; ++ *tagn = b->tag_num; ++ tag[0] = 'S'; ++ tag[1] = '0' + b->tag_num / 100; ++ tag[2] = '0' + (b->tag_num / 10) % 10; ++ tag[3] = '0' + b->tag_num % 10; ++} ++ ++int __t2audio_send_prepare(struct t2audio_bce *b, struct t2audio_send_ctx *ctx, char *tag) ++{ ++ int status; ++ size_t index; ++ void *dptr; ++ struct t2audio_msg_header *header; ++ if ((status = t2bce_core_reserve_submission(b->qout.sq, &ctx->timeout))) ++ return status; ++ spin_lock_irqsave(&b->spinlock, ctx->irq_flags); ++ index = b->qout.data_tail; ++ dptr = (u8 *) b->qout.data + index * b->qout.el_size; ++ ctx->msg.data = dptr; ++ header = dptr; ++ if (tag) ++ *((u32 *) header->tag) = *((u32 *) tag); ++ else ++ t2audio_send_create_tag(b, &ctx->tag_n, header->tag); ++ return 0; ++} ++ ++void __t2audio_send(struct t2audio_bce *b, struct t2audio_send_ctx *ctx) ++{ ++#ifdef DEBUG ++ pr_debug("t2bce_audio: Sending command data\n"); ++ print_hex_dump(KERN_DEBUG, "t2bce_audio:OUT ", DUMP_PREFIX_NONE, 32, 1, ctx->msg.data, ctx->msg.size, true); ++#endif ++ t2bce_core_set_next_submission_single(b->qout.sq, ++ b->qout.dma_addr + (dma_addr_t) (ctx->msg.data - b->qout.data), ctx->msg.size); ++ t2bce_core_submit_to_device(b->qout.sq); ++ b->qout.data_tail = (b->qout.data_tail + 1) % b->qout.el_count; ++ spin_unlock_irqrestore(&b->spinlock, ctx->irq_flags); ++} ++ ++int __t2audio_send_cmd_sync(struct t2audio_bce *b, struct t2audio_send_ctx *ctx, struct t2audio_msg *reply) ++{ ++ struct t2audio_bce_queue_entry ent; ++ DECLARE_COMPLETION_ONSTACK(cmpl); ++ ent.msg = reply; ++ ent.cmpl = &cmpl; ++ b->pending_entries[ctx->tag_n] = &ent; ++ __t2audio_send(b, ctx); /* drops b->spinlock */ ++ ctx->timeout = wait_for_completion_timeout(&cmpl, ctx->timeout); ++ if (ctx->timeout == 0) { ++ /* ++ * Timed-out replies may still arrive later; remove the waiter before ++ * returning so a stale reply cannot complete a reused stack object. ++ */ ++ spin_lock_irqsave(&b->spinlock, ctx->irq_flags); ++ if (b->pending_entries[ctx->tag_n] == &ent) ++ b->pending_entries[ctx->tag_n] = NULL; ++ spin_unlock_irqrestore(&b->spinlock, ctx->irq_flags); ++ return -ETIMEDOUT; ++ } ++ return 0; ++} ++ ++static void t2audio_handle_reply(struct t2audio_bce *b, struct t2audio_msg *reply) ++{ ++ const char *tag; ++ int tagn; ++ unsigned long irq_flags; ++ char tag_zero[5]; ++ struct t2audio_bce_queue_entry *entry; ++ ++ tag = ((struct t2audio_msg_header *) reply->data)->tag; ++ if (tag[0] != 'S') { ++ pr_err("t2bce_audio: unexpected reply tag: %.4s\n", tag); ++ return; ++ } ++ *((u32 *) tag_zero) = *((u32 *) tag); ++ tag_zero[4] = 0; ++ if (kstrtoint(&tag_zero[1], 10, &tagn)) { ++ pr_err("t2bce_audio: reply tag parse failed: %.4s\n", tag); ++ return; ++ } ++ ++ spin_lock_irqsave(&b->spinlock, irq_flags); ++ entry = b->pending_entries[tagn]; ++ if (entry) { ++ if (reply->size < entry->msg->size) ++ entry->msg->size = reply->size; ++ memcpy(entry->msg->data, reply->data, entry->msg->size); ++ complete(entry->cmpl); ++ ++ b->pending_entries[tagn] = NULL; ++ } else { ++ pr_warn_ratelimited("t2bce_audio: stale reply without queued command tag=%.4s\n", tag); ++ } ++ spin_unlock_irqrestore(&b->spinlock, irq_flags); ++} ++ ++static void t2audio_bce_out_queue_completion(struct t2bce_core_queue_sq *sq) ++{ ++ while (t2bce_core_next_completion(sq)) { ++ t2bce_core_notify_submission_complete(sq); ++ } ++} ++ ++static void t2audio_bce_in_queue_handle_msg(struct t2audio_device *a, struct t2audio_msg *msg); ++ ++static void t2audio_deferred_msg_work(struct work_struct *ws) ++{ ++ struct t2audio_deferred_msg *work = container_of(ws, struct t2audio_deferred_msg, ws); ++ struct t2audio_msg_header *header = work->msg.data; ++ ++ if (header->type == T2AUDIO_MSG_TYPE_COMMAND) ++ t2audio_handle_command(work->a, &work->msg); ++ else if (header->type == T2AUDIO_MSG_TYPE_NOTIFICATION) ++ t2audio_handle_notification(work->a, &work->msg); ++ ++ kfree(work->msg.data); ++ kfree(work); ++} ++ ++static void t2audio_bce_in_queue_completion(struct t2bce_core_queue_sq *sq) ++{ ++ struct t2audio_msg msg; ++ struct t2audio_device *dev = t2bce_core_queue_sq_userdata(sq); ++ struct t2audio_bce_queue *q = &dev->bcem.qin; ++ struct t2bce_core_sq_completion_data *c; ++ size_t cnt = 0; ++ ++ mb(); ++ while ((c = t2bce_core_next_completion(sq))) { ++ msg.data = (u8 *) q->data + q->data_head * q->el_size; ++ msg.size = c->data_size; ++#ifdef DEBUG ++ pr_debug("t2bce_audio: Received command data %llx\n", c->data_size); ++ print_hex_dump(KERN_DEBUG, "t2bce_audio:IN ", DUMP_PREFIX_NONE, 32, 1, msg.data, min(msg.size, 128UL), true); ++#endif ++ t2audio_bce_in_queue_handle_msg(dev, &msg); ++ ++ q->data_head = (q->data_head + 1) % q->el_count; ++ ++ t2bce_core_notify_submission_complete(sq); ++ ++cnt; ++ } ++ t2audio_bce_in_queue_submit_pending(q, cnt); ++} ++ ++static void t2audio_bce_in_queue_handle_msg(struct t2audio_device *a, struct t2audio_msg *msg) ++{ ++ struct t2audio_msg_header *header = (struct t2audio_msg_header *) msg->data; ++ struct t2audio_deferred_msg *work; ++ ++ if (msg->size < sizeof(struct t2audio_msg_header)) { ++ pr_err("t2bce_audio: Msg size smaller than header (%lx)", msg->size); ++ return; ++ } ++ if (header->type == T2AUDIO_MSG_TYPE_RESPONSE) { ++ t2audio_handle_reply(&a->bcem, msg); ++ return; ++ } ++ ++ work = kzalloc(sizeof(*work), GFP_ATOMIC); ++ if (!work) { ++ pr_err("t2bce_audio: Failed to allocate deferred message work\n"); ++ return; ++ } ++ ++ work->msg.data = kmemdup(msg->data, msg->size, GFP_ATOMIC); ++ if (!work->msg.data) { ++ kfree(work); ++ pr_err("t2bce_audio: Failed to copy deferred message\n"); ++ return; ++ } ++ ++ work->a = a; ++ work->msg.size = msg->size; ++ INIT_WORK(&work->ws, t2audio_deferred_msg_work); ++ schedule_work(&work->ws); ++} ++ ++void t2audio_bce_in_queue_submit_pending(struct t2audio_bce_queue *q, size_t count) ++{ ++ while (count--) { ++ if (t2bce_core_reserve_submission(q->sq, NULL)) { ++ pr_err("t2bce_audio: Failed to reserve an event queue submission\n"); ++ break; ++ } ++ t2bce_core_set_next_submission_single(q->sq, ++ q->dma_addr + (dma_addr_t) (q->data_tail * q->el_size), q->el_size); ++ q->data_tail = (q->data_tail + 1) % q->el_count; ++ } ++ t2bce_core_submit_to_device(q->sq); ++} ++ ++struct t2audio_msg t2audio_reply_alloc(void) ++{ ++ struct t2audio_msg ret; ++ ret.size = T2AUDIO_BCE_QUEUE_ELEMENT_SIZE; ++ ret.data = kmalloc(ret.size, GFP_KERNEL); ++ return ret; ++} ++ ++void t2audio_reply_free(struct t2audio_msg *reply) ++{ ++ kfree(reply->data); ++} +diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_audio/protocol_bce.h b/drivers/staging/t2bce/t2bce_audio/protocol_bce.h +--- a/drivers/staging/t2bce/t2bce_audio/protocol_bce.h 1970-01-01 01:00:00.000000000 +0100 ++++ b/drivers/staging/t2bce/t2bce_audio/protocol_bce.h 2026-10-03 14:48:53.000000000 +0200 +@@ -0,0 +1,72 @@ ++#ifndef T2AUDIO_PROTOCOL_BCE_H ++#define T2AUDIO_PROTOCOL_BCE_H ++ ++#include "protocol.h" ++#include "t2bce_core_transport.h" ++ ++#define T2AUDIO_BCE_QUEUE_ELEMENT_SIZE 0x1000 ++#define T2AUDIO_BCE_QUEUE_ELEMENT_COUNT 20 ++ ++#define T2AUDIO_BCE_QUEUE_TAG_COUNT 1000 ++ ++struct t2audio_device; ++ ++struct t2audio_bce_queue_entry { ++ struct t2audio_msg *msg; ++ struct completion *cmpl; ++}; ++struct t2audio_bce_queue { ++ struct t2bce_core_queue_cq *cq; ++ struct t2bce_core_queue_sq *sq; ++ void *data; ++ dma_addr_t dma_addr; ++ size_t data_head, data_tail; ++ size_t el_size, el_count; ++}; ++struct t2audio_bce { ++ struct t2bce_core_queue_cq *cq; ++ struct t2audio_bce_queue qin; ++ struct t2audio_bce_queue qout; ++ int tag_num; ++ struct t2audio_bce_queue_entry *pending_entries[T2AUDIO_BCE_QUEUE_TAG_COUNT]; ++ struct spinlock spinlock; ++}; ++ ++struct t2audio_send_ctx { ++ int status; ++ int tag_n; ++ unsigned long irq_flags; ++ struct t2audio_msg msg; ++ unsigned long timeout; ++}; ++ ++int t2audio_bce_init(struct t2audio_device *dev); ++int __t2audio_send_prepare(struct t2audio_bce *b, struct t2audio_send_ctx *ctx, char *tag); ++void __t2audio_send(struct t2audio_bce *b, struct t2audio_send_ctx *ctx); ++int __t2audio_send_cmd_sync(struct t2audio_bce *b, struct t2audio_send_ctx *ctx, struct t2audio_msg *reply); ++ ++#define t2audio_send_with_tag(a, ctx, tag, tout, fn, ...) ({ \ ++ (ctx)->timeout = msecs_to_jiffies(tout); \ ++ (ctx)->status = __t2audio_send_prepare(&(a)->bcem, (ctx), (tag)); \ ++ if (!(ctx)->status) { \ ++ fn(&(ctx)->msg, ##__VA_ARGS__); \ ++ __t2audio_send(&(a)->bcem, (ctx)); \ ++ } \ ++ (ctx)->status; \ ++}) ++#define t2audio_send(a, ctx, tout, fn, ...) t2audio_send_with_tag(a, ctx, NULL, tout, fn, ##__VA_ARGS__) ++ ++#define t2audio_send_cmd_sync(a, ctx, reply, tout, fn, ...) ({ \ ++ (ctx)->timeout = msecs_to_jiffies(tout); \ ++ (ctx)->status = __t2audio_send_prepare(&(a)->bcem, (ctx), NULL); \ ++ if (!(ctx)->status) { \ ++ fn(&(ctx)->msg, ##__VA_ARGS__); \ ++ (ctx)->status = __t2audio_send_cmd_sync(&(a)->bcem, (ctx), (reply)); \ ++ } \ ++ (ctx)->status; \ ++}) ++ ++struct t2audio_msg t2audio_reply_alloc(void); ++void t2audio_reply_free(struct t2audio_msg *reply); ++ ++#endif //T2AUDIO_PROTOCOL_BCE_H +diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_core/Makefile b/drivers/staging/t2bce/t2bce_core/Makefile +--- a/drivers/staging/t2bce/t2bce_core/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ b/drivers/staging/t2bce/t2bce_core/Makefile 2026-10-03 14:48:53.000000000 +0200 +@@ -0,0 +1,7 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++obj-$(CONFIG_T2BCE_CORE) += t2bce_core.o ++t2bce_core-y := t2bce_main.o mailbox.o transport.o ++ ++ccflags-y += -DWITHOUT_NVME_PATCH ++ccflags-y += -I$(src)/include ++ccflags-y += -I$(src)/../t2bce_dma/include diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_core/include/t2bce_core_transport.h b/drivers/staging/t2bce/t2bce_core/include/t2bce_core_transport.h --- a/drivers/staging/t2bce/t2bce_core/include/t2bce_core_transport.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_core/include/t2bce_core_transport.h 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/t2bce_core/include/t2bce_core_transport.h 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,83 @@ +#ifndef T2BCE_CORE_TRANSPORT_H +#define T2BCE_CORE_TRANSPORT_H @@ -20372,7 +21028,7 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_core/include/t2 +#endif diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_core/mailbox.c b/drivers/staging/t2bce/t2bce_core/mailbox.c --- a/drivers/staging/t2bce/t2bce_core/mailbox.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_core/mailbox.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/t2bce_core/mailbox.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,234 @@ +#include "mailbox.h" +#include @@ -20610,7 +21266,7 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_core/mailbox.c +} diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_core/mailbox.h b/drivers/staging/t2bce/t2bce_core/mailbox.h --- a/drivers/staging/t2bce/t2bce_core/mailbox.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_core/mailbox.h 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/t2bce_core/mailbox.h 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,64 @@ +#ifndef BCE_MAILBOX_H +#define BCE_MAILBOX_H @@ -20676,20 +21332,9 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_core/mailbox.h +void bce_xhci_pm_stop(struct bce_xhci_pm *pm); + +#endif //BCEDRIVER_MAILBOX_H -diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_core/Makefile b/drivers/staging/t2bce/t2bce_core/Makefile ---- a/drivers/staging/t2bce/t2bce_core/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_core/Makefile 2026-09-23 12:56:16.000000000 +0200 -@@ -0,0 +1,7 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+obj-$(CONFIG_T2BCE_CORE) += t2bce_core.o -+t2bce_core-y := t2bce_main.o mailbox.o transport.o -+ -+ccflags-y += -DWITHOUT_NVME_PATCH -+ccflags-y += -I$(src)/include -+ccflags-y += -I$(src)/../t2bce_dma/include diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_core/t2bce.h b/drivers/staging/t2bce/t2bce_core/t2bce.h --- a/drivers/staging/t2bce/t2bce_core/t2bce.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_core/t2bce.h 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/t2bce_core/t2bce.h 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,51 @@ +#ifndef APPLE_BCE_H +#define APPLE_BCE_H @@ -20744,8 +21389,8 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_core/t2bce.h b/ +#endif //APPLE_BCE_H diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_core/t2bce_main.c b/drivers/staging/t2bce/t2bce_core/t2bce_main.c --- a/drivers/staging/t2bce/t2bce_core/t2bce_main.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_core/t2bce_main.c 2026-09-23 12:56:16.000000000 +0200 -@@ -0,0 +1,766 @@ ++++ b/drivers/staging/t2bce/t2bce_core/t2bce_main.c 2026-10-03 14:48:53.000000000 +0200 +@@ -0,0 +1,770 @@ +#include "t2bce.h" +#include +#include @@ -21510,11 +22155,15 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_core/t2bce_main +MODULE_DESCRIPTION("T2 BCE core driver"); +MODULE_VERSION("0.06"); +MODULE_SOFTDEP("post: t2bce_vhci"); ++/* ++ * Legacy compat alias for existing installs. ++ */ ++MODULE_ALIAS("apple-bce"); +module_init(t2bce_module_init); +module_exit(t2bce_module_exit); diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_core/transport.c b/drivers/staging/t2bce/t2bce_core/transport.c --- a/drivers/staging/t2bce/t2bce_core/transport.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_core/transport.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/t2bce_core/transport.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,406 @@ +#include "t2bce_core_transport.h" +#include "t2bce.h" @@ -21922,9 +22571,19 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_core/transport. + return t2bce_dma_flush_sq(&client->bce->dma, to_bce_sq(sq)); +} +EXPORT_SYMBOL_GPL(t2bce_core_flush_queue); +diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_dma/Makefile b/drivers/staging/t2bce/t2bce_dma/Makefile +--- a/drivers/staging/t2bce/t2bce_dma/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ b/drivers/staging/t2bce/t2bce_dma/Makefile 2026-10-03 14:48:53.000000000 +0200 +@@ -0,0 +1,6 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++obj-$(CONFIG_T2BCE_DMA) += t2bce_dma.o ++t2bce_dma-y := queue.o ++ ++ccflags-y += -DWITHOUT_NVME_PATCH ++ccflags-y += -I$(src)/include diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_dma/include/t2bce_dma_queue.h b/drivers/staging/t2bce/t2bce_dma/include/t2bce_dma_queue.h --- a/drivers/staging/t2bce/t2bce_dma/include/t2bce_dma_queue.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_dma/include/t2bce_dma_queue.h 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/t2bce_dma/include/t2bce_dma_queue.h 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,182 @@ +#ifndef T2BCE_DMA_QUEUE_H +#define T2BCE_DMA_QUEUE_H @@ -22108,19 +22767,9 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_dma/include/t2b +int t2bce_dma_flush_sq(struct t2bce_dma_engine *dma, struct bce_queue_sq *sq); + +#endif -diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_dma/Makefile b/drivers/staging/t2bce/t2bce_dma/Makefile ---- a/drivers/staging/t2bce/t2bce_dma/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_dma/Makefile 2026-09-23 12:56:16.000000000 +0200 -@@ -0,0 +1,6 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+obj-$(CONFIG_T2BCE_DMA) += t2bce_dma.o -+t2bce_dma-y := queue.o -+ -+ccflags-y += -DWITHOUT_NVME_PATCH -+ccflags-y += -I$(src)/include diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_dma/queue.c b/drivers/staging/t2bce/t2bce_dma/queue.c --- a/drivers/staging/t2bce/t2bce_dma/queue.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_dma/queue.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/t2bce_dma/queue.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,625 @@ +#include "t2bce_dma_queue.h" +#include @@ -22747,9 +23396,20 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_dma/queue.c b/d +MODULE_DESCRIPTION("Apple T2 BCE DMA queue engine"); +MODULE_VERSION("0.01"); +MODULE_LICENSE("GPL"); +diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_vhci/Makefile b/drivers/staging/t2bce/t2bce_vhci/Makefile +--- a/drivers/staging/t2bce/t2bce_vhci/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ b/drivers/staging/t2bce/t2bce_vhci/Makefile 2026-10-03 14:48:53.000000000 +0200 +@@ -0,0 +1,7 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++obj-$(CONFIG_T2BCE_VHCI) += t2bce_vhci.o ++t2bce_vhci-y := vhci.o queue.o transfer.o ++ ++ccflags-y += -DWITHOUT_NVME_PATCH ++ccflags-y += -I$(src) ++ccflags-y += -I$(src)/../t2bce_core/include diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_vhci/command.h b/drivers/staging/t2bce/t2bce_vhci/command.h --- a/drivers/staging/t2bce/t2bce_vhci/command.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_vhci/command.h 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/t2bce_vhci/command.h 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,206 @@ +#ifndef BCE_VHCI_COMMAND_H +#define BCE_VHCI_COMMAND_H @@ -22957,20 +23617,9 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_vhci/command.h + + +#endif //BCE_VHCI_COMMAND_H -diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_vhci/Makefile b/drivers/staging/t2bce/t2bce_vhci/Makefile ---- a/drivers/staging/t2bce/t2bce_vhci/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_vhci/Makefile 2026-09-23 12:56:16.000000000 +0200 -@@ -0,0 +1,7 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+obj-$(CONFIG_T2BCE_VHCI) += t2bce_vhci.o -+t2bce_vhci-y := vhci.o queue.o transfer.o -+ -+ccflags-y += -DWITHOUT_NVME_PATCH -+ccflags-y += -I$(src) -+ccflags-y += -I$(src)/../t2bce_core/include diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_vhci/queue.c b/drivers/staging/t2bce/t2bce_vhci/queue.c --- a/drivers/staging/t2bce/t2bce_vhci/queue.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_vhci/queue.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/t2bce_vhci/queue.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,269 @@ +#include "queue.h" +#include "vhci.h" @@ -23243,7 +23892,7 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_vhci/queue.c b/ +} diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_vhci/queue.h b/drivers/staging/t2bce/t2bce_vhci/queue.h --- a/drivers/staging/t2bce/t2bce_vhci/queue.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_vhci/queue.h 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/t2bce_vhci/queue.h 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,76 @@ +#ifndef BCE_VHCI_QUEUE_H +#define BCE_VHCI_QUEUE_H @@ -23323,7 +23972,7 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_vhci/queue.h b/ +#endif //BCE_VHCI_QUEUE_H diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_vhci/transfer.c b/drivers/staging/t2bce/t2bce_vhci/transfer.c --- a/drivers/staging/t2bce/t2bce_vhci/transfer.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_vhci/transfer.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/t2bce_vhci/transfer.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,1261 @@ +#include "transfer.h" +#include "vhci.h" @@ -24588,7 +25237,7 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_vhci/transfer.c +} diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_vhci/transfer.h b/drivers/staging/t2bce/t2bce_vhci/transfer.h --- a/drivers/staging/t2bce/t2bce_vhci/transfer.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_vhci/transfer.h 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/t2bce_vhci/transfer.h 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,86 @@ +#ifndef BCEDRIVER_TRANSFER_H +#define BCEDRIVER_TRANSFER_H @@ -24678,7 +25327,7 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_vhci/transfer.h +#endif //BCEDRIVER_TRANSFER_H diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_vhci/vhci.c b/drivers/staging/t2bce/t2bce_vhci/vhci.c --- a/drivers/staging/t2bce/t2bce_vhci/vhci.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_vhci/vhci.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/t2bce_vhci/vhci.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,1293 @@ +#include "vhci.h" +#include "command.h" @@ -25975,7 +26624,7 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_vhci/vhci.c b/d +module_exit(bce_vhci_module_exit); diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_vhci/vhci.h b/drivers/staging/t2bce/t2bce_vhci/vhci.h --- a/drivers/staging/t2bce/t2bce_vhci/vhci.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/staging/t2bce/t2bce_vhci/vhci.h 2026-09-23 12:56:16.000000000 +0200 ++++ b/drivers/staging/t2bce/t2bce_vhci/vhci.h 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,69 @@ +#ifndef BCE_VHCI_H +#define BCE_VHCI_H @@ -26047,8 +26696,8 @@ diff -ruN --no-dereference -x .git a/drivers/staging/t2bce/t2bce_vhci/vhci.h b/d + +#endif //BCE_VHCI_H diff -ruN --no-dereference -x .git a/drivers/usb/core/message.c b/drivers/usb/core/message.c ---- a/drivers/usb/core/message.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/drivers/usb/core/message.c 2026-09-23 12:56:16.000000000 +0200 +--- a/drivers/usb/core/message.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/drivers/usb/core/message.c 2026-10-03 14:48:53.000000000 +0200 @@ -1052,6 +1052,25 @@ UTF16_LITTLE_ENDIAN, buf, size); buf[err] = 0; @@ -26076,8 +26725,8 @@ diff -ruN --no-dereference -x .git a/drivers/usb/core/message.c b/drivers/usb/co dev_dbg(&dev->dev, "wrong descriptor type %02x for string %d (\"%s\")\n", diff -ruN --no-dereference -x .git a/fs/readdir.c b/fs/readdir.c ---- a/fs/readdir.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/fs/readdir.c 2026-09-23 12:56:16.000000000 +0200 +--- a/fs/readdir.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/fs/readdir.c 2026-10-03 14:48:53.000000000 +0200 @@ -149,7 +149,7 @@ */ static int verify_dirent_name(const char *name, int len) @@ -26088,8 +26737,8 @@ diff -ruN --no-dereference -x .git a/fs/readdir.c b/fs/readdir.c if (memchr(name, '/', len)) return -EIO; diff -ruN --no-dereference -x .git a/include/drm/drm_connector.h b/include/drm/drm_connector.h ---- a/include/drm/drm_connector.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/drm/drm_connector.h 2026-09-23 12:56:16.000000000 +0200 +--- a/include/drm/drm_connector.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/include/drm/drm_connector.h 2026-10-03 14:48:53.000000000 +0200 @@ -255,6 +255,44 @@ }; @@ -26165,8 +26814,8 @@ diff -ruN --no-dereference -x .git a/include/drm/drm_connector.h b/include/drm/d */ u8 *vics; diff -ruN --no-dereference -x .git a/include/drm/drm_modes.h b/include/drm/drm_modes.h ---- a/include/drm/drm_modes.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/drm/drm_modes.h 2026-09-23 12:56:16.000000000 +0200 +--- a/include/drm/drm_modes.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/include/drm/drm_modes.h 2026-10-03 14:48:53.000000000 +0200 @@ -417,6 +417,16 @@ */ enum hdmi_picture_aspect picture_aspect_ratio; @@ -26185,8 +26834,8 @@ diff -ruN --no-dereference -x .git a/include/drm/drm_modes.h b/include/drm/drm_m /** diff -ruN --no-dereference -x .git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h ---- a/include/drm/ttm/ttm_resource.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/drm/ttm/ttm_resource.h 2026-09-23 12:56:16.000000000 +0200 +--- a/include/drm/ttm/ttm_resource.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/include/drm/ttm/ttm_resource.h 2026-10-03 14:48:53.000000000 +0200 @@ -458,10 +458,14 @@ void ttm_resource_fini(struct ttm_resource_manager *man, struct ttm_resource *res); @@ -26205,7 +26854,7 @@ diff -ruN --no-dereference -x .git a/include/drm/ttm/ttm_resource.h b/include/dr struct ttm_resource *res, diff -ruN --no-dereference -x .git a/include/linux/cachy-t2.h b/include/linux/cachy-t2.h --- a/include/linux/cachy-t2.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/include/linux/cachy-t2.h 2026-09-23 12:56:16.000000000 +0200 ++++ b/include/linux/cachy-t2.h 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,35 @@ +#ifndef CACHYOS_T2_H +#define CACHYOS_T2_H @@ -26242,9 +26891,40 @@ diff -ruN --no-dereference -x .git a/include/linux/cachy-t2.h b/include/linux/ca +}; + +#endif +diff -ruN --no-dereference -x .git a/include/linux/cgroup.h b/include/linux/cgroup.h +--- a/include/linux/cgroup.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/include/linux/cgroup.h 2026-10-03 14:48:53.000000000 +0200 +@@ -624,6 +624,27 @@ + } + + /** ++ * cgroup_common_ancestor - find common ancestor of two cgroups ++ * @a: first cgroup to find common ancestor of ++ * @b: second cgroup to find common ancestor of ++ * ++ * Find the first cgroup that is an ancestor of both @a and @b, if it exists ++ * and return a pointer to it. If such a cgroup doesn't exist, return NULL. ++ * ++ * This function is safe to call as long as both @a and @b are accessible. ++ */ ++static inline struct cgroup *cgroup_common_ancestor(struct cgroup *a, ++ struct cgroup *b) ++{ ++ int level; ++ ++ for (level = min(a->level, b->level); level >= 0; level--) ++ if (a->ancestors[level] == b->ancestors[level]) ++ return a->ancestors[level]; ++ return NULL; ++} ++ ++/** + * task_under_cgroup_hierarchy - test task's membership of cgroup ancestry + * @task: the task to be tested + * @ancestor: possible ancestor of @task's cgroup diff -ruN --no-dereference -x .git a/include/linux/cgroup_dmem.h b/include/linux/cgroup_dmem.h ---- a/include/linux/cgroup_dmem.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/linux/cgroup_dmem.h 2026-09-23 12:56:16.000000000 +0200 +--- a/include/linux/cgroup_dmem.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/include/linux/cgroup_dmem.h 2026-10-03 14:48:53.000000000 +0200 @@ -24,6 +24,12 @@ bool dmem_cgroup_state_evict_valuable(struct dmem_cgroup_pool_state *limit_pool, struct dmem_cgroup_pool_state *test_pool, @@ -26284,40 +26964,9 @@ diff -ruN --no-dereference -x .git a/include/linux/cgroup_dmem.h b/include/linux static inline void dmem_cgroup_pool_state_put(struct dmem_cgroup_pool_state *pool) { } -diff -ruN --no-dereference -x .git a/include/linux/cgroup.h b/include/linux/cgroup.h ---- a/include/linux/cgroup.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/linux/cgroup.h 2026-09-23 12:56:16.000000000 +0200 -@@ -624,6 +624,27 @@ - } - - /** -+ * cgroup_common_ancestor - find common ancestor of two cgroups -+ * @a: first cgroup to find common ancestor of -+ * @b: second cgroup to find common ancestor of -+ * -+ * Find the first cgroup that is an ancestor of both @a and @b, if it exists -+ * and return a pointer to it. If such a cgroup doesn't exist, return NULL. -+ * -+ * This function is safe to call as long as both @a and @b are accessible. -+ */ -+static inline struct cgroup *cgroup_common_ancestor(struct cgroup *a, -+ struct cgroup *b) -+{ -+ int level; -+ -+ for (level = min(a->level, b->level); level >= 0; level--) -+ if (a->ancestors[level] == b->ancestors[level]) -+ return a->ancestors[level]; -+ return NULL; -+} -+ -+/** - * task_under_cgroup_hierarchy - test task's membership of cgroup ancestry - * @task: the task to be tested - * @ancestor: possible ancestor of @task's cgroup diff -ruN --no-dereference -x .git a/include/linux/cpuset.h b/include/linux/cpuset.h ---- a/include/linux/cpuset.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/linux/cpuset.h 2026-09-23 12:56:16.000000000 +0200 +--- a/include/linux/cpuset.h 2026-10-07 05:21:41.396626235 +0200 ++++ b/include/linux/cpuset.h 2026-10-03 14:48:53.000000000 +0200 @@ -80,6 +80,7 @@ extern void cpuset_cpus_allowed_locked(struct task_struct *p, struct cpumask *mask); extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask); @@ -26339,8 +26988,8 @@ diff -ruN --no-dereference -x .git a/include/linux/cpuset.h b/include/linux/cpus { return node_possible_map; diff -ruN --no-dereference -x .git a/include/linux/hid.h b/include/linux/hid.h ---- a/include/linux/hid.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/linux/hid.h 2026-09-23 12:56:16.000000000 +0200 +--- a/include/linux/hid.h 2026-10-07 05:21:41.397844869 +0200 ++++ b/include/linux/hid.h 2026-10-03 14:48:53.000000000 +0200 @@ -625,7 +625,9 @@ enum hid_type { HID_TYPE_OTHER = 0, @@ -26362,8 +27011,8 @@ diff -ruN --no-dereference -x .git a/include/linux/hid.h b/include/linux/hid.h #define HID_REPORT_ID(rep) \ .report_type = (rep) diff -ruN --no-dereference -x .git a/include/linux/pagemap.h b/include/linux/pagemap.h ---- a/include/linux/pagemap.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/linux/pagemap.h 2026-09-23 12:56:16.000000000 +0200 +--- a/include/linux/pagemap.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/include/linux/pagemap.h 2026-10-03 14:48:53.000000000 +0200 @@ -1363,7 +1363,7 @@ ._index = i, \ } @@ -26374,9 +27023,9 @@ diff -ruN --no-dereference -x .git a/include/linux/pagemap.h b/include/linux/pag void page_cache_ra_unbounded(struct readahead_control *, unsigned long nr_to_read, unsigned long lookahead_count); diff -ruN --no-dereference -x .git a/include/linux/perf_event.h b/include/linux/perf_event.h ---- a/include/linux/perf_event.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/linux/perf_event.h 2026-09-23 12:56:16.000000000 +0200 -@@ -1632,7 +1632,7 @@ +--- a/include/linux/perf_event.h 2026-10-07 05:21:41.401953601 +0200 ++++ b/include/linux/perf_event.h 2026-10-03 14:48:53.000000000 +0200 +@@ -1615,7 +1615,7 @@ task->sched_migrated = 1; } @@ -26386,8 +27035,8 @@ diff -ruN --no-dereference -x .git a/include/linux/perf_event.h b/include/linux/ { if (static_branch_unlikely(&perf_sched_events)) diff -ruN --no-dereference -x .git a/include/linux/rmap.h b/include/linux/rmap.h ---- a/include/linux/rmap.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/linux/rmap.h 2026-09-23 12:56:16.000000000 +0200 +--- a/include/linux/rmap.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/include/linux/rmap.h 2026-10-03 14:48:53.000000000 +0200 @@ -843,7 +843,7 @@ * Called from mm/vmscan.c to handle paging out */ @@ -26411,8 +27060,8 @@ diff -ruN --no-dereference -x .git a/include/linux/rmap.h b/include/linux/rmap.h } diff -ruN --no-dereference -x .git a/include/linux/sched/mm.h b/include/linux/sched/mm.h ---- a/include/linux/sched/mm.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/linux/sched/mm.h 2026-09-23 12:56:16.000000000 +0200 +--- a/include/linux/sched/mm.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/include/linux/sched/mm.h 2026-10-03 14:48:53.000000000 +0200 @@ -32,7 +32,7 @@ * See also for an in-depth explanation * of &mm_struct.mm_count vs &mm_struct.mm_users. @@ -26497,8 +27146,8 @@ diff -ruN --no-dereference -x .git a/include/linux/sched/mm.h b/include/linux/sc /* * The atomic_read() below prevents CSE. The following should diff -ruN --no-dereference -x .git a/include/linux/sched/topology.h b/include/linux/sched/topology.h ---- a/include/linux/sched/topology.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/linux/sched/topology.h 2026-09-23 12:56:16.000000000 +0200 +--- a/include/linux/sched/topology.h 2026-10-07 05:21:41.402719305 +0200 ++++ b/include/linux/sched/topology.h 2026-10-03 14:48:53.000000000 +0200 @@ -86,6 +86,52 @@ unsigned long util_avg; unsigned long capacity; @@ -26553,8 +27202,8 @@ diff -ruN --no-dereference -x .git a/include/linux/sched/topology.h b/include/li struct sched_domain { diff -ruN --no-dereference -x .git a/include/linux/sched.h b/include/linux/sched.h ---- a/include/linux/sched.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/linux/sched.h 2026-09-23 12:56:16.000000000 +0200 +--- a/include/linux/sched.h 2026-10-07 05:21:41.402514566 +0200 ++++ b/include/linux/sched.h 2026-10-03 14:48:53.000000000 +0200 @@ -575,6 +575,7 @@ struct sched_entity { /* For load-balancing: */ @@ -26590,8 +27239,8 @@ diff -ruN --no-dereference -x .git a/include/linux/sched.h b/include/linux/sched unsigned long preempt_disable_ip; #endif diff -ruN --no-dereference -x .git a/include/linux/smp.h b/include/linux/smp.h ---- a/include/linux/smp.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/linux/smp.h 2026-09-23 12:56:16.000000000 +0200 +--- a/include/linux/smp.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/include/linux/smp.h 2026-10-03 14:48:53.000000000 +0200 @@ -47,8 +47,7 @@ /* total number of cpus in this system (may exceed NR_CPUS) */ extern unsigned int total_cpus; @@ -26623,7 +27272,7 @@ diff -ruN --no-dereference -x .git a/include/linux/smp.h b/include/linux/smp.h * diff -ruN --no-dereference -x .git a/include/linux/soc/apple/dockchannel.h b/include/linux/soc/apple/dockchannel.h --- a/include/linux/soc/apple/dockchannel.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/include/linux/soc/apple/dockchannel.h 2026-09-23 12:56:16.000000000 +0200 ++++ b/include/linux/soc/apple/dockchannel.h 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ +/* @@ -26652,8 +27301,8 @@ diff -ruN --no-dereference -x .git a/include/linux/soc/apple/dockchannel.h b/inc +#endif +#endif diff -ruN --no-dereference -x .git a/include/linux/tcp.h b/include/linux/tcp.h ---- a/include/linux/tcp.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/linux/tcp.h 2026-09-23 12:56:16.000000000 +0200 +--- a/include/linux/tcp.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/include/linux/tcp.h 2026-10-03 14:48:53.000000000 +0200 @@ -232,7 +232,8 @@ tcp_usec_ts : 1, /* TSval values in usec */ is_sack_reneg:1, /* in recovery from loss with SACK reneg? */ @@ -26675,8 +27324,8 @@ diff -ruN --no-dereference -x .git a/include/linux/tcp.h b/include/linux/tcp.h accecn_opt_sent_w_dsack:1,/* Sent ACCECN opt in previous ACK w/ D-SACK */ unused2:3; diff -ruN --no-dereference -x .git a/include/linux/tick.h b/include/linux/tick.h ---- a/include/linux/tick.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/linux/tick.h 2026-09-23 12:56:16.000000000 +0200 +--- a/include/linux/tick.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/include/linux/tick.h 2026-10-03 14:48:53.000000000 +0200 @@ -175,7 +175,7 @@ #ifdef CONFIG_NO_HZ_FULL extern bool tick_nohz_full_running; @@ -26696,8 +27345,8 @@ diff -ruN --no-dereference -x .git a/include/linux/tick.h b/include/linux/tick.h if (tick_nohz_full_enabled()) __tick_nohz_task_switch(); diff -ruN --no-dereference -x .git a/include/linux/vtime.h b/include/linux/vtime.h ---- a/include/linux/vtime.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/linux/vtime.h 2026-09-23 12:56:16.000000000 +0200 +--- a/include/linux/vtime.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/include/linux/vtime.h 2026-10-03 14:48:53.000000000 +0200 @@ -89,24 +89,24 @@ * For now vtime state is tied to context tracking. We might want to decouple * those later if necessary. @@ -26728,8 +27377,8 @@ diff -ruN --no-dereference -x .git a/include/linux/vtime.h b/include/linux/vtime if (vtime_accounting_enabled_this_cpu()) vtime_task_switch_generic(prev); diff -ruN --no-dereference -x .git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h ---- a/include/net/inet_connection_sock.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/net/inet_connection_sock.h 2026-09-23 12:56:16.000000000 +0200 +--- a/include/net/inet_connection_sock.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/include/net/inet_connection_sock.h 2026-10-03 14:48:53.000000000 +0200 @@ -138,8 +138,8 @@ u32 icsk_probes_tstamp; u32 icsk_user_timeout; @@ -26741,34 +27390,9 @@ diff -ruN --no-dereference -x .git a/include/net/inet_connection_sock.h b/includ }; #define ICSK_TIME_RETRANS 1 /* Retransmit timer */ -diff -ruN --no-dereference -x .git a/include/net/tcp_ecn.h b/include/net/tcp_ecn.h ---- a/include/net/tcp_ecn.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/net/tcp_ecn.h 2026-09-23 12:56:16.000000000 +0200 -@@ -606,10 +606,9 @@ - use_ecn = tcp_ecn == TCP_ECN_IN_ECN_OUT_ECN || - tcp_ecn == TCP_ECN_IN_ACCECN_OUT_ECN || - tcp_ca_needs_ecn(sk) || bpf_needs_ecn || use_accecn; -+ const struct dst_entry *dst = __sk_dst_get(sk); - - if (!use_ecn) { -- const struct dst_entry *dst = __sk_dst_get(sk); -- - if (dst && dst_feature(dst, RTAX_FEATURE_ECN)) - use_ecn = true; - } -@@ -627,6 +626,9 @@ - tp->syn_ect_snt = inet_sk(sk)->tos & INET_ECN_MASK; - } else { - tcp_ecn_mode_set(tp, TCP_ECN_MODE_RFC3168); -+ -+ if (dst) -+ tcp_set_ecn_low_from_dst(sk, dst); - } - } - } diff -ruN --no-dereference -x .git a/include/net/tcp.h b/include/net/tcp.h ---- a/include/net/tcp.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/net/tcp.h 2026-09-23 12:56:16.000000000 +0200 +--- a/include/net/tcp.h 2026-10-07 05:21:41.406923367 +0200 ++++ b/include/net/tcp.h 2026-10-03 14:48:53.000000000 +0200 @@ -428,6 +428,8 @@ #define TCP_ECN_DEMAND_CWR BIT(2) #define TCP_ECN_SEEN BIT(3) @@ -26929,9 +27553,34 @@ diff -ruN --no-dereference -x .git a/include/net/tcp.h b/include/net/tcp.h static inline void tcp_plb_init(const struct sock *sk, struct tcp_plb_state *plb) +diff -ruN --no-dereference -x .git a/include/net/tcp_ecn.h b/include/net/tcp_ecn.h +--- a/include/net/tcp_ecn.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/include/net/tcp_ecn.h 2026-10-03 14:48:53.000000000 +0200 +@@ -606,10 +606,9 @@ + use_ecn = tcp_ecn == TCP_ECN_IN_ECN_OUT_ECN || + tcp_ecn == TCP_ECN_IN_ACCECN_OUT_ECN || + tcp_ca_needs_ecn(sk) || bpf_needs_ecn || use_accecn; ++ const struct dst_entry *dst = __sk_dst_get(sk); + + if (!use_ecn) { +- const struct dst_entry *dst = __sk_dst_get(sk); +- + if (dst && dst_feature(dst, RTAX_FEATURE_ECN)) + use_ecn = true; + } +@@ -627,6 +626,9 @@ + tp->syn_ect_snt = inet_sk(sk)->tos & INET_ECN_MASK; + } else { + tcp_ecn_mode_set(tp, TCP_ECN_MODE_RFC3168); ++ ++ if (dst) ++ tcp_set_ecn_low_from_dst(sk, dst); + } + } + } diff -ruN --no-dereference -x .git a/include/sound/aw88399.h b/include/sound/aw88399.h --- a/include/sound/aw88399.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/include/sound/aw88399.h 2026-09-23 12:56:16.000000000 +0200 ++++ b/include/sound/aw88399.h 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,621 @@ +/* SPDX-License-Identifier: GPL-2.0-only + * @@ -27555,8 +28204,8 @@ diff -ruN --no-dereference -x .git a/include/sound/aw88399.h b/include/sound/aw8 + +#endif /* __SOUND_AW88399_H */ diff -ruN --no-dereference -x .git a/include/uapi/linux/inet_diag.h b/include/uapi/linux/inet_diag.h ---- a/include/uapi/linux/inet_diag.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/uapi/linux/inet_diag.h 2026-09-23 12:56:16.000000000 +0200 +--- a/include/uapi/linux/inet_diag.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/include/uapi/linux/inet_diag.h 2026-10-03 14:48:53.000000000 +0200 @@ -238,6 +238,29 @@ __u32 bbr_min_rtt; /* min-filtered RTT in uSec */ __u32 bbr_pacing_gain; /* pacing gain shifted left 8 bits */ @@ -27588,8 +28237,8 @@ diff -ruN --no-dereference -x .git a/include/uapi/linux/inet_diag.h b/include/ua union tcp_cc_info { diff -ruN --no-dereference -x .git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h ---- a/include/uapi/linux/rtnetlink.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/uapi/linux/rtnetlink.h 2026-09-23 12:56:16.000000000 +0200 +--- a/include/uapi/linux/rtnetlink.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/include/uapi/linux/rtnetlink.h 2026-10-03 14:48:53.000000000 +0200 @@ -517,12 +517,14 @@ #define RTAX_FEATURE_TIMESTAMP (1 << 2) /* unused */ #define RTAX_FEATURE_ALLFRAG (1 << 3) /* unused */ @@ -27607,8 +28256,8 @@ diff -ruN --no-dereference -x .git a/include/uapi/linux/rtnetlink.h b/include/ua struct rta_session { __u8 proto; diff -ruN --no-dereference -x .git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h ---- a/include/uapi/linux/tcp.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/include/uapi/linux/tcp.h 2026-09-23 12:56:16.000000000 +0200 +--- a/include/uapi/linux/tcp.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/include/uapi/linux/tcp.h 2026-10-03 14:48:53.000000000 +0200 @@ -185,6 +185,7 @@ #define TCPI_OPT_SYN_DATA 32 /* SYN-ACK acked data in SYN sent or rcvd */ #define TCPI_OPT_USEC_TS 64 /* usec timestamps */ @@ -27618,8 +28267,8 @@ diff -ruN --no-dereference -x .git a/include/uapi/linux/tcp.h b/include/uapi/lin /* * Sender's congestion state indicating normal or abnormal situations diff -ruN --no-dereference -x .git a/init/Kconfig b/init/Kconfig ---- a/init/Kconfig 2026-09-21 15:09:00.000000000 +0200 -+++ b/init/Kconfig 2026-09-23 12:56:16.000000000 +0200 +--- a/init/Kconfig 2026-08-16 23:32:26.000000000 +0200 ++++ b/init/Kconfig 2026-10-03 14:48:53.000000000 +0200 @@ -218,6 +218,10 @@ menu "General setup" @@ -27664,10 +28313,63 @@ diff -ruN --no-dereference -x .git a/init/Kconfig b/init/Kconfig config CC_OPTIMIZE_FOR_SIZE bool "Optimize for size (-Os)" help +diff -ruN --no-dereference -x .git a/kernel/Kconfig.hz b/kernel/Kconfig.hz +--- a/kernel/Kconfig.hz 2026-08-16 23:32:26.000000000 +0200 ++++ b/kernel/Kconfig.hz 2026-10-03 14:48:53.000000000 +0200 +@@ -40,6 +40,27 @@ + on SMP and NUMA systems and exactly dividing by both PAL and + NTSC frame rates for video and multimedia work. + ++ config HZ_500 ++ bool "500 HZ" ++ help ++ 500 Hz is a balanced timer frequency. Provides fast interactivity ++ on desktops with good smoothness without increasing CPU power ++ consumption and sacrificing the battery life on laptops. ++ ++ config HZ_600 ++ bool "600 HZ" ++ help ++ 600 Hz is a balanced timer frequency. Provides fast interactivity ++ on desktops with good smoothness without increasing CPU power ++ consumption and sacrificing the battery life on laptops. ++ ++ config HZ_750 ++ bool "750 HZ" ++ help ++ 750 Hz is a balanced timer frequency. Provides fast interactivity ++ on desktops with good smoothness without increasing CPU power ++ consumption and sacrificing the battery life on laptops. ++ + config HZ_1000 + bool "1000 HZ" + help +@@ -53,6 +74,9 @@ + default 100 if HZ_100 + default 250 if HZ_250 + default 300 if HZ_300 ++ default 500 if HZ_500 ++ default 600 if HZ_600 ++ default 750 if HZ_750 + default 1000 if HZ_1000 + + config SCHED_HRTICK +diff -ruN --no-dereference -x .git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt +--- a/kernel/Kconfig.preempt 2026-10-07 05:21:41.409731629 +0200 ++++ b/kernel/Kconfig.preempt 2026-10-03 14:48:53.000000000 +0200 +@@ -91,7 +91,7 @@ + + config PREEMPT_RT + bool "Fully Preemptible Kernel (Real-Time)" +- depends on EXPERT && ARCH_SUPPORTS_RT && !COMPILE_TEST ++ depends on ARCH_SUPPORTS_RT && !COMPILE_TEST + select PREEMPTION + help + This option turns the kernel into a real-time kernel by replacing diff -ruN --no-dereference -x .git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c ---- a/kernel/cgroup/cpuset.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/kernel/cgroup/cpuset.c 2026-09-23 12:56:16.000000000 +0200 -@@ -4157,6 +4157,28 @@ +--- a/kernel/cgroup/cpuset.c 2026-10-07 05:21:41.415615872 +0200 ++++ b/kernel/cgroup/cpuset.c 2026-10-03 14:48:53.000000000 +0200 +@@ -4158,6 +4158,28 @@ return changed; } @@ -27697,8 +28399,8 @@ diff -ruN --no-dereference -x .git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpus { nodes_setall(current->mems_allowed); diff -ruN --no-dereference -x .git a/kernel/cgroup/dmem.c b/kernel/cgroup/dmem.c ---- a/kernel/cgroup/dmem.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/kernel/cgroup/dmem.c 2026-09-23 12:56:16.000000000 +0200 +--- a/kernel/cgroup/dmem.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/kernel/cgroup/dmem.c 2026-10-03 14:48:53.000000000 +0200 @@ -695,6 +695,110 @@ } EXPORT_SYMBOL_GPL(dmem_cgroup_try_charge); @@ -27811,8 +28513,8 @@ diff -ruN --no-dereference -x .git a/kernel/cgroup/dmem.c b/kernel/cgroup/dmem.c { struct dmem_cgroup_region *region; diff -ruN --no-dereference -x .git a/kernel/fork.c b/kernel/fork.c ---- a/kernel/fork.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/kernel/fork.c 2026-09-23 12:56:16.000000000 +0200 +--- a/kernel/fork.c 2026-10-07 05:21:41.417534966 +0200 ++++ b/kernel/fork.c 2026-10-03 14:48:53.000000000 +0200 @@ -127,6 +127,12 @@ #include @@ -27898,62 +28600,9 @@ diff -ruN --no-dereference -x .git a/kernel/fork.c b/kernel/fork.c }; static int __init init_fork_sysctl(void) -diff -ruN --no-dereference -x .git a/kernel/Kconfig.hz b/kernel/Kconfig.hz ---- a/kernel/Kconfig.hz 2026-09-21 15:09:00.000000000 +0200 -+++ b/kernel/Kconfig.hz 2026-09-23 12:56:16.000000000 +0200 -@@ -40,6 +40,27 @@ - on SMP and NUMA systems and exactly dividing by both PAL and - NTSC frame rates for video and multimedia work. - -+ config HZ_500 -+ bool "500 HZ" -+ help -+ 500 Hz is a balanced timer frequency. Provides fast interactivity -+ on desktops with good smoothness without increasing CPU power -+ consumption and sacrificing the battery life on laptops. -+ -+ config HZ_600 -+ bool "600 HZ" -+ help -+ 600 Hz is a balanced timer frequency. Provides fast interactivity -+ on desktops with good smoothness without increasing CPU power -+ consumption and sacrificing the battery life on laptops. -+ -+ config HZ_750 -+ bool "750 HZ" -+ help -+ 750 Hz is a balanced timer frequency. Provides fast interactivity -+ on desktops with good smoothness without increasing CPU power -+ consumption and sacrificing the battery life on laptops. -+ - config HZ_1000 - bool "1000 HZ" - help -@@ -53,6 +74,9 @@ - default 100 if HZ_100 - default 250 if HZ_250 - default 300 if HZ_300 -+ default 500 if HZ_500 -+ default 600 if HZ_600 -+ default 750 if HZ_750 - default 1000 if HZ_1000 - - config SCHED_HRTICK -diff -ruN --no-dereference -x .git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt ---- a/kernel/Kconfig.preempt 2026-09-21 15:09:00.000000000 +0200 -+++ b/kernel/Kconfig.preempt 2026-09-23 12:56:16.000000000 +0200 -@@ -91,7 +91,7 @@ - - config PREEMPT_RT - bool "Fully Preemptible Kernel (Real-Time)" -- depends on EXPERT && ARCH_SUPPORTS_RT && !COMPILE_TEST -+ depends on ARCH_SUPPORTS_RT && !COMPILE_TEST - select PREEMPTION - help - This option turns the kernel into a real-time kernel by replacing diff -ruN --no-dereference -x .git a/kernel/scftorture.c b/kernel/scftorture.c ---- a/kernel/scftorture.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/kernel/scftorture.c 2026-09-23 12:56:16.000000000 +0200 +--- a/kernel/scftorture.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/kernel/scftorture.c 2026-10-03 14:48:53.000000000 +0200 @@ -348,6 +348,8 @@ int ret = 0; struct scf_check *scfcp = NULL; @@ -28006,8 +28655,8 @@ diff -ruN --no-dereference -x .git a/kernel/scftorture.c b/kernel/scftorture.c schedule_timeout_idle((1 + longwait) * HZ); // Let no-wait handlers complete. else if (!(torture_random(trsp) & 0xfff)) diff -ruN --no-dereference -x .git a/kernel/sched/core.c b/kernel/sched/core.c ---- a/kernel/sched/core.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/kernel/sched/core.c 2026-09-23 12:56:16.000000000 +0200 +--- a/kernel/sched/core.c 2026-10-07 05:21:41.420809544 +0200 ++++ b/kernel/sched/core.c 2026-10-03 14:48:53.000000000 +0200 @@ -674,7 +674,7 @@ /* Matches synchronize_rcu() in __sched_core_enable() */ @@ -28026,7 +28675,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/core.c b/kernel/sched/core.c return; rq->clock += delta; -@@ -5091,7 +5091,7 @@ +@@ -5098,7 +5098,7 @@ WRITE_ONCE(next->on_cpu, 1); } @@ -28035,7 +28684,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/core.c b/kernel/sched/core.c { /* * This must be the very last reference to @prev from this CPU. After -@@ -5135,7 +5135,7 @@ +@@ -5142,7 +5142,7 @@ rq->balance_callback = found ? &balance_push_callback : NULL; } @@ -28044,7 +28693,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/core.c b/kernel/sched/core.c { void (*func)(struct rq *rq); struct balance_callback *next; -@@ -5170,7 +5170,7 @@ +@@ -5177,7 +5177,7 @@ .func = balance_push, }; @@ -28053,7 +28702,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/core.c b/kernel/sched/core.c __splice_balance_callbacks(struct rq *rq, bool split) { struct balance_callback *head = rq->balance_callback; -@@ -5244,7 +5244,7 @@ +@@ -5251,7 +5251,7 @@ __acquire(__rq_lockp(this_rq())); } @@ -28062,7 +28711,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/core.c b/kernel/sched/core.c __releases(__rq_lockp(rq)) { /* -@@ -5278,7 +5278,7 @@ +@@ -5285,7 +5285,7 @@ #endif } @@ -28071,7 +28720,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/core.c b/kernel/sched/core.c { #ifdef CONFIG_KMAP_LOCAL if (unlikely(current->kmap_ctrl.idx)) -@@ -5332,7 +5332,7 @@ +@@ -5339,7 +5339,7 @@ * past. 'prev == current' is still correct but we need to recalculate this_rq * because prev may have moved to another CPU. */ @@ -28080,7 +28729,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/core.c b/kernel/sched/core.c __releases(__rq_lockp(this_rq())) { struct rq *rq = this_rq(); -@@ -5674,11 +5674,8 @@ +@@ -5681,11 +5681,8 @@ */ static inline void prefetch_curr_exec_start(struct task_struct *p) { @@ -28093,7 +28742,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/core.c b/kernel/sched/core.c prefetch(curr); prefetch(&curr->exec_start); } -@@ -6243,7 +6240,7 @@ +@@ -6250,7 +6247,7 @@ struct rq *rq_i; bool need_sync = false; @@ -28102,7 +28751,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/core.c b/kernel/sched/core.c return __pick_next_task(rq, rf); cpu = cpu_of(rq); -@@ -7791,7 +7788,7 @@ +@@ -7798,7 +7795,7 @@ #if !defined(CONFIG_PREEMPTION) || defined(CONFIG_PREEMPT_DYNAMIC) int __sched __cond_resched(void) { @@ -28112,8 +28761,8 @@ diff -ruN --no-dereference -x .git a/kernel/sched/core.c b/kernel/sched/core.c return 1; } diff -ruN --no-dereference -x .git a/kernel/sched/debug.c b/kernel/sched/debug.c ---- a/kernel/sched/debug.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/kernel/sched/debug.c 2026-09-23 12:56:16.000000000 +0200 +--- a/kernel/sched/debug.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/kernel/sched/debug.c 2026-10-03 14:48:53.000000000 +0200 @@ -633,6 +633,82 @@ } } @@ -28241,9 +28890,9 @@ diff -ruN --no-dereference -x .git a/kernel/sched/debug.c b/kernel/sched/debug.c #ifdef CONFIG_CFS_BANDWIDTH SEQ_printf(m, " .%-30s: %d\n", "throttled", diff -ruN --no-dereference -x .git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c ---- a/kernel/sched/ext/ext.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/kernel/sched/ext/ext.c 2026-09-23 12:56:16.000000000 +0200 -@@ -6363,6 +6363,9 @@ +--- a/kernel/sched/ext/ext.c 2026-10-07 05:21:41.421842335 +0200 ++++ b/kernel/sched/ext/ext.c 2026-10-03 14:48:53.000000000 +0200 +@@ -6368,6 +6368,9 @@ mutex_unlock(&scx_enable_mutex); WARN_ON_ONCE(scx_set_enable_state(SCX_DISABLED) != SCX_DISABLING); @@ -28253,7 +28902,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/ext/ext.c b/kernel/sched/ext/e done: scx_bypass(sch, false); } -@@ -7577,6 +7580,10 @@ +@@ -7584,6 +7587,10 @@ } } @@ -28265,8 +28914,8 @@ diff -ruN --no-dereference -x .git a/kernel/sched/ext/ext.c b/kernel/sched/ext/e sch->ops.name, scx_switched_all() ? "" : " (partial)"); kobject_uevent(&sch->kobj, KOBJ_ADD); diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c ---- a/kernel/sched/fair.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/kernel/sched/fair.c 2026-09-23 12:56:16.000000000 +0200 +--- a/kernel/sched/fair.c 2026-10-07 05:21:41.422913619 +0200 ++++ b/kernel/sched/fair.c 2026-10-03 14:48:53.000000000 +0200 @@ -38,6 +38,7 @@ #include #include @@ -28466,7 +29115,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c #ifdef CONFIG_SCHED_CACHE /* -@@ -1998,7 +1974,7 @@ +@@ -2069,7 +2045,7 @@ * not necessarily be the actual task running * (rq->curr.se). This is easy to confuse! */ @@ -28475,7 +29124,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c struct rq *rq = rq_of(cfs_rq); s64 delta_exec; bool resched; -@@ -2010,26 +1986,29 @@ +@@ -2081,26 +2057,29 @@ if (unlikely(delta_exec <= 0)) return; @@ -28521,7 +29170,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c return; if (resched || !protect_slice(curr)) { -@@ -2040,7 +2019,10 @@ +@@ -2111,7 +2090,10 @@ static void update_curr_fair(struct rq *rq) { @@ -28533,7 +29182,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c } static inline void -@@ -2116,7 +2098,7 @@ +@@ -2187,7 +2169,7 @@ * Are we enqueueing a waiting task? (for current tasks * a dequeue/enqueue event is a NOP) */ @@ -28542,7 +29191,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c update_stats_wait_start_fair(cfs_rq, se); if (flags & ENQUEUE_WAKEUP) -@@ -2134,7 +2116,7 @@ +@@ -2205,7 +2187,7 @@ * Mark the end of the wait period if dequeueing a * waiting task: */ @@ -28551,7 +29200,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c update_stats_wait_end_fair(cfs_rq, se); if ((flags & DEQUEUE_SLEEP) && entity_is_task(se)) { -@@ -4475,6 +4457,7 @@ +@@ -4551,6 +4533,7 @@ static void account_entity_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se) { @@ -28559,7 +29208,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c update_load_add(&cfs_rq->load, se->load.weight); if (entity_is_task(se)) { struct task_struct *p = task_of(se); -@@ -4490,6 +4473,7 @@ +@@ -4566,6 +4549,7 @@ static void account_entity_dequeue(struct cfs_rq *cfs_rq, struct sched_entity *se) { @@ -28567,7 +29216,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c update_load_sub(&cfs_rq->load, se->load.weight); if (entity_is_task(se)) { struct task_struct *p = task_of(se); -@@ -4571,7 +4555,7 @@ +@@ -4647,7 +4631,7 @@ static void rescale_entity(struct sched_entity *se, unsigned long weight, bool rel_vprot) { @@ -28576,7 +29225,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c /* * VRUNTIME -@@ -4671,16 +4655,17 @@ +@@ -4747,16 +4731,17 @@ se->vprot = div64_long(se->vprot * old_weight, weight); } @@ -28599,7 +29248,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c avruntime = avg_vruntime(cfs_rq); se->vlag = entity_lag(cfs_rq, se, avruntime); se->deadline -= avruntime; -@@ -4690,46 +4675,90 @@ +@@ -4766,46 +4751,90 @@ rel_vprot = true; } @@ -28707,7 +29356,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c } static inline int throttled_hierarchy(struct cfs_rq *cfs_rq); -@@ -4808,12 +4837,10 @@ +@@ -4884,12 +4913,10 @@ * * hence icky! */ @@ -28722,7 +29371,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c load = max(scale_load_down(cfs_rq->load.weight), cfs_rq->avg.load_avg); -@@ -4839,7 +4866,120 @@ +@@ -4915,7 +4942,120 @@ * case no task is runnable on a CPU MIN_SHARES=2 should be returned * instead of 0. */ @@ -28844,7 +29493,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c } /* -@@ -4858,9 +4998,8 @@ +@@ -4934,9 +5074,8 @@ if (!gcfs_rq || !gcfs_rq->load.weight) return; @@ -28856,7 +29505,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c } #else /* !CONFIG_FAIR_GROUP_SCHED: */ -@@ -4978,11 +5117,11 @@ +@@ -5054,11 +5193,11 @@ * differential update where we store the last value we propagated. This in * turn allows skipping updates if the differential is 'small'. * @@ -28870,7 +29519,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c u64 now; /* -@@ -5003,17 +5142,21 @@ +@@ -5079,17 +5218,21 @@ if (now - cfs_rq->last_update_tg_load_avg < NSEC_PER_MSEC) return; @@ -28896,7 +29545,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c u64 now; /* -@@ -5023,9 +5166,12 @@ +@@ -5099,9 +5242,12 @@ return; now = rq_clock(rq_of(cfs_rq)); @@ -28911,7 +29560,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c cfs_rq->last_update_tg_load_avg = now; } -@@ -5439,7 +5585,7 @@ +@@ -5515,7 +5661,7 @@ * The cfs_rq avg is the direct sum of all its entities (blocked and runnable) * avg. The immediate corollary is that all (fair) tasks must be attached. * @@ -28920,7 +29569,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c * * Return: true if the load decayed or we removed load. * -@@ -5977,6 +6123,7 @@ +@@ -6053,6 +6199,7 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) { u64 vslice, vruntime = avg_vruntime(cfs_rq); @@ -28928,7 +29577,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c bool update_zero = false; s64 lag = 0; -@@ -5984,6 +6131,9 @@ +@@ -6060,6 +6207,9 @@ se->slice = sysctl_sched_base_slice; vslice = calc_delta_fair(se->slice, se); @@ -28938,7 +29587,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c /* * Due to how V is constructed as the weighted average of entities, * adding tasks with positive lag, or removing tasks with negative lag -@@ -5992,7 +6142,7 @@ +@@ -6068,7 +6218,7 @@ * * EEVDF: placement strategy #1 / #2 */ @@ -28947,7 +29596,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c struct sched_entity *curr = cfs_rq->curr; long load, weight; -@@ -6052,9 +6202,9 @@ +@@ -6128,9 +6278,9 @@ */ load = cfs_rq->sum_weight; if (curr && curr->on_rq) @@ -28959,7 +29608,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c lag *= load + weight; if (WARN_ON_ONCE(!load)) load = 1; -@@ -6113,22 +6263,8 @@ +@@ -6189,22 +6339,8 @@ static inline int cfs_rq_throttled(struct cfs_rq *cfs_rq); static void @@ -28982,7 +29631,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c /* * When enqueuing a sched_entity, we must: * - Update loads to have both entity and cfs_rq synced with now. -@@ -6147,13 +6283,6 @@ +@@ -6223,13 +6359,6 @@ */ update_cfs_group(se); @@ -28996,7 +29645,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c account_entity_enqueue(cfs_rq, se); /* Entity has migrated, no longer consider this task hot */ -@@ -6162,8 +6291,6 @@ +@@ -6238,8 +6367,6 @@ check_schedstat_required(); update_stats_enqueue_fair(cfs_rq, se, flags); @@ -29005,7 +29654,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c se->on_rq = 1; if (cfs_rq->nr_queued == 1) { -@@ -6181,21 +6308,19 @@ +@@ -6257,21 +6384,19 @@ } } @@ -29034,7 +29683,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c } static __always_inline void return_cfs_rq_runtime(struct cfs_rq *cfs_rq); -@@ -6206,7 +6331,7 @@ +@@ -6282,7 +6407,7 @@ /* * Delayed se of cfs_rq have no tasks queued on them. @@ -29043,7 +29692,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c * will account it for blocked tasks. */ if (!entity_is_task(se)) -@@ -6239,45 +6364,16 @@ +@@ -6315,45 +6440,16 @@ } } @@ -29092,7 +29741,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c action |= UPDATE_UTIL_EST; } -@@ -6295,14 +6391,6 @@ +@@ -6371,14 +6467,6 @@ update_stats_dequeue_fair(cfs_rq, se, flags); @@ -29107,7 +29756,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c se->on_rq = 0; account_entity_dequeue(cfs_rq, se); -@@ -6311,9 +6399,6 @@ +@@ -6387,9 +6475,6 @@ update_cfs_group(se); @@ -29117,7 +29766,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c if (cfs_rq->nr_queued == 0) { update_idle_cfs_rq_clock_pelt(cfs_rq); #ifdef CONFIG_CFS_BANDWIDTH -@@ -6326,15 +6411,11 @@ +@@ -6402,15 +6487,11 @@ } #endif } @@ -29134,7 +29783,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c /* 'current' is not kept within the tree. */ if (se->on_rq) { /* -@@ -6343,16 +6424,12 @@ +@@ -6419,16 +6500,12 @@ * runqueue. */ update_stats_wait_end_fair(cfs_rq, se); @@ -29153,7 +29802,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c /* * Track our maximum slice length, if the CPU's load is at -@@ -6372,23 +6449,17 @@ +@@ -6448,23 +6525,17 @@ se->prev_sum_exec_runtime = se->sum_exec_runtime; } @@ -29181,7 +29830,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c /* * Must not reference @se again, see __block_task(). */ -@@ -6408,13 +6479,11 @@ +@@ -6484,13 +6555,11 @@ if (prev->on_rq) { update_stats_wait_start_fair(cfs_rq, prev); @@ -29197,7 +29846,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c } static void -@@ -6969,7 +7038,7 @@ +@@ -7045,7 +7114,7 @@ assert_list_leaf_cfs_rq(rq); /* Determine whether we need to wake up potentially idle CPU: */ @@ -29206,7 +29855,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c resched_curr(rq); } -@@ -7304,7 +7373,7 @@ +@@ -7380,7 +7449,7 @@ return; /* an active group must be handled by the update_curr() path */ @@ -29215,7 +29864,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c return; /* ensure the group is not already throttled */ -@@ -7676,7 +7745,7 @@ +@@ -7752,7 +7821,7 @@ resched_curr(rq); return; } @@ -29224,7 +29873,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c /* * Correct for instantaneous load of other classes. -@@ -7776,10 +7845,8 @@ +@@ -7852,10 +7921,8 @@ } static void @@ -29236,7 +29885,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c /* * se->sched_delayed should imply: se->on_rq == 1. * Because a delayed entity is one that is still on -@@ -7791,19 +7858,58 @@ +@@ -7867,19 +7934,58 @@ update_curr(cfs_rq); if (update_entity_lag(cfs_rq, se)) { @@ -29297,7 +29946,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c /* * The enqueue_task method is called before nr_running is * increased. Here we update the fair scheduling stats and -@@ -7812,13 +7918,12 @@ +@@ -7888,13 +7994,12 @@ static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags) { @@ -29316,7 +29965,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c if (task_is_throttled(p) && enqueue_throttled_task(p)) return; -@@ -7830,10 +7935,10 @@ +@@ -7906,10 +8011,10 @@ * estimated utilization, before we update schedutil. */ if (!p->se.sched_delayed || (flags & ENQUEUE_DELAYED)) @@ -29329,7 +29978,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c return; } -@@ -7845,57 +7950,22 @@ +@@ -7921,57 +8026,22 @@ if (p->in_iowait) cpufreq_update_util(rq, SCHED_CPUFREQ_IOWAIT); @@ -29400,7 +30049,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c } if (!rq_h_nr_queued && rq->cfs.h_nr_queued) -@@ -7926,105 +7996,109 @@ +@@ -8002,105 +8072,109 @@ hrtick_update(rq); } @@ -29573,7 +30222,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c WARN_ON_ONCE(!task_sleep); WARN_ON_ONCE(p->on_rq != 1); -@@ -8036,7 +8110,7 @@ +@@ -8112,7 +8186,7 @@ __block_task(rq, p); } @@ -29582,7 +30231,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c } /* -@@ -8054,11 +8128,11 @@ +@@ -8130,11 +8204,11 @@ if (!p->se.sched_delayed) util_est_dequeue(&rq->cfs, p); @@ -29596,7 +30245,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c */ return true; } -@@ -8479,6 +8553,20 @@ +@@ -8555,6 +8629,20 @@ } /* @@ -29617,7 +30266,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c * Scan the entire LLC domain for idle cores; this dynamically switches off if * there are no idle cores left in the system; tracked through * sd_balance_shared->has_idle_cores and enabled through update_idle_core() -@@ -8805,16 +8893,38 @@ +@@ -8881,16 +8969,38 @@ return true; } @@ -29657,7 +30306,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c /* * On asymmetric system, update task utilization because we will check * that the task fits with CPU's capacity. -@@ -8831,23 +8941,13 @@ +@@ -8907,23 +9017,13 @@ */ lockdep_assert_irqs_disabled(); @@ -29686,7 +30335,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c /* * Allow a per-cpu kthread to stack with the wakee if the -@@ -8865,24 +8965,6 @@ +@@ -8941,24 +9041,6 @@ return prev; } @@ -29711,7 +30360,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c /* * For asymmetric CPU capacity systems, our domain of interest is * sd_asym_cpucapacity rather than sd_llc. -@@ -8907,6 +8989,74 @@ +@@ -8983,6 +9065,74 @@ if (!sd) return target; @@ -29786,7 +30435,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c if (sched_smt_active()) { has_idle_core = test_idle_cores(target); -@@ -8921,6 +9071,9 @@ +@@ -8997,6 +9147,9 @@ if ((unsigned)i < nr_cpumask_bits) return i; @@ -29796,7 +30445,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c /* * For cluster machines which have lower sharing cache like L2 or * LLC Tag, we tend to find an idle CPU in the target's cluster -@@ -8932,6 +9085,13 @@ +@@ -9008,6 +9161,13 @@ if ((unsigned int)recent_used_cpu < nr_cpumask_bits) return recent_used_cpu; @@ -29810,7 +30459,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c return target; } -@@ -9614,7 +9774,7 @@ +@@ -9690,7 +9850,7 @@ /* Fast path */ if (wake_flags & WF_TTWU) @@ -29819,7 +30468,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c return new_cpu; } -@@ -9653,19 +9813,6 @@ +@@ -9729,19 +9889,6 @@ static void task_dead_fair(struct task_struct *p) { struct sched_entity *se = &p->se; @@ -29839,7 +30488,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c remove_entity_load_avg(se); } -@@ -9699,21 +9846,10 @@ +@@ -9775,21 +9922,10 @@ set_task_max_allowed_capacity(p); } @@ -29862,7 +30511,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c PREEMPT_WAKEUP_RESCHED, /* Force reschedule. */ }; -@@ -9730,7 +9866,7 @@ +@@ -9806,7 +9942,7 @@ if (cfs_rq->next && entity_before(cfs_rq->next, pse)) return false; @@ -29871,7 +30520,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c return true; } -@@ -9783,7 +9919,7 @@ +@@ -9859,7 +9995,7 @@ enum preempt_wakeup_action preempt_action = PREEMPT_WAKEUP_PICK; struct task_struct *donor = rq->donor; struct sched_entity *nse, *se = &donor->se, *pse = &p->se; @@ -29880,7 +30529,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c int cse_is_idle, pse_is_idle; /* -@@ -9821,7 +9957,6 @@ +@@ -9897,7 +10033,6 @@ if (!sched_feat(WAKEUP_PREEMPTION)) return; @@ -29888,7 +30537,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c WARN_ON_ONCE(!pse); cse_is_idle = se_is_idle(se); -@@ -9849,8 +9984,7 @@ +@@ -9925,8 +10060,7 @@ if (unlikely(!normal_policy(p->policy))) return; @@ -29898,7 +30547,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c /* * If @p has a shorter slice than current and @p is eligible, override * current's slice protection in order to allow preemption. -@@ -9894,18 +10028,15 @@ +@@ -9970,18 +10104,15 @@ } pick: @@ -29926,7 +30575,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c if (sched_feat(RUN_TO_PARITY)) update_protect_slice(cfs_rq, se); -@@ -9924,33 +10055,24 @@ +@@ -10000,33 +10131,24 @@ struct task_struct *pick_task_fair(struct rq *rq, struct rq_flags *rf) __must_hold(__rq_lockp(rq)) { @@ -29968,7 +30617,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c return p; idle: -@@ -9987,7 +10109,7 @@ +@@ -10063,7 +10185,7 @@ static void put_prev_task_fair(struct rq *rq, struct task_struct *prev, struct task_struct *next) { struct sched_entity *se = &prev->se; @@ -29977,7 +30626,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c struct sched_entity *nse = NULL; #ifdef CONFIG_FAIR_GROUP_SCHED -@@ -9997,7 +10119,7 @@ +@@ -10073,7 +10195,7 @@ while (se) { cfs_rq = cfs_rq_of(se); @@ -29986,7 +30635,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c put_prev_entity(cfs_rq, se); #ifdef CONFIG_FAIR_GROUP_SCHED if (nse) { -@@ -10016,6 +10138,14 @@ +@@ -10092,6 +10214,14 @@ #endif se = parent_entity(se); } @@ -30001,7 +30650,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c } /* -@@ -10024,8 +10154,8 @@ +@@ -10100,8 +10230,8 @@ static void yield_task_fair(struct rq *rq) { struct task_struct *curr = rq->donor; @@ -30011,7 +30660,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c /* * Are we the only task in the tree? -@@ -10066,11 +10196,11 @@ +@@ -10142,11 +10272,11 @@ struct sched_entity *se = &p->se; /* !se->on_rq also covers throttled task */ @@ -30025,7 +30674,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c yield_task_fair(rq); -@@ -10409,15 +10539,10 @@ +@@ -10485,15 +10615,10 @@ */ static inline int task_is_ineligible_on_dst_cpu(struct task_struct *p, int dest_cpu) { @@ -30044,7 +30693,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c return 1; return 0; -@@ -11200,7 +11325,7 @@ +@@ -11281,7 +11406,7 @@ while ((se = READ_ONCE(cfs_rq->h_load_next)) != NULL) { load = cfs_rq->h_load; load = div64_ul(load * se->avg.load_avg, @@ -30053,7 +30702,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c cfs_rq = group_cfs_rq(se); cfs_rq->h_load = load; cfs_rq->last_h_load_update = now; -@@ -13350,12 +13475,15 @@ +@@ -13431,12 +13556,15 @@ * still unbalanced. ld_moved simply stays zero, so it is * correctly treated as an imbalance. */ @@ -30071,7 +30720,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c /* * cur_ld_moved - load moved in current iteration * ld_moved - cumulative load moved across iterations -@@ -14594,7 +14722,7 @@ +@@ -14675,7 +14803,7 @@ * MIN_NR_TASKS_DURING_FORCEIDLE - 1 tasks and use that to check * if we need to give up the CPU. */ @@ -30080,7 +30729,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c __entity_slice_used(&curr->se, MIN_NR_TASKS_DURING_FORCEIDLE)) resched_curr(rq); } -@@ -14803,30 +14931,8 @@ +@@ -14884,30 +15012,8 @@ WARN_ON_ONCE(task_rq(b)->core != rq->core); @@ -30111,7 +30760,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c /* * Find delta after normalizing se's vruntime with its cfs_rq's -@@ -14865,11 +14971,20 @@ +@@ -14946,11 +15052,20 @@ static void task_tick_fair(struct rq *rq, struct task_struct *curr, int queued) { struct sched_entity *se = &curr->se; @@ -30136,7 +30785,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c } if (queued) -@@ -14909,7 +15024,7 @@ +@@ -14990,7 +15105,7 @@ if (p->prio == oldprio) return; @@ -30145,7 +30794,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c return; /* -@@ -15038,33 +15153,44 @@ +@@ -15119,33 +15234,44 @@ } } @@ -30201,7 +30850,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c if (task_on_rq_queued(p)) { /* -@@ -15177,17 +15303,8 @@ +@@ -15258,17 +15384,8 @@ struct sched_entity *se = tg_se(tg, cpu); struct rq *rq = cpu_rq(cpu); @@ -30221,8 +30870,8 @@ diff -ruN --no-dereference -x .git a/kernel/sched/fair.c b/kernel/sched/fair.c /* * Only empty task groups can be destroyed; so we can speculatively diff -ruN --no-dereference -x .git a/kernel/sched/idle.c b/kernel/sched/idle.c ---- a/kernel/sched/idle.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/kernel/sched/idle.c 2026-09-23 12:56:16.000000000 +0200 +--- a/kernel/sched/idle.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/kernel/sched/idle.c 2026-10-03 14:48:53.000000000 +0200 @@ -305,6 +305,11 @@ __current_set_polling(); tick_nohz_idle_enter(); @@ -30248,8 +30897,8 @@ diff -ruN --no-dereference -x .git a/kernel/sched/idle.c b/kernel/sched/idle.c * Since we fell out of the loop above, we know TIF_NEED_RESCHED must * be set, propagate it into PREEMPT_NEED_RESCHED. diff -ruN --no-dereference -x .git a/kernel/sched/pelt.c b/kernel/sched/pelt.c ---- a/kernel/sched/pelt.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/kernel/sched/pelt.c 2026-09-23 12:56:16.000000000 +0200 +--- a/kernel/sched/pelt.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/kernel/sched/pelt.c 2026-10-03 14:48:53.000000000 +0200 @@ -206,7 +206,7 @@ /* * running is a subset of runnable (weight) so running can't be set if @@ -30279,7 +30928,7 @@ diff -ruN --no-dereference -x .git a/kernel/sched/pelt.c b/kernel/sched/pelt.c trace_pelt_cfs_tp(cfs_rq); diff -ruN --no-dereference -x .git a/kernel/sched/poc_selector.c b/kernel/sched/poc_selector.c --- a/kernel/sched/poc_selector.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/kernel/sched/poc_selector.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/kernel/sched/poc_selector.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,2038 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -32320,8 +32969,8 @@ diff -ruN --no-dereference -x .git a/kernel/sched/poc_selector.c b/kernel/sched/ +#endif /* CONFIG_SYSFS */ +#endif /* CONFIG_SCHED_POC_SELECTOR */ diff -ruN --no-dereference -x .git a/kernel/sched/sched.h b/kernel/sched/sched.h ---- a/kernel/sched/sched.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/kernel/sched/sched.h 2026-09-23 12:56:16.000000000 +0200 +--- a/kernel/sched/sched.h 2026-10-07 05:21:41.423770015 +0200 ++++ b/kernel/sched/sched.h 2026-10-03 14:48:53.000000000 +0200 @@ -493,6 +493,8 @@ * will also be accessed at each tick. */ @@ -32648,9 +33297,9 @@ diff -ruN --no-dereference -x .git a/kernel/sched/sched.h b/kernel/sched/sched.h #if defined(CONFIG_SCHED_CORE) && defined(CONFIG_SCHEDSTATS) diff -ruN --no-dereference -x .git a/kernel/sched/topology.c b/kernel/sched/topology.c ---- a/kernel/sched/topology.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/kernel/sched/topology.c 2026-09-23 12:56:16.000000000 +0200 -@@ -3170,6 +3170,9 @@ +--- a/kernel/sched/topology.c 2026-10-07 05:21:41.423981807 +0200 ++++ b/kernel/sched/topology.c 2026-10-03 14:48:53.000000000 +0200 +@@ -3174,6 +3174,9 @@ if (sd->flags & SD_SHARE_LLC) { init_sched_domain_shared(&d, sd, SD_SHARE_LLC); @@ -32661,8 +33310,8 @@ diff -ruN --no-dereference -x .git a/kernel/sched/topology.c b/kernel/sched/topo /* * In presence of higher domains, adjust the diff -ruN --no-dereference -x .git a/kernel/smp.c b/kernel/smp.c ---- a/kernel/smp.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/kernel/smp.c 2026-09-23 12:56:16.000000000 +0200 +--- a/kernel/smp.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/kernel/smp.c 2026-10-03 14:48:53.000000000 +0200 @@ -16,6 +16,7 @@ #include #include @@ -33009,8 +33658,8 @@ diff -ruN --no-dereference -x .git a/kernel/smp.c b/kernel/smp.c EXPORT_SYMBOL(on_each_cpu_cond_mask); diff -ruN --no-dereference -x .git a/kernel/up.c b/kernel/up.c ---- a/kernel/up.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/kernel/up.c 2026-09-23 12:56:16.000000000 +0200 +--- a/kernel/up.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/kernel/up.c 2026-10-03 14:48:53.000000000 +0200 @@ -9,8 +9,7 @@ #include #include @@ -33021,33 +33670,9 @@ diff -ruN --no-dereference -x .git a/kernel/up.c b/kernel/up.c { unsigned long flags; -diff -ruN --no-dereference -x .git a/Makefile b/Makefile ---- a/Makefile 2026-09-21 15:09:00.000000000 +0200 -+++ b/Makefile 2026-09-23 12:56:16.000000000 +0200 -@@ -932,11 +932,20 @@ - ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE - KBUILD_CFLAGS += -O2 - KBUILD_RUSTFLAGS += -Copt-level=2 -+else ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE_O3 -+KBUILD_CFLAGS += -O3 -+KBUILD_RUSTFLAGS += -Copt-level=3 - else ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE - KBUILD_CFLAGS += -Os - KBUILD_RUSTFLAGS += -Copt-level=s - endif - -+# Perform swing modulo scheduling immediately before the first scheduling pass. -+# This pass looks at innermost loops and reorders their instructions by -+# overlapping different iterations. -+KBUILD_CFLAGS += $(call cc-option,-fmodulo-sched -fmodulo-sched-allow-regmoves -fivopts) -+KBUILD_CFLAGS += $(call cc-option,-mllvm -enable-pipeliner) -+ - # Always set `debug-assertions` and `overflow-checks` because their default - # depends on `opt-level` and `debug-assertions`, respectively. - KBUILD_RUSTFLAGS += -Cdebug-assertions=$(if $(CONFIG_RUST_DEBUG_ASSERTIONS),y,n) diff -ruN --no-dereference -x .git a/mm/compaction.c b/mm/compaction.c ---- a/mm/compaction.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/mm/compaction.c 2026-09-23 12:56:16.000000000 +0200 +--- a/mm/compaction.c 2026-10-07 05:21:41.431912495 +0200 ++++ b/mm/compaction.c 2026-10-03 14:48:53.000000000 +0200 @@ -1935,7 +1935,11 @@ * aggressively the kernel should compact memory in the * background. It takes values in the range [0, 100]. @@ -33061,8 +33686,8 @@ diff -ruN --no-dereference -x .git a/mm/compaction.c b/mm/compaction.c static int __read_mostly sysctl_compact_memory; diff -ruN --no-dereference -x .git a/mm/huge_memory.c b/mm/huge_memory.c ---- a/mm/huge_memory.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/mm/huge_memory.c 2026-09-23 12:56:16.000000000 +0200 +--- a/mm/huge_memory.c 2026-10-07 05:21:41.434853610 +0200 ++++ b/mm/huge_memory.c 2026-10-03 14:48:53.000000000 +0200 @@ -65,7 +65,11 @@ #ifdef CONFIG_TRANSPARENT_HUGEPAGE_MADVISE (1<vma; diff -ruN --no-dereference -x .git a/mm/page_alloc.c b/mm/page_alloc.c ---- a/mm/page_alloc.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/mm/page_alloc.c 2026-09-23 12:56:16.000000000 +0200 +--- a/mm/page_alloc.c 2026-10-07 05:21:41.439994772 +0200 ++++ b/mm/page_alloc.c 2026-10-03 14:48:53.000000000 +0200 @@ -270,7 +270,11 @@ int min_free_kbytes = 1024; @@ -33230,9 +33855,9 @@ diff -ruN --no-dereference -x .git a/mm/page_alloc.c b/mm/page_alloc.c int defrag_mode; diff -ruN --no-dereference -x .git a/mm/rmap.c b/mm/rmap.c ---- a/mm/rmap.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/mm/rmap.c 2026-09-23 12:56:16.000000000 +0200 -@@ -907,7 +907,7 @@ +--- a/mm/rmap.c 2026-10-07 05:21:41.440574713 +0200 ++++ b/mm/rmap.c 2026-10-03 14:48:53.000000000 +0200 +@@ -911,7 +911,7 @@ struct folio_referenced_arg { int mapcount; int referenced; @@ -33241,7 +33866,7 @@ diff -ruN --no-dereference -x .git a/mm/rmap.c b/mm/rmap.c struct mem_cgroup *memcg; }; -@@ -926,7 +926,7 @@ +@@ -930,7 +930,7 @@ address = pvmw.address; nr = 1; @@ -33250,7 +33875,7 @@ diff -ruN --no-dereference -x .git a/mm/rmap.c b/mm/rmap.c ptes++; pra->mapcount--; -@@ -947,7 +947,7 @@ +@@ -951,7 +951,7 @@ /* Restore the mlock which got missed */ mlock_vma_folio(folio, vma); page_vma_mapped_walk_done(&pvmw); @@ -33259,7 +33884,7 @@ diff -ruN --no-dereference -x .git a/mm/rmap.c b/mm/rmap.c return false; /* To break the loop */ } -@@ -1015,8 +1015,11 @@ +@@ -1019,8 +1019,11 @@ referenced++; if (referenced) { @@ -33272,7 +33897,7 @@ diff -ruN --no-dereference -x .git a/mm/rmap.c b/mm/rmap.c } if (!pra->mapcount) -@@ -1054,7 +1057,7 @@ +@@ -1058,7 +1061,7 @@ * @folio: The folio to test. * @is_locked: Caller holds lock on the folio. * @memcg: target memory cgroup @@ -33281,7 +33906,7 @@ diff -ruN --no-dereference -x .git a/mm/rmap.c b/mm/rmap.c * * Quick test_and_clear_referenced for all mappings of a folio, * -@@ -1062,7 +1065,7 @@ +@@ -1066,7 +1069,7 @@ * the function bailed out due to rmap lock contention. */ int folio_referenced(struct folio *folio, int is_locked, @@ -33290,7 +33915,7 @@ diff -ruN --no-dereference -x .git a/mm/rmap.c b/mm/rmap.c { bool we_locked = false; struct folio_referenced_arg pra = { -@@ -1078,7 +1081,7 @@ +@@ -1082,7 +1085,7 @@ }; VM_WARN_ON_ONCE_FOLIO(folio_is_zone_device(folio), folio); @@ -33299,7 +33924,7 @@ diff -ruN --no-dereference -x .git a/mm/rmap.c b/mm/rmap.c if (!pra.mapcount) return 0; -@@ -1092,7 +1095,7 @@ +@@ -1096,7 +1099,7 @@ } rmap_walk(folio, &rwc); @@ -33309,8 +33934,8 @@ diff -ruN --no-dereference -x .git a/mm/rmap.c b/mm/rmap.c if (we_locked) folio_unlock(folio); diff -ruN --no-dereference -x .git a/mm/swap.c b/mm/swap.c ---- a/mm/swap.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/mm/swap.c 2026-09-23 12:56:16.000000000 +0200 +--- a/mm/swap.c 2026-10-07 05:21:41.441439285 +0200 ++++ b/mm/swap.c 2026-10-03 14:48:53.000000000 +0200 @@ -1198,17 +1198,8 @@ */ void __init swap_setup(void) @@ -33332,8 +33957,8 @@ diff -ruN --no-dereference -x .git a/mm/swap.c b/mm/swap.c register_sysctl_init("vm", swap_sysctl_table); } diff -ruN --no-dereference -x .git a/mm/vmscan.c b/mm/vmscan.c ---- a/mm/vmscan.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/mm/vmscan.c 2026-09-23 12:56:16.000000000 +0200 +--- a/mm/vmscan.c 2026-10-07 05:21:41.442576494 +0200 ++++ b/mm/vmscan.c 2026-10-03 14:48:53.000000000 +0200 @@ -196,7 +196,11 @@ /* * From 0 .. MAX_SWAPPINESS. Higher means more swappy. @@ -33564,30 +34189,9 @@ diff -ruN --no-dereference -x .git a/mm/vmscan.c b/mm/vmscan.c lazy_mmu_mode_disable(); -diff -ruN --no-dereference -x .git a/net/ipv4/bpf_tcp_ca.c b/net/ipv4/bpf_tcp_ca.c ---- a/net/ipv4/bpf_tcp_ca.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/net/ipv4/bpf_tcp_ca.c 2026-09-23 12:56:16.000000000 +0200 -@@ -284,7 +284,7 @@ - { - } - --static u32 bpf_tcp_ca_min_tso_segs(struct sock *sk) -+static u32 bpf_tcp_ca_tso_segs(struct sock *sk, unsigned int mss_now) - { - return 0; - } -@@ -320,7 +320,7 @@ - .cwnd_event_tx_start = bpf_tcp_ca_cwnd_event_tx_start, - .in_ack_event = bpf_tcp_ca_in_ack_event, - .pkts_acked = bpf_tcp_ca_pkts_acked, -- .min_tso_segs = bpf_tcp_ca_min_tso_segs, -+ .tso_segs = bpf_tcp_ca_tso_segs, - .cong_control = bpf_tcp_ca_cong_control, - .undo_cwnd = bpf_tcp_ca_undo_cwnd, - .sndbuf_expand = bpf_tcp_ca_sndbuf_expand, diff -ruN --no-dereference -x .git a/net/ipv4/Kconfig b/net/ipv4/Kconfig ---- a/net/ipv4/Kconfig 2026-09-21 15:09:00.000000000 +0200 -+++ b/net/ipv4/Kconfig 2026-09-23 12:56:16.000000000 +0200 +--- a/net/ipv4/Kconfig 2026-08-16 23:32:26.000000000 +0200 ++++ b/net/ipv4/Kconfig 2026-10-03 14:48:53.000000000 +0200 @@ -668,15 +668,33 @@ default n help @@ -33650,8 +34254,8 @@ diff -ruN --no-dereference -x .git a/net/ipv4/Kconfig b/net/ipv4/Kconfig config TCP_AO diff -ruN --no-dereference -x .git a/net/ipv4/Makefile b/net/ipv4/Makefile ---- a/net/ipv4/Makefile 2026-09-21 15:09:00.000000000 +0200 -+++ b/net/ipv4/Makefile 2026-09-23 12:56:16.000000000 +0200 +--- a/net/ipv4/Makefile 2026-08-16 23:32:26.000000000 +0200 ++++ b/net/ipv4/Makefile 2026-10-03 14:48:53.000000000 +0200 @@ -45,6 +45,7 @@ obj-$(CONFIG_INET_UDP_DIAG) += udp_diag.o obj-$(CONFIG_INET_RAW_DIAG) += raw_diag.o @@ -33660,9 +34264,86 @@ diff -ruN --no-dereference -x .git a/net/ipv4/Makefile b/net/ipv4/Makefile obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o obj-$(CONFIG_TCP_CONG_CDG) += tcp_cdg.o obj-$(CONFIG_TCP_CONG_CUBIC) += tcp_cubic.o +diff -ruN --no-dereference -x .git a/net/ipv4/bpf_tcp_ca.c b/net/ipv4/bpf_tcp_ca.c +--- a/net/ipv4/bpf_tcp_ca.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/net/ipv4/bpf_tcp_ca.c 2026-10-03 14:48:53.000000000 +0200 +@@ -284,7 +284,7 @@ + { + } + +-static u32 bpf_tcp_ca_min_tso_segs(struct sock *sk) ++static u32 bpf_tcp_ca_tso_segs(struct sock *sk, unsigned int mss_now) + { + return 0; + } +@@ -320,7 +320,7 @@ + .cwnd_event_tx_start = bpf_tcp_ca_cwnd_event_tx_start, + .in_ack_event = bpf_tcp_ca_in_ack_event, + .pkts_acked = bpf_tcp_ca_pkts_acked, +- .min_tso_segs = bpf_tcp_ca_min_tso_segs, ++ .tso_segs = bpf_tcp_ca_tso_segs, + .cong_control = bpf_tcp_ca_cong_control, + .undo_cwnd = bpf_tcp_ca_undo_cwnd, + .sndbuf_expand = bpf_tcp_ca_sndbuf_expand, +diff -ruN --no-dereference -x .git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +--- a/net/ipv4/tcp.c 2026-10-07 05:21:41.455659596 +0200 ++++ b/net/ipv4/tcp.c 2026-10-03 14:48:53.000000000 +0200 +@@ -3482,6 +3482,7 @@ + tp->rx_opt.dsack = 0; + tp->rx_opt.num_sacks = 0; + tp->rcv_ooopack = 0; ++ tp->fast_ack_mode = 0; + + + /* Clean up fastopen related fields */ +@@ -4267,6 +4268,8 @@ + info->tcpi_options |= TCPI_OPT_ECN; + if (tp->ecn_flags & TCP_ECN_SEEN) + info->tcpi_options |= TCPI_OPT_ECN_SEEN; ++ if (tp->ecn_flags & TCP_ECN_LOW) ++ info->tcpi_options |= TCPI_OPT_ECN_LOW; + if (tp->syn_data_acked) + info->tcpi_options |= TCPI_OPT_SYN_DATA; + if (tp->tcp_usec_ts) +diff -ruN --no-dereference -x .git a/net/ipv4/tcp_bbr.c b/net/ipv4/tcp_bbr.c +--- a/net/ipv4/tcp_bbr.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/net/ipv4/tcp_bbr.c 2026-10-03 14:48:53.000000000 +0200 +@@ -302,6 +302,23 @@ + return READ_ONCE(sk->sk_pacing_rate) < (bbr_min_tso_rate >> 3) ? 1 : 2; + } + ++__bpf_kfunc static u32 bbr_tso_segs(struct sock *sk, unsigned int mss_now) ++{ ++ unsigned long bytes; ++ u32 r; ++ ++ bytes = READ_ONCE(sk->sk_pacing_rate) >> READ_ONCE(sk->sk_pacing_shift); ++ ++ r = tcp_min_rtt(tcp_sk(sk)) >> ++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_tso_rtt_log); ++ if (r < BITS_PER_TYPE(sk->sk_gso_max_size)) ++ bytes += sk->sk_gso_max_size >> r; ++ ++ bytes = min_t(unsigned long, bytes, sk->sk_gso_max_size); ++ ++ return max_t(u32, bytes / mss_now, bbr_min_tso_segs(sk)); ++} ++ + static u32 bbr_tso_segs_goal(struct sock *sk) + { + struct tcp_sock *tp = tcp_sk(sk); +@@ -1151,7 +1168,7 @@ + .undo_cwnd = bbr_undo_cwnd, + .cwnd_event_tx_start = bbr_cwnd_event_tx_start, + .ssthresh = bbr_ssthresh, +- .min_tso_segs = bbr_min_tso_segs, ++ .tso_segs = bbr_tso_segs, + .get_info = bbr_get_info, + .set_state = bbr_set_state, + }; diff -ruN --no-dereference -x .git a/net/ipv4/tcp_bbr3.c b/net/ipv4/tcp_bbr3.c --- a/net/ipv4/tcp_bbr3.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/net/ipv4/tcp_bbr3.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/net/ipv4/tcp_bbr3.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,2418 @@ +// SPDX-License-Identifier: GPL-2.0 +/* BBR (Bottleneck Bandwidth and RTT) congestion control @@ -36082,65 +36763,9 @@ diff -ruN --no-dereference -x .git a/net/ipv4/tcp_bbr3.c b/net/ipv4/tcp_bbr3.c +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_DESCRIPTION("TCP BBR (Bottleneck Bandwidth and RTT)"); +MODULE_VERSION(__stringify(BBR_VERSION)); -diff -ruN --no-dereference -x .git a/net/ipv4/tcp_bbr.c b/net/ipv4/tcp_bbr.c ---- a/net/ipv4/tcp_bbr.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/net/ipv4/tcp_bbr.c 2026-09-23 12:56:16.000000000 +0200 -@@ -302,6 +302,23 @@ - return READ_ONCE(sk->sk_pacing_rate) < (bbr_min_tso_rate >> 3) ? 1 : 2; - } - -+__bpf_kfunc static u32 bbr_tso_segs(struct sock *sk, unsigned int mss_now) -+{ -+ unsigned long bytes; -+ u32 r; -+ -+ bytes = READ_ONCE(sk->sk_pacing_rate) >> READ_ONCE(sk->sk_pacing_shift); -+ -+ r = tcp_min_rtt(tcp_sk(sk)) >> -+ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_tso_rtt_log); -+ if (r < BITS_PER_TYPE(sk->sk_gso_max_size)) -+ bytes += sk->sk_gso_max_size >> r; -+ -+ bytes = min_t(unsigned long, bytes, sk->sk_gso_max_size); -+ -+ return max_t(u32, bytes / mss_now, bbr_min_tso_segs(sk)); -+} -+ - static u32 bbr_tso_segs_goal(struct sock *sk) - { - struct tcp_sock *tp = tcp_sk(sk); -@@ -1151,7 +1168,7 @@ - .undo_cwnd = bbr_undo_cwnd, - .cwnd_event_tx_start = bbr_cwnd_event_tx_start, - .ssthresh = bbr_ssthresh, -- .min_tso_segs = bbr_min_tso_segs, -+ .tso_segs = bbr_tso_segs, - .get_info = bbr_get_info, - .set_state = bbr_set_state, - }; -diff -ruN --no-dereference -x .git a/net/ipv4/tcp.c b/net/ipv4/tcp.c ---- a/net/ipv4/tcp.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/net/ipv4/tcp.c 2026-09-23 12:56:16.000000000 +0200 -@@ -3482,6 +3482,7 @@ - tp->rx_opt.dsack = 0; - tp->rx_opt.num_sacks = 0; - tp->rcv_ooopack = 0; -+ tp->fast_ack_mode = 0; - - - /* Clean up fastopen related fields */ -@@ -4267,6 +4268,8 @@ - info->tcpi_options |= TCPI_OPT_ECN; - if (tp->ecn_flags & TCP_ECN_SEEN) - info->tcpi_options |= TCPI_OPT_ECN_SEEN; -+ if (tp->ecn_flags & TCP_ECN_LOW) -+ info->tcpi_options |= TCPI_OPT_ECN_LOW; - if (tp->syn_data_acked) - info->tcpi_options |= TCPI_OPT_SYN_DATA; - if (tp->tcp_usec_ts) diff -ruN --no-dereference -x .git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c ---- a/net/ipv4/tcp_cong.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/net/ipv4/tcp_cong.c 2026-09-23 12:56:16.000000000 +0200 +--- a/net/ipv4/tcp_cong.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/net/ipv4/tcp_cong.c 2026-10-03 14:48:53.000000000 +0200 @@ -238,6 +238,7 @@ struct inet_connection_sock *icsk = inet_csk(sk); @@ -36150,8 +36775,8 @@ diff -ruN --no-dereference -x .git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c icsk->icsk_ca_ops->init(sk); if (tcp_ca_needs_ecn(sk)) diff -ruN --no-dereference -x .git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c ---- a/net/ipv4/tcp_input.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/net/ipv4/tcp_input.c 2026-09-23 12:56:16.000000000 +0200 +--- a/net/ipv4/tcp_input.c 2026-10-07 05:21:41.456135740 +0200 ++++ b/net/ipv4/tcp_input.c 2026-10-03 14:48:53.000000000 +0200 @@ -358,7 +358,7 @@ tcp_enter_quickack_mode(sk, 2); break; @@ -36325,8 +36950,8 @@ diff -ruN --no-dereference -x .git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c tcp_in_quickack_mode(sk) || /* Protocol state mandates a one-time immediate ACK */ diff -ruN --no-dereference -x .git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c ---- a/net/ipv4/tcp_minisocks.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/net/ipv4/tcp_minisocks.c 2026-09-23 12:56:16.000000000 +0200 +--- a/net/ipv4/tcp_minisocks.c 2026-10-07 05:21:41.456585364 +0200 ++++ b/net/ipv4/tcp_minisocks.c 2026-10-03 14:48:53.000000000 +0200 @@ -500,6 +500,8 @@ u32 ca_key = dst_metric(dst, RTAX_CC_ALGO); bool ca_got_dst = false; @@ -36337,8 +36962,8 @@ diff -ruN --no-dereference -x .git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_min const struct tcp_congestion_ops *ca; diff -ruN --no-dereference -x .git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c ---- a/net/ipv4/tcp_output.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/net/ipv4/tcp_output.c 2026-09-23 12:56:16.000000000 +0200 +--- a/net/ipv4/tcp_output.c 2026-10-07 05:21:41.456777288 +0200 ++++ b/net/ipv4/tcp_output.c 2026-10-03 14:48:53.000000000 +0200 @@ -365,7 +365,8 @@ th->cwr = 1; skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_ECN; @@ -36460,8 +37085,8 @@ diff -ruN --no-dereference -x .git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output goto rearm_timer; diff -ruN --no-dereference -x .git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c ---- a/net/ipv4/tcp_timer.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/net/ipv4/tcp_timer.c 2026-09-23 12:56:16.000000000 +0200 +--- a/net/ipv4/tcp_timer.c 2026-10-07 05:21:41.456951479 +0200 ++++ b/net/ipv4/tcp_timer.c 2026-10-03 14:48:53.000000000 +0200 @@ -708,6 +708,7 @@ tcp_timeout_expires(sk)); return; @@ -36471,8 +37096,8 @@ diff -ruN --no-dereference -x .git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c event = icsk->icsk_pending; diff -ruN --no-dereference -x .git a/scripts/package/PKGBUILD b/scripts/package/PKGBUILD ---- a/scripts/package/PKGBUILD 2026-09-21 15:09:00.000000000 +0200 -+++ b/scripts/package/PKGBUILD 2026-09-23 12:56:16.000000000 +0200 +--- a/scripts/package/PKGBUILD 2026-08-16 23:32:26.000000000 +0200 ++++ b/scripts/package/PKGBUILD 2026-10-03 14:48:53.000000000 +0200 @@ -90,6 +90,11 @@ "${srctree}/scripts/package/install-extmod-build" "${builddir}" fi @@ -36487,7 +37112,7 @@ diff -ruN --no-dereference -x .git a/scripts/package/PKGBUILD b/scripts/package/ cp System.map "${builddir}/System.map" diff -ruN --no-dereference -x .git a/sound/hda/codecs/helpers/razer_blade16_2025.c b/sound/hda/codecs/helpers/razer_blade16_2025.c --- a/sound/hda/codecs/helpers/razer_blade16_2025.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/sound/hda/codecs/helpers/razer_blade16_2025.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/sound/hda/codecs/helpers/razer_blade16_2025.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,820 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* @@ -37310,8 +37935,8 @@ diff -ruN --no-dereference -x .git a/sound/hda/codecs/helpers/razer_blade16_2025 + } +} diff -ruN --no-dereference -x .git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c ---- a/sound/hda/codecs/realtek/alc269.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/sound/hda/codecs/realtek/alc269.c 2026-09-23 12:56:16.000000000 +0200 +--- a/sound/hda/codecs/realtek/alc269.c 2026-10-07 05:21:41.486992199 +0200 ++++ b/sound/hda/codecs/realtek/alc269.c 2026-10-03 14:48:53.000000000 +0200 @@ -3262,6 +3262,36 @@ comp_generic_fixup(cdc, HDA_FIXUP_ACT_PRE_PROBE, bus, acpi_ids[i].hid, match, count); } @@ -37390,7 +38015,7 @@ diff -ruN --no-dereference -x .git a/sound/hda/codecs/realtek/alc269.c b/sound/h ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, ALC256_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, ALC295_FIXUP_ASUS_MIC_NO_PRESENCE, -@@ -4236,6 +4278,8 @@ +@@ -4237,6 +4279,8 @@ ALC236_FIXUP_DELL_HP_POP_NOISE, ALC274_FIXUP_HP_89E9_GPIO, ALC274_FIXUP_HP_VERBS, @@ -37399,7 +38024,7 @@ diff -ruN --no-dereference -x .git a/sound/hda/codecs/realtek/alc269.c b/sound/h }; /* A special fixup for Lenovo C940 and Yoga Duet 7; -@@ -4280,6 +4324,20 @@ +@@ -4281,6 +4325,20 @@ { } }, }, @@ -37420,7 +38045,7 @@ diff -ruN --no-dereference -x .git a/sound/hda/codecs/realtek/alc269.c b/sound/h [ALC269_FIXUP_GPIO2] = { .type = HDA_FIXUP_FUNC, .v.func = alc_fixup_gpio2, -@@ -5870,6 +5928,10 @@ +@@ -5871,6 +5929,10 @@ .type = HDA_FIXUP_FUNC, .v.func = alc298_fixup_lg_gram_style_14 }, @@ -37431,7 +38056,7 @@ diff -ruN --no-dereference -x .git a/sound/hda/codecs/realtek/alc269.c b/sound/h [ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET] = { .type = HDA_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { -@@ -6907,6 +6969,29 @@ +@@ -6914,6 +6976,29 @@ .chained = true, .chain_id = ALC274_FIXUP_HP_89E9_GPIO, }, @@ -37461,7 +38086,7 @@ diff -ruN --no-dereference -x .git a/sound/hda/codecs/realtek/alc269.c b/sound/h }; static const struct hda_quirk alc269_fixup_tbl[] = { -@@ -7543,6 +7628,7 @@ +@@ -7550,6 +7635,7 @@ SND_PCI_QUIRK(0x1043, 0x12a3, "Asus N7691ZM", ALC269_FIXUP_ASUS_N7601ZM), SND_PCI_QUIRK(0x1043, 0x12af, "ASUS UX582ZS", ALC245_FIXUP_CS35L41_SPI_2), SND_PCI_QUIRK(0x1043, 0x12b4, "ASUS B3405CCA / P3405CCA", ALC294_FIXUP_ASUS_CS35L41_SPI_2), @@ -37469,7 +38094,7 @@ diff -ruN --no-dereference -x .git a/sound/hda/codecs/realtek/alc269.c b/sound/h SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1043, 0x1313, "Asus K42JZ", ALC269VB_FIXUP_ASUS_MIC_NO_PRESENCE), -@@ -7725,6 +7811,11 @@ +@@ -7732,6 +7818,11 @@ SND_PCI_QUIRK(0x144d, 0xc876, "Samsung 730QED (NP730QED-KA2US)", ALC256_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET), SND_PCI_QUIRK(0x144d, 0xca03, "Samsung Galaxy Book2 Pro 360 (NP930QED)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x144d, 0xca06, "Samsung Galaxy Book3 360 (NP730QFG)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET), @@ -37481,7 +38106,7 @@ diff -ruN --no-dereference -x .git a/sound/hda/codecs/realtek/alc269.c b/sound/h SND_PCI_QUIRK(0x144d, 0xc868, "Samsung Galaxy Book2 Pro (NP930XED)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x144d, 0xc870, "Samsung Galaxy Book2 Pro (NP950XED)", ALC298_FIXUP_SAMSUNG_AMP_V2_2_AMPS), SND_PCI_QUIRK(0x144d, 0xc872, "Samsung Galaxy Book2 Pro (NP950XEE)", ALC298_FIXUP_SAMSUNG_AMP_V2_2_AMPS), -@@ -7972,6 +8063,11 @@ +@@ -7979,6 +8070,11 @@ SND_PCI_QUIRK(0x17aa, 0x38b8, "Yoga S780-14.5 proX AMD YC Dual", ALC287_FIXUP_TAS2781_I2C), SND_PCI_QUIRK(0x17aa, 0x38b9, "Yoga S780-14.5 proX AMD LX Dual", ALC287_FIXUP_TAS2781_I2C), SND_PCI_QUIRK(0x17aa, 0x38ba, "Yoga S780-14.5 Air AMD quad YC", ALC287_FIXUP_TAS2781_I2C), @@ -37493,7 +38118,7 @@ diff -ruN --no-dereference -x .git a/sound/hda/codecs/realtek/alc269.c b/sound/h SND_PCI_QUIRK(0x17aa, 0x38bb, "Yoga S780-14.5 Air AMD quad AAC", ALC287_FIXUP_TAS2781_I2C), SND_PCI_QUIRK(0x17aa, 0x38be, "Yoga S980-14.5 proX YC Dual", ALC287_FIXUP_TAS2781_I2C), SND_PCI_QUIRK(0x17aa, 0x38bf, "Yoga S980-14.5 proX LX Dual", ALC287_FIXUP_TAS2781_I2C), -@@ -7999,6 +8095,8 @@ +@@ -8006,6 +8102,8 @@ SND_PCI_QUIRK(0x17aa, 0x38fc, "Lenovo Yoga Pro 7 15ASH11", ALC287_FIXUP_LENOVO_YOGA_PRO7), SND_PCI_QUIRK(0x17aa, 0x38fd, "ThinkBook plus Gen5 Hybrid", ALC287_FIXUP_TAS2781_I2C), SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI), @@ -37502,7 +38127,7 @@ diff -ruN --no-dereference -x .git a/sound/hda/codecs/realtek/alc269.c b/sound/h SND_PCI_QUIRK(0x17aa, 0x390d, "Lenovo Yoga Pro 7 14ASP10", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN), SND_PCI_QUIRK(0x17aa, 0x3911, "Lenovo Yoga Pro 7 14IAH10", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN), SND_PCI_QUIRK(0x17aa, 0x3912, "Lenovo Xiaoxin 14 GT", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN), -@@ -8007,6 +8105,8 @@ +@@ -8014,6 +8112,8 @@ SND_PCI_QUIRK(0x17aa, 0x3920, "Yoga S990-16 pro Quad VECO Quad", ALC287_FIXUP_TXNW2781_I2C), SND_PCI_QUIRK(0x17aa, 0x3929, "Thinkbook 13x Gen 5", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD), SND_PCI_QUIRK(0x17aa, 0x392b, "Thinkbook 13x Gen 5", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD), @@ -37511,7 +38136,7 @@ diff -ruN --no-dereference -x .git a/sound/hda/codecs/realtek/alc269.c b/sound/h HDA_CODEC_QUIRK(0x17aa, 0x394c, "Lenovo Yoga Slim 7 14AGP11", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN), SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI), -@@ -8044,6 +8144,8 @@ +@@ -8051,6 +8151,8 @@ SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS), SND_PCI_QUIRK(0x19e5, 0x320f, "Huawei WRT-WX9 ", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x19e5, 0x3212, "Huawei KLV-WX9 ", ALC256_FIXUP_ACER_HEADSET_MIC), @@ -37520,7 +38145,7 @@ diff -ruN --no-dereference -x .git a/sound/hda/codecs/realtek/alc269.c b/sound/h SND_PCI_QUIRK(0x1b35, 0x1235, "CZC B20", ALC269_FIXUP_CZC_B20), SND_PCI_QUIRK(0x1b35, 0x1236, "CZC TMI", ALC269_FIXUP_CZC_TMI), SND_PCI_QUIRK(0x1b35, 0x1237, "CZC L101", ALC269_FIXUP_CZC_L101), -@@ -8289,6 +8391,7 @@ +@@ -8298,6 +8400,7 @@ {.id = ALC298_FIXUP_SAMSUNG_AMP, .name = "alc298-samsung-amp"}, {.id = ALC298_FIXUP_SAMSUNG_AMP_V2_2_AMPS, .name = "alc298-samsung-amp-v2-2-amps"}, {.id = ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS, .name = "alc298-samsung-amp-v2-4-amps"}, @@ -37528,7 +38153,7 @@ diff -ruN --no-dereference -x .git a/sound/hda/codecs/realtek/alc269.c b/sound/h {.id = ALC256_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, .name = "alc256-samsung-headphone"}, {.id = ALC255_FIXUP_XIAOMI_HEADSET_MIC, .name = "alc255-xiaomi-headset"}, {.id = ALC274_FIXUP_HP_MIC, .name = "alc274-hp-mic-detect"}, -@@ -8307,6 +8410,7 @@ +@@ -8316,6 +8419,7 @@ {.id = ALC2XX_FIXUP_HEADSET_MIC, .name = "alc2xx-fixup-headset-mic"}, {.id = ALC245_FIXUP_BASS_HP_DAC, .name = "alc245-fixup-bass-hp-dac"}, {.id = ALC256_FIXUP_HONOR_MRB_XXX_M1020_AUDIO, .name = "alc256-honor-mrb-xxx-m1020-audio"}, @@ -37536,9 +38161,92 @@ diff -ruN --no-dereference -x .git a/sound/hda/codecs/realtek/alc269.c b/sound/h {} }; #define ALC225_STANDARD_PINS \ +diff -ruN --no-dereference -x .git a/sound/hda/codecs/side-codecs/Kconfig b/sound/hda/codecs/side-codecs/Kconfig +--- a/sound/hda/codecs/side-codecs/Kconfig 2026-08-16 23:32:26.000000000 +0200 ++++ b/sound/hda/codecs/side-codecs/Kconfig 2026-10-03 14:48:53.000000000 +0200 +@@ -13,6 +13,24 @@ + Documentation/dev-tools/kunit/. + If in doubt, say "N". + ++config SND_HDA_SCODEC_AW88399 ++ tristate ++ select SND_HDA_GENERIC ++ ++config SND_HDA_SCODEC_AW88399_I2C ++ tristate "Build AW88399 HD-audio side codec support for I2C Bus" ++ depends on I2C ++ depends on ACPI ++ depends on SND_SOC ++ select SND_HDA_SCODEC_AW88399 ++ select SND_SOC_AW88399_LIB ++ help ++ Say Y or M here to include AW88399 I2C HD-audio side codec support ++ in snd-hda-intel driver, such as ALC287. ++ ++comment "Set to Y if you want auto-loading the side codec driver" ++ depends on SND_HDA=y && SND_HDA_SCODEC_AW88399_I2C=m ++ + config SND_HDA_SCODEC_CS35L41 + tristate + select SND_HDA_GENERIC +@@ -143,3 +161,22 @@ + + comment "Set to Y if you want auto-loading the side codec driver" + depends on SND_HDA=y && SND_HDA_SCODEC_TAS2781_SPI=m ++ ++config SND_HDA_SCODEC_MAX98390 ++ tristate ++ select SND_HDA_GENERIC ++ select SND_HDA_SCODEC_COMPONENT ++ ++config SND_HDA_SCODEC_MAX98390_I2C ++ tristate "Build MAX98390 HD-audio side codec support for I2C Bus" ++ depends on I2C ++ depends on ACPI ++ depends on SND_SOC ++ select SND_SOC_MAX98390 ++ select SND_HDA_SCODEC_MAX98390 ++ help ++ Say Y or M here to include MAX98390 I2C HD-audio side codec support ++ in snd-hda-intel driver, such as ALC298. ++ ++comment "Set to Y if you want auto-loading the side codec driver" ++ depends on SND_HDA=y && SND_HDA_SCODEC_MAX98390_I2C=m +diff -ruN --no-dereference -x .git a/sound/hda/codecs/side-codecs/Makefile b/sound/hda/codecs/side-codecs/Makefile +--- a/sound/hda/codecs/side-codecs/Makefile 2026-08-16 23:32:26.000000000 +0200 ++++ b/sound/hda/codecs/side-codecs/Makefile 2026-10-03 14:48:53.000000000 +0200 +@@ -3,6 +3,8 @@ + + snd-hda-cirrus-scodec-y := cirrus_scodec.o + snd-hda-cirrus-scodec-test-y := cirrus_scodec_test.o ++snd-hda-scodec-aw88399-y := aw88399_hda.o ++snd-hda-scodec-aw88399-i2c-y := aw88399_hda_i2c.o + snd-hda-scodec-cs35l41-y := cs35l41_hda.o cs35l41_hda_property.o + snd-hda-scodec-cs35l41-i2c-y := cs35l41_hda_i2c.o + snd-hda-scodec-cs35l41-spi-y := cs35l41_hda_spi.o +@@ -13,9 +15,13 @@ + snd-hda-scodec-tas2781-y := tas2781_hda.o + snd-hda-scodec-tas2781-i2c-y := tas2781_hda_i2c.o + snd-hda-scodec-tas2781-spi-y := tas2781_hda_spi.o ++snd-hda-scodec-max98390-y := max98390_hda.o max98390_hda_filters.o ++snd-hda-scodec-max98390-i2c-y := max98390_hda_i2c.o + + obj-$(CONFIG_SND_HDA_CIRRUS_SCODEC) += snd-hda-cirrus-scodec.o + obj-$(CONFIG_SND_HDA_CIRRUS_SCODEC_KUNIT_TEST) += snd-hda-cirrus-scodec-test.o ++obj-$(CONFIG_SND_HDA_SCODEC_AW88399) += snd-hda-scodec-aw88399.o ++obj-$(CONFIG_SND_HDA_SCODEC_AW88399_I2C) += snd-hda-scodec-aw88399-i2c.o + obj-$(CONFIG_SND_HDA_SCODEC_CS35L41) += snd-hda-scodec-cs35l41.o + obj-$(CONFIG_SND_HDA_SCODEC_CS35L41_I2C) += snd-hda-scodec-cs35l41-i2c.o + obj-$(CONFIG_SND_HDA_SCODEC_CS35L41_SPI) += snd-hda-scodec-cs35l41-spi.o +@@ -26,3 +32,5 @@ + obj-$(CONFIG_SND_HDA_SCODEC_TAS2781) += snd-hda-scodec-tas2781.o + obj-$(CONFIG_SND_HDA_SCODEC_TAS2781_I2C) += snd-hda-scodec-tas2781-i2c.o + obj-$(CONFIG_SND_HDA_SCODEC_TAS2781_SPI) += snd-hda-scodec-tas2781-spi.o ++obj-$(CONFIG_SND_HDA_SCODEC_MAX98390) += snd-hda-scodec-max98390.o ++obj-$(CONFIG_SND_HDA_SCODEC_MAX98390_I2C) += snd-hda-scodec-max98390-i2c.o diff -ruN --no-dereference -x .git a/sound/hda/codecs/side-codecs/aw88399_hda.c b/sound/hda/codecs/side-codecs/aw88399_hda.c --- a/sound/hda/codecs/side-codecs/aw88399_hda.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/sound/hda/codecs/side-codecs/aw88399_hda.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/sound/hda/codecs/side-codecs/aw88399_hda.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,372 @@ +// SPDX-License-Identifier: GPL-2.0-only +// @@ -37914,7 +38622,7 @@ diff -ruN --no-dereference -x .git a/sound/hda/codecs/side-codecs/aw88399_hda.c +MODULE_FIRMWARE("aw88399_acf.bin"); diff -ruN --no-dereference -x .git a/sound/hda/codecs/side-codecs/aw88399_hda.h b/sound/hda/codecs/side-codecs/aw88399_hda.h --- a/sound/hda/codecs/side-codecs/aw88399_hda.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/sound/hda/codecs/side-codecs/aw88399_hda.h 2026-09-23 12:56:16.000000000 +0200 ++++ b/sound/hda/codecs/side-codecs/aw88399_hda.h 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-only + * @@ -37954,7 +38662,7 @@ diff -ruN --no-dereference -x .git a/sound/hda/codecs/side-codecs/aw88399_hda.h +#endif /* __AW88399_HDA_H__ */ diff -ruN --no-dereference -x .git a/sound/hda/codecs/side-codecs/aw88399_hda_i2c.c b/sound/hda/codecs/side-codecs/aw88399_hda_i2c.c --- a/sound/hda/codecs/side-codecs/aw88399_hda_i2c.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/sound/hda/codecs/side-codecs/aw88399_hda_i2c.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/sound/hda/codecs/side-codecs/aw88399_hda_i2c.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0-only +// @@ -38010,92 +38718,9 @@ diff -ruN --no-dereference -x .git a/sound/hda/codecs/side-codecs/aw88399_hda_i2 +MODULE_IMPORT_NS("SND_HDA_SCODEC_AW88399"); +MODULE_AUTHOR("Yakov Till "); +MODULE_LICENSE("GPL"); -diff -ruN --no-dereference -x .git a/sound/hda/codecs/side-codecs/Kconfig b/sound/hda/codecs/side-codecs/Kconfig ---- a/sound/hda/codecs/side-codecs/Kconfig 2026-09-21 15:09:00.000000000 +0200 -+++ b/sound/hda/codecs/side-codecs/Kconfig 2026-09-23 12:56:16.000000000 +0200 -@@ -13,6 +13,24 @@ - Documentation/dev-tools/kunit/. - If in doubt, say "N". - -+config SND_HDA_SCODEC_AW88399 -+ tristate -+ select SND_HDA_GENERIC -+ -+config SND_HDA_SCODEC_AW88399_I2C -+ tristate "Build AW88399 HD-audio side codec support for I2C Bus" -+ depends on I2C -+ depends on ACPI -+ depends on SND_SOC -+ select SND_HDA_SCODEC_AW88399 -+ select SND_SOC_AW88399_LIB -+ help -+ Say Y or M here to include AW88399 I2C HD-audio side codec support -+ in snd-hda-intel driver, such as ALC287. -+ -+comment "Set to Y if you want auto-loading the side codec driver" -+ depends on SND_HDA=y && SND_HDA_SCODEC_AW88399_I2C=m -+ - config SND_HDA_SCODEC_CS35L41 - tristate - select SND_HDA_GENERIC -@@ -143,3 +161,22 @@ - - comment "Set to Y if you want auto-loading the side codec driver" - depends on SND_HDA=y && SND_HDA_SCODEC_TAS2781_SPI=m -+ -+config SND_HDA_SCODEC_MAX98390 -+ tristate -+ select SND_HDA_GENERIC -+ select SND_HDA_SCODEC_COMPONENT -+ -+config SND_HDA_SCODEC_MAX98390_I2C -+ tristate "Build MAX98390 HD-audio side codec support for I2C Bus" -+ depends on I2C -+ depends on ACPI -+ depends on SND_SOC -+ select SND_SOC_MAX98390 -+ select SND_HDA_SCODEC_MAX98390 -+ help -+ Say Y or M here to include MAX98390 I2C HD-audio side codec support -+ in snd-hda-intel driver, such as ALC298. -+ -+comment "Set to Y if you want auto-loading the side codec driver" -+ depends on SND_HDA=y && SND_HDA_SCODEC_MAX98390_I2C=m -diff -ruN --no-dereference -x .git a/sound/hda/codecs/side-codecs/Makefile b/sound/hda/codecs/side-codecs/Makefile ---- a/sound/hda/codecs/side-codecs/Makefile 2026-09-21 15:09:00.000000000 +0200 -+++ b/sound/hda/codecs/side-codecs/Makefile 2026-09-23 12:56:16.000000000 +0200 -@@ -3,6 +3,8 @@ - - snd-hda-cirrus-scodec-y := cirrus_scodec.o - snd-hda-cirrus-scodec-test-y := cirrus_scodec_test.o -+snd-hda-scodec-aw88399-y := aw88399_hda.o -+snd-hda-scodec-aw88399-i2c-y := aw88399_hda_i2c.o - snd-hda-scodec-cs35l41-y := cs35l41_hda.o cs35l41_hda_property.o - snd-hda-scodec-cs35l41-i2c-y := cs35l41_hda_i2c.o - snd-hda-scodec-cs35l41-spi-y := cs35l41_hda_spi.o -@@ -13,9 +15,13 @@ - snd-hda-scodec-tas2781-y := tas2781_hda.o - snd-hda-scodec-tas2781-i2c-y := tas2781_hda_i2c.o - snd-hda-scodec-tas2781-spi-y := tas2781_hda_spi.o -+snd-hda-scodec-max98390-y := max98390_hda.o max98390_hda_filters.o -+snd-hda-scodec-max98390-i2c-y := max98390_hda_i2c.o - - obj-$(CONFIG_SND_HDA_CIRRUS_SCODEC) += snd-hda-cirrus-scodec.o - obj-$(CONFIG_SND_HDA_CIRRUS_SCODEC_KUNIT_TEST) += snd-hda-cirrus-scodec-test.o -+obj-$(CONFIG_SND_HDA_SCODEC_AW88399) += snd-hda-scodec-aw88399.o -+obj-$(CONFIG_SND_HDA_SCODEC_AW88399_I2C) += snd-hda-scodec-aw88399-i2c.o - obj-$(CONFIG_SND_HDA_SCODEC_CS35L41) += snd-hda-scodec-cs35l41.o - obj-$(CONFIG_SND_HDA_SCODEC_CS35L41_I2C) += snd-hda-scodec-cs35l41-i2c.o - obj-$(CONFIG_SND_HDA_SCODEC_CS35L41_SPI) += snd-hda-scodec-cs35l41-spi.o -@@ -26,3 +32,5 @@ - obj-$(CONFIG_SND_HDA_SCODEC_TAS2781) += snd-hda-scodec-tas2781.o - obj-$(CONFIG_SND_HDA_SCODEC_TAS2781_I2C) += snd-hda-scodec-tas2781-i2c.o - obj-$(CONFIG_SND_HDA_SCODEC_TAS2781_SPI) += snd-hda-scodec-tas2781-spi.o -+obj-$(CONFIG_SND_HDA_SCODEC_MAX98390) += snd-hda-scodec-max98390.o -+obj-$(CONFIG_SND_HDA_SCODEC_MAX98390_I2C) += snd-hda-scodec-max98390-i2c.o diff -ruN --no-dereference -x .git a/sound/hda/codecs/side-codecs/max98390_hda.c b/sound/hda/codecs/side-codecs/max98390_hda.c --- a/sound/hda/codecs/side-codecs/max98390_hda.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/sound/hda/codecs/side-codecs/max98390_hda.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/sound/hda/codecs/side-codecs/max98390_hda.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,214 @@ +// SPDX-License-Identifier: GPL-2.0 +// @@ -38311,9 +38936,46 @@ diff -ruN --no-dereference -x .git a/sound/hda/codecs/side-codecs/max98390_hda.c +MODULE_DESCRIPTION("HDA MAX98390 side codec library"); +MODULE_AUTHOR("Kevin Cuperus "); +MODULE_LICENSE("GPL"); +diff -ruN --no-dereference -x .git a/sound/hda/codecs/side-codecs/max98390_hda.h b/sound/hda/codecs/side-codecs/max98390_hda.h +--- a/sound/hda/codecs/side-codecs/max98390_hda.h 1970-01-01 01:00:00.000000000 +0100 ++++ b/sound/hda/codecs/side-codecs/max98390_hda.h 2026-10-03 14:48:53.000000000 +0200 +@@ -0,0 +1,33 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * MAX98390 HDA audio driver ++ */ ++ ++#ifndef __MAX98390_HDA_H__ ++#define __MAX98390_HDA_H__ ++ ++#include ++#include ++ ++enum max98390_hda_bus_type { ++ MAX98390_HDA_I2C, ++}; ++ ++struct max98390_hda_priv { ++ struct device *dev; ++ struct regmap *regmap; ++ enum max98390_hda_bus_type bus_type; ++ int irq; ++ int index; ++ const char *acpi_subsystem_id; ++ int i2c_addr; /* I2C address for speaker identification */ ++}; ++ ++int max98390_hda_probe(struct device *dev, const char *device_name, ++ int id, int irq, struct regmap *regmap, ++ enum max98390_hda_bus_type bus_type, int i2c_addr); ++void max98390_hda_remove(struct device *dev); ++ ++extern const struct dev_pm_ops max98390_hda_pm_ops; ++ ++#endif /* __MAX98390_HDA_H__ */ diff -ruN --no-dereference -x .git a/sound/hda/codecs/side-codecs/max98390_hda_filters.c b/sound/hda/codecs/side-codecs/max98390_hda_filters.c --- a/sound/hda/codecs/side-codecs/max98390_hda_filters.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/sound/hda/codecs/side-codecs/max98390_hda_filters.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/sound/hda/codecs/side-codecs/max98390_hda_filters.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,236 @@ +// High-pass filter configuration for MAX98390 HDA driver +// This file contains the filter configuration functions @@ -38553,7 +39215,7 @@ diff -ruN --no-dereference -x .git a/sound/hda/codecs/side-codecs/max98390_hda_f +MODULE_LICENSE("GPL"); diff -ruN --no-dereference -x .git a/sound/hda/codecs/side-codecs/max98390_hda_filters.h b/sound/hda/codecs/side-codecs/max98390_hda_filters.h --- a/sound/hda/codecs/side-codecs/max98390_hda_filters.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/sound/hda/codecs/side-codecs/max98390_hda_filters.h 2026-09-23 12:56:16.000000000 +0200 ++++ b/sound/hda/codecs/side-codecs/max98390_hda_filters.h 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// @@ -38571,46 +39233,9 @@ diff -ruN --no-dereference -x .git a/sound/hda/codecs/side-codecs/max98390_hda_f + +#endif /* __MAX98390_HDA_FILTERS_H */ \ No newline at end of file -diff -ruN --no-dereference -x .git a/sound/hda/codecs/side-codecs/max98390_hda.h b/sound/hda/codecs/side-codecs/max98390_hda.h ---- a/sound/hda/codecs/side-codecs/max98390_hda.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/sound/hda/codecs/side-codecs/max98390_hda.h 2026-09-23 12:56:16.000000000 +0200 -@@ -0,0 +1,33 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * MAX98390 HDA audio driver -+ */ -+ -+#ifndef __MAX98390_HDA_H__ -+#define __MAX98390_HDA_H__ -+ -+#include -+#include -+ -+enum max98390_hda_bus_type { -+ MAX98390_HDA_I2C, -+}; -+ -+struct max98390_hda_priv { -+ struct device *dev; -+ struct regmap *regmap; -+ enum max98390_hda_bus_type bus_type; -+ int irq; -+ int index; -+ const char *acpi_subsystem_id; -+ int i2c_addr; /* I2C address for speaker identification */ -+}; -+ -+int max98390_hda_probe(struct device *dev, const char *device_name, -+ int id, int irq, struct regmap *regmap, -+ enum max98390_hda_bus_type bus_type, int i2c_addr); -+void max98390_hda_remove(struct device *dev); -+ -+extern const struct dev_pm_ops max98390_hda_pm_ops; -+ -+#endif /* __MAX98390_HDA_H__ */ diff -ruN --no-dereference -x .git a/sound/hda/codecs/side-codecs/max98390_hda_i2c.c b/sound/hda/codecs/side-codecs/max98390_hda_i2c.c --- a/sound/hda/codecs/side-codecs/max98390_hda_i2c.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/sound/hda/codecs/side-codecs/max98390_hda_i2c.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/sound/hda/codecs/side-codecs/max98390_hda_i2c.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0 +// @@ -38687,8 +39312,8 @@ diff -ruN --no-dereference -x .git a/sound/hda/codecs/side-codecs/max98390_hda_i +MODULE_AUTHOR("Kevin Cuperus "); +MODULE_LICENSE("GPL"); diff -ruN --no-dereference -x .git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c ---- a/sound/soc/amd/yc/acp6x-mach.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/sound/soc/amd/yc/acp6x-mach.c 2026-09-23 12:56:16.000000000 +0200 +--- a/sound/soc/amd/yc/acp6x-mach.c 2026-10-07 05:21:41.489368501 +0200 ++++ b/sound/soc/amd/yc/acp6x-mach.c 2026-10-03 14:48:53.000000000 +0200 @@ -615,6 +615,13 @@ { .driver_data = &acp6x_card, @@ -38703,1987 +39328,50 @@ diff -ruN --no-dereference -x .git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/a DMI_MATCH(DMI_BOARD_VENDOR, "IRBIS"), DMI_MATCH(DMI_PRODUCT_NAME, "15NBC1011"), } -diff -ruN --no-dereference -x .git a/sound/soc/codecs/aw88399.c b/sound/soc/codecs/aw88399.c ---- a/sound/soc/codecs/aw88399.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/sound/soc/codecs/aw88399.c 2026-09-23 12:56:16.000000000 +0200 -@@ -10,1217 +10,12 @@ - #include - #include - #include --#include --#include - #include - #include - #include - #include "aw88399.h" - #include "aw88395/aw88395_device.h" +diff -ruN --no-dereference -x .git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +--- a/sound/soc/codecs/Kconfig 2026-08-16 23:32:26.000000000 +0200 ++++ b/sound/soc/codecs/Kconfig 2026-10-03 14:48:53.000000000 +0200 +@@ -726,6 +726,10 @@ + sound quality, which is a new high efficiency, low + noise, constant large volume, 6th Smart K audio amplifier. --static const struct regmap_config aw88399_remap_config = { -- .val_bits = 16, -- .reg_bits = 8, -- .max_register = AW88399_REG_MAX, -- .reg_format_endian = REGMAP_ENDIAN_LITTLE, -- .val_format_endian = REGMAP_ENDIAN_BIG, --}; -- --static void aw_dev_pwd(struct aw_device *aw_dev, bool pwd) --{ -- int ret; -- -- if (pwd) -- ret = regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, -- ~AW88399_PWDN_MASK, AW88399_PWDN_POWER_DOWN_VALUE); -- else -- ret = regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, -- ~AW88399_PWDN_MASK, AW88399_PWDN_WORKING_VALUE); -- -- if (ret) -- dev_dbg(aw_dev->dev, "%s failed", __func__); --} -- --static void aw_dev_get_int_status(struct aw_device *aw_dev, unsigned short *int_status) --{ -- unsigned int reg_val; -- int ret; -- -- ret = regmap_read(aw_dev->regmap, AW88399_SYSINT_REG, ®_val); -- if (ret) -- dev_err(aw_dev->dev, "read interrupt reg fail, ret=%d", ret); -- else -- *int_status = reg_val; -- -- dev_dbg(aw_dev->dev, "read interrupt reg=0x%04x", *int_status); --} -- --static void aw_dev_clear_int_status(struct aw_device *aw_dev) --{ -- u16 int_status; -- -- /* read int status and clear */ -- aw_dev_get_int_status(aw_dev, &int_status); -- /* make sure int status is clear */ -- aw_dev_get_int_status(aw_dev, &int_status); -- if (int_status) -- dev_dbg(aw_dev->dev, "int status(%d) is not cleaned.\n", int_status); --} -- --static int aw_dev_get_iis_status(struct aw_device *aw_dev) --{ -- unsigned int reg_val; -- int ret; -- -- ret = regmap_read(aw_dev->regmap, AW88399_SYSST_REG, ®_val); -- if (ret) -- return ret; -- if ((reg_val & AW88399_BIT_PLL_CHECK) != AW88399_BIT_PLL_CHECK) { -- dev_err(aw_dev->dev, "check pll lock fail, reg_val:0x%04x", reg_val); -- return -EINVAL; -- } -- -- return 0; --} -- --static int aw_dev_check_mode1_pll(struct aw_device *aw_dev) --{ -- int ret, i; -- -- for (i = 0; i < AW88399_DEV_SYSST_CHECK_MAX; i++) { -- ret = aw_dev_get_iis_status(aw_dev); -- if (ret) { -- dev_err(aw_dev->dev, "mode1 iis signal check error"); -- usleep_range(AW88399_2000_US, AW88399_2000_US + 10); -- } else { -- return 0; -- } -- } -- -- return -EPERM; --} -- --static int aw_dev_check_mode2_pll(struct aw_device *aw_dev) --{ -- unsigned int reg_val; -- int ret, i; -- -- ret = regmap_read(aw_dev->regmap, AW88399_PLLCTRL2_REG, ®_val); -- if (ret) -- return ret; -- -- reg_val &= (~AW88399_CCO_MUX_MASK); -- if (reg_val == AW88399_CCO_MUX_DIVIDED_VALUE) { -- dev_dbg(aw_dev->dev, "CCO_MUX is already divider"); -- return -EPERM; -- } -- -- /* change mode2 */ -- ret = regmap_update_bits(aw_dev->regmap, AW88399_PLLCTRL2_REG, -- ~AW88399_CCO_MUX_MASK, AW88399_CCO_MUX_DIVIDED_VALUE); -- if (ret) -- return ret; -- -- for (i = 0; i < AW88399_DEV_SYSST_CHECK_MAX; i++) { -- ret = aw_dev_get_iis_status(aw_dev); -- if (ret) { -- dev_err(aw_dev->dev, "mode2 iis signal check error"); -- usleep_range(AW88399_2000_US, AW88399_2000_US + 10); -- } else { -- break; -- } -- } -- -- /* change mode1 */ -- regmap_update_bits(aw_dev->regmap, AW88399_PLLCTRL2_REG, -- ~AW88399_CCO_MUX_MASK, AW88399_CCO_MUX_BYPASS_VALUE); -- if (ret == 0) { -- usleep_range(AW88399_2000_US, AW88399_2000_US + 10); -- for (i = 0; i < AW88399_DEV_SYSST_CHECK_MAX; i++) { -- ret = aw_dev_get_iis_status(aw_dev); -- if (ret) { -- dev_err(aw_dev->dev, "mode2 switch to mode1, iis signal check error"); -- usleep_range(AW88399_2000_US, AW88399_2000_US + 10); -- } else { -- break; -- } -- } -- } -- -- return ret; --} -- --static int aw_dev_check_syspll(struct aw_device *aw_dev) --{ -- int ret; -- -- ret = aw_dev_check_mode1_pll(aw_dev); -- if (ret) { -- dev_dbg(aw_dev->dev, "mode1 check iis failed try switch to mode2 check"); -- ret = aw_dev_check_mode2_pll(aw_dev); -- if (ret) { -- dev_err(aw_dev->dev, "mode2 check iis failed"); -- return ret; -- } -- } -- -- return 0; --} -- --static int aw_dev_check_sysst(struct aw_device *aw_dev) --{ -- unsigned int check_val; -- unsigned int reg_val; -- int ret, i; -- -- ret = regmap_read(aw_dev->regmap, AW88399_PWMCTRL3_REG, ®_val); -- if (ret) -- return ret; -- -- if (reg_val & (~AW88399_NOISE_GATE_EN_MASK)) -- check_val = AW88399_BIT_SYSST_NOSWS_CHECK; -- else -- check_val = AW88399_BIT_SYSST_SWS_CHECK; -- -- for (i = 0; i < AW88399_DEV_SYSST_CHECK_MAX; i++) { -- ret = regmap_read(aw_dev->regmap, AW88399_SYSST_REG, ®_val); -- if (ret) -- return ret; -- -- if ((reg_val & (~AW88399_BIT_SYSST_CHECK_MASK) & check_val) != check_val) { -- dev_err(aw_dev->dev, "check sysst fail, cnt=%d, reg_val=0x%04x, check:0x%x", -- i, reg_val, AW88399_BIT_SYSST_NOSWS_CHECK); -- usleep_range(AW88399_2000_US, AW88399_2000_US + 10); -- } else { -- return 0; -- } -- } -- -- return -EPERM; --} -- --static void aw_dev_amppd(struct aw_device *aw_dev, bool amppd) --{ -- int ret; -- -- if (amppd) -- ret = regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, -- ~AW88399_AMPPD_MASK, AW88399_AMPPD_POWER_DOWN_VALUE); -- else -- ret = regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, -- ~AW88399_AMPPD_MASK, AW88399_AMPPD_WORKING_VALUE); -- -- if (ret) -- dev_dbg(aw_dev->dev, "%s failed", __func__); --} -- --static void aw_dev_dsp_enable(struct aw_device *aw_dev, bool is_enable) --{ -- int ret; -- -- if (is_enable) -- ret = regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, -- ~AW88399_DSPBY_MASK, AW88399_DSPBY_WORKING_VALUE); -- else -- ret = regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, -- ~AW88399_DSPBY_MASK, AW88399_DSPBY_BYPASS_VALUE); -- -- if (ret) -- dev_dbg(aw_dev->dev, "%s failed\n", __func__); --} -- --static int aw88399_dev_get_icalk(struct aw88399 *aw88399, int16_t *icalk) --{ -- uint16_t icalkh_val, icalkl_val, icalk_val; -- struct aw_device *aw_dev = aw88399->aw_pa; -- unsigned int reg_val; -- int ret; -- -- ret = regmap_read(aw_dev->regmap, AW88399_EFRH4_REG, ®_val); -- if (ret) -- return ret; -- icalkh_val = reg_val & (~AW88399_EF_ISN_GESLP_H_MASK); -- -- ret = regmap_read(aw_dev->regmap, AW88399_EFRL4_REG, ®_val); -- if (ret) -- return ret; -- icalkl_val = reg_val & (~AW88399_EF_ISN_GESLP_L_MASK); -- -- if (aw88399->check_val == AW_EF_AND_CHECK) -- icalk_val = icalkh_val & icalkl_val; -- else -- icalk_val = icalkh_val | icalkl_val; -- -- if (icalk_val & (~AW88399_EF_ISN_GESLP_SIGN_MASK)) -- icalk_val = icalk_val | AW88399_EF_ISN_GESLP_SIGN_NEG; -- *icalk = (int16_t)icalk_val; -- -- return 0; --} -- --static int aw88399_dev_get_vcalk(struct aw88399 *aw88399, int16_t *vcalk) --{ -- uint16_t vcalkh_val, vcalkl_val, vcalk_val; -- struct aw_device *aw_dev = aw88399->aw_pa; -- unsigned int reg_val; -- int ret; -- -- ret = regmap_read(aw_dev->regmap, AW88399_EFRH3_REG, ®_val); -- if (ret) -- return ret; -- -- vcalkh_val = reg_val & (~AW88399_EF_VSN_GESLP_H_MASK); -- -- ret = regmap_read(aw_dev->regmap, AW88399_EFRL3_REG, ®_val); -- if (ret) -- return ret; -- -- vcalkl_val = reg_val & (~AW88399_EF_VSN_GESLP_L_MASK); -- -- if (aw88399->check_val == AW_EF_AND_CHECK) -- vcalk_val = vcalkh_val & vcalkl_val; -- else -- vcalk_val = vcalkh_val | vcalkl_val; -- -- if (vcalk_val & AW88399_EF_VSN_GESLP_SIGN_MASK) -- vcalk_val = vcalk_val | AW88399_EF_VSN_GESLP_SIGN_NEG; -- *vcalk = (int16_t)vcalk_val; -- -- return 0; --} -- --static int aw88399_dev_get_internal_vcalk(struct aw88399 *aw88399, int16_t *vcalk) --{ -- uint16_t vcalkh_val, vcalkl_val, vcalk_val; -- struct aw_device *aw_dev = aw88399->aw_pa; -- unsigned int reg_val; -- int ret; -- -- ret = regmap_read(aw_dev->regmap, AW88399_EFRH2_REG, ®_val); -- if (ret) -- return ret; -- vcalkh_val = reg_val & (~AW88399_INTERNAL_VSN_TRIM_H_MASK); -- -- ret = regmap_read(aw_dev->regmap, AW88399_EFRL2_REG, ®_val); -- if (ret) -- return ret; -- vcalkl_val = reg_val & (~AW88399_INTERNAL_VSN_TRIM_L_MASK); -- -- if (aw88399->check_val == AW_EF_AND_CHECK) -- vcalk_val = (vcalkh_val >> AW88399_INTERNAL_VSN_TRIM_H_START_BIT) & -- (vcalkl_val >> AW88399_INTERNAL_VSN_TRIM_L_START_BIT); -- else -- vcalk_val = (vcalkh_val >> AW88399_INTERNAL_VSN_TRIM_H_START_BIT) | -- (vcalkl_val >> AW88399_INTERNAL_VSN_TRIM_L_START_BIT); -- -- if (vcalk_val & (~AW88399_TEM4_SIGN_MASK)) -- vcalk_val = vcalk_val | AW88399_TEM4_SIGN_NEG; -- -- *vcalk = (int16_t)vcalk_val; -- -- return 0; --} -- --static int aw_dev_set_vcalb(struct aw88399 *aw88399) --{ -- struct aw_device *aw_dev = aw88399->aw_pa; -- unsigned int vsense_select, vsense_value; -- int32_t ical_k, vcal_k, vcalb; -- int16_t icalk, vcalk; -- uint16_t reg_val; -- int ret; -- -- ret = regmap_read(aw_dev->regmap, AW88399_VSNCTRL1_REG, &vsense_value); -- if (ret) -- return ret; -- -- vsense_select = vsense_value & (~AW88399_VDSEL_MASK); -- -- ret = aw88399_dev_get_icalk(aw88399, &icalk); -- if (ret) { -- dev_err(aw_dev->dev, "get icalk failed\n"); -- return ret; -- } -- -- ical_k = icalk * AW88399_ICABLK_FACTOR + AW88399_CABL_BASE_VALUE; -- -- switch (vsense_select) { -- case AW88399_DEV_VDSEL_VSENSE: -- ret = aw88399_dev_get_vcalk(aw88399, &vcalk); -- vcal_k = vcalk * AW88399_VCABLK_FACTOR + AW88399_CABL_BASE_VALUE; -- vcalb = AW88399_VCALB_ACCURACY * AW88399_VSCAL_FACTOR / AW88399_ISCAL_FACTOR * -- ical_k / vcal_k * aw88399->vcalb_init_val; -- break; -- case AW88399_DEV_VDSEL_DAC: -- ret = aw88399_dev_get_internal_vcalk(aw88399, &vcalk); -- vcal_k = vcalk * AW88399_VCABLK_DAC_FACTOR + AW88399_CABL_BASE_VALUE; -- vcalb = AW88399_VCALB_ACCURACY * AW88399_VSCAL_DAC_FACTOR / -- AW88399_ISCAL_DAC_FACTOR * ical_k / -- vcal_k * aw88399->vcalb_init_val; -- break; -- default: -- dev_err(aw_dev->dev, "%s: unsupported vsense\n", __func__); -- ret = -EINVAL; -- break; -- } -- if (ret) -- return ret; -- -- vcalb = vcalb >> AW88399_VCALB_ADJ_FACTOR; -- reg_val = (uint32_t)vcalb; -- -- regmap_write(aw_dev->regmap, AW88399_DSPVCALB_REG, reg_val); -- -- return 0; --} -- --static int aw_dev_update_cali_re(struct aw_cali_desc *cali_desc) --{ -- struct aw_device *aw_dev = -- container_of(cali_desc, struct aw_device, cali_desc); -- uint16_t re_lbits, re_hbits; -- u32 cali_re; -- int ret; -- -- if ((aw_dev->cali_desc.cali_re >= AW88399_CALI_RE_MAX) || -- (aw_dev->cali_desc.cali_re <= AW88399_CALI_RE_MIN)) -- return -EINVAL; -- -- cali_re = AW88399_SHOW_RE_TO_DSP_RE((aw_dev->cali_desc.cali_re + -- aw_dev->cali_desc.ra), AW88399_DSP_RE_SHIFT); -- -- re_hbits = (cali_re & (~AW88399_CALI_RE_HBITS_MASK)) >> AW88399_CALI_RE_HBITS_SHIFT; -- re_lbits = (cali_re & (~AW88399_CALI_RE_LBITS_MASK)) >> AW88399_CALI_RE_LBITS_SHIFT; -- -- ret = regmap_write(aw_dev->regmap, AW88399_ACR1_REG, re_hbits); -- if (ret) { -- dev_err(aw_dev->dev, "set cali re error"); -- return ret; -- } -- -- ret = regmap_write(aw_dev->regmap, AW88399_ACR2_REG, re_lbits); -- if (ret) -- dev_err(aw_dev->dev, "set cali re error"); -- -- return ret; --} -- --static int aw_dev_fw_crc_check(struct aw_device *aw_dev) --{ -- uint16_t check_val, fw_len_val; -- unsigned int reg_val; -- int ret; -- -- /* calculate fw_end_addr */ -- fw_len_val = ((aw_dev->dsp_fw_len / AW_FW_ADDR_LEN) - 1) + AW88399_CRC_FW_BASE_ADDR; -- -- /* write fw_end_addr to crc_end_addr */ -- ret = regmap_update_bits(aw_dev->regmap, AW88399_CRCCTRL_REG, -- ~AW88399_CRC_END_ADDR_MASK, fw_len_val); -- if (ret) -- return ret; -- /* enable fw crc check */ -- ret = regmap_update_bits(aw_dev->regmap, AW88399_CRCCTRL_REG, -- ~AW88399_CRC_CODE_EN_MASK, AW88399_CRC_CODE_EN_ENABLE_VALUE); -- -- usleep_range(AW88399_2000_US, AW88399_2000_US + 10); -- -- /* read crc check result */ -- regmap_read(aw_dev->regmap, AW88399_HAGCST_REG, ®_val); -- if (ret) -- return ret; -- -- check_val = (reg_val & (~AW88399_CRC_CHECK_BITS_MASK)) >> AW88399_CRC_CHECK_START_BIT; -- -- /* disable fw crc check */ -- ret = regmap_update_bits(aw_dev->regmap, AW88399_CRCCTRL_REG, -- ~AW88399_CRC_CODE_EN_MASK, AW88399_CRC_CODE_EN_DISABLE_VALUE); -- if (ret) -- return ret; -- -- if (check_val != AW88399_CRC_CHECK_PASS_VAL) { -- dev_err(aw_dev->dev, "%s failed, check_val 0x%x != 0x%x", -- __func__, check_val, AW88399_CRC_CHECK_PASS_VAL); -- ret = -EINVAL; -- } -- -- return ret; --} -- --static int aw_dev_cfg_crc_check(struct aw_device *aw_dev) --{ -- uint16_t check_val, cfg_len_val; -- unsigned int reg_val; -- int ret; -- -- /* calculate cfg end addr */ -- cfg_len_val = ((aw_dev->dsp_cfg_len / AW_FW_ADDR_LEN) - 1) + AW88399_CRC_CFG_BASE_ADDR; -- -- /* write cfg_end_addr to crc_end_addr */ -- ret = regmap_update_bits(aw_dev->regmap, AW88399_CRCCTRL_REG, -- ~AW88399_CRC_END_ADDR_MASK, cfg_len_val); -- if (ret) -- return ret; -- -- /* enable cfg crc check */ -- ret = regmap_update_bits(aw_dev->regmap, AW88399_CRCCTRL_REG, -- ~AW88399_CRC_CFG_EN_MASK, AW88399_CRC_CFG_EN_ENABLE_VALUE); -- if (ret) -- return ret; -- -- usleep_range(AW88399_1000_US, AW88399_1000_US + 10); -- -- /* read crc check result */ -- ret = regmap_read(aw_dev->regmap, AW88399_HAGCST_REG, ®_val); -- if (ret) -- return ret; -- -- check_val = (reg_val & (~AW88399_CRC_CHECK_BITS_MASK)) >> AW88399_CRC_CHECK_START_BIT; -- -- /* disable cfg crc check */ -- ret = regmap_update_bits(aw_dev->regmap, AW88399_CRCCTRL_REG, -- ~AW88399_CRC_CFG_EN_MASK, AW88399_CRC_CFG_EN_DISABLE_VALUE); -- if (ret) -- return ret; -- -- if (check_val != AW88399_CRC_CHECK_PASS_VAL) { -- dev_err(aw_dev->dev, "crc_check failed, check val 0x%x != 0x%x", -- check_val, AW88399_CRC_CHECK_PASS_VAL); -- ret = -EINVAL; -- } -- -- return ret; --} -- --static int aw_dev_hw_crc_check(struct aw88399 *aw88399) --{ -- struct aw_device *aw_dev = aw88399->aw_pa; -- int ret; -- -- ret = regmap_update_bits(aw_dev->regmap, AW88399_I2SCFG1_REG, -- ~AW88399_RAM_CG_BYP_MASK, AW88399_RAM_CG_BYP_BYPASS_VALUE); -- if (ret) -- return ret; -- -- ret = aw_dev_fw_crc_check(aw_dev); -- if (ret) { -- dev_err(aw_dev->dev, "fw_crc_check failed\n"); -- goto crc_check_failed; -- } -- -- ret = aw_dev_cfg_crc_check(aw_dev); -- if (ret) { -- dev_err(aw_dev->dev, "cfg_crc_check failed\n"); -- goto crc_check_failed; -- } -- -- ret = regmap_write(aw_dev->regmap, AW88399_CRCCTRL_REG, aw88399->crc_init_val); -- if (ret) -- return ret; -- -- ret = regmap_update_bits(aw_dev->regmap, AW88399_I2SCFG1_REG, -- ~AW88399_RAM_CG_BYP_MASK, AW88399_RAM_CG_BYP_WORK_VALUE); -- -- return ret; -- --crc_check_failed: -- regmap_update_bits(aw_dev->regmap, AW88399_I2SCFG1_REG, -- ~AW88399_RAM_CG_BYP_MASK, AW88399_RAM_CG_BYP_WORK_VALUE); -- return ret; --} -- --static void aw_dev_i2s_tx_enable(struct aw_device *aw_dev, bool flag) --{ -- int ret; -- -- if (flag) -- ret = regmap_update_bits(aw_dev->regmap, AW88399_I2SCTRL3_REG, -- ~AW88399_I2STXEN_MASK, AW88399_I2STXEN_ENABLE_VALUE); -- else -- ret = regmap_update_bits(aw_dev->regmap, AW88399_I2SCFG1_REG, -- ~AW88399_I2STXEN_MASK, AW88399_I2STXEN_DISABLE_VALUE); -- -- if (ret) -- dev_dbg(aw_dev->dev, "%s failed", __func__); --} -- --static int aw_dev_get_dsp_status(struct aw_device *aw_dev) --{ -- unsigned int reg_val; -- int ret; -- -- ret = regmap_read(aw_dev->regmap, AW88399_WDT_REG, ®_val); -- if (ret) -- return ret; -- if (!(reg_val & (~AW88399_WDT_CNT_MASK))) -- return -EPERM; -- -- return 0; --} -- --static int aw_dev_dsp_check(struct aw_device *aw_dev) --{ -- int ret, i; -- -- switch (aw_dev->dsp_cfg) { -- case AW88399_DEV_DSP_BYPASS: -- dev_dbg(aw_dev->dev, "dsp bypass"); -- ret = 0; -- break; -- case AW88399_DEV_DSP_WORK: -- aw_dev_dsp_enable(aw_dev, false); -- aw_dev_dsp_enable(aw_dev, true); -- usleep_range(AW88399_1000_US, AW88399_1000_US + 10); -- for (i = 0; i < AW88399_DEV_DSP_CHECK_MAX; i++) { -- ret = aw_dev_get_dsp_status(aw_dev); -- if (ret) { -- dev_err(aw_dev->dev, "dsp wdt status error=%d", ret); -- usleep_range(AW88399_2000_US, AW88399_2000_US + 10); -- } -- } -- break; -- default: -- dev_err(aw_dev->dev, "unknown dsp cfg=%d", aw_dev->dsp_cfg); -- ret = -EINVAL; -- break; -- } -- -- return ret; --} -- --static int aw_dev_set_volume(struct aw_device *aw_dev, unsigned int value) --{ -- struct aw_volume_desc *vol_desc = &aw_dev->volume_desc; -- unsigned int reg_value; -- u16 real_value; -- int ret; -- -- real_value = min((value + vol_desc->init_volume), (unsigned int)AW88399_MUTE_VOL); -- -- ret = regmap_read(aw_dev->regmap, AW88399_SYSCTRL2_REG, ®_value); -- if (ret) -- return ret; -- -- dev_dbg(aw_dev->dev, "value 0x%x , reg:0x%x", value, real_value); -- -- real_value = (real_value << AW88399_VOL_START_BIT) | (reg_value & AW88399_VOL_MASK); -- -- ret = regmap_write(aw_dev->regmap, AW88399_SYSCTRL2_REG, real_value); -- -- return ret; --} -- --static void aw_dev_fade_in(struct aw_device *aw_dev) --{ -- struct aw_volume_desc *desc = &aw_dev->volume_desc; -- u16 fade_in_vol = desc->ctl_volume; -- int fade_step = aw_dev->fade_step; -- int i; -- -- if (fade_step == 0 || aw_dev->fade_in_time == 0) { -- aw_dev_set_volume(aw_dev, fade_in_vol); -- return; -- } -- -- for (i = AW88399_MUTE_VOL; i >= fade_in_vol; i -= fade_step) { -- aw_dev_set_volume(aw_dev, i); -- usleep_range(aw_dev->fade_in_time, aw_dev->fade_in_time + 10); -- } -- -- if (i != fade_in_vol) -- aw_dev_set_volume(aw_dev, fade_in_vol); --} -- --static void aw_dev_fade_out(struct aw_device *aw_dev) --{ -- struct aw_volume_desc *desc = &aw_dev->volume_desc; -- int fade_step = aw_dev->fade_step; -- int i; -- -- if (fade_step == 0 || aw_dev->fade_out_time == 0) { -- aw_dev_set_volume(aw_dev, AW88399_MUTE_VOL); -- return; -- } -- -- for (i = desc->ctl_volume; i <= AW88399_MUTE_VOL; i += fade_step) { -- aw_dev_set_volume(aw_dev, i); -- usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10); -- } -- -- if (i != AW88399_MUTE_VOL) { -- aw_dev_set_volume(aw_dev, AW88399_MUTE_VOL); -- usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10); -- } --} -- --static void aw88399_dev_mute(struct aw_device *aw_dev, bool is_mute) --{ -- if (is_mute) { -- aw_dev_fade_out(aw_dev); -- regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, -- ~AW88399_HMUTE_MASK, AW88399_HMUTE_ENABLE_VALUE); -- } else { -- regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, -- ~AW88399_HMUTE_MASK, AW88399_HMUTE_DISABLE_VALUE); -- aw_dev_fade_in(aw_dev); -- } --} -- --static void aw88399_dev_set_dither(struct aw88399 *aw88399, bool dither) --{ -- struct aw_device *aw_dev = aw88399->aw_pa; -- -- if (dither) -- regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, -- ~AW88399_DITHER_EN_MASK, AW88399_DITHER_EN_ENABLE_VALUE); -- else -- regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, -- ~AW88399_DITHER_EN_MASK, AW88399_DITHER_EN_DISABLE_VALUE); --} -- --static int aw88399_dev_start(struct aw88399 *aw88399) --{ -- struct aw_device *aw_dev = aw88399->aw_pa; -- int ret; -- -- if (aw_dev->status == AW88399_DEV_PW_ON) { -- dev_dbg(aw_dev->dev, "already power on"); -- return 0; -- } -- -- aw88399_dev_set_dither(aw88399, false); -- -- /* power on */ -- aw_dev_pwd(aw_dev, false); -- usleep_range(AW88399_2000_US, AW88399_2000_US + 10); -- -- ret = aw_dev_check_syspll(aw_dev); -- if (ret) { -- dev_err(aw_dev->dev, "pll check failed cannot start"); -- goto pll_check_fail; -- } -- -- /* amppd on */ -- aw_dev_amppd(aw_dev, false); -- usleep_range(AW88399_1000_US, AW88399_1000_US + 50); -- -- /* check i2s status */ -- ret = aw_dev_check_sysst(aw_dev); -- if (ret) { -- dev_err(aw_dev->dev, "sysst check failed"); -- goto sysst_check_fail; -- } -- -- if (aw_dev->dsp_cfg == AW88399_DEV_DSP_WORK) { -- ret = aw_dev_hw_crc_check(aw88399); -- if (ret) { -- dev_err(aw_dev->dev, "dsp crc check failed"); -- goto crc_check_fail; -- } -- aw_dev_dsp_enable(aw_dev, false); -- aw_dev_set_vcalb(aw88399); -- aw_dev_update_cali_re(&aw_dev->cali_desc); -- -- ret = aw_dev_dsp_check(aw_dev); -- if (ret) { -- dev_err(aw_dev->dev, "dsp status check failed"); -- goto dsp_check_fail; -- } -- } else { -- dev_dbg(aw_dev->dev, "start pa with dsp bypass"); -- } -- -- /* enable tx feedback */ -- aw_dev_i2s_tx_enable(aw_dev, true); -- -- if (aw88399->dither_st == AW88399_DITHER_EN_ENABLE_VALUE) -- aw88399_dev_set_dither(aw88399, true); -- -- /* close mute */ -- aw88399_dev_mute(aw_dev, false); -- /* clear inturrupt */ -- aw_dev_clear_int_status(aw_dev); -- aw_dev->status = AW88399_DEV_PW_ON; -- -- return 0; -- --dsp_check_fail: --crc_check_fail: -- aw_dev_dsp_enable(aw_dev, false); --sysst_check_fail: -- aw_dev_clear_int_status(aw_dev); -- aw_dev_amppd(aw_dev, true); --pll_check_fail: -- aw_dev_pwd(aw_dev, true); -- aw_dev->status = AW88399_DEV_PW_OFF; -- -- return ret; --} -- --static int aw_dev_dsp_update_container(struct aw_device *aw_dev, -- unsigned char *data, unsigned int len, unsigned short base) --{ -- u32 tmp_len; -- int i, ret; -- -- ret = regmap_write(aw_dev->regmap, AW88399_DSPMADD_REG, base); -- if (ret) -- return ret; -- -- for (i = 0; i < len; i += AW88399_MAX_RAM_WRITE_BYTE_SIZE) { -- tmp_len = min(len - i, AW88399_MAX_RAM_WRITE_BYTE_SIZE); -- ret = regmap_raw_write(aw_dev->regmap, AW88399_DSPMDAT_REG, -- &data[i], tmp_len); -- if (ret) -- return ret; -- } -- -- return 0; --} -- --static int aw_dev_get_ra(struct aw_cali_desc *cali_desc) --{ -- struct aw_device *aw_dev = -- container_of(cali_desc, struct aw_device, cali_desc); -- u32 dsp_ra; -- int ret; -- -- ret = aw_dev_dsp_read(aw_dev, AW88399_DSP_REG_CFG_ADPZ_RA, -- &dsp_ra, AW_DSP_32_DATA); -- if (ret) { -- dev_err(aw_dev->dev, "read ra error"); -- return ret; -- } -- -- cali_desc->ra = AW88399_DSP_RE_TO_SHOW_RE(dsp_ra, -- AW88399_DSP_RE_SHIFT); -- -- return 0; --} -- --static int aw_dev_dsp_update_cfg(struct aw_device *aw_dev, -- unsigned char *data, unsigned int len) --{ -- int ret; -- -- dev_dbg(aw_dev->dev, "dsp config len:%d", len); -- -- if (!len || !data) { -- dev_err(aw_dev->dev, "dsp config data is null or len is 0"); -- return -EINVAL; -- } -- -- ret = aw_dev_dsp_update_container(aw_dev, data, len, AW88399_DSP_CFG_ADDR); -- if (ret) -- return ret; -- -- aw_dev->dsp_cfg_len = len; -- -- ret = aw_dev_get_ra(&aw_dev->cali_desc); -- -- return ret; --} -- --static int aw_dev_dsp_update_fw(struct aw_device *aw_dev, -- unsigned char *data, unsigned int len) --{ -- int ret; -- -- dev_dbg(aw_dev->dev, "dsp firmware len:%d", len); -- -- if (!len || !data) { -- dev_err(aw_dev->dev, "dsp firmware data is null or len is 0"); -- return -EINVAL; -- } -- -- aw_dev->dsp_fw_len = len; -- ret = aw_dev_dsp_update_container(aw_dev, data, len, AW88399_DSP_FW_ADDR); -- -- return ret; --} -- --static int aw_dev_check_sram(struct aw_device *aw_dev) --{ -- unsigned int reg_val; -- -- /* read dsp_rom_check_reg */ -- aw_dev_dsp_read(aw_dev, AW88399_DSP_ROM_CHECK_ADDR, ®_val, AW_DSP_16_DATA); -- if (reg_val != AW88399_DSP_ROM_CHECK_DATA) { -- dev_err(aw_dev->dev, "check dsp rom failed, read[0x%x] != check[0x%x]", -- reg_val, AW88399_DSP_ROM_CHECK_DATA); -- return -EPERM; -- } -- -- /* check dsp_cfg_base_addr */ -- aw_dev_dsp_write(aw_dev, AW88399_DSP_CFG_ADDR, -- AW88399_DSP_ODD_NUM_BIT_TEST, AW_DSP_16_DATA); -- aw_dev_dsp_read(aw_dev, AW88399_DSP_CFG_ADDR, ®_val, AW_DSP_16_DATA); -- if (reg_val != AW88399_DSP_ODD_NUM_BIT_TEST) { -- dev_err(aw_dev->dev, "check dsp cfg failed, read[0x%x] != write[0x%x]", -- reg_val, AW88399_DSP_ODD_NUM_BIT_TEST); -- return -EPERM; -- } -- -- return 0; --} -- --static void aw_dev_select_memclk(struct aw_device *aw_dev, unsigned char flag) --{ -- int ret; -- -- switch (flag) { -- case AW88399_DEV_MEMCLK_PLL: -- ret = regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, -- ~AW88399_MEM_CLKSEL_MASK, -- AW88399_MEM_CLKSEL_DAPHCLK_VALUE); -- if (ret) -- dev_err(aw_dev->dev, "memclk select pll failed"); -- break; -- case AW88399_DEV_MEMCLK_OSC: -- ret = regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, -- ~AW88399_MEM_CLKSEL_MASK, -- AW88399_MEM_CLKSEL_OSCCLK_VALUE); -- if (ret) -- dev_err(aw_dev->dev, "memclk select OSC failed"); -- break; -- default: -- dev_err(aw_dev->dev, "unknown memclk config, flag=0x%x", flag); -- break; -- } --} -- --static void aw_dev_get_cur_mode_st(struct aw_device *aw_dev) --{ -- struct aw_profctrl_desc *profctrl_desc = &aw_dev->profctrl_desc; -- unsigned int reg_val; -- int ret; -- -- ret = regmap_read(aw_dev->regmap, AW88399_SYSCTRL_REG, ®_val); -- if (ret) { -- dev_dbg(aw_dev->dev, "%s failed", __func__); -- return; -- } -- if ((reg_val & (~AW88399_RCV_MODE_MASK)) == AW88399_RCV_MODE_RECEIVER_VALUE) -- profctrl_desc->cur_mode = AW88399_RCV_MODE; -- else -- profctrl_desc->cur_mode = AW88399_NOT_RCV_MODE; --} -- --static int aw_dev_update_reg_container(struct aw88399 *aw88399, -- unsigned char *data, unsigned int len) --{ -- struct aw_device *aw_dev = aw88399->aw_pa; -- struct aw_volume_desc *vol_desc = &aw_dev->volume_desc; -- u16 read_vol, reg_val; -- int data_len, i, ret; -- int16_t *reg_data; -- u8 reg_addr; -- -- reg_data = (int16_t *)data; -- data_len = len >> 1; -- -- if (data_len & 0x1) { -- dev_err(aw_dev->dev, "data len:%d unsupported", data_len); -- return -EINVAL; -- } -- -- for (i = 0; i < data_len; i += 2) { -- reg_addr = reg_data[i]; -- reg_val = reg_data[i + 1]; -- -- if (reg_addr == AW88399_DSPVCALB_REG) { -- aw88399->vcalb_init_val = reg_val; -- continue; -- } -- -- if (reg_addr == AW88399_SYSCTRL_REG) { -- if (reg_val & (~AW88399_DSPBY_MASK)) -- aw_dev->dsp_cfg = AW88399_DEV_DSP_BYPASS; -- else -- aw_dev->dsp_cfg = AW88399_DEV_DSP_WORK; -- -- reg_val &= (AW88399_HMUTE_MASK | AW88399_PWDN_MASK | -- AW88399_DSPBY_MASK); -- reg_val |= (AW88399_HMUTE_ENABLE_VALUE | AW88399_PWDN_POWER_DOWN_VALUE | -- AW88399_DSPBY_BYPASS_VALUE); -- } -- -- if (reg_addr == AW88399_I2SCTRL3_REG) { -- reg_val &= AW88399_I2STXEN_MASK; -- reg_val |= AW88399_I2STXEN_DISABLE_VALUE; -- } -- -- if (reg_addr == AW88399_SYSCTRL2_REG) { -- read_vol = (reg_val & (~AW88399_VOL_MASK)) >> -- AW88399_VOL_START_BIT; -- aw_dev->volume_desc.init_volume = read_vol; -- } -- -- if (reg_addr == AW88399_DBGCTRL_REG) { -- if ((reg_val & (~AW88399_EF_DBMD_MASK)) == AW88399_EF_DBMD_OR_VALUE) -- aw88399->check_val = AW_EF_OR_CHECK; -- else -- aw88399->check_val = AW_EF_AND_CHECK; -- -- aw88399->dither_st = reg_val & (~AW88399_DITHER_EN_MASK); -- } -- -- if (reg_addr == AW88399_CRCCTRL_REG) -- aw88399->crc_init_val = reg_val; -- -- ret = regmap_write(aw_dev->regmap, reg_addr, reg_val); -- if (ret) -- return ret; -- } -- -- aw_dev_pwd(aw_dev, false); -- usleep_range(AW88399_1000_US, AW88399_1000_US + 10); -- -- aw_dev_get_cur_mode_st(aw_dev); -- -- if (aw_dev->prof_cur != aw_dev->prof_index) -- vol_desc->ctl_volume = 0; -- else -- aw_dev_set_volume(aw_dev, vol_desc->ctl_volume); -- -- return 0; --} -- --static int aw_dev_reg_update(struct aw88399 *aw88399, -- unsigned char *data, unsigned int len) --{ -- int ret; -- -- if (!len || !data) { -- dev_err(aw88399->aw_pa->dev, "reg data is null or len is 0"); -- return -EINVAL; -- } -- -- ret = aw_dev_update_reg_container(aw88399, data, len); -- if (ret) -- dev_err(aw88399->aw_pa->dev, "reg update failed"); -- -- return ret; --} -- --static int aw88399_dev_get_prof_name(struct aw_device *aw_dev, int index, char **prof_name) --{ -- struct aw_prof_info *prof_info = &aw_dev->prof_info; -- struct aw_prof_desc *prof_desc; -- -- if ((index >= aw_dev->prof_info.count) || (index < 0)) { -- dev_err(aw_dev->dev, "index[%d] overflow count[%d]", -- index, aw_dev->prof_info.count); -- return -EINVAL; -- } -- -- prof_desc = &aw_dev->prof_info.prof_desc[index]; -- -- *prof_name = prof_info->prof_name_list[prof_desc->id]; -- -- return 0; --} -- --static int aw88399_dev_get_prof_data(struct aw_device *aw_dev, int index, -- struct aw_prof_desc **prof_desc) --{ -- if ((index >= aw_dev->prof_info.count) || (index < 0)) { -- dev_err(aw_dev->dev, "%s: index[%d] overflow count[%d]\n", -- __func__, index, aw_dev->prof_info.count); -- return -EINVAL; -- } -- -- *prof_desc = &aw_dev->prof_info.prof_desc[index]; -- -- return 0; --} -- --static int aw88399_dev_fw_update(struct aw88399 *aw88399, bool up_dsp_fw_en, bool force_up_en) --{ -- struct aw_device *aw_dev = aw88399->aw_pa; -- struct aw_prof_desc *prof_index_desc; -- struct aw_sec_data_desc *sec_desc; -- char *prof_name; -- int ret; -- -- if ((aw_dev->prof_cur == aw_dev->prof_index) && -- (force_up_en == AW88399_FORCE_UPDATE_OFF)) { -- dev_dbg(aw_dev->dev, "scene no change, not update"); -- return 0; -- } -- -- if (aw_dev->fw_status == AW88399_DEV_FW_FAILED) { -- dev_err(aw_dev->dev, "fw status[%d] error", aw_dev->fw_status); -- return -EPERM; -- } -- -- ret = aw88399_dev_get_prof_name(aw_dev, aw_dev->prof_index, &prof_name); -- if (ret) -- return ret; -- -- dev_dbg(aw_dev->dev, "start update %s", prof_name); -- -- ret = aw88399_dev_get_prof_data(aw_dev, aw_dev->prof_index, &prof_index_desc); -- if (ret) -- return ret; -- -- /* update reg */ -- sec_desc = prof_index_desc->sec_desc; -- ret = aw_dev_reg_update(aw88399, sec_desc[AW88395_DATA_TYPE_REG].data, -- sec_desc[AW88395_DATA_TYPE_REG].len); -- if (ret) { -- dev_err(aw_dev->dev, "update reg failed"); -- return ret; -- } -- -- aw88399_dev_mute(aw_dev, true); -- -- if (aw_dev->dsp_cfg == AW88399_DEV_DSP_WORK) -- aw_dev_dsp_enable(aw_dev, false); -- -- aw_dev_select_memclk(aw_dev, AW88399_DEV_MEMCLK_OSC); -- -- ret = aw_dev_check_sram(aw_dev); -- if (ret) { -- dev_err(aw_dev->dev, "check sram failed"); -- goto error; -- } -- -- if (up_dsp_fw_en) { -- dev_dbg(aw_dev->dev, "fw_ver: [%x]", prof_index_desc->fw_ver); -- ret = aw_dev_dsp_update_fw(aw_dev, sec_desc[AW88395_DATA_TYPE_DSP_FW].data, -- sec_desc[AW88395_DATA_TYPE_DSP_FW].len); -- if (ret) { -- dev_err(aw_dev->dev, "update dsp fw failed"); -- goto error; -- } -- } -- -- /* update dsp config */ -- ret = aw_dev_dsp_update_cfg(aw_dev, sec_desc[AW88395_DATA_TYPE_DSP_CFG].data, -- sec_desc[AW88395_DATA_TYPE_DSP_CFG].len); -- if (ret) { -- dev_err(aw_dev->dev, "update dsp cfg failed"); -- goto error; -- } -- -- aw_dev_select_memclk(aw_dev, AW88399_DEV_MEMCLK_PLL); -- -- aw_dev->prof_cur = aw_dev->prof_index; -- -- return 0; -- --error: -- aw_dev_select_memclk(aw_dev, AW88399_DEV_MEMCLK_PLL); -- return ret; --} -- --static void aw88399_start_pa(struct aw88399 *aw88399) --{ -- int ret, i; -- -- for (i = 0; i < AW88399_START_RETRIES; i++) { -- ret = aw88399_dev_start(aw88399); -- if (ret) { -- dev_err(aw88399->aw_pa->dev, "aw88399 device start failed. retry = %d", i); -- ret = aw88399_dev_fw_update(aw88399, AW88399_DSP_FW_UPDATE_ON, true); -- if (ret) { -- dev_err(aw88399->aw_pa->dev, "fw update failed"); -- continue; -- } -- } else { -- dev_dbg(aw88399->aw_pa->dev, "start success\n"); -- break; -- } -- } --} -- --static void aw88399_startup_work(struct work_struct *work) --{ -- struct aw88399 *aw88399 = -- container_of(work, struct aw88399, start_work.work); -- -- mutex_lock(&aw88399->lock); -- aw88399_start_pa(aw88399); -- mutex_unlock(&aw88399->lock); --} -- --static void aw88399_start(struct aw88399 *aw88399, bool sync_start) --{ -- int ret; -- -- if (aw88399->aw_pa->fw_status != AW88399_DEV_FW_OK) -- return; -- -- if (aw88399->aw_pa->status == AW88399_DEV_PW_ON) -- return; -- -- ret = aw88399_dev_fw_update(aw88399, AW88399_DSP_FW_UPDATE_OFF, true); -- if (ret) { -- dev_err(aw88399->aw_pa->dev, "fw update failed."); -- return; -- } -- -- if (sync_start == AW88399_SYNC_START) -- aw88399_start_pa(aw88399); -- else -- queue_delayed_work(system_dfl_wq, -- &aw88399->start_work, -- AW88399_START_WORK_DELAY_MS); --} -- --static int aw_dev_check_sysint(struct aw_device *aw_dev) --{ -- u16 reg_val; -- -- aw_dev_get_int_status(aw_dev, ®_val); -- if (reg_val & AW88399_BIT_SYSINT_CHECK) { -- dev_err(aw_dev->dev, "pa stop check fail:0x%04x", reg_val); -- return -EINVAL; -- } -- -- return 0; --} -- --static int aw88399_stop(struct aw_device *aw_dev) --{ -- struct aw_sec_data_desc *dsp_cfg = -- &aw_dev->prof_info.prof_desc[aw_dev->prof_cur].sec_desc[AW88395_DATA_TYPE_DSP_CFG]; -- struct aw_sec_data_desc *dsp_fw = -- &aw_dev->prof_info.prof_desc[aw_dev->prof_cur].sec_desc[AW88395_DATA_TYPE_DSP_FW]; -- int int_st; -- -- if (aw_dev->status == AW88399_DEV_PW_OFF) { -- dev_dbg(aw_dev->dev, "already power off"); -- return 0; -- } -- -- aw_dev->status = AW88399_DEV_PW_OFF; -- -- aw88399_dev_mute(aw_dev, true); -- usleep_range(AW88399_4000_US, AW88399_4000_US + 100); -- -- aw_dev_i2s_tx_enable(aw_dev, false); -- usleep_range(AW88399_1000_US, AW88399_1000_US + 100); -- -- int_st = aw_dev_check_sysint(aw_dev); -- -- aw_dev_dsp_enable(aw_dev, false); -- -- aw_dev_amppd(aw_dev, true); -- -- if (int_st) { -- aw_dev_select_memclk(aw_dev, AW88399_DEV_MEMCLK_OSC); -- aw_dev_dsp_update_fw(aw_dev, dsp_fw->data, dsp_fw->len); -- aw_dev_dsp_update_cfg(aw_dev, dsp_cfg->data, dsp_cfg->len); -- aw_dev_select_memclk(aw_dev, AW88399_DEV_MEMCLK_PLL); -- } -- -- aw_dev_pwd(aw_dev, true); -- -- return 0; --} -- - static struct snd_soc_dai_driver aw88399_dai[] = { - { - .name = "aw88399-aif", -@@ -1869,86 +664,6 @@ - return 0; - } - --static int aw88399_dev_init(struct aw88399 *aw88399, struct aw_container *aw_cfg) --{ -- struct aw_device *aw_dev = aw88399->aw_pa; -- int ret; -- -- ret = aw88395_dev_cfg_load(aw_dev, aw_cfg); -- if (ret) { -- dev_err(aw_dev->dev, "aw_dev acf parse failed"); -- return -EINVAL; -- } -- aw_dev->fade_in_time = AW88399_1000_US / 10; -- aw_dev->fade_out_time = AW88399_1000_US >> 1; -- aw_dev->prof_cur = aw_dev->prof_info.prof_desc[0].id; -- aw_dev->prof_index = aw_dev->prof_info.prof_desc[0].id; -- -- ret = aw88399_dev_fw_update(aw88399, AW88399_FORCE_UPDATE_ON, AW88399_DSP_FW_UPDATE_ON); -- if (ret) { -- dev_err(aw_dev->dev, "fw update failed ret = %d\n", ret); -- return ret; -- } -- -- aw88399_dev_mute(aw_dev, true); -- -- /* close tx feedback */ -- aw_dev_i2s_tx_enable(aw_dev, false); -- usleep_range(AW88399_1000_US, AW88399_1000_US + 100); -- -- /* enable amppd */ -- aw_dev_amppd(aw_dev, true); -- -- /* close dsp */ -- aw_dev_dsp_enable(aw_dev, false); -- /* set power down */ -- aw_dev_pwd(aw_dev, true); -- -- return 0; --} -- --static int aw88399_request_firmware_file(struct aw88399 *aw88399) --{ -- const struct firmware *cont = NULL; -- int ret; -- -- aw88399->aw_pa->fw_status = AW88399_DEV_FW_FAILED; -- -- ret = request_firmware(&cont, AW88399_ACF_FILE, aw88399->aw_pa->dev); -- if (ret) { -- dev_err(aw88399->aw_pa->dev, "request [%s] failed!", AW88399_ACF_FILE); -- return ret; -- } -- -- dev_dbg(aw88399->aw_pa->dev, "loaded %s - size: %zu\n", -- AW88399_ACF_FILE, cont ? cont->size : 0); -- -- aw88399->aw_cfg = devm_kzalloc(aw88399->aw_pa->dev, -- struct_size(aw88399->aw_cfg, data, cont->size), GFP_KERNEL); -- if (!aw88399->aw_cfg) { -- release_firmware(cont); -- return -ENOMEM; -- } -- aw88399->aw_cfg->len = (int)cont->size; -- memcpy(aw88399->aw_cfg->data, cont->data, cont->size); -- release_firmware(cont); -- -- ret = aw88395_dev_load_acf_check(aw88399->aw_pa, aw88399->aw_cfg); -- if (ret) { -- dev_err(aw88399->aw_pa->dev, "load [%s] failed!", AW88399_ACF_FILE); -- return ret; -- } -- -- mutex_lock(&aw88399->lock); -- /* aw device init */ -- ret = aw88399_dev_init(aw88399, aw88399->aw_cfg); -- if (ret) -- dev_err(aw88399->aw_pa->dev, "dev init failed"); -- mutex_unlock(&aw88399->lock); -- -- return ret; --} -- - static const struct snd_kcontrol_new aw88399_controls[] = { - SOC_SINGLE_EXT("PCM Playback Volume", AW88399_SYSCTRL2_REG, - 6, AW88399_MUTE_VOL, 0, aw88399_volume_get, -@@ -2040,70 +755,6 @@ - .num_controls = ARRAY_SIZE(aw88399_controls), - }; - --static void aw88399_hw_reset(struct aw88399 *aw88399) --{ -- if (aw88399->reset_gpio) { -- gpiod_set_value_cansleep(aw88399->reset_gpio, 1); -- usleep_range(AW88399_1000_US, AW88399_1000_US + 10); -- gpiod_set_value_cansleep(aw88399->reset_gpio, 0); -- usleep_range(AW88399_1000_US, AW88399_1000_US + 10); -- gpiod_set_value_cansleep(aw88399->reset_gpio, 1); -- usleep_range(AW88399_1000_US, AW88399_1000_US + 10); -- } --} -- --static void aw88399_parse_channel_dt(struct aw_device *aw_dev) --{ -- struct device_node *np = aw_dev->dev->of_node; -- u32 channel_value; -- -- of_property_read_u32(np, "awinic,audio-channel", &channel_value); -- aw_dev->channel = channel_value; --} -- --static int aw88399_init(struct aw88399 *aw88399, struct i2c_client *i2c, struct regmap *regmap) --{ -- struct aw_device *aw_dev; -- unsigned int chip_id; -- int ret; -- -- ret = regmap_read(regmap, AW88399_ID_REG, &chip_id); -- if (ret) { -- dev_err(&i2c->dev, "%s read chipid error. ret = %d", __func__, ret); -- return ret; -- } -- if (chip_id != AW88399_CHIP_ID) { -- dev_err(&i2c->dev, "unsupported device"); -- return -ENXIO; -- } -- dev_dbg(&i2c->dev, "chip id = %x\n", chip_id); -- -- aw_dev = devm_kzalloc(&i2c->dev, sizeof(*aw_dev), GFP_KERNEL); -- if (!aw_dev) -- return -ENOMEM; -- aw88399->aw_pa = aw_dev; -- -- aw_dev->i2c = i2c; -- aw_dev->dev = &i2c->dev; -- aw_dev->regmap = regmap; -- mutex_init(&aw_dev->dsp_lock); -- -- aw_dev->chip_id = chip_id; -- aw_dev->acf = NULL; -- aw_dev->prof_info.prof_desc = NULL; -- aw_dev->prof_info.count = 0; -- aw_dev->prof_info.prof_type = AW88395_DEV_NONE_TYPE_ID; -- aw_dev->channel = AW88399_DEV_DEFAULT_CH; -- aw_dev->fw_status = AW88399_DEV_FW_FAILED; -- -- aw_dev->fade_step = AW88399_VOLUME_STEP_DB; -- aw_dev->volume_desc.ctl_volume = AW88399_VOL_DEFAULT_VALUE; -- -- aw88399_parse_channel_dt(aw_dev); -- -- return 0; --} -- - static int aw88399_i2c_probe(struct i2c_client *i2c) - { - struct aw88399 *aw88399; -diff -ruN --no-dereference -x .git a/sound/soc/codecs/aw88399.h b/sound/soc/codecs/aw88399.h ---- a/sound/soc/codecs/aw88399.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/sound/soc/codecs/aw88399.h 2026-09-23 12:56:16.000000000 +0200 -@@ -10,512 +10,10 @@ - #ifndef __AW88399_H__ - #define __AW88399_H__ - --/* registers list */ --#define AW88399_ID_REG (0x00) --#define AW88399_SYSST_REG (0x01) --#define AW88399_SYSINT_REG (0x02) --#define AW88399_SYSINTM_REG (0x03) --#define AW88399_SYSCTRL_REG (0x04) --#define AW88399_SYSCTRL2_REG (0x05) --#define AW88399_I2SCTRL1_REG (0x06) --#define AW88399_I2SCTRL2_REG (0x07) --#define AW88399_I2SCTRL3_REG (0x08) --#define AW88399_DACCFG1_REG (0x09) --#define AW88399_DACCFG2_REG (0x0A) --#define AW88399_DACCFG3_REG (0x0B) --#define AW88399_DACCFG4_REG (0x0C) --#define AW88399_DACCFG5_REG (0x0D) --#define AW88399_DACCFG6_REG (0x0E) --#define AW88399_DACCFG7_REG (0x0F) --#define AW88399_MPDCFG1_REG (0x10) --#define AW88399_MPDCFG2_REG (0x11) --#define AW88399_MPDCFG3_REG (0x12) --#define AW88399_MPDCFG4_REG (0x13) --#define AW88399_PWMCTRL1_REG (0x14) --#define AW88399_PWMCTRL2_REG (0x15) --#define AW88399_PWMCTRL3_REG (0x16) --#define AW88399_I2SCFG1_REG (0x17) --#define AW88399_DBGCTRL_REG (0x18) --#define AW88399_HAGCST_REG (0x20) --#define AW88399_VBAT_REG (0x21) --#define AW88399_TEMP_REG (0x22) --#define AW88399_PVDD_REG (0x23) --#define AW88399_ISNDAT_REG (0x24) --#define AW88399_VSNDAT_REG (0x25) --#define AW88399_I2SINT_REG (0x26) --#define AW88399_I2SCAPCNT_REG (0x27) --#define AW88399_ANASTA1_REG (0x28) --#define AW88399_ANASTA2_REG (0x29) --#define AW88399_ANASTA3_REG (0x2A) --#define AW88399_TESTDET_REG (0x2B) --#define AW88399_DSMCFG1_REG (0x30) --#define AW88399_DSMCFG2_REG (0x31) --#define AW88399_DSMCFG3_REG (0x32) --#define AW88399_DSMCFG4_REG (0x33) --#define AW88399_DSMCFG5_REG (0x34) --#define AW88399_DSMCFG6_REG (0x35) --#define AW88399_DSMCFG7_REG (0x36) --#define AW88399_DSMCFG8_REG (0x37) --#define AW88399_TESTIN_REG (0x38) --#define AW88399_TESTOUT_REG (0x39) --#define AW88399_MEMTEST_REG (0x3A) --#define AW88399_VSNCTRL1_REG (0x3B) --#define AW88399_ISNCTRL1_REG (0x3C) --#define AW88399_ISNCTRL2_REG (0x3D) --#define AW88399_DSPMADD_REG (0x40) --#define AW88399_DSPMDAT_REG (0x41) --#define AW88399_WDT_REG (0x42) --#define AW88399_ACR1_REG (0x43) --#define AW88399_ACR2_REG (0x44) --#define AW88399_ASR1_REG (0x45) --#define AW88399_ASR2_REG (0x46) --#define AW88399_DSPCFG_REG (0x47) --#define AW88399_ASR3_REG (0x48) --#define AW88399_ASR4_REG (0x49) --#define AW88399_DSPVCALB_REG (0x4A) --#define AW88399_CRCCTRL_REG (0x4B) --#define AW88399_DSPDBG1_REG (0x4C) --#define AW88399_DSPDBG2_REG (0x4D) --#define AW88399_DSPDBG3_REG (0x4E) --#define AW88399_PLLCTRL1_REG (0x50) --#define AW88399_PLLCTRL2_REG (0x51) --#define AW88399_PLLCTRL3_REG (0x52) --#define AW88399_CDACTRL1_REG (0x53) --#define AW88399_CDACTRL2_REG (0x54) --#define AW88399_CDACTRL3_REG (0x55) --#define AW88399_SADCCTRL1_REG (0x56) --#define AW88399_SADCCTRL2_REG (0x57) --#define AW88399_BOPCTRL1_REG (0x58) --#define AW88399_BOPCTRL2_REG (0x5A) --#define AW88399_BOPCTRL3_REG (0x5B) --#define AW88399_BOPCTRL4_REG (0x5C) --#define AW88399_BOPCTRL5_REG (0x5D) --#define AW88399_BOPCTRL6_REG (0x5E) --#define AW88399_BOPCTRL7_REG (0x5F) --#define AW88399_BSTCTRL1_REG (0x60) --#define AW88399_BSTCTRL2_REG (0x61) --#define AW88399_BSTCTRL3_REG (0x62) --#define AW88399_BSTCTRL4_REG (0x63) --#define AW88399_BSTCTRL5_REG (0x64) --#define AW88399_BSTCTRL6_REG (0x65) --#define AW88399_BSTCTRL7_REG (0x66) --#define AW88399_BSTCTRL8_REG (0x67) --#define AW88399_BSTCTRL9_REG (0x68) --#define AW88399_BSTCTRL10_REG (0x69) --#define AW88399_CPCTRL_REG (0x6A) --#define AW88399_EFWH_REG (0x6C) --#define AW88399_EFWM2_REG (0x6D) --#define AW88399_EFWM1_REG (0x6E) --#define AW88399_EFWL_REG (0x6F) --#define AW88399_TESTCTRL1_REG (0x70) --#define AW88399_TESTCTRL2_REG (0x71) --#define AW88399_EFCTRL1_REG (0x72) --#define AW88399_EFCTRL2_REG (0x73) --#define AW88399_EFRH4_REG (0x74) --#define AW88399_EFRH3_REG (0x75) --#define AW88399_EFRH2_REG (0x76) --#define AW88399_EFRH1_REG (0x77) --#define AW88399_EFRL4_REG (0x78) --#define AW88399_EFRL3_REG (0x79) --#define AW88399_EFRL2_REG (0x7A) --#define AW88399_EFRL1_REG (0x7B) --#define AW88399_TM_REG (0x7C) --#define AW88399_TM2_REG (0x7D) -- --#define AW88399_REG_MAX (0x7E) --#define AW88399_MUTE_VOL (1023) -- --#define AW88399_DSP_CFG_ADDR (0x9B00) --#define AW88399_DSP_REG_CFG_ADPZ_RA (0x9B68) --#define AW88399_DSP_FW_ADDR (0x8980) --#define AW88399_DSP_ROM_CHECK_ADDR (0x1F40) --#define AW88399_DSP_ROM_CHECK_DATA (0x4638) -- --#define AW88399_CALI_RE_HBITS_MASK (~(0xFFFF0000)) --#define AW88399_CALI_RE_HBITS_SHIFT (16) -- --#define AW88399_CALI_RE_LBITS_MASK (~(0xFFFF)) --#define AW88399_CALI_RE_LBITS_SHIFT (0) -- --#define AW88399_I2STXEN_START_BIT (9) --#define AW88399_I2STXEN_BITS_LEN (1) --#define AW88399_I2STXEN_MASK \ -- (~(((1<> (shift)) --#define AW88399_SHOW_RE_TO_DSP_RE(re, shift) (((re) << shift) / (1000)) --#define AW88399_CRC_CHECK_PASS_VAL (0x4) -- --#define AW88399_CRC_CFG_BASE_ADDR (0xD80) --#define AW88399_CRC_FW_BASE_ADDR (0x4C0) --#define AW88399_ACF_FILE "aw88399_acf.bin" --#define AW88399_DEV_SYSST_CHECK_MAX (10) --#define AW88399_CHIP_ID 0x2183 -+#include - - #define AW88399_I2C_NAME "aw88399" - --#define AW88399_START_RETRIES (5) --#define AW88399_START_WORK_DELAY_MS (0) -- - #define AW88399_RATES (SNDRV_PCM_RATE_8000_48000 | \ - SNDRV_PCM_RATE_96000) - #define AW88399_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ -@@ -550,80 +48,4 @@ - .put = profile_set, \ - } - --enum { -- AW_EF_AND_CHECK = 0, -- AW_EF_OR_CHECK, --}; -- --enum { -- AW88399_DEV_VDSEL_DAC = 0, -- AW88399_DEV_VDSEL_VSENSE = 32, --}; -- --enum { -- AW88399_DSP_CRC_NA = 0, -- AW88399_DSP_CRC_OK = 1, --}; -- --enum { -- AW88399_DSP_FW_UPDATE_OFF = 0, -- AW88399_DSP_FW_UPDATE_ON = 1, --}; -- --enum { -- AW88399_FORCE_UPDATE_OFF = 0, -- AW88399_FORCE_UPDATE_ON = 1, --}; -- --enum { -- AW88399_1000_US = 1000, -- AW88399_2000_US = 2000, -- AW88399_3000_US = 3000, -- AW88399_4000_US = 4000, --}; -- --enum AW88399_DEV_STATUS { -- AW88399_DEV_PW_OFF = 0, -- AW88399_DEV_PW_ON, --}; -- --enum AW88399_DEV_FW_STATUS { -- AW88399_DEV_FW_FAILED = 0, -- AW88399_DEV_FW_OK, --}; -- --enum AW88399_DEV_MEMCLK { -- AW88399_DEV_MEMCLK_OSC = 0, -- AW88399_DEV_MEMCLK_PLL = 1, --}; -- --enum AW88399_DEV_DSP_CFG { -- AW88399_DEV_DSP_WORK = 0, -- AW88399_DEV_DSP_BYPASS = 1, --}; -- --enum { -- AW88399_NOT_RCV_MODE = 0, -- AW88399_RCV_MODE = 1, --}; -- --enum { -- AW88399_SYNC_START = 0, -- AW88399_ASYNC_START, --}; -- --struct aw88399 { -- struct aw_device *aw_pa; -- struct mutex lock; -- struct gpio_desc *reset_gpio; -- struct delayed_work start_work; -- struct regmap *regmap; -- struct aw_container *aw_cfg; -- -- unsigned int check_val; -- unsigned int crc_init_val; -- unsigned int vcalb_init_val; -- unsigned int dither_st; --}; -- --#endif -+#endif /* __AW88399_H__ */ ++config SND_SOC_AW88399_LIB ++ tristate ++ select SND_SOC_AW88395_LIB ++ + config SND_SOC_AW88399 + tristate "Soc Audio for awinic aw88399" + depends on I2C +@@ -733,6 +737,7 @@ + select REGMAP_I2C + select GPIOLIB + select SND_SOC_AW88395_LIB ++ select SND_SOC_AW88399_LIB + help + This option enables support for aw88399 Smart PA. + The awinic AW88399 is an I2S/TDM input, high efficiency +diff -ruN --no-dereference -x .git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile +--- a/sound/soc/codecs/Makefile 2026-08-16 23:32:26.000000000 +0200 ++++ b/sound/soc/codecs/Makefile 2026-10-03 14:48:53.000000000 +0200 +@@ -55,6 +55,7 @@ + snd-soc-aw88166-y := aw88166.o + snd-soc-aw88261-y := aw88261.o + snd-soc-aw88399-y := aw88399.o ++snd-soc-aw88399-lib-y := aw88399-lib.o + snd-soc-bd28623-y := bd28623.o + snd-soc-bt-sco-y := bt-sco.o + snd-soc-chv3-codec-y := chv3-codec.o +@@ -496,6 +497,7 @@ + obj-$(CONFIG_SND_SOC_AW88166) +=snd-soc-aw88166.o + obj-$(CONFIG_SND_SOC_AW88261) +=snd-soc-aw88261.o + obj-$(CONFIG_SND_SOC_AW88399) += snd-soc-aw88399.o ++obj-$(CONFIG_SND_SOC_AW88399_LIB) += snd-soc-aw88399-lib.o + obj-$(CONFIG_SND_SOC_BD28623) += snd-soc-bd28623.o + obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o + obj-$(CONFIG_SND_SOC_CHV3_CODEC) += snd-soc-chv3-codec.o diff -ruN --no-dereference -x .git a/sound/soc/codecs/aw88399-lib.c b/sound/soc/codecs/aw88399-lib.c --- a/sound/soc/codecs/aw88399-lib.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/sound/soc/codecs/aw88399-lib.c 2026-09-23 12:56:16.000000000 +0200 ++++ b/sound/soc/codecs/aw88399-lib.c 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,1411 @@ +// SPDX-License-Identifier: GPL-2.0-only +// @@ -42096,50 +40784,1987 @@ diff -ruN --no-dereference -x .git a/sound/soc/codecs/aw88399-lib.c b/sound/soc/ + +MODULE_DESCRIPTION("AW88399 common device library"); +MODULE_LICENSE("GPL"); -diff -ruN --no-dereference -x .git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig ---- a/sound/soc/codecs/Kconfig 2026-09-21 15:09:00.000000000 +0200 -+++ b/sound/soc/codecs/Kconfig 2026-09-23 12:56:16.000000000 +0200 -@@ -726,6 +726,10 @@ - sound quality, which is a new high efficiency, low - noise, constant large volume, 6th Smart K audio amplifier. +diff -ruN --no-dereference -x .git a/sound/soc/codecs/aw88399.c b/sound/soc/codecs/aw88399.c +--- a/sound/soc/codecs/aw88399.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/sound/soc/codecs/aw88399.c 2026-10-03 14:48:53.000000000 +0200 +@@ -10,1217 +10,12 @@ + #include + #include + #include +-#include +-#include + #include + #include + #include + #include "aw88399.h" + #include "aw88395/aw88395_device.h" -+config SND_SOC_AW88399_LIB -+ tristate -+ select SND_SOC_AW88395_LIB -+ - config SND_SOC_AW88399 - tristate "Soc Audio for awinic aw88399" - depends on I2C -@@ -733,6 +737,7 @@ - select REGMAP_I2C - select GPIOLIB - select SND_SOC_AW88395_LIB -+ select SND_SOC_AW88399_LIB - help - This option enables support for aw88399 Smart PA. - The awinic AW88399 is an I2S/TDM input, high efficiency -diff -ruN --no-dereference -x .git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile ---- a/sound/soc/codecs/Makefile 2026-09-21 15:09:00.000000000 +0200 -+++ b/sound/soc/codecs/Makefile 2026-09-23 12:56:16.000000000 +0200 -@@ -55,6 +55,7 @@ - snd-soc-aw88166-y := aw88166.o - snd-soc-aw88261-y := aw88261.o - snd-soc-aw88399-y := aw88399.o -+snd-soc-aw88399-lib-y := aw88399-lib.o - snd-soc-bd28623-y := bd28623.o - snd-soc-bt-sco-y := bt-sco.o - snd-soc-chv3-codec-y := chv3-codec.o -@@ -496,6 +497,7 @@ - obj-$(CONFIG_SND_SOC_AW88166) +=snd-soc-aw88166.o - obj-$(CONFIG_SND_SOC_AW88261) +=snd-soc-aw88261.o - obj-$(CONFIG_SND_SOC_AW88399) += snd-soc-aw88399.o -+obj-$(CONFIG_SND_SOC_AW88399_LIB) += snd-soc-aw88399-lib.o - obj-$(CONFIG_SND_SOC_BD28623) += snd-soc-bd28623.o - obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o - obj-$(CONFIG_SND_SOC_CHV3_CODEC) += snd-soc-chv3-codec.o +-static const struct regmap_config aw88399_remap_config = { +- .val_bits = 16, +- .reg_bits = 8, +- .max_register = AW88399_REG_MAX, +- .reg_format_endian = REGMAP_ENDIAN_LITTLE, +- .val_format_endian = REGMAP_ENDIAN_BIG, +-}; +- +-static void aw_dev_pwd(struct aw_device *aw_dev, bool pwd) +-{ +- int ret; +- +- if (pwd) +- ret = regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, +- ~AW88399_PWDN_MASK, AW88399_PWDN_POWER_DOWN_VALUE); +- else +- ret = regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, +- ~AW88399_PWDN_MASK, AW88399_PWDN_WORKING_VALUE); +- +- if (ret) +- dev_dbg(aw_dev->dev, "%s failed", __func__); +-} +- +-static void aw_dev_get_int_status(struct aw_device *aw_dev, unsigned short *int_status) +-{ +- unsigned int reg_val; +- int ret; +- +- ret = regmap_read(aw_dev->regmap, AW88399_SYSINT_REG, ®_val); +- if (ret) +- dev_err(aw_dev->dev, "read interrupt reg fail, ret=%d", ret); +- else +- *int_status = reg_val; +- +- dev_dbg(aw_dev->dev, "read interrupt reg=0x%04x", *int_status); +-} +- +-static void aw_dev_clear_int_status(struct aw_device *aw_dev) +-{ +- u16 int_status; +- +- /* read int status and clear */ +- aw_dev_get_int_status(aw_dev, &int_status); +- /* make sure int status is clear */ +- aw_dev_get_int_status(aw_dev, &int_status); +- if (int_status) +- dev_dbg(aw_dev->dev, "int status(%d) is not cleaned.\n", int_status); +-} +- +-static int aw_dev_get_iis_status(struct aw_device *aw_dev) +-{ +- unsigned int reg_val; +- int ret; +- +- ret = regmap_read(aw_dev->regmap, AW88399_SYSST_REG, ®_val); +- if (ret) +- return ret; +- if ((reg_val & AW88399_BIT_PLL_CHECK) != AW88399_BIT_PLL_CHECK) { +- dev_err(aw_dev->dev, "check pll lock fail, reg_val:0x%04x", reg_val); +- return -EINVAL; +- } +- +- return 0; +-} +- +-static int aw_dev_check_mode1_pll(struct aw_device *aw_dev) +-{ +- int ret, i; +- +- for (i = 0; i < AW88399_DEV_SYSST_CHECK_MAX; i++) { +- ret = aw_dev_get_iis_status(aw_dev); +- if (ret) { +- dev_err(aw_dev->dev, "mode1 iis signal check error"); +- usleep_range(AW88399_2000_US, AW88399_2000_US + 10); +- } else { +- return 0; +- } +- } +- +- return -EPERM; +-} +- +-static int aw_dev_check_mode2_pll(struct aw_device *aw_dev) +-{ +- unsigned int reg_val; +- int ret, i; +- +- ret = regmap_read(aw_dev->regmap, AW88399_PLLCTRL2_REG, ®_val); +- if (ret) +- return ret; +- +- reg_val &= (~AW88399_CCO_MUX_MASK); +- if (reg_val == AW88399_CCO_MUX_DIVIDED_VALUE) { +- dev_dbg(aw_dev->dev, "CCO_MUX is already divider"); +- return -EPERM; +- } +- +- /* change mode2 */ +- ret = regmap_update_bits(aw_dev->regmap, AW88399_PLLCTRL2_REG, +- ~AW88399_CCO_MUX_MASK, AW88399_CCO_MUX_DIVIDED_VALUE); +- if (ret) +- return ret; +- +- for (i = 0; i < AW88399_DEV_SYSST_CHECK_MAX; i++) { +- ret = aw_dev_get_iis_status(aw_dev); +- if (ret) { +- dev_err(aw_dev->dev, "mode2 iis signal check error"); +- usleep_range(AW88399_2000_US, AW88399_2000_US + 10); +- } else { +- break; +- } +- } +- +- /* change mode1 */ +- regmap_update_bits(aw_dev->regmap, AW88399_PLLCTRL2_REG, +- ~AW88399_CCO_MUX_MASK, AW88399_CCO_MUX_BYPASS_VALUE); +- if (ret == 0) { +- usleep_range(AW88399_2000_US, AW88399_2000_US + 10); +- for (i = 0; i < AW88399_DEV_SYSST_CHECK_MAX; i++) { +- ret = aw_dev_get_iis_status(aw_dev); +- if (ret) { +- dev_err(aw_dev->dev, "mode2 switch to mode1, iis signal check error"); +- usleep_range(AW88399_2000_US, AW88399_2000_US + 10); +- } else { +- break; +- } +- } +- } +- +- return ret; +-} +- +-static int aw_dev_check_syspll(struct aw_device *aw_dev) +-{ +- int ret; +- +- ret = aw_dev_check_mode1_pll(aw_dev); +- if (ret) { +- dev_dbg(aw_dev->dev, "mode1 check iis failed try switch to mode2 check"); +- ret = aw_dev_check_mode2_pll(aw_dev); +- if (ret) { +- dev_err(aw_dev->dev, "mode2 check iis failed"); +- return ret; +- } +- } +- +- return 0; +-} +- +-static int aw_dev_check_sysst(struct aw_device *aw_dev) +-{ +- unsigned int check_val; +- unsigned int reg_val; +- int ret, i; +- +- ret = regmap_read(aw_dev->regmap, AW88399_PWMCTRL3_REG, ®_val); +- if (ret) +- return ret; +- +- if (reg_val & (~AW88399_NOISE_GATE_EN_MASK)) +- check_val = AW88399_BIT_SYSST_NOSWS_CHECK; +- else +- check_val = AW88399_BIT_SYSST_SWS_CHECK; +- +- for (i = 0; i < AW88399_DEV_SYSST_CHECK_MAX; i++) { +- ret = regmap_read(aw_dev->regmap, AW88399_SYSST_REG, ®_val); +- if (ret) +- return ret; +- +- if ((reg_val & (~AW88399_BIT_SYSST_CHECK_MASK) & check_val) != check_val) { +- dev_err(aw_dev->dev, "check sysst fail, cnt=%d, reg_val=0x%04x, check:0x%x", +- i, reg_val, AW88399_BIT_SYSST_NOSWS_CHECK); +- usleep_range(AW88399_2000_US, AW88399_2000_US + 10); +- } else { +- return 0; +- } +- } +- +- return -EPERM; +-} +- +-static void aw_dev_amppd(struct aw_device *aw_dev, bool amppd) +-{ +- int ret; +- +- if (amppd) +- ret = regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, +- ~AW88399_AMPPD_MASK, AW88399_AMPPD_POWER_DOWN_VALUE); +- else +- ret = regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, +- ~AW88399_AMPPD_MASK, AW88399_AMPPD_WORKING_VALUE); +- +- if (ret) +- dev_dbg(aw_dev->dev, "%s failed", __func__); +-} +- +-static void aw_dev_dsp_enable(struct aw_device *aw_dev, bool is_enable) +-{ +- int ret; +- +- if (is_enable) +- ret = regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, +- ~AW88399_DSPBY_MASK, AW88399_DSPBY_WORKING_VALUE); +- else +- ret = regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, +- ~AW88399_DSPBY_MASK, AW88399_DSPBY_BYPASS_VALUE); +- +- if (ret) +- dev_dbg(aw_dev->dev, "%s failed\n", __func__); +-} +- +-static int aw88399_dev_get_icalk(struct aw88399 *aw88399, int16_t *icalk) +-{ +- uint16_t icalkh_val, icalkl_val, icalk_val; +- struct aw_device *aw_dev = aw88399->aw_pa; +- unsigned int reg_val; +- int ret; +- +- ret = regmap_read(aw_dev->regmap, AW88399_EFRH4_REG, ®_val); +- if (ret) +- return ret; +- icalkh_val = reg_val & (~AW88399_EF_ISN_GESLP_H_MASK); +- +- ret = regmap_read(aw_dev->regmap, AW88399_EFRL4_REG, ®_val); +- if (ret) +- return ret; +- icalkl_val = reg_val & (~AW88399_EF_ISN_GESLP_L_MASK); +- +- if (aw88399->check_val == AW_EF_AND_CHECK) +- icalk_val = icalkh_val & icalkl_val; +- else +- icalk_val = icalkh_val | icalkl_val; +- +- if (icalk_val & (~AW88399_EF_ISN_GESLP_SIGN_MASK)) +- icalk_val = icalk_val | AW88399_EF_ISN_GESLP_SIGN_NEG; +- *icalk = (int16_t)icalk_val; +- +- return 0; +-} +- +-static int aw88399_dev_get_vcalk(struct aw88399 *aw88399, int16_t *vcalk) +-{ +- uint16_t vcalkh_val, vcalkl_val, vcalk_val; +- struct aw_device *aw_dev = aw88399->aw_pa; +- unsigned int reg_val; +- int ret; +- +- ret = regmap_read(aw_dev->regmap, AW88399_EFRH3_REG, ®_val); +- if (ret) +- return ret; +- +- vcalkh_val = reg_val & (~AW88399_EF_VSN_GESLP_H_MASK); +- +- ret = regmap_read(aw_dev->regmap, AW88399_EFRL3_REG, ®_val); +- if (ret) +- return ret; +- +- vcalkl_val = reg_val & (~AW88399_EF_VSN_GESLP_L_MASK); +- +- if (aw88399->check_val == AW_EF_AND_CHECK) +- vcalk_val = vcalkh_val & vcalkl_val; +- else +- vcalk_val = vcalkh_val | vcalkl_val; +- +- if (vcalk_val & AW88399_EF_VSN_GESLP_SIGN_MASK) +- vcalk_val = vcalk_val | AW88399_EF_VSN_GESLP_SIGN_NEG; +- *vcalk = (int16_t)vcalk_val; +- +- return 0; +-} +- +-static int aw88399_dev_get_internal_vcalk(struct aw88399 *aw88399, int16_t *vcalk) +-{ +- uint16_t vcalkh_val, vcalkl_val, vcalk_val; +- struct aw_device *aw_dev = aw88399->aw_pa; +- unsigned int reg_val; +- int ret; +- +- ret = regmap_read(aw_dev->regmap, AW88399_EFRH2_REG, ®_val); +- if (ret) +- return ret; +- vcalkh_val = reg_val & (~AW88399_INTERNAL_VSN_TRIM_H_MASK); +- +- ret = regmap_read(aw_dev->regmap, AW88399_EFRL2_REG, ®_val); +- if (ret) +- return ret; +- vcalkl_val = reg_val & (~AW88399_INTERNAL_VSN_TRIM_L_MASK); +- +- if (aw88399->check_val == AW_EF_AND_CHECK) +- vcalk_val = (vcalkh_val >> AW88399_INTERNAL_VSN_TRIM_H_START_BIT) & +- (vcalkl_val >> AW88399_INTERNAL_VSN_TRIM_L_START_BIT); +- else +- vcalk_val = (vcalkh_val >> AW88399_INTERNAL_VSN_TRIM_H_START_BIT) | +- (vcalkl_val >> AW88399_INTERNAL_VSN_TRIM_L_START_BIT); +- +- if (vcalk_val & (~AW88399_TEM4_SIGN_MASK)) +- vcalk_val = vcalk_val | AW88399_TEM4_SIGN_NEG; +- +- *vcalk = (int16_t)vcalk_val; +- +- return 0; +-} +- +-static int aw_dev_set_vcalb(struct aw88399 *aw88399) +-{ +- struct aw_device *aw_dev = aw88399->aw_pa; +- unsigned int vsense_select, vsense_value; +- int32_t ical_k, vcal_k, vcalb; +- int16_t icalk, vcalk; +- uint16_t reg_val; +- int ret; +- +- ret = regmap_read(aw_dev->regmap, AW88399_VSNCTRL1_REG, &vsense_value); +- if (ret) +- return ret; +- +- vsense_select = vsense_value & (~AW88399_VDSEL_MASK); +- +- ret = aw88399_dev_get_icalk(aw88399, &icalk); +- if (ret) { +- dev_err(aw_dev->dev, "get icalk failed\n"); +- return ret; +- } +- +- ical_k = icalk * AW88399_ICABLK_FACTOR + AW88399_CABL_BASE_VALUE; +- +- switch (vsense_select) { +- case AW88399_DEV_VDSEL_VSENSE: +- ret = aw88399_dev_get_vcalk(aw88399, &vcalk); +- vcal_k = vcalk * AW88399_VCABLK_FACTOR + AW88399_CABL_BASE_VALUE; +- vcalb = AW88399_VCALB_ACCURACY * AW88399_VSCAL_FACTOR / AW88399_ISCAL_FACTOR * +- ical_k / vcal_k * aw88399->vcalb_init_val; +- break; +- case AW88399_DEV_VDSEL_DAC: +- ret = aw88399_dev_get_internal_vcalk(aw88399, &vcalk); +- vcal_k = vcalk * AW88399_VCABLK_DAC_FACTOR + AW88399_CABL_BASE_VALUE; +- vcalb = AW88399_VCALB_ACCURACY * AW88399_VSCAL_DAC_FACTOR / +- AW88399_ISCAL_DAC_FACTOR * ical_k / +- vcal_k * aw88399->vcalb_init_val; +- break; +- default: +- dev_err(aw_dev->dev, "%s: unsupported vsense\n", __func__); +- ret = -EINVAL; +- break; +- } +- if (ret) +- return ret; +- +- vcalb = vcalb >> AW88399_VCALB_ADJ_FACTOR; +- reg_val = (uint32_t)vcalb; +- +- regmap_write(aw_dev->regmap, AW88399_DSPVCALB_REG, reg_val); +- +- return 0; +-} +- +-static int aw_dev_update_cali_re(struct aw_cali_desc *cali_desc) +-{ +- struct aw_device *aw_dev = +- container_of(cali_desc, struct aw_device, cali_desc); +- uint16_t re_lbits, re_hbits; +- u32 cali_re; +- int ret; +- +- if ((aw_dev->cali_desc.cali_re >= AW88399_CALI_RE_MAX) || +- (aw_dev->cali_desc.cali_re <= AW88399_CALI_RE_MIN)) +- return -EINVAL; +- +- cali_re = AW88399_SHOW_RE_TO_DSP_RE((aw_dev->cali_desc.cali_re + +- aw_dev->cali_desc.ra), AW88399_DSP_RE_SHIFT); +- +- re_hbits = (cali_re & (~AW88399_CALI_RE_HBITS_MASK)) >> AW88399_CALI_RE_HBITS_SHIFT; +- re_lbits = (cali_re & (~AW88399_CALI_RE_LBITS_MASK)) >> AW88399_CALI_RE_LBITS_SHIFT; +- +- ret = regmap_write(aw_dev->regmap, AW88399_ACR1_REG, re_hbits); +- if (ret) { +- dev_err(aw_dev->dev, "set cali re error"); +- return ret; +- } +- +- ret = regmap_write(aw_dev->regmap, AW88399_ACR2_REG, re_lbits); +- if (ret) +- dev_err(aw_dev->dev, "set cali re error"); +- +- return ret; +-} +- +-static int aw_dev_fw_crc_check(struct aw_device *aw_dev) +-{ +- uint16_t check_val, fw_len_val; +- unsigned int reg_val; +- int ret; +- +- /* calculate fw_end_addr */ +- fw_len_val = ((aw_dev->dsp_fw_len / AW_FW_ADDR_LEN) - 1) + AW88399_CRC_FW_BASE_ADDR; +- +- /* write fw_end_addr to crc_end_addr */ +- ret = regmap_update_bits(aw_dev->regmap, AW88399_CRCCTRL_REG, +- ~AW88399_CRC_END_ADDR_MASK, fw_len_val); +- if (ret) +- return ret; +- /* enable fw crc check */ +- ret = regmap_update_bits(aw_dev->regmap, AW88399_CRCCTRL_REG, +- ~AW88399_CRC_CODE_EN_MASK, AW88399_CRC_CODE_EN_ENABLE_VALUE); +- +- usleep_range(AW88399_2000_US, AW88399_2000_US + 10); +- +- /* read crc check result */ +- regmap_read(aw_dev->regmap, AW88399_HAGCST_REG, ®_val); +- if (ret) +- return ret; +- +- check_val = (reg_val & (~AW88399_CRC_CHECK_BITS_MASK)) >> AW88399_CRC_CHECK_START_BIT; +- +- /* disable fw crc check */ +- ret = regmap_update_bits(aw_dev->regmap, AW88399_CRCCTRL_REG, +- ~AW88399_CRC_CODE_EN_MASK, AW88399_CRC_CODE_EN_DISABLE_VALUE); +- if (ret) +- return ret; +- +- if (check_val != AW88399_CRC_CHECK_PASS_VAL) { +- dev_err(aw_dev->dev, "%s failed, check_val 0x%x != 0x%x", +- __func__, check_val, AW88399_CRC_CHECK_PASS_VAL); +- ret = -EINVAL; +- } +- +- return ret; +-} +- +-static int aw_dev_cfg_crc_check(struct aw_device *aw_dev) +-{ +- uint16_t check_val, cfg_len_val; +- unsigned int reg_val; +- int ret; +- +- /* calculate cfg end addr */ +- cfg_len_val = ((aw_dev->dsp_cfg_len / AW_FW_ADDR_LEN) - 1) + AW88399_CRC_CFG_BASE_ADDR; +- +- /* write cfg_end_addr to crc_end_addr */ +- ret = regmap_update_bits(aw_dev->regmap, AW88399_CRCCTRL_REG, +- ~AW88399_CRC_END_ADDR_MASK, cfg_len_val); +- if (ret) +- return ret; +- +- /* enable cfg crc check */ +- ret = regmap_update_bits(aw_dev->regmap, AW88399_CRCCTRL_REG, +- ~AW88399_CRC_CFG_EN_MASK, AW88399_CRC_CFG_EN_ENABLE_VALUE); +- if (ret) +- return ret; +- +- usleep_range(AW88399_1000_US, AW88399_1000_US + 10); +- +- /* read crc check result */ +- ret = regmap_read(aw_dev->regmap, AW88399_HAGCST_REG, ®_val); +- if (ret) +- return ret; +- +- check_val = (reg_val & (~AW88399_CRC_CHECK_BITS_MASK)) >> AW88399_CRC_CHECK_START_BIT; +- +- /* disable cfg crc check */ +- ret = regmap_update_bits(aw_dev->regmap, AW88399_CRCCTRL_REG, +- ~AW88399_CRC_CFG_EN_MASK, AW88399_CRC_CFG_EN_DISABLE_VALUE); +- if (ret) +- return ret; +- +- if (check_val != AW88399_CRC_CHECK_PASS_VAL) { +- dev_err(aw_dev->dev, "crc_check failed, check val 0x%x != 0x%x", +- check_val, AW88399_CRC_CHECK_PASS_VAL); +- ret = -EINVAL; +- } +- +- return ret; +-} +- +-static int aw_dev_hw_crc_check(struct aw88399 *aw88399) +-{ +- struct aw_device *aw_dev = aw88399->aw_pa; +- int ret; +- +- ret = regmap_update_bits(aw_dev->regmap, AW88399_I2SCFG1_REG, +- ~AW88399_RAM_CG_BYP_MASK, AW88399_RAM_CG_BYP_BYPASS_VALUE); +- if (ret) +- return ret; +- +- ret = aw_dev_fw_crc_check(aw_dev); +- if (ret) { +- dev_err(aw_dev->dev, "fw_crc_check failed\n"); +- goto crc_check_failed; +- } +- +- ret = aw_dev_cfg_crc_check(aw_dev); +- if (ret) { +- dev_err(aw_dev->dev, "cfg_crc_check failed\n"); +- goto crc_check_failed; +- } +- +- ret = regmap_write(aw_dev->regmap, AW88399_CRCCTRL_REG, aw88399->crc_init_val); +- if (ret) +- return ret; +- +- ret = regmap_update_bits(aw_dev->regmap, AW88399_I2SCFG1_REG, +- ~AW88399_RAM_CG_BYP_MASK, AW88399_RAM_CG_BYP_WORK_VALUE); +- +- return ret; +- +-crc_check_failed: +- regmap_update_bits(aw_dev->regmap, AW88399_I2SCFG1_REG, +- ~AW88399_RAM_CG_BYP_MASK, AW88399_RAM_CG_BYP_WORK_VALUE); +- return ret; +-} +- +-static void aw_dev_i2s_tx_enable(struct aw_device *aw_dev, bool flag) +-{ +- int ret; +- +- if (flag) +- ret = regmap_update_bits(aw_dev->regmap, AW88399_I2SCTRL3_REG, +- ~AW88399_I2STXEN_MASK, AW88399_I2STXEN_ENABLE_VALUE); +- else +- ret = regmap_update_bits(aw_dev->regmap, AW88399_I2SCFG1_REG, +- ~AW88399_I2STXEN_MASK, AW88399_I2STXEN_DISABLE_VALUE); +- +- if (ret) +- dev_dbg(aw_dev->dev, "%s failed", __func__); +-} +- +-static int aw_dev_get_dsp_status(struct aw_device *aw_dev) +-{ +- unsigned int reg_val; +- int ret; +- +- ret = regmap_read(aw_dev->regmap, AW88399_WDT_REG, ®_val); +- if (ret) +- return ret; +- if (!(reg_val & (~AW88399_WDT_CNT_MASK))) +- return -EPERM; +- +- return 0; +-} +- +-static int aw_dev_dsp_check(struct aw_device *aw_dev) +-{ +- int ret, i; +- +- switch (aw_dev->dsp_cfg) { +- case AW88399_DEV_DSP_BYPASS: +- dev_dbg(aw_dev->dev, "dsp bypass"); +- ret = 0; +- break; +- case AW88399_DEV_DSP_WORK: +- aw_dev_dsp_enable(aw_dev, false); +- aw_dev_dsp_enable(aw_dev, true); +- usleep_range(AW88399_1000_US, AW88399_1000_US + 10); +- for (i = 0; i < AW88399_DEV_DSP_CHECK_MAX; i++) { +- ret = aw_dev_get_dsp_status(aw_dev); +- if (ret) { +- dev_err(aw_dev->dev, "dsp wdt status error=%d", ret); +- usleep_range(AW88399_2000_US, AW88399_2000_US + 10); +- } +- } +- break; +- default: +- dev_err(aw_dev->dev, "unknown dsp cfg=%d", aw_dev->dsp_cfg); +- ret = -EINVAL; +- break; +- } +- +- return ret; +-} +- +-static int aw_dev_set_volume(struct aw_device *aw_dev, unsigned int value) +-{ +- struct aw_volume_desc *vol_desc = &aw_dev->volume_desc; +- unsigned int reg_value; +- u16 real_value; +- int ret; +- +- real_value = min((value + vol_desc->init_volume), (unsigned int)AW88399_MUTE_VOL); +- +- ret = regmap_read(aw_dev->regmap, AW88399_SYSCTRL2_REG, ®_value); +- if (ret) +- return ret; +- +- dev_dbg(aw_dev->dev, "value 0x%x , reg:0x%x", value, real_value); +- +- real_value = (real_value << AW88399_VOL_START_BIT) | (reg_value & AW88399_VOL_MASK); +- +- ret = regmap_write(aw_dev->regmap, AW88399_SYSCTRL2_REG, real_value); +- +- return ret; +-} +- +-static void aw_dev_fade_in(struct aw_device *aw_dev) +-{ +- struct aw_volume_desc *desc = &aw_dev->volume_desc; +- u16 fade_in_vol = desc->ctl_volume; +- int fade_step = aw_dev->fade_step; +- int i; +- +- if (fade_step == 0 || aw_dev->fade_in_time == 0) { +- aw_dev_set_volume(aw_dev, fade_in_vol); +- return; +- } +- +- for (i = AW88399_MUTE_VOL; i >= fade_in_vol; i -= fade_step) { +- aw_dev_set_volume(aw_dev, i); +- usleep_range(aw_dev->fade_in_time, aw_dev->fade_in_time + 10); +- } +- +- if (i != fade_in_vol) +- aw_dev_set_volume(aw_dev, fade_in_vol); +-} +- +-static void aw_dev_fade_out(struct aw_device *aw_dev) +-{ +- struct aw_volume_desc *desc = &aw_dev->volume_desc; +- int fade_step = aw_dev->fade_step; +- int i; +- +- if (fade_step == 0 || aw_dev->fade_out_time == 0) { +- aw_dev_set_volume(aw_dev, AW88399_MUTE_VOL); +- return; +- } +- +- for (i = desc->ctl_volume; i <= AW88399_MUTE_VOL; i += fade_step) { +- aw_dev_set_volume(aw_dev, i); +- usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10); +- } +- +- if (i != AW88399_MUTE_VOL) { +- aw_dev_set_volume(aw_dev, AW88399_MUTE_VOL); +- usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10); +- } +-} +- +-static void aw88399_dev_mute(struct aw_device *aw_dev, bool is_mute) +-{ +- if (is_mute) { +- aw_dev_fade_out(aw_dev); +- regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, +- ~AW88399_HMUTE_MASK, AW88399_HMUTE_ENABLE_VALUE); +- } else { +- regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, +- ~AW88399_HMUTE_MASK, AW88399_HMUTE_DISABLE_VALUE); +- aw_dev_fade_in(aw_dev); +- } +-} +- +-static void aw88399_dev_set_dither(struct aw88399 *aw88399, bool dither) +-{ +- struct aw_device *aw_dev = aw88399->aw_pa; +- +- if (dither) +- regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, +- ~AW88399_DITHER_EN_MASK, AW88399_DITHER_EN_ENABLE_VALUE); +- else +- regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, +- ~AW88399_DITHER_EN_MASK, AW88399_DITHER_EN_DISABLE_VALUE); +-} +- +-static int aw88399_dev_start(struct aw88399 *aw88399) +-{ +- struct aw_device *aw_dev = aw88399->aw_pa; +- int ret; +- +- if (aw_dev->status == AW88399_DEV_PW_ON) { +- dev_dbg(aw_dev->dev, "already power on"); +- return 0; +- } +- +- aw88399_dev_set_dither(aw88399, false); +- +- /* power on */ +- aw_dev_pwd(aw_dev, false); +- usleep_range(AW88399_2000_US, AW88399_2000_US + 10); +- +- ret = aw_dev_check_syspll(aw_dev); +- if (ret) { +- dev_err(aw_dev->dev, "pll check failed cannot start"); +- goto pll_check_fail; +- } +- +- /* amppd on */ +- aw_dev_amppd(aw_dev, false); +- usleep_range(AW88399_1000_US, AW88399_1000_US + 50); +- +- /* check i2s status */ +- ret = aw_dev_check_sysst(aw_dev); +- if (ret) { +- dev_err(aw_dev->dev, "sysst check failed"); +- goto sysst_check_fail; +- } +- +- if (aw_dev->dsp_cfg == AW88399_DEV_DSP_WORK) { +- ret = aw_dev_hw_crc_check(aw88399); +- if (ret) { +- dev_err(aw_dev->dev, "dsp crc check failed"); +- goto crc_check_fail; +- } +- aw_dev_dsp_enable(aw_dev, false); +- aw_dev_set_vcalb(aw88399); +- aw_dev_update_cali_re(&aw_dev->cali_desc); +- +- ret = aw_dev_dsp_check(aw_dev); +- if (ret) { +- dev_err(aw_dev->dev, "dsp status check failed"); +- goto dsp_check_fail; +- } +- } else { +- dev_dbg(aw_dev->dev, "start pa with dsp bypass"); +- } +- +- /* enable tx feedback */ +- aw_dev_i2s_tx_enable(aw_dev, true); +- +- if (aw88399->dither_st == AW88399_DITHER_EN_ENABLE_VALUE) +- aw88399_dev_set_dither(aw88399, true); +- +- /* close mute */ +- aw88399_dev_mute(aw_dev, false); +- /* clear inturrupt */ +- aw_dev_clear_int_status(aw_dev); +- aw_dev->status = AW88399_DEV_PW_ON; +- +- return 0; +- +-dsp_check_fail: +-crc_check_fail: +- aw_dev_dsp_enable(aw_dev, false); +-sysst_check_fail: +- aw_dev_clear_int_status(aw_dev); +- aw_dev_amppd(aw_dev, true); +-pll_check_fail: +- aw_dev_pwd(aw_dev, true); +- aw_dev->status = AW88399_DEV_PW_OFF; +- +- return ret; +-} +- +-static int aw_dev_dsp_update_container(struct aw_device *aw_dev, +- unsigned char *data, unsigned int len, unsigned short base) +-{ +- u32 tmp_len; +- int i, ret; +- +- ret = regmap_write(aw_dev->regmap, AW88399_DSPMADD_REG, base); +- if (ret) +- return ret; +- +- for (i = 0; i < len; i += AW88399_MAX_RAM_WRITE_BYTE_SIZE) { +- tmp_len = min(len - i, AW88399_MAX_RAM_WRITE_BYTE_SIZE); +- ret = regmap_raw_write(aw_dev->regmap, AW88399_DSPMDAT_REG, +- &data[i], tmp_len); +- if (ret) +- return ret; +- } +- +- return 0; +-} +- +-static int aw_dev_get_ra(struct aw_cali_desc *cali_desc) +-{ +- struct aw_device *aw_dev = +- container_of(cali_desc, struct aw_device, cali_desc); +- u32 dsp_ra; +- int ret; +- +- ret = aw_dev_dsp_read(aw_dev, AW88399_DSP_REG_CFG_ADPZ_RA, +- &dsp_ra, AW_DSP_32_DATA); +- if (ret) { +- dev_err(aw_dev->dev, "read ra error"); +- return ret; +- } +- +- cali_desc->ra = AW88399_DSP_RE_TO_SHOW_RE(dsp_ra, +- AW88399_DSP_RE_SHIFT); +- +- return 0; +-} +- +-static int aw_dev_dsp_update_cfg(struct aw_device *aw_dev, +- unsigned char *data, unsigned int len) +-{ +- int ret; +- +- dev_dbg(aw_dev->dev, "dsp config len:%d", len); +- +- if (!len || !data) { +- dev_err(aw_dev->dev, "dsp config data is null or len is 0"); +- return -EINVAL; +- } +- +- ret = aw_dev_dsp_update_container(aw_dev, data, len, AW88399_DSP_CFG_ADDR); +- if (ret) +- return ret; +- +- aw_dev->dsp_cfg_len = len; +- +- ret = aw_dev_get_ra(&aw_dev->cali_desc); +- +- return ret; +-} +- +-static int aw_dev_dsp_update_fw(struct aw_device *aw_dev, +- unsigned char *data, unsigned int len) +-{ +- int ret; +- +- dev_dbg(aw_dev->dev, "dsp firmware len:%d", len); +- +- if (!len || !data) { +- dev_err(aw_dev->dev, "dsp firmware data is null or len is 0"); +- return -EINVAL; +- } +- +- aw_dev->dsp_fw_len = len; +- ret = aw_dev_dsp_update_container(aw_dev, data, len, AW88399_DSP_FW_ADDR); +- +- return ret; +-} +- +-static int aw_dev_check_sram(struct aw_device *aw_dev) +-{ +- unsigned int reg_val; +- +- /* read dsp_rom_check_reg */ +- aw_dev_dsp_read(aw_dev, AW88399_DSP_ROM_CHECK_ADDR, ®_val, AW_DSP_16_DATA); +- if (reg_val != AW88399_DSP_ROM_CHECK_DATA) { +- dev_err(aw_dev->dev, "check dsp rom failed, read[0x%x] != check[0x%x]", +- reg_val, AW88399_DSP_ROM_CHECK_DATA); +- return -EPERM; +- } +- +- /* check dsp_cfg_base_addr */ +- aw_dev_dsp_write(aw_dev, AW88399_DSP_CFG_ADDR, +- AW88399_DSP_ODD_NUM_BIT_TEST, AW_DSP_16_DATA); +- aw_dev_dsp_read(aw_dev, AW88399_DSP_CFG_ADDR, ®_val, AW_DSP_16_DATA); +- if (reg_val != AW88399_DSP_ODD_NUM_BIT_TEST) { +- dev_err(aw_dev->dev, "check dsp cfg failed, read[0x%x] != write[0x%x]", +- reg_val, AW88399_DSP_ODD_NUM_BIT_TEST); +- return -EPERM; +- } +- +- return 0; +-} +- +-static void aw_dev_select_memclk(struct aw_device *aw_dev, unsigned char flag) +-{ +- int ret; +- +- switch (flag) { +- case AW88399_DEV_MEMCLK_PLL: +- ret = regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, +- ~AW88399_MEM_CLKSEL_MASK, +- AW88399_MEM_CLKSEL_DAPHCLK_VALUE); +- if (ret) +- dev_err(aw_dev->dev, "memclk select pll failed"); +- break; +- case AW88399_DEV_MEMCLK_OSC: +- ret = regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, +- ~AW88399_MEM_CLKSEL_MASK, +- AW88399_MEM_CLKSEL_OSCCLK_VALUE); +- if (ret) +- dev_err(aw_dev->dev, "memclk select OSC failed"); +- break; +- default: +- dev_err(aw_dev->dev, "unknown memclk config, flag=0x%x", flag); +- break; +- } +-} +- +-static void aw_dev_get_cur_mode_st(struct aw_device *aw_dev) +-{ +- struct aw_profctrl_desc *profctrl_desc = &aw_dev->profctrl_desc; +- unsigned int reg_val; +- int ret; +- +- ret = regmap_read(aw_dev->regmap, AW88399_SYSCTRL_REG, ®_val); +- if (ret) { +- dev_dbg(aw_dev->dev, "%s failed", __func__); +- return; +- } +- if ((reg_val & (~AW88399_RCV_MODE_MASK)) == AW88399_RCV_MODE_RECEIVER_VALUE) +- profctrl_desc->cur_mode = AW88399_RCV_MODE; +- else +- profctrl_desc->cur_mode = AW88399_NOT_RCV_MODE; +-} +- +-static int aw_dev_update_reg_container(struct aw88399 *aw88399, +- unsigned char *data, unsigned int len) +-{ +- struct aw_device *aw_dev = aw88399->aw_pa; +- struct aw_volume_desc *vol_desc = &aw_dev->volume_desc; +- u16 read_vol, reg_val; +- int data_len, i, ret; +- int16_t *reg_data; +- u8 reg_addr; +- +- reg_data = (int16_t *)data; +- data_len = len >> 1; +- +- if (data_len & 0x1) { +- dev_err(aw_dev->dev, "data len:%d unsupported", data_len); +- return -EINVAL; +- } +- +- for (i = 0; i < data_len; i += 2) { +- reg_addr = reg_data[i]; +- reg_val = reg_data[i + 1]; +- +- if (reg_addr == AW88399_DSPVCALB_REG) { +- aw88399->vcalb_init_val = reg_val; +- continue; +- } +- +- if (reg_addr == AW88399_SYSCTRL_REG) { +- if (reg_val & (~AW88399_DSPBY_MASK)) +- aw_dev->dsp_cfg = AW88399_DEV_DSP_BYPASS; +- else +- aw_dev->dsp_cfg = AW88399_DEV_DSP_WORK; +- +- reg_val &= (AW88399_HMUTE_MASK | AW88399_PWDN_MASK | +- AW88399_DSPBY_MASK); +- reg_val |= (AW88399_HMUTE_ENABLE_VALUE | AW88399_PWDN_POWER_DOWN_VALUE | +- AW88399_DSPBY_BYPASS_VALUE); +- } +- +- if (reg_addr == AW88399_I2SCTRL3_REG) { +- reg_val &= AW88399_I2STXEN_MASK; +- reg_val |= AW88399_I2STXEN_DISABLE_VALUE; +- } +- +- if (reg_addr == AW88399_SYSCTRL2_REG) { +- read_vol = (reg_val & (~AW88399_VOL_MASK)) >> +- AW88399_VOL_START_BIT; +- aw_dev->volume_desc.init_volume = read_vol; +- } +- +- if (reg_addr == AW88399_DBGCTRL_REG) { +- if ((reg_val & (~AW88399_EF_DBMD_MASK)) == AW88399_EF_DBMD_OR_VALUE) +- aw88399->check_val = AW_EF_OR_CHECK; +- else +- aw88399->check_val = AW_EF_AND_CHECK; +- +- aw88399->dither_st = reg_val & (~AW88399_DITHER_EN_MASK); +- } +- +- if (reg_addr == AW88399_CRCCTRL_REG) +- aw88399->crc_init_val = reg_val; +- +- ret = regmap_write(aw_dev->regmap, reg_addr, reg_val); +- if (ret) +- return ret; +- } +- +- aw_dev_pwd(aw_dev, false); +- usleep_range(AW88399_1000_US, AW88399_1000_US + 10); +- +- aw_dev_get_cur_mode_st(aw_dev); +- +- if (aw_dev->prof_cur != aw_dev->prof_index) +- vol_desc->ctl_volume = 0; +- else +- aw_dev_set_volume(aw_dev, vol_desc->ctl_volume); +- +- return 0; +-} +- +-static int aw_dev_reg_update(struct aw88399 *aw88399, +- unsigned char *data, unsigned int len) +-{ +- int ret; +- +- if (!len || !data) { +- dev_err(aw88399->aw_pa->dev, "reg data is null or len is 0"); +- return -EINVAL; +- } +- +- ret = aw_dev_update_reg_container(aw88399, data, len); +- if (ret) +- dev_err(aw88399->aw_pa->dev, "reg update failed"); +- +- return ret; +-} +- +-static int aw88399_dev_get_prof_name(struct aw_device *aw_dev, int index, char **prof_name) +-{ +- struct aw_prof_info *prof_info = &aw_dev->prof_info; +- struct aw_prof_desc *prof_desc; +- +- if ((index >= aw_dev->prof_info.count) || (index < 0)) { +- dev_err(aw_dev->dev, "index[%d] overflow count[%d]", +- index, aw_dev->prof_info.count); +- return -EINVAL; +- } +- +- prof_desc = &aw_dev->prof_info.prof_desc[index]; +- +- *prof_name = prof_info->prof_name_list[prof_desc->id]; +- +- return 0; +-} +- +-static int aw88399_dev_get_prof_data(struct aw_device *aw_dev, int index, +- struct aw_prof_desc **prof_desc) +-{ +- if ((index >= aw_dev->prof_info.count) || (index < 0)) { +- dev_err(aw_dev->dev, "%s: index[%d] overflow count[%d]\n", +- __func__, index, aw_dev->prof_info.count); +- return -EINVAL; +- } +- +- *prof_desc = &aw_dev->prof_info.prof_desc[index]; +- +- return 0; +-} +- +-static int aw88399_dev_fw_update(struct aw88399 *aw88399, bool up_dsp_fw_en, bool force_up_en) +-{ +- struct aw_device *aw_dev = aw88399->aw_pa; +- struct aw_prof_desc *prof_index_desc; +- struct aw_sec_data_desc *sec_desc; +- char *prof_name; +- int ret; +- +- if ((aw_dev->prof_cur == aw_dev->prof_index) && +- (force_up_en == AW88399_FORCE_UPDATE_OFF)) { +- dev_dbg(aw_dev->dev, "scene no change, not update"); +- return 0; +- } +- +- if (aw_dev->fw_status == AW88399_DEV_FW_FAILED) { +- dev_err(aw_dev->dev, "fw status[%d] error", aw_dev->fw_status); +- return -EPERM; +- } +- +- ret = aw88399_dev_get_prof_name(aw_dev, aw_dev->prof_index, &prof_name); +- if (ret) +- return ret; +- +- dev_dbg(aw_dev->dev, "start update %s", prof_name); +- +- ret = aw88399_dev_get_prof_data(aw_dev, aw_dev->prof_index, &prof_index_desc); +- if (ret) +- return ret; +- +- /* update reg */ +- sec_desc = prof_index_desc->sec_desc; +- ret = aw_dev_reg_update(aw88399, sec_desc[AW88395_DATA_TYPE_REG].data, +- sec_desc[AW88395_DATA_TYPE_REG].len); +- if (ret) { +- dev_err(aw_dev->dev, "update reg failed"); +- return ret; +- } +- +- aw88399_dev_mute(aw_dev, true); +- +- if (aw_dev->dsp_cfg == AW88399_DEV_DSP_WORK) +- aw_dev_dsp_enable(aw_dev, false); +- +- aw_dev_select_memclk(aw_dev, AW88399_DEV_MEMCLK_OSC); +- +- ret = aw_dev_check_sram(aw_dev); +- if (ret) { +- dev_err(aw_dev->dev, "check sram failed"); +- goto error; +- } +- +- if (up_dsp_fw_en) { +- dev_dbg(aw_dev->dev, "fw_ver: [%x]", prof_index_desc->fw_ver); +- ret = aw_dev_dsp_update_fw(aw_dev, sec_desc[AW88395_DATA_TYPE_DSP_FW].data, +- sec_desc[AW88395_DATA_TYPE_DSP_FW].len); +- if (ret) { +- dev_err(aw_dev->dev, "update dsp fw failed"); +- goto error; +- } +- } +- +- /* update dsp config */ +- ret = aw_dev_dsp_update_cfg(aw_dev, sec_desc[AW88395_DATA_TYPE_DSP_CFG].data, +- sec_desc[AW88395_DATA_TYPE_DSP_CFG].len); +- if (ret) { +- dev_err(aw_dev->dev, "update dsp cfg failed"); +- goto error; +- } +- +- aw_dev_select_memclk(aw_dev, AW88399_DEV_MEMCLK_PLL); +- +- aw_dev->prof_cur = aw_dev->prof_index; +- +- return 0; +- +-error: +- aw_dev_select_memclk(aw_dev, AW88399_DEV_MEMCLK_PLL); +- return ret; +-} +- +-static void aw88399_start_pa(struct aw88399 *aw88399) +-{ +- int ret, i; +- +- for (i = 0; i < AW88399_START_RETRIES; i++) { +- ret = aw88399_dev_start(aw88399); +- if (ret) { +- dev_err(aw88399->aw_pa->dev, "aw88399 device start failed. retry = %d", i); +- ret = aw88399_dev_fw_update(aw88399, AW88399_DSP_FW_UPDATE_ON, true); +- if (ret) { +- dev_err(aw88399->aw_pa->dev, "fw update failed"); +- continue; +- } +- } else { +- dev_dbg(aw88399->aw_pa->dev, "start success\n"); +- break; +- } +- } +-} +- +-static void aw88399_startup_work(struct work_struct *work) +-{ +- struct aw88399 *aw88399 = +- container_of(work, struct aw88399, start_work.work); +- +- mutex_lock(&aw88399->lock); +- aw88399_start_pa(aw88399); +- mutex_unlock(&aw88399->lock); +-} +- +-static void aw88399_start(struct aw88399 *aw88399, bool sync_start) +-{ +- int ret; +- +- if (aw88399->aw_pa->fw_status != AW88399_DEV_FW_OK) +- return; +- +- if (aw88399->aw_pa->status == AW88399_DEV_PW_ON) +- return; +- +- ret = aw88399_dev_fw_update(aw88399, AW88399_DSP_FW_UPDATE_OFF, true); +- if (ret) { +- dev_err(aw88399->aw_pa->dev, "fw update failed."); +- return; +- } +- +- if (sync_start == AW88399_SYNC_START) +- aw88399_start_pa(aw88399); +- else +- queue_delayed_work(system_dfl_wq, +- &aw88399->start_work, +- AW88399_START_WORK_DELAY_MS); +-} +- +-static int aw_dev_check_sysint(struct aw_device *aw_dev) +-{ +- u16 reg_val; +- +- aw_dev_get_int_status(aw_dev, ®_val); +- if (reg_val & AW88399_BIT_SYSINT_CHECK) { +- dev_err(aw_dev->dev, "pa stop check fail:0x%04x", reg_val); +- return -EINVAL; +- } +- +- return 0; +-} +- +-static int aw88399_stop(struct aw_device *aw_dev) +-{ +- struct aw_sec_data_desc *dsp_cfg = +- &aw_dev->prof_info.prof_desc[aw_dev->prof_cur].sec_desc[AW88395_DATA_TYPE_DSP_CFG]; +- struct aw_sec_data_desc *dsp_fw = +- &aw_dev->prof_info.prof_desc[aw_dev->prof_cur].sec_desc[AW88395_DATA_TYPE_DSP_FW]; +- int int_st; +- +- if (aw_dev->status == AW88399_DEV_PW_OFF) { +- dev_dbg(aw_dev->dev, "already power off"); +- return 0; +- } +- +- aw_dev->status = AW88399_DEV_PW_OFF; +- +- aw88399_dev_mute(aw_dev, true); +- usleep_range(AW88399_4000_US, AW88399_4000_US + 100); +- +- aw_dev_i2s_tx_enable(aw_dev, false); +- usleep_range(AW88399_1000_US, AW88399_1000_US + 100); +- +- int_st = aw_dev_check_sysint(aw_dev); +- +- aw_dev_dsp_enable(aw_dev, false); +- +- aw_dev_amppd(aw_dev, true); +- +- if (int_st) { +- aw_dev_select_memclk(aw_dev, AW88399_DEV_MEMCLK_OSC); +- aw_dev_dsp_update_fw(aw_dev, dsp_fw->data, dsp_fw->len); +- aw_dev_dsp_update_cfg(aw_dev, dsp_cfg->data, dsp_cfg->len); +- aw_dev_select_memclk(aw_dev, AW88399_DEV_MEMCLK_PLL); +- } +- +- aw_dev_pwd(aw_dev, true); +- +- return 0; +-} +- + static struct snd_soc_dai_driver aw88399_dai[] = { + { + .name = "aw88399-aif", +@@ -1869,86 +664,6 @@ + return 0; + } + +-static int aw88399_dev_init(struct aw88399 *aw88399, struct aw_container *aw_cfg) +-{ +- struct aw_device *aw_dev = aw88399->aw_pa; +- int ret; +- +- ret = aw88395_dev_cfg_load(aw_dev, aw_cfg); +- if (ret) { +- dev_err(aw_dev->dev, "aw_dev acf parse failed"); +- return -EINVAL; +- } +- aw_dev->fade_in_time = AW88399_1000_US / 10; +- aw_dev->fade_out_time = AW88399_1000_US >> 1; +- aw_dev->prof_cur = aw_dev->prof_info.prof_desc[0].id; +- aw_dev->prof_index = aw_dev->prof_info.prof_desc[0].id; +- +- ret = aw88399_dev_fw_update(aw88399, AW88399_FORCE_UPDATE_ON, AW88399_DSP_FW_UPDATE_ON); +- if (ret) { +- dev_err(aw_dev->dev, "fw update failed ret = %d\n", ret); +- return ret; +- } +- +- aw88399_dev_mute(aw_dev, true); +- +- /* close tx feedback */ +- aw_dev_i2s_tx_enable(aw_dev, false); +- usleep_range(AW88399_1000_US, AW88399_1000_US + 100); +- +- /* enable amppd */ +- aw_dev_amppd(aw_dev, true); +- +- /* close dsp */ +- aw_dev_dsp_enable(aw_dev, false); +- /* set power down */ +- aw_dev_pwd(aw_dev, true); +- +- return 0; +-} +- +-static int aw88399_request_firmware_file(struct aw88399 *aw88399) +-{ +- const struct firmware *cont = NULL; +- int ret; +- +- aw88399->aw_pa->fw_status = AW88399_DEV_FW_FAILED; +- +- ret = request_firmware(&cont, AW88399_ACF_FILE, aw88399->aw_pa->dev); +- if (ret) { +- dev_err(aw88399->aw_pa->dev, "request [%s] failed!", AW88399_ACF_FILE); +- return ret; +- } +- +- dev_dbg(aw88399->aw_pa->dev, "loaded %s - size: %zu\n", +- AW88399_ACF_FILE, cont ? cont->size : 0); +- +- aw88399->aw_cfg = devm_kzalloc(aw88399->aw_pa->dev, +- struct_size(aw88399->aw_cfg, data, cont->size), GFP_KERNEL); +- if (!aw88399->aw_cfg) { +- release_firmware(cont); +- return -ENOMEM; +- } +- aw88399->aw_cfg->len = (int)cont->size; +- memcpy(aw88399->aw_cfg->data, cont->data, cont->size); +- release_firmware(cont); +- +- ret = aw88395_dev_load_acf_check(aw88399->aw_pa, aw88399->aw_cfg); +- if (ret) { +- dev_err(aw88399->aw_pa->dev, "load [%s] failed!", AW88399_ACF_FILE); +- return ret; +- } +- +- mutex_lock(&aw88399->lock); +- /* aw device init */ +- ret = aw88399_dev_init(aw88399, aw88399->aw_cfg); +- if (ret) +- dev_err(aw88399->aw_pa->dev, "dev init failed"); +- mutex_unlock(&aw88399->lock); +- +- return ret; +-} +- + static const struct snd_kcontrol_new aw88399_controls[] = { + SOC_SINGLE_EXT("PCM Playback Volume", AW88399_SYSCTRL2_REG, + 6, AW88399_MUTE_VOL, 0, aw88399_volume_get, +@@ -2040,70 +755,6 @@ + .num_controls = ARRAY_SIZE(aw88399_controls), + }; + +-static void aw88399_hw_reset(struct aw88399 *aw88399) +-{ +- if (aw88399->reset_gpio) { +- gpiod_set_value_cansleep(aw88399->reset_gpio, 1); +- usleep_range(AW88399_1000_US, AW88399_1000_US + 10); +- gpiod_set_value_cansleep(aw88399->reset_gpio, 0); +- usleep_range(AW88399_1000_US, AW88399_1000_US + 10); +- gpiod_set_value_cansleep(aw88399->reset_gpio, 1); +- usleep_range(AW88399_1000_US, AW88399_1000_US + 10); +- } +-} +- +-static void aw88399_parse_channel_dt(struct aw_device *aw_dev) +-{ +- struct device_node *np = aw_dev->dev->of_node; +- u32 channel_value; +- +- of_property_read_u32(np, "awinic,audio-channel", &channel_value); +- aw_dev->channel = channel_value; +-} +- +-static int aw88399_init(struct aw88399 *aw88399, struct i2c_client *i2c, struct regmap *regmap) +-{ +- struct aw_device *aw_dev; +- unsigned int chip_id; +- int ret; +- +- ret = regmap_read(regmap, AW88399_ID_REG, &chip_id); +- if (ret) { +- dev_err(&i2c->dev, "%s read chipid error. ret = %d", __func__, ret); +- return ret; +- } +- if (chip_id != AW88399_CHIP_ID) { +- dev_err(&i2c->dev, "unsupported device"); +- return -ENXIO; +- } +- dev_dbg(&i2c->dev, "chip id = %x\n", chip_id); +- +- aw_dev = devm_kzalloc(&i2c->dev, sizeof(*aw_dev), GFP_KERNEL); +- if (!aw_dev) +- return -ENOMEM; +- aw88399->aw_pa = aw_dev; +- +- aw_dev->i2c = i2c; +- aw_dev->dev = &i2c->dev; +- aw_dev->regmap = regmap; +- mutex_init(&aw_dev->dsp_lock); +- +- aw_dev->chip_id = chip_id; +- aw_dev->acf = NULL; +- aw_dev->prof_info.prof_desc = NULL; +- aw_dev->prof_info.count = 0; +- aw_dev->prof_info.prof_type = AW88395_DEV_NONE_TYPE_ID; +- aw_dev->channel = AW88399_DEV_DEFAULT_CH; +- aw_dev->fw_status = AW88399_DEV_FW_FAILED; +- +- aw_dev->fade_step = AW88399_VOLUME_STEP_DB; +- aw_dev->volume_desc.ctl_volume = AW88399_VOL_DEFAULT_VALUE; +- +- aw88399_parse_channel_dt(aw_dev); +- +- return 0; +-} +- + static int aw88399_i2c_probe(struct i2c_client *i2c) + { + struct aw88399 *aw88399; +diff -ruN --no-dereference -x .git a/sound/soc/codecs/aw88399.h b/sound/soc/codecs/aw88399.h +--- a/sound/soc/codecs/aw88399.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/sound/soc/codecs/aw88399.h 2026-10-03 14:48:53.000000000 +0200 +@@ -10,512 +10,10 @@ + #ifndef __AW88399_H__ + #define __AW88399_H__ + +-/* registers list */ +-#define AW88399_ID_REG (0x00) +-#define AW88399_SYSST_REG (0x01) +-#define AW88399_SYSINT_REG (0x02) +-#define AW88399_SYSINTM_REG (0x03) +-#define AW88399_SYSCTRL_REG (0x04) +-#define AW88399_SYSCTRL2_REG (0x05) +-#define AW88399_I2SCTRL1_REG (0x06) +-#define AW88399_I2SCTRL2_REG (0x07) +-#define AW88399_I2SCTRL3_REG (0x08) +-#define AW88399_DACCFG1_REG (0x09) +-#define AW88399_DACCFG2_REG (0x0A) +-#define AW88399_DACCFG3_REG (0x0B) +-#define AW88399_DACCFG4_REG (0x0C) +-#define AW88399_DACCFG5_REG (0x0D) +-#define AW88399_DACCFG6_REG (0x0E) +-#define AW88399_DACCFG7_REG (0x0F) +-#define AW88399_MPDCFG1_REG (0x10) +-#define AW88399_MPDCFG2_REG (0x11) +-#define AW88399_MPDCFG3_REG (0x12) +-#define AW88399_MPDCFG4_REG (0x13) +-#define AW88399_PWMCTRL1_REG (0x14) +-#define AW88399_PWMCTRL2_REG (0x15) +-#define AW88399_PWMCTRL3_REG (0x16) +-#define AW88399_I2SCFG1_REG (0x17) +-#define AW88399_DBGCTRL_REG (0x18) +-#define AW88399_HAGCST_REG (0x20) +-#define AW88399_VBAT_REG (0x21) +-#define AW88399_TEMP_REG (0x22) +-#define AW88399_PVDD_REG (0x23) +-#define AW88399_ISNDAT_REG (0x24) +-#define AW88399_VSNDAT_REG (0x25) +-#define AW88399_I2SINT_REG (0x26) +-#define AW88399_I2SCAPCNT_REG (0x27) +-#define AW88399_ANASTA1_REG (0x28) +-#define AW88399_ANASTA2_REG (0x29) +-#define AW88399_ANASTA3_REG (0x2A) +-#define AW88399_TESTDET_REG (0x2B) +-#define AW88399_DSMCFG1_REG (0x30) +-#define AW88399_DSMCFG2_REG (0x31) +-#define AW88399_DSMCFG3_REG (0x32) +-#define AW88399_DSMCFG4_REG (0x33) +-#define AW88399_DSMCFG5_REG (0x34) +-#define AW88399_DSMCFG6_REG (0x35) +-#define AW88399_DSMCFG7_REG (0x36) +-#define AW88399_DSMCFG8_REG (0x37) +-#define AW88399_TESTIN_REG (0x38) +-#define AW88399_TESTOUT_REG (0x39) +-#define AW88399_MEMTEST_REG (0x3A) +-#define AW88399_VSNCTRL1_REG (0x3B) +-#define AW88399_ISNCTRL1_REG (0x3C) +-#define AW88399_ISNCTRL2_REG (0x3D) +-#define AW88399_DSPMADD_REG (0x40) +-#define AW88399_DSPMDAT_REG (0x41) +-#define AW88399_WDT_REG (0x42) +-#define AW88399_ACR1_REG (0x43) +-#define AW88399_ACR2_REG (0x44) +-#define AW88399_ASR1_REG (0x45) +-#define AW88399_ASR2_REG (0x46) +-#define AW88399_DSPCFG_REG (0x47) +-#define AW88399_ASR3_REG (0x48) +-#define AW88399_ASR4_REG (0x49) +-#define AW88399_DSPVCALB_REG (0x4A) +-#define AW88399_CRCCTRL_REG (0x4B) +-#define AW88399_DSPDBG1_REG (0x4C) +-#define AW88399_DSPDBG2_REG (0x4D) +-#define AW88399_DSPDBG3_REG (0x4E) +-#define AW88399_PLLCTRL1_REG (0x50) +-#define AW88399_PLLCTRL2_REG (0x51) +-#define AW88399_PLLCTRL3_REG (0x52) +-#define AW88399_CDACTRL1_REG (0x53) +-#define AW88399_CDACTRL2_REG (0x54) +-#define AW88399_CDACTRL3_REG (0x55) +-#define AW88399_SADCCTRL1_REG (0x56) +-#define AW88399_SADCCTRL2_REG (0x57) +-#define AW88399_BOPCTRL1_REG (0x58) +-#define AW88399_BOPCTRL2_REG (0x5A) +-#define AW88399_BOPCTRL3_REG (0x5B) +-#define AW88399_BOPCTRL4_REG (0x5C) +-#define AW88399_BOPCTRL5_REG (0x5D) +-#define AW88399_BOPCTRL6_REG (0x5E) +-#define AW88399_BOPCTRL7_REG (0x5F) +-#define AW88399_BSTCTRL1_REG (0x60) +-#define AW88399_BSTCTRL2_REG (0x61) +-#define AW88399_BSTCTRL3_REG (0x62) +-#define AW88399_BSTCTRL4_REG (0x63) +-#define AW88399_BSTCTRL5_REG (0x64) +-#define AW88399_BSTCTRL6_REG (0x65) +-#define AW88399_BSTCTRL7_REG (0x66) +-#define AW88399_BSTCTRL8_REG (0x67) +-#define AW88399_BSTCTRL9_REG (0x68) +-#define AW88399_BSTCTRL10_REG (0x69) +-#define AW88399_CPCTRL_REG (0x6A) +-#define AW88399_EFWH_REG (0x6C) +-#define AW88399_EFWM2_REG (0x6D) +-#define AW88399_EFWM1_REG (0x6E) +-#define AW88399_EFWL_REG (0x6F) +-#define AW88399_TESTCTRL1_REG (0x70) +-#define AW88399_TESTCTRL2_REG (0x71) +-#define AW88399_EFCTRL1_REG (0x72) +-#define AW88399_EFCTRL2_REG (0x73) +-#define AW88399_EFRH4_REG (0x74) +-#define AW88399_EFRH3_REG (0x75) +-#define AW88399_EFRH2_REG (0x76) +-#define AW88399_EFRH1_REG (0x77) +-#define AW88399_EFRL4_REG (0x78) +-#define AW88399_EFRL3_REG (0x79) +-#define AW88399_EFRL2_REG (0x7A) +-#define AW88399_EFRL1_REG (0x7B) +-#define AW88399_TM_REG (0x7C) +-#define AW88399_TM2_REG (0x7D) +- +-#define AW88399_REG_MAX (0x7E) +-#define AW88399_MUTE_VOL (1023) +- +-#define AW88399_DSP_CFG_ADDR (0x9B00) +-#define AW88399_DSP_REG_CFG_ADPZ_RA (0x9B68) +-#define AW88399_DSP_FW_ADDR (0x8980) +-#define AW88399_DSP_ROM_CHECK_ADDR (0x1F40) +-#define AW88399_DSP_ROM_CHECK_DATA (0x4638) +- +-#define AW88399_CALI_RE_HBITS_MASK (~(0xFFFF0000)) +-#define AW88399_CALI_RE_HBITS_SHIFT (16) +- +-#define AW88399_CALI_RE_LBITS_MASK (~(0xFFFF)) +-#define AW88399_CALI_RE_LBITS_SHIFT (0) +- +-#define AW88399_I2STXEN_START_BIT (9) +-#define AW88399_I2STXEN_BITS_LEN (1) +-#define AW88399_I2STXEN_MASK \ +- (~(((1<> (shift)) +-#define AW88399_SHOW_RE_TO_DSP_RE(re, shift) (((re) << shift) / (1000)) +-#define AW88399_CRC_CHECK_PASS_VAL (0x4) +- +-#define AW88399_CRC_CFG_BASE_ADDR (0xD80) +-#define AW88399_CRC_FW_BASE_ADDR (0x4C0) +-#define AW88399_ACF_FILE "aw88399_acf.bin" +-#define AW88399_DEV_SYSST_CHECK_MAX (10) +-#define AW88399_CHIP_ID 0x2183 ++#include + + #define AW88399_I2C_NAME "aw88399" + +-#define AW88399_START_RETRIES (5) +-#define AW88399_START_WORK_DELAY_MS (0) +- + #define AW88399_RATES (SNDRV_PCM_RATE_8000_48000 | \ + SNDRV_PCM_RATE_96000) + #define AW88399_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ +@@ -550,80 +48,4 @@ + .put = profile_set, \ + } + +-enum { +- AW_EF_AND_CHECK = 0, +- AW_EF_OR_CHECK, +-}; +- +-enum { +- AW88399_DEV_VDSEL_DAC = 0, +- AW88399_DEV_VDSEL_VSENSE = 32, +-}; +- +-enum { +- AW88399_DSP_CRC_NA = 0, +- AW88399_DSP_CRC_OK = 1, +-}; +- +-enum { +- AW88399_DSP_FW_UPDATE_OFF = 0, +- AW88399_DSP_FW_UPDATE_ON = 1, +-}; +- +-enum { +- AW88399_FORCE_UPDATE_OFF = 0, +- AW88399_FORCE_UPDATE_ON = 1, +-}; +- +-enum { +- AW88399_1000_US = 1000, +- AW88399_2000_US = 2000, +- AW88399_3000_US = 3000, +- AW88399_4000_US = 4000, +-}; +- +-enum AW88399_DEV_STATUS { +- AW88399_DEV_PW_OFF = 0, +- AW88399_DEV_PW_ON, +-}; +- +-enum AW88399_DEV_FW_STATUS { +- AW88399_DEV_FW_FAILED = 0, +- AW88399_DEV_FW_OK, +-}; +- +-enum AW88399_DEV_MEMCLK { +- AW88399_DEV_MEMCLK_OSC = 0, +- AW88399_DEV_MEMCLK_PLL = 1, +-}; +- +-enum AW88399_DEV_DSP_CFG { +- AW88399_DEV_DSP_WORK = 0, +- AW88399_DEV_DSP_BYPASS = 1, +-}; +- +-enum { +- AW88399_NOT_RCV_MODE = 0, +- AW88399_RCV_MODE = 1, +-}; +- +-enum { +- AW88399_SYNC_START = 0, +- AW88399_ASYNC_START, +-}; +- +-struct aw88399 { +- struct aw_device *aw_pa; +- struct mutex lock; +- struct gpio_desc *reset_gpio; +- struct delayed_work start_work; +- struct regmap *regmap; +- struct aw_container *aw_cfg; +- +- unsigned int check_val; +- unsigned int crc_init_val; +- unsigned int vcalb_init_val; +- unsigned int dither_st; +-}; +- +-#endif ++#endif /* __AW88399_H__ */ diff -ruN --no-dereference -x .git a/sound/soc/codecs/max98390.c b/sound/soc/codecs/max98390.c ---- a/sound/soc/codecs/max98390.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/sound/soc/codecs/max98390.c 2026-09-23 12:56:16.000000000 +0200 +--- a/sound/soc/codecs/max98390.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/sound/soc/codecs/max98390.c 2026-10-03 14:48:53.000000000 +0200 @@ -978,7 +978,7 @@ .endianness = 1, }; @@ -42166,8 +42791,8 @@ diff -ruN --no-dereference -x .git a/sound/soc/codecs/max98390.c b/sound/soc/cod {}, }; diff -ruN --no-dereference -x .git a/sound/soc/codecs/max98390.h b/sound/soc/codecs/max98390.h ---- a/sound/soc/codecs/max98390.h 2026-09-21 15:09:00.000000000 +0200 -+++ b/sound/soc/codecs/max98390.h 2026-09-23 12:56:16.000000000 +0200 +--- a/sound/soc/codecs/max98390.h 2026-08-16 23:32:26.000000000 +0200 ++++ b/sound/soc/codecs/max98390.h 2026-10-03 14:48:53.000000000 +0200 @@ -664,4 +664,8 @@ unsigned int ambient_temp_value; const char *dsm_param_name; @@ -42178,8 +42803,8 @@ diff -ruN --no-dereference -x .git a/sound/soc/codecs/max98390.h b/sound/soc/cod + #endif diff -ruN --no-dereference -x .git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c ---- a/sound/soc/intel/boards/sof_sdw.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/sound/soc/intel/boards/sof_sdw.c 2026-09-23 12:56:16.000000000 +0200 +--- a/sound/soc/intel/boards/sof_sdw.c 2026-10-07 05:21:41.493567674 +0200 ++++ b/sound/soc/intel/boards/sof_sdw.c 2026-10-03 14:48:53.000000000 +0200 @@ -845,6 +845,15 @@ }, .driver_data = (void *)(SOC_SDW_PCH_DMIC), @@ -42198,7 +42823,7 @@ diff -ruN --no-dereference -x .git a/sound/soc/intel/boards/sof_sdw.c b/sound/so diff -ruN --no-dereference -x .git a/tag-release.sh b/tag-release.sh --- a/tag-release.sh 1970-01-01 01:00:00.000000000 +0100 -+++ b/tag-release.sh 2026-09-23 12:56:16.000000000 +0200 ++++ b/tag-release.sh 2026-10-03 14:48:53.000000000 +0200 @@ -0,0 +1,271 @@ +#!/bin/bash +# tag-release.sh - Create signed CachyOS kernel tags in cachyos/linux @@ -42472,8 +43097,8 @@ diff -ruN --no-dereference -x .git a/tag-release.sh b/tag-release.sh + echo "Push with: git push origin $TAG" +fi diff -ruN --no-dereference -x .git a/tools/testing/selftests/bpf/progs/tcp_ca_kfunc.c b/tools/testing/selftests/bpf/progs/tcp_ca_kfunc.c ---- a/tools/testing/selftests/bpf/progs/tcp_ca_kfunc.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/tools/testing/selftests/bpf/progs/tcp_ca_kfunc.c 2026-09-23 12:56:16.000000000 +0200 +--- a/tools/testing/selftests/bpf/progs/tcp_ca_kfunc.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/tools/testing/selftests/bpf/progs/tcp_ca_kfunc.c 2026-10-03 14:48:53.000000000 +0200 @@ -8,6 +8,7 @@ extern void bbr_main(struct sock *sk, u32 ack, int flag, const struct rate_sample *rs) __ksym; extern u32 bbr_sndbuf_expand(struct sock *sk) __ksym; @@ -42491,8 +43116,8 @@ diff -ruN --no-dereference -x .git a/tools/testing/selftests/bpf/progs/tcp_ca_kf } diff -ruN --no-dereference -x .git a/tools/testing/selftests/mm/rmap.c b/tools/testing/selftests/mm/rmap.c ---- a/tools/testing/selftests/mm/rmap.c 2026-09-21 15:09:00.000000000 +0200 -+++ b/tools/testing/selftests/mm/rmap.c 2026-09-23 12:56:16.000000000 +0200 +--- a/tools/testing/selftests/mm/rmap.c 2026-08-16 23:32:26.000000000 +0200 ++++ b/tools/testing/selftests/mm/rmap.c 2026-10-03 14:48:53.000000000 +0200 @@ -430,4 +430,85 @@ propagate_children(_metadata, data); } diff --git a/optional/kernel/snapshot.json b/optional/kernel/snapshot.json index f0cf6fa..06f3b8f 100644 --- a/optional/kernel/snapshot.json +++ b/optional/kernel/snapshot.json @@ -1,10 +1,9 @@ { - "atom": "=sys-kernel/gentoo-kernel-7.2.8", - "patch_kernel": "7.2.7", - "cachyos_tag": "cachyos-7.2.7-1", + "atom": "=sys-kernel/gentoo-kernel-7.2.9", + "patch_kernel": "7.2.9", + "cachyos_tag": "cachyos-7.2.9-2", "tested_kernel_versions": [ - "7.2.7", - "7.2.8" + "7.2.9" ], - "patch_sha256": "c1aca3cbd113866e5660cb827403ee73a8ca6f0eb5dcb497fad90561e059ef75" + "patch_sha256": "49e635ff0b35ebfbff5ddfab117dcd49bafc2b04f8794fccd6c7ff201f27ebf9" } diff --git a/optional/tuning/70-fiw-performance.conf b/optional/tuning/70-fiw-performance.conf new file mode 100644 index 0000000..4d45d81 --- /dev/null +++ b/optional/tuning/70-fiw-performance.conf @@ -0,0 +1,22 @@ +# Installed as /etc/sysctl.d/70-fiw-dots-performance.conf (Fiw's Ryzen preset) +# Desktop/gaming tuning, mostly from CachyOS-Settings (70-cachyos-settings.conf). +# swappiness 100 / page-cluster 0 (zram) and nmi_watchdog 0 already come from the CachyOS patch. + +# Games under Proton (CS2, Star Citizen, Hogwarts Legacy...) need many memory maps. +# Gentoo default 65530; Arch/CachyOS/Fedora use 1048576. +vm.max_map_count = 1048576 + +# Keep directory/inode cache longer (default 100). +vm.vfs_cache_pressure = 50 + +# Flush dirty pages in small chunks instead of % of 32 GB RAM: fewer stalls on big writes. +vm.dirty_bytes = 268435456 +vm.dirty_background_bytes = 67108864 +vm.dirty_writeback_centisecs = 1500 + +# Bigger network receive queue. +net.core.netdev_max_backlog = 4096 + +# TCP BBR congestion control with fq pacing (module loaded by modules-load.d/bbr.conf). +net.core.default_qdisc = fq +net.ipv4.tcp_congestion_control = bbr diff --git a/optional/tuning/bbr.conf b/optional/tuning/bbr.conf new file mode 100644 index 0000000..6c9b7bf --- /dev/null +++ b/optional/tuning/bbr.conf @@ -0,0 +1,2 @@ +# Installed as /etc/modules-load.d/fiw-dots-bbr.conf (Fiw's Ryzen preset) +tcp_bbr diff --git a/packages/dev.list b/packages/dev.list index 1a1ca6f..f3e0954 100644 --- a/packages/dev.list +++ b/packages/dev.list @@ -14,3 +14,4 @@ dev-qt/qtdeclarative media-video/pipewire dev-db/sqlite llvm-core/clang +gui-apps/grim diff --git a/packages/tidewm.list b/packages/tidewm.list index f1121f9..4caa8fd 100644 --- a/packages/tidewm.list +++ b/packages/tidewm.list @@ -2,4 +2,4 @@ gui-wm/tidewm::fiw-dots gui-apps/xwayland-satellite::guru gui-apps/wlr-randr::guru -gui-apps/grim +gui-apps/mpvpaper