diff --git a/.github/workflows/build-dev.yaml b/.github/workflows/build-dev.yaml index 6778076fd..b5a2921d7 100644 --- a/.github/workflows/build-dev.yaml +++ b/.github/workflows/build-dev.yaml @@ -100,7 +100,7 @@ jobs: * Decompress the image. * Write the image to an SDCARD using an imaging tool. Common imaging tools include [Balena Etcher](https://www.balena.io/etcher/), [Raspberry Pi Imager](https://www.raspberrypi.com/software/), and [Win32 Disk Imager](https://sourceforge.net/projects/win32diskimager/). If you're skilled with the command line, dd works fine too. - Download: [[Win600/Atari VCS/Generic x86_64](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/JELOS-handheld.x86_64-${{ steps.version.outputs.version }}.img.gz)] [[RG353V/RG353P](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/JELOS-RG353P.aarch64-${{ steps.version.outputs.version }}.img.gz)] [[RG503](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/JELOS-RG503.aarch64-${{ steps.version.outputs.version }}.img.gz)] [[RG552](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/JELOS-RG552.aarch64-${{ steps.version.outputs.version }}.img.gz)] [[RG351P](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/JELOS-RG351P.aarch64-${{ steps.version.outputs.version }}.img.gz)] [[RG351V](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/JELOS-RG351V.aarch64-${{ steps.version.outputs.version }}.img.gz)] [[RG351MP](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/JELOS-RG351MP.aarch64-${{ steps.version.outputs.version }}.img.gz)] + Download: [[Win600/Atari VCS/Generic x86_64](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/JELOS-handheld.x86_64-${{ steps.version.outputs.version }}.img.gz)] [[RG353P/RG353M/RG353V](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/JELOS-RG353P.aarch64-${{ steps.version.outputs.version }}.img.gz)] [[RG503](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/JELOS-RG503.aarch64-${{ steps.version.outputs.version }}.img.gz)] [[RG552](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/JELOS-RG552.aarch64-${{ steps.version.outputs.version }}.img.gz)] [[RG351P/RG351M](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/JELOS-RG351P.aarch64-${{ steps.version.outputs.version }}.img.gz)] [[RG351V](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/JELOS-RG351V.aarch64-${{ steps.version.outputs.version }}.img.gz)] [[RG351MP](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/JELOS-RG351MP.aarch64-${{ steps.version.outputs.version }}.img.gz)] > RG353V users, enable "DEVICE IS RG353V" in the system settings menu after flashing. @@ -111,7 +111,7 @@ jobs: * Copy the update to your device over the network to your device's update share. * Reboot the device, and the update will begin automatically. - Download: [[Win600/x86_64](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/${{ steps.version.outputs.version }}/JELOS-handheld.x86_64-${{ steps.version.outputs.version }}.tar)] [[RG353V/RG353P](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/${{ steps.version.outputs.version }}/JELOS-RG353P.aarch64-${{ steps.version.outputs.version }}.tar)] [[RG503](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/${{ steps.version.outputs.version }}/JELOS-RG503.aarch64-${{ steps.version.outputs.version }}.tar)] [[RG552](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/${{ steps.version.outputs.version }}/JELOS-RG552.aarch64-${{ steps.version.outputs.version }}.tar)] [[RG351P](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/${{ steps.version.outputs.version }}/JELOS-RG351P.aarch64-${{ steps.version.outputs.version }}.tar)] [[RG351V](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/${{ steps.version.outputs.version }}/JELOS-RG351V.aarch64-${{ steps.version.outputs.version }}.tar)] [[RG351MP](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/${{ steps.version.outputs.version }}/JELOS-RG351MP.aarch64-${{ steps.version.outputs.version }}.tar)] + Download: [[Win600/x86_64](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/${{ steps.version.outputs.version }}/JELOS-handheld.x86_64-${{ steps.version.outputs.version }}.tar)] [[RG353P/RG353M/RG353V](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/${{ steps.version.outputs.version }}/JELOS-RG353P.aarch64-${{ steps.version.outputs.version }}.tar)] [[RG503](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/${{ steps.version.outputs.version }}/JELOS-RG503.aarch64-${{ steps.version.outputs.version }}.tar)] [[RG552](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/${{ steps.version.outputs.version }}/JELOS-RG552.aarch64-${{ steps.version.outputs.version }}.tar)] [[RG351P](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/${{ steps.version.outputs.version }}/JELOS-RG351P.aarch64-${{ steps.version.outputs.version }}.tar)] [[RG351V](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/${{ steps.version.outputs.version }}/JELOS-RG351V.aarch64-${{ steps.version.outputs.version }}.tar)] [[RG351MP](https://github.com/JustEnoughLinuxOS/distribution-dev/releases/download/${{ steps.version.outputs.version }}/JELOS-RG351MP.aarch64-${{ steps.version.outputs.version }}.tar)] ## Documentation * [Home](https://github.com/JustEnoughLinuxOS/distribution/wiki) diff --git a/.github/workflows/build-main.yaml b/.github/workflows/build-main.yaml index 7f5f2d470..260a6f0b7 100644 --- a/.github/workflows/build-main.yaml +++ b/.github/workflows/build-main.yaml @@ -97,7 +97,7 @@ jobs: * Decompress the image. * Write the image to an SDCARD using an imaging tool. Common imaging tools include [Balena Etcher](https://www.balena.io/etcher/), [Raspberry Pi Imager](https://www.raspberrypi.com/software/), and [Win32 Disk Imager](https://sourceforge.net/projects/win32diskimager/). If you're skilled with the command line, dd works fine too. - Download: [[Win600/Atari VCS/Generic x86_64](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-handheld.x86_64-${{ steps.version.outputs.version }}.img.gz)] [[RG353V/RG353P](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG353P.aarch64-${{ steps.version.outputs.version }}.img.gz)] [[RG503](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG503.aarch64-${{ steps.version.outputs.version }}.img.gz)] [[RG552](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG552.aarch64-${{ steps.version.outputs.version }}.img.gz)] [[RG351P](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG351P.aarch64-${{ steps.version.outputs.version }}.img.gz)] [[RG351V](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG351V.aarch64-${{ steps.version.outputs.version }}.img.gz)] [[RG351MP](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG351MP.aarch64-${{ steps.version.outputs.version }}.img.gz)] + Download: [[Win600/Atari VCS/Generic x86_64](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-handheld.x86_64-${{ steps.version.outputs.version }}.img.gz)] [[RG353P/RG353M/RG353V](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG353P.aarch64-${{ steps.version.outputs.version }}.img.gz)] [[RG503](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG503.aarch64-${{ steps.version.outputs.version }}.img.gz)] [[RG552](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG552.aarch64-${{ steps.version.outputs.version }}.img.gz)] [[RG351P/RG351M](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG351P.aarch64-${{ steps.version.outputs.version }}.img.gz)] [[RG351V](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG351V.aarch64-${{ steps.version.outputs.version }}.img.gz)] [[RG351MP](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG351MP.aarch64-${{ steps.version.outputs.version }}.img.gz)] > RG353V users, enable "DEVICE IS RG353V" in the system settings menu after flashing. @@ -110,7 +110,7 @@ jobs: * Copy the update to your device over the network to your device's update share. * Reboot the device, and the update will begin automatically. - Download: [[Win600/x86_64](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-handheld.x86_64-${{ steps.version.outputs.version }}.tar)] [[RG353V/RG353P](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG353P.aarch64-${{ steps.version.outputs.version }}.tar)] [[RG503](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG503.aarch64-${{ steps.version.outputs.version }}.tar)] [[RG552](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG552.aarch64-${{ steps.version.outputs.version }}.tar)] [[RG351P](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG351P.aarch64-${{ steps.version.outputs.version }}.tar)] [[RG351V](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG351V.aarch64-${{ steps.version.outputs.version }}.tar)] [[RG351MP](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG351MP.aarch64-${{ steps.version.outputs.version }}.tar)] + Download: [[Win600/x86_64](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-handheld.x86_64-${{ steps.version.outputs.version }}.tar)] [[RG353P/RG353M/RG353P](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG353P.aarch64-${{ steps.version.outputs.version }}.tar)] [[RG503](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG503.aarch64-${{ steps.version.outputs.version }}.tar)] [[RG552](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG552.aarch64-${{ steps.version.outputs.version }}.tar)] [[RG351P/RG353M](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG351P.aarch64-${{ steps.version.outputs.version }}.tar)] [[RG351V](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG351V.aarch64-${{ steps.version.outputs.version }}.tar)] [[RG351MP](https://github.com/JustEnoughLinuxOS/distribution/releases/download/${{ steps.version.outputs.version }}/JELOS-RG351MP.aarch64-${{ steps.version.outputs.version }}.tar)] ## Documentation * [Home](https://github.com/JustEnoughLinuxOS/distribution/wiki) diff --git a/.gitignore b/.gitignore index 93ac6a81f..d8c7a7d32 100644 --- a/.gitignore +++ b/.gitignore @@ -28,7 +28,7 @@ mkpkg-temp /lost+found/ # symlinks... -/sources +/sources* /.work # ccache diff --git a/README.md b/README.md index 1c80d2295..c4407bc3f 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Just Enough Linux Operating System (JELOS) is a community developed Linux distri * Supports FAT32, ExFAT, and EXT4 file systems on removable storage (slot/device #2). * 2.4GHz and 5GHz 802.11 A/B/G/N/AC WIFI support. * Online update capability for easy access to stable or development builds. -* Support for the Anbernic WIN600, RG552, RG503, RG353P, RG353V, RG351P/M, RG351MP, RG351V, and Atari VCS. +* Support for the Anbernic WIN600, RG552, RG503, RG353P, RG353M, RG353V, RG351P, RG351M, RG351MP, RG351V, and Atari VCS. * Developed by a small, friendly community. ## Licenses diff --git a/config/blocklist b/config/blocklist index 3f9c6df13..22277916e 100644 --- a/config/blocklist +++ b/config/blocklist @@ -2,3 +2,4 @@ np2kai # Last major commit before hiatus is broken vicesa # Doesn't support updating with the script. duckstationsa # Latest commits break device patching. Need to research. ecwolf +raze diff --git a/config/functions b/config/functions index 9b7c1d868..b4aff1cb9 100644 --- a/config/functions +++ b/config/functions @@ -719,6 +719,15 @@ do_autoreconf() { export LIBTOOLIZE=$TOOLCHAIN/bin/libtoolize fi + # >autoconf-2.69 will call gtkdocize when used in macros + # when called with --install parameter. + # use "true" unless gtkdocsize is in the toolchain. + if [ -e "$TOOLCHAIN/bin/gtkdocize" ]; then + export GTKDOCIZE=$TOOLCHAIN/bin/gtkdocize + else + export GTKDOCIZE=true + fi + if [ -e "$TOOLCHAIN/bin/intltoolize" ]; then export INTLTOOLIZE=$TOOLCHAIN/bin/intltoolize fi diff --git a/config/path b/config/path index 5ac862e88..a98b7e62d 100644 --- a/config/path +++ b/config/path @@ -61,18 +61,12 @@ XORG_PATH_DRIVERS=/usr/lib/xorg/modules/drivers . config/optimize -# use ARM toolchain on 64/32 split builds +# use different toolchain for 64/32 split builds if [ -z "$KERNEL_TOOLCHAIN" -a "$TARGET_KERNEL_ARCH" = "arm64" -a "$TARGET_ARCH" = "arm" ]; then - if [ "${MACHINE_HARDWARE_NAME}" = "x86_64" ]; then - KERNEL_TOOLCHAIN="aarch64-none-linux-gnu" - elif [ "${MACHINE_HARDWARE_NAME}" = "aarch64" ]; then - KERNEL_TOOLCHAIN="aarch64-none-elf" - else - die "No known toolchain available for ${MACHINE_HARDWARE_NAME}." - fi + KERNEL_TOOLCHAIN="aarch64" fi if [ -n "$KERNEL_TOOLCHAIN" ]; then - TARGET_KERNEL_PREFIX=$TOOLCHAIN/lib/gcc-arm-$KERNEL_TOOLCHAIN/bin/$KERNEL_TOOLCHAIN- + TARGET_KERNEL_PREFIX=$KERNEL_TOOLCHAIN-none-elf- else TARGET_KERNEL_PREFIX=$TARGET_PREFIX fi @@ -106,3 +100,6 @@ unset CONFIG_SITE # Ignore custom python installs... unset PYTHONHOME PYTHONPATH PYTHONSTARTUP export PYTHONNOUSERSITE=yes #disable PEP 370 + +# Fix #4737 +unset PYTHONDONTWRITEBYTECODE diff --git a/packages/devel/android-headers/package.mk b/packages/devel/android-headers/package.mk deleted file mode 100644 index 0db28e4d2..000000000 --- a/packages/devel/android-headers/package.mk +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv) - -PKG_NAME="android-headers" -PKG_VERSION="25" -PKG_SHA256="1e0ecdf56c33aaa523109254e2c475878d8cfc5795ebd4bb5ecbaf80926f4fe9" -PKG_LICENSE="Apache" -PKG_SITE="https://android.googlesource.com/" -PKG_URL="$DISTRO_SRC/$PKG_NAME-$PKG_VERSION.tar.gz" -PKG_DEPENDS_TARGET="toolchain" -PKG_LONGDESC="Android Platform Headers from AOSP releases." -PKG_TOOLCHAIN="manual" diff --git a/packages/devel/attr/package.mk b/packages/devel/attr/package.mk index 12a624ee9..e60c6e98f 100644 --- a/packages/devel/attr/package.mk +++ b/packages/devel/attr/package.mk @@ -4,8 +4,8 @@ # Copyright (C) 2020-present Team LibreELEC (https://libreelec.tv) PKG_NAME="attr" -PKG_VERSION="2.4.48" -PKG_SHA256="5ead72b358ec709ed00bbf7a9eaef1654baad937c001c044fe8b74c57f5324e7" +PKG_VERSION="2.5.1" +PKG_SHA256="bae1c6949b258a0d68001367ce0c741cebdacdd3b62965d17e5eb23cd78adaf8" PKG_LICENSE="GPL" PKG_SITE="https://savannah.nongnu.org/projects/attr" PKG_URL="http://download.savannah.nongnu.org/releases/attr/${PKG_NAME}-${PKG_VERSION}.tar.gz" diff --git a/packages/devel/autoconf-archive/package.mk b/packages/devel/autoconf-archive/package.mk index cfd912670..34a9df883 100644 --- a/packages/devel/autoconf-archive/package.mk +++ b/packages/devel/autoconf-archive/package.mk @@ -3,8 +3,8 @@ # Copyright (C) 2020-present Team LibreELEC (https://libreelec.tv) PKG_NAME="autoconf-archive" -PKG_VERSION="2019.01.06" -PKG_SHA256="17195c833098da79de5778ee90948f4c5d90ed1a0cf8391b4ab348e2ec511e3f" +PKG_VERSION="2022.09.03" +PKG_SHA256="e07454f00d8cae7907bed42d0747798927809947684d94c37207a4d63a32f423" PKG_LICENSE="GPL" PKG_SITE="https://www.gnu.org/software/autoconf-archive/" PKG_URL="http://ftpmirror.gnu.org/autoconf-archive/${PKG_NAME}-${PKG_VERSION}.tar.xz" diff --git a/packages/devel/autoconf/package.mk b/packages/devel/autoconf/package.mk index 18172507a..73397a8e9 100644 --- a/packages/devel/autoconf/package.mk +++ b/packages/devel/autoconf/package.mk @@ -2,8 +2,8 @@ # Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) PKG_NAME="autoconf" -PKG_VERSION="2.69" -PKG_SHA256="64ebcec9f8ac5b2487125a86a7760d2591ac9e1d3dbd59489633f9de62a57684" +PKG_VERSION="2.71" +PKG_SHA256="f14c83cfebcc9427f2c3cea7258bd90df972d92eb26752da4ddad81c87a0faa4" PKG_LICENSE="GPL" PKG_SITE="http://sources.redhat.com/autoconf/" PKG_URL="http://ftpmirror.gnu.org/autoconf/${PKG_NAME}-${PKG_VERSION}.tar.xz" diff --git a/packages/devel/autoconf/patches/autoconf-0100-backport-runstatedir.patch b/packages/devel/autoconf/patches/autoconf-0100-backport-runstatedir.patch deleted file mode 100644 index 37a03843a..000000000 --- a/packages/devel/autoconf/patches/autoconf-0100-backport-runstatedir.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 8e269b13bc042bc2504d5860e0d453b4aac32909 Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Sun, 24 Jun 2018 13:45:26 +0200 -Subject: [PATCH] backport AC_INIT: add --runstatedir option to configure - -Backport of a197431414088a417b407b9b20583b2e8f7363bd. -Changes to NEWS and doc/autoconf.tex have been dropped. ---- - lib/autoconf/general.m4 | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - -diff --git a/lib/autoconf/general.m4 b/lib/autoconf/general.m4 -index adfae1db..1437c0ca 100644 ---- a/lib/autoconf/general.m4 -+++ b/lib/autoconf/general.m4 -@@ -586,6 +586,7 @@ AC_SUBST([datadir], ['${datarootdir}'])dnl - AC_SUBST([sysconfdir], ['${prefix}/etc'])dnl - AC_SUBST([sharedstatedir], ['${prefix}/com'])dnl - AC_SUBST([localstatedir], ['${prefix}/var'])dnl -+AC_SUBST([runstatedir], ['${localstatedir}/run'])dnl - AC_SUBST([includedir], ['${prefix}/include'])dnl - AC_SUBST([oldincludedir], ['/usr/include'])dnl - AC_SUBST([docdir], [m4_ifset([AC_PACKAGE_TARNAME], -@@ -812,6 +813,15 @@ do - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - -+ -runstatedir | --runstatedir | --runstatedi | --runstated \ -+ | --runstate | --runstat | --runsta | --runst | --runs \ -+ | --run | --ru | --r) -+ ac_prev=runstatedir ;; -+ -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ -+ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ -+ | --run=* | --ru=* | --r=*) -+ runstatedir=$ac_optarg ;; -+ - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ -@@ -921,7 +931,7 @@ fi - for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ -- libdir localedir mandir -+ libdir localedir mandir runstatedir - do - eval ac_val=\$$ac_var - # Remove trailing slashes. -@@ -1058,6 +1068,7 @@ Fine tuning of the installation directories: - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] -+ --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] --- -2.11.0 - diff --git a/packages/devel/autoconf/patches/autoconf-0200-performance.patch b/packages/devel/autoconf/patches/autoconf-0200-performance.patch deleted file mode 100644 index 1842fe92b..000000000 --- a/packages/devel/autoconf/patches/autoconf-0200-performance.patch +++ /dev/null @@ -1,60 +0,0 @@ -The check for solaris 'print' causes significant problems on a linux machine -with dash as /bin/sh since it triggers the execution of "print" which on some -linux systems is a perl script which is part of mailcap. Worse, this perl -script calls "which file" and if successful ignores the path file was found -in and just runs "file" without a path. Each exection causes PATH to be searched. - -Simply assuming the shell's printf function works cuts out all the fork overhead -and when parallel tasks are running, this overhead appears to be significant. - -RP -2015/11/28 -Upstream-Status: Inappropriate - -Index: autoconf-2.69/lib/m4sugar/m4sh.m4 -=================================================================== ---- autoconf-2.69.orig/lib/m4sugar/m4sh.m4 -+++ autoconf-2.69/lib/m4sugar/m4sh.m4 -@@ -1045,40 +1045,8 @@ m4_defun([_AS_ECHO_PREPARE], - [[as_nl=' - ' - export as_nl --# Printing a long string crashes Solaris 7 /usr/bin/printf. --as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' --as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo --as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo --# Prefer a ksh shell builtin over an external printf program on Solaris, --# but without wasting forks for bash or zsh. --if test -z "$BASH_VERSION$ZSH_VERSION" \ -- && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then -- as_echo='print -r --' -- as_echo_n='print -rn --' --elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then -- as_echo='printf %s\n' -- as_echo_n='printf %s' --else -- if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then -- as_echo_body='eval /usr/ucb/echo -n "$][1$as_nl"' -- as_echo_n='/usr/ucb/echo -n' -- else -- as_echo_body='eval expr "X$][1" : "X\\(.*\\)"' -- as_echo_n_body='eval -- arg=$][1; -- case $arg in @%:@( -- *"$as_nl"*) -- expr "X$arg" : "X\\(.*\\)$as_nl"; -- arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; -- esac; -- expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" -- ' -- export as_echo_n_body -- as_echo_n='sh -c $as_echo_n_body as_echo' -- fi -- export as_echo_body -- as_echo='sh -c $as_echo_body as_echo' --fi -+as_echo='printf %s\n' -+as_echo_n='printf %s' - ]])# _AS_ECHO_PREPARE - - diff --git a/packages/devel/autoconf/patches/autoconf-autoreconf-exclude.patch b/packages/devel/autoconf/patches/autoconf-autoreconf-exclude.patch index d1bd3a2a3..f3f239cbc 100644 --- a/packages/devel/autoconf/patches/autoconf-autoreconf-exclude.patch +++ b/packages/devel/autoconf/patches/autoconf-autoreconf-exclude.patch @@ -43,39 +43,30 @@ Index: autoconf-2.63/bin/autoreconf.in # Even if the user specified a configure.ac, trim to get the # directory, and look for configure.ac again. Because (i) the code # is simpler, and (ii) we are still able to diagnose simultaneous -@@ -255,6 +266,11 @@ - { - my ($aclocal, $flags) = @_; - -+ @ex = grep (/^aclocal$/, @exclude); -+ if ($#ex != -1) { -+ return; -+ } -+ - # aclocal 1.8+ does all this for free. It can be recognized by its - # --force support. - if ($aclocal_supports_force) @@ -368,7 +384,10 @@ } else { -- xsystem_hint ("autopoint is needed because this package uses Gettext", "$autopoint"); +- xsystem_hint ("autopoint is needed because this package uses Gettext", +- $autopoint); + @ex = grep (/^autopoint$/, @exclude); + if ($#ex == -1) { -+ xsystem_hint ("autopoint is needed because this package uses Gettext", "$autopoint"); ++ xsystem_hint ("autopoint is needed because this package uses Gettext", ++ $autopoint); + } } - -@@ -532,16 +551,17 @@ +@@ -532,16 +551,19 @@ { $libtoolize .= " --ltdl"; } -- xsystem_hint ("libtoolize is needed because this package uses Libtool", $libtoolize); +- xsystem_hint ("libtoolize is needed because this package uses Libtool", +- $libtoolize); - $rerun_aclocal = 1; + @ex = grep (/^libtoolize$/, @exclude); + if ($#ex == -1) { -+ xsystem_hint ("libtoolize is needed because this package uses Libtool", $libtoolize); ++ xsystem_hint ("libtoolize is needed because this package uses Libtool", ++ $libtoolize); + $rerun_aclocal = 1; + } } @@ -84,11 +75,24 @@ Index: autoconf-2.63/bin/autoreconf.in verb "$configure_ac: not running libtoolize: --install not given"; } -- -- - # ------------------- # - # Rerunning aclocal. # - # ------------------- # + + # --------------------- # + # Running intltoolize. # + # --------------------- # +@@ -748,8 +748,11 @@ + } + elsif ($install) + { +- xsystem_hint ("gtkdocize is needed because this package uses Gtkdoc", +- $gtkdocize); ++ @ex = grep (/^autopoint$/, @exclude); ++ if ($#ex == -1) { ++ xsystem_hint ("gtkdocize is needed because this package uses Gtkdoc", ++ $gtkdocize); ++ } + } + else + { @@ -572,7 +592,10 @@ # latter runs the former, and (ii) autoconf is stricter than # autoheader. So all in all, autoconf should give better error @@ -115,8 +119,8 @@ Index: autoconf-2.63/bin/autoreconf.in @@ -610,7 +636,10 @@ # We should always run automake, and let it decide whether it shall - # update the file or not. In fact, the effect of `$force' is already - # included in `$automake' via `--no-force'. + # update the file or not. In fact, the effect of '$force' is already + # included in '$automake' via '--no-force'. - xsystem ($automake); + @ex = grep (/^automake$/, @exclude); + if ($#ex == -1) { @@ -124,7 +128,7 @@ Index: autoconf-2.63/bin/autoreconf.in + } } - + # ---------------------------------------------------- # @@ -634,7 +663,10 @@ } else diff --git a/packages/devel/autoconf/patches/man-exclude.patch b/packages/devel/autoconf/patches/man-exclude.patch new file mode 100644 index 000000000..55e77ba0a --- /dev/null +++ b/packages/devel/autoconf/patches/man-exclude.patch @@ -0,0 +1,10 @@ +--- a/Makefile.in 2021-02-28 12:25:11.000000000 +0000 ++++ b/Makefile.in 2021-02-28 12:25:11.000000000 +0000 +@@ -780,7 +780,6 @@ + man/autoconf.1 \ + man/autoheader.1 \ + man/autom4te.1 \ +- man/autoreconf.1 \ + man/autoscan.1 \ + man/autoupdate.1 \ + man/ifnames.1 diff --git a/packages/devel/automake/package.mk b/packages/devel/automake/package.mk index de321db9a..c34acc5f2 100644 --- a/packages/devel/automake/package.mk +++ b/packages/devel/automake/package.mk @@ -9,6 +9,7 @@ PKG_SITE="http://sources.redhat.com/automake/" PKG_URL="http://ftpmirror.gnu.org/automake/${PKG_NAME}-${PKG_VERSION}.tar.xz" PKG_DEPENDS_HOST="ccache:host autoconf:host" PKG_LONGDESC="A GNU tool for automatically creating Makefiles." +PKG_BUILD_FLAGS="-parallel" PKG_CONFIGURE_OPTS_HOST="--target=${TARGET_NAME} --disable-silent-rules" diff --git a/packages/devel/binutils-aarch64/package.mk b/packages/devel/binutils-aarch64/package.mk new file mode 100644 index 000000000..b5bd86848 --- /dev/null +++ b/packages/devel/binutils-aarch64/package.mk @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="binutils-aarch64" +PKG_VERSION="$(get_pkg_version binutils)" +PKG_LICENSE="GPL" +PKG_URL="" +PKG_DEPENDS_HOST="toolchain:host" +PKG_LONGDESC="A GNU collection of binary utilities for 64-bit ARM." +PKG_DEPENDS_UNPACK+=" binutils" +PKG_PATCH_DIRS+=" $(get_pkg_directory binutils)/patches" + +PKG_CONFIGURE_OPTS_HOST="--target=aarch64-none-elf \ + --with-sysroot=${SYSROOT_PREFIX} \ + --with-lib-path=${SYSROOT_PREFIX}/lib:${SYSROOT_PREFIX}/usr/lib \ + --without-ppl \ + --enable-static \ + --without-cloog \ + --disable-werror \ + --disable-multilib \ + --disable-libada \ + --disable-libssp \ + --enable-version-specific-runtime-libs \ + --enable-plugins \ + --enable-gold \ + --enable-ld=default \ + --enable-lto \ + --disable-nls" + +unpack() { + mkdir -p ${PKG_BUILD} + tar --strip-components=1 -xf ${SOURCES}/binutils/binutils-${PKG_VERSION}.tar.xz -C ${PKG_BUILD} +} + +pre_configure_host() { + unset CPPFLAGS + unset CFLAGS + unset CXXFLAGS + unset LDFLAGS +} + +make_host() { + make configure-host + # override the makeinfo binary with true - this does not build the documentation + make MAKEINFO=true +} + +makeinstall_host() { + cp -v ../include/libiberty.h ${SYSROOT_PREFIX}/usr/include + make -C bfd install # fix parallel build with libctf requiring bfd + # override the makeinfo binary with true - this does not build the documentation + make MAKEINFO=true install +} diff --git a/packages/devel/binutils-arm-none-eabi/package.mk b/packages/devel/binutils-arm-none-eabi/package.mk new file mode 100644 index 000000000..67649111e --- /dev/null +++ b/packages/devel/binutils-arm-none-eabi/package.mk @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="binutils-arm-none-eabi" +PKG_VERSION="$(get_pkg_version binutils)" +PKG_LICENSE="GPL" +PKG_URL="" +PKG_DEPENDS_HOST="toolchain:host" +PKG_LONGDESC="A GNU collection of binary utilities for ARM Cortex-R/M processors." +PKG_DEPENDS_UNPACK+=" binutils" +PKG_PATCH_DIRS+=" $(get_pkg_directory binutils)/patches" + +PKG_CONFIGURE_OPTS_HOST="--target=arm-none-eabi \ + --with-sysroot=${SYSROOT_PREFIX} \ + --with-lib-path=${SYSROOT_PREFIX}/lib:${SYSROOT_PREFIX}/usr/lib \ + --without-ppl \ + --enable-static \ + --without-cloog \ + --disable-werror \ + --disable-multilib \ + --disable-libada \ + --disable-libssp \ + --enable-version-specific-runtime-libs \ + --enable-plugins \ + --enable-gold \ + --enable-ld=default \ + --enable-lto \ + --disable-nls" + +unpack() { + mkdir -p ${PKG_BUILD} + tar --strip-components=1 -xf ${SOURCES}/binutils/binutils-${PKG_VERSION}.tar.xz -C ${PKG_BUILD} +} + +pre_configure_host() { + unset CPPFLAGS + unset CFLAGS + unset CXXFLAGS + unset LDFLAGS +} + +make_host() { + make configure-host + # override the makeinfo binary with true - this does not build the documentation + make MAKEINFO=true +} + +makeinstall_host() { + cp -v ../include/libiberty.h ${SYSROOT_PREFIX}/usr/include + make -C bfd install # fix parallel build with libctf requiring bfd + # override the makeinfo binary with true - this does not build the documentation + make MAKEINFO=true install +} diff --git a/packages/devel/binutils-bpf/package.mk b/packages/devel/binutils-bpf/package.mk new file mode 100644 index 000000000..ae1034732 --- /dev/null +++ b/packages/devel/binutils-bpf/package.mk @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="binutils-bpf" +PKG_VERSION="$(get_pkg_version binutils)" +PKG_LICENSE="GPL" +PKG_URL="" +PKG_DEPENDS_HOST="toolchain:host" +PKG_LONGDESC="A GNU collection of binary utilities for 64-bit ARM." +PKG_DEPENDS_UNPACK+=" binutils" +PKG_PATCH_DIRS+=" $(get_pkg_directory binutils)/patches" + +PKG_CONFIGURE_OPTS_HOST="--target=bpf \ + --with-sysroot=${SYSROOT_PREFIX} \ + --with-lib-path=${SYSROOT_PREFIX}/lib:${SYSROOT_PREFIX}/usr/lib \ + --without-ppl \ + --enable-static \ + --without-cloog \ + --disable-werror \ + --disable-multilib \ + --disable-libada \ + --disable-libssp \ + --enable-version-specific-runtime-libs \ + --enable-plugins \ + --enable-gold \ + --enable-ld=default \ + --enable-lto \ + --disable-nls" + +unpack() { + mkdir -p ${PKG_BUILD} + tar --strip-components=1 -xf ${SOURCES}/binutils/binutils-${PKG_VERSION}.tar.xz -C ${PKG_BUILD} +} + +pre_configure_host() { + unset CPPFLAGS + unset CFLAGS + unset CXXFLAGS + unset LDFLAGS +} + +make_host() { + make configure-host + # override the makeinfo binary with true - this does not build the documentation + make MAKEINFO=true +} + +makeinstall_host() { + cp -v ../include/libiberty.h ${SYSROOT_PREFIX}/usr/include + make -C bfd install # fix parallel build with libctf requiring bfd + # override the makeinfo binary with true - this does not build the documentation + make MAKEINFO=true install +} diff --git a/packages/devel/binutils-or1k/package.mk b/packages/devel/binutils-or1k/package.mk new file mode 100644 index 000000000..c5e0e1739 --- /dev/null +++ b/packages/devel/binutils-or1k/package.mk @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="binutils-or1k" +PKG_VERSION="$(get_pkg_version binutils)" +PKG_LICENSE="GPL" +PKG_URL="" +PKG_DEPENDS_HOST="toolchain:host" +PKG_LONGDESC="A GNU collection of binary utilities for OpenRISC 1000." +PKG_DEPENDS_UNPACK+=" binutils" +PKG_PATCH_DIRS+=" $(get_pkg_directory binutils)/patches" + +PKG_CONFIGURE_OPTS_HOST="--target=or1k-none-elf \ + --with-sysroot=${SYSROOT_PREFIX} \ + --with-lib-path=${SYSROOT_PREFIX}/lib:${SYSROOT_PREFIX}/usr/lib \ + --without-ppl \ + --enable-static \ + --without-cloog \ + --disable-werror \ + --disable-multilib \ + --disable-libada \ + --disable-libssp \ + --enable-version-specific-runtime-libs \ + --enable-plugins \ + --enable-gold \ + --enable-ld=default \ + --enable-lto \ + --disable-nls" + +unpack() { + mkdir -p ${PKG_BUILD} + tar --strip-components=1 -xf ${SOURCES}/binutils/binutils-${PKG_VERSION}.tar.xz -C ${PKG_BUILD} +} + +pre_configure_host() { + unset CPPFLAGS + unset CFLAGS + unset CXXFLAGS + unset LDFLAGS +} + +make_host() { + make configure-host + # override the makeinfo binary with true - this does not build the documentation + make MAKEINFO=true +} + +makeinstall_host() { + cp -v ../include/libiberty.h ${SYSROOT_PREFIX}/usr/include + make -C bfd install # fix parallel build with libctf requiring bfd + # override the makeinfo binary with true - this does not build the documentation + make MAKEINFO=true install +} diff --git a/packages/devel/binutils/package.mk b/packages/devel/binutils/package.mk index 871539ffa..40fc3a375 100644 --- a/packages/devel/binutils/package.mk +++ b/packages/devel/binutils/package.mk @@ -3,10 +3,11 @@ # Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) PKG_NAME="binutils" -PKG_VERSION="2.38" +PKG_VERSION="2.39" +PKG_SHA256="645c25f563b8adc0a81dbd6a41cffbf4d37083a382e02d5d3df4f65c09516d00" PKG_LICENSE="GPL" -PKG_SITE="http://www.gnu.org/software/binutils/" -PKG_URL="http://ftp.gnu.org/gnu/binutils/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_SITE="https://www.gnu.org/software/binutils/" +PKG_URL="https://ftp.gnu.org/gnu/binutils/${PKG_NAME}-${PKG_VERSION}.tar.xz" PKG_DEPENDS_HOST="ccache:host bison:host flex:host linux:host" PKG_DEPENDS_TARGET="toolchain zlib binutils:host" PKG_LONGDESC="A GNU collection of binary utilities." @@ -15,6 +16,7 @@ PKG_CONFIGURE_OPTS_HOST="--target=${TARGET_NAME} \ --with-sysroot=${SYSROOT_PREFIX} \ --with-lib-path=${SYSROOT_PREFIX}/lib:${SYSROOT_PREFIX}/usr/lib \ --without-ppl \ + --enable-static \ --without-cloog \ --disable-werror \ --disable-multilib \ @@ -33,8 +35,8 @@ PKG_CONFIGURE_OPTS_TARGET="--target=${TARGET_NAME} \ --with-system-zlib \ --without-ppl \ --without-cloog \ - --disable-static \ - --enable-shared \ + --enable-static \ + --disable-shared \ --disable-werror \ --disable-multilib \ --disable-libada \ @@ -54,12 +56,15 @@ pre_configure_host() { make_host() { make configure-host - make + # override the makeinfo binary with true - this does not build the documentation + make MAKEINFO=true } makeinstall_host() { cp -v ../include/libiberty.h ${SYSROOT_PREFIX}/usr/include - make install + make -C bfd install # fix parallel build with libctf requiring bfd + # override the makeinfo binary with true - this does not build the documentation + make HELP2MAN=true MAKEINFO=true install } make_target() { diff --git a/packages/devel/binutils/patches/binutils-01-warn-for-uses-of-system-directories-when-link.patch b/packages/devel/binutils/patches/binutils-01-warn-for-uses-of-system-directories-when-link.patch index 91c501eec..1619cef94 100644 --- a/packages/devel/binutils/patches/binutils-01-warn-for-uses-of-system-directories-when-link.patch +++ b/packages/devel/binutils/patches/binutils-01-warn-for-uses-of-system-directories-when-link.patch @@ -10,9 +10,9 @@ From: Khem Raj Date: Fri, 15 Jan 2016 06:31:09 +0000 Subject: [PATCH 09/13] warn for uses of system directories when cross linking ---- a/ld/ldfile.c 2015-11-13 09:27:42.000000000 +0100 -+++ b/ld/ldfile.c 2016-11-15 19:09:31.658371254 +0100 -@@ -102,6 +102,17 @@ ldfile_add_library_path (const char *nam +--- a/ld/ldfile.c ++++ b/ld/ldfile.c +@@ -103,6 +103,17 @@ ldfile_add_library_path (const char *nam if (!cmdline && config.only_cmd_line_lib_dirs) return; diff --git a/packages/devel/binutils/patches/binutils-02-binutils-2-39-dont-error-on-missing-makeinfo.patch b/packages/devel/binutils/patches/binutils-02-binutils-2-39-dont-error-on-missing-makeinfo.patch new file mode 100644 index 000000000..e14501d4d --- /dev/null +++ b/packages/devel/binutils/patches/binutils-02-binutils-2-39-dont-error-on-missing-makeinfo.patch @@ -0,0 +1,11 @@ +--- a/bfd/Makefile.in 2022-08-05 09:53:59.000000000 +0000 ++++ b/bfd/Makefile.in 2022-08-07 11:22:25.397501975 +0000 +@@ -264,7 +264,7 @@ + am__v_texidevnull_0 = > /dev/null + am__v_texidevnull_1 = + am__dirstamp = $(am__leading_dot)dirstamp +-INFO_DEPS = doc/bfd.info ++INFO_DEPS = + am__TEXINFO_TEX_DIR = $(srcdir) + DVIS = doc/bfd.dvi + PDFS = doc/bfd.pdf diff --git a/packages/devel/boost/package.mk b/packages/devel/boost/package.mk index 994b0c837..8bf8f5d9a 100644 --- a/packages/devel/boost/package.mk +++ b/packages/devel/boost/package.mk @@ -3,8 +3,7 @@ # Copyright (C) 2019-present Team LibreELEC (https://libreelec.tv) PKG_NAME="boost" -PKG_VERSION="1.78.0" -PKG_SHA256="8681f175d4bdb26c52222665793eef08490d7758529330f98d3b29dd0735bccc" +PKG_VERSION="1.80.0" PKG_LICENSE="OSS" PKG_SITE="http://www.boost.org/" PKG_URL="https://boostorg.jfrog.io/artifactory/main/release/${PKG_VERSION}/source/${PKG_NAME}_${PKG_VERSION//./_}.tar.bz2" @@ -21,7 +20,7 @@ make_host() { makeinstall_host() { mkdir -p ${TOOLCHAIN}/bin - cp bjam ${TOOLCHAIN}/bin + cp b2 ${TOOLCHAIN}/bin } pre_configure_target() { @@ -31,7 +30,7 @@ pre_configure_target() { configure_target() { sh bootstrap.sh --prefix=/usr \ - --with-bjam=${TOOLCHAIN}/bin/bjam \ + --with-bjam=${TOOLCHAIN}/bin/b2 \ --with-python=${TOOLCHAIN}/bin/python \ --with-python-root=${SYSROOT_PREFIX}/usr @@ -42,6 +41,7 @@ configure_target() { } makeinstall_target() { + ln -sf ${TOOLCHAIN}/bin/b2 ${TOOLCHAIN}/bin/bjam ${TOOLCHAIN}/bin/bjam -d2 --ignore-site-config \ --layout=system \ --prefix=${SYSROOT_PREFIX}/usr \ diff --git a/packages/devel/cmake/package.mk b/packages/devel/cmake/package.mk index ec3778849..6e0bcf409 100644 --- a/packages/devel/cmake/package.mk +++ b/packages/devel/cmake/package.mk @@ -3,8 +3,8 @@ # Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) PKG_NAME="cmake" -PKG_VERSION="3.23.2" -PKG_SHA256="f316b40053466f9a416adf981efda41b160ca859e97f6a484b447ea299ff26aa" +PKG_VERSION="3.24.2" +PKG_SHA256="0d9020f06f3ddf17fb537dc228e1a56c927ee506b486f55fe2dc19f69bf0c8db" PKG_LICENSE="BSD" PKG_SITE="https://cmake.org/" PKG_URL="https://cmake.org/files/v$(get_pkg_version_maj_min)/cmake-${PKG_VERSION}.tar.gz" diff --git a/packages/devel/configtools/package.mk b/packages/devel/configtools/package.mk index 6f4a009eb..655ce1473 100644 --- a/packages/devel/configtools/package.mk +++ b/packages/devel/configtools/package.mk @@ -3,8 +3,8 @@ # Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) PKG_NAME="configtools" -PKG_VERSION="c8ddc8472f8efcadafc1ef53ca1d863415fddd5f" # 2020-12-22 -PKG_SHA256="6389d62e4e55554c764c2c0deb5b42767f34d7f274728c28355fedbaa337165b" +PKG_VERSION="20403c5701973a4cbd7e0b4bbeb627fcd424a0f1" # 2022-08-01 +PKG_SHA256="d89be2c5a06d45e4a8731404cd6eb52ddde393480a56754a68b44f36753e38d7" PKG_LICENSE="GPL" PKG_SITE="http://git.savannah.gnu.org/cgit/config.git" PKG_URL="http://git.savannah.gnu.org/cgit/config.git/snapshot/config-${PKG_VERSION}.tar.gz" diff --git a/packages/devel/crossguid/package.mk b/packages/devel/crossguid/package.mk index cb08fe613..45a0c78be 100644 --- a/packages/devel/crossguid/package.mk +++ b/packages/devel/crossguid/package.mk @@ -1,24 +1,15 @@ # SPDX-License-Identifier: GPL-2.0-or-later # Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv) PKG_NAME="crossguid" -PKG_VERSION="8f399e8bd4252be9952f3dfa8199924cc8487ca4" -PKG_SHA256="022c9f02cc36e865cd8fd0111a597ff2bd91988deeb348dbe2aba64aed1abd99" +PKG_VERSION="ca1bf4b810e2d188d04cb6286f957008ee1b7681" # 2019-05-30 +PKG_SHA256="6be27e0b3a4907f0cd3cfadec255ee1b925569e1bd06e67a4d2f4267299b69c4" PKG_LICENSE="GPL" PKG_SITE="https://github.com/graeme-hill/crossguid" PKG_URL="https://github.com/graeme-hill/crossguid/archive/${PKG_VERSION}.tar.gz" PKG_DEPENDS_TARGET="toolchain util-linux" PKG_LONGDESC="minimal, cross platform, C++ GUID library" -PKG_TOOLCHAIN="manual" -make_target() { - ${CXX} -c guid.cpp -o guid.o ${CXXFLAGS} -std=c++11 -DGUID_LIBUUID - ${AR} rvs libcrossguid.a guid.o -} - -makeinstall_target() { - mkdir -p ${SYSROOT_PREFIX}/usr/lib/ - cp libcrossguid.a ${SYSROOT_PREFIX}/usr/lib/ - mkdir -p ${SYSROOT_PREFIX}/usr/include/ - cp guid.h ${SYSROOT_PREFIX}/usr/include -} +PKG_CMAKE_OPTS_TARGET="-DCROSSGUID_TESTS=OFF \ + -Wno-dev" diff --git a/packages/devel/dbus-glib/package.mk b/packages/devel/dbus-glib/package.mk index 205973e03..f18e0f642 100644 --- a/packages/devel/dbus-glib/package.mk +++ b/packages/devel/dbus-glib/package.mk @@ -1,10 +1,11 @@ # SPDX-License-Identifier: GPL-2.0-or-later # Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) # Copyright (C) 2020-present Team LibreELEC (https://libreelec.tv) +# Copyright (C) 2022-present Team CoreELEC (https://coreelec.org) PKG_NAME="dbus-glib" -PKG_VERSION="0.110" -PKG_SHA256="7ce4760cf66c69148f6bd6c92feaabb8812dee30846b24cd0f7395c436d7e825" +PKG_VERSION="0.112" +PKG_SHA256="7d550dccdfcd286e33895501829ed971eeb65c614e73aadb4a08aeef719b143a" PKG_LICENSE="GPL" PKG_SITE="https://freedesktop.org/wiki/Software/dbus" PKG_URL="https://dbus.freedesktop.org/releases/dbus-glib/${PKG_NAME}-${PKG_VERSION}.tar.gz" diff --git a/packages/devel/ecm/package.mk b/packages/devel/ecm/package.mk new file mode 100644 index 000000000..3a76c9065 --- /dev/null +++ b/packages/devel/ecm/package.mk @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present BrooksyTech (https://github.com/brooksytech) + +PKG_NAME="ecm" +PKG_VERSION="v5.84.0" +PKG_ARCH="any" +PKG_LICENSE="GPLv3" +PKG_SITE="https://github.com/KDE/extra-cmake-modules" +PKG_URL="$PKG_SITE/archive/$PKG_VERSION.tar.gz" +PKG_SHORTDESC="KDE Extra CMake Modules" +PKG_TOOLCHAIN="cmake" + +PKG_CMAKE_OPTS_TARGET+=" -DBUILD_TESTING=OFF -DBUILD_HTML_DOCS=OFF -DBUILD_MAN_DOCS=OFF -DBUILD_QTHELP_DOCS=OFF" diff --git a/packages/devel/elfutils/package.mk b/packages/devel/elfutils/package.mk index 24b03077a..77a95de84 100644 --- a/packages/devel/elfutils/package.mk +++ b/packages/devel/elfutils/package.mk @@ -3,8 +3,8 @@ # Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) PKG_NAME="elfutils" -PKG_VERSION="0.186" -PKG_SHA256="7f6fb9149b1673d38d9178a0d3e0fb8a1ec4f53a9f4c2ff89469609879641177" +PKG_VERSION="0.187" +PKG_SHA256="e70b0dfbe610f90c4d1fe0d71af142a4e25c3c4ef9ebab8d2d72b65159d454c8" PKG_LICENSE="GPL" PKG_SITE="https://sourceware.org/elfutils/" PKG_URL="https://sourceware.org/elfutils/ftp/${PKG_VERSION}/${PKG_NAME}-${PKG_VERSION}.tar.bz2" diff --git a/packages/devel/fakeroot/package.mk b/packages/devel/fakeroot/package.mk index fe858206d..b7694f694 100644 --- a/packages/devel/fakeroot/package.mk +++ b/packages/devel/fakeroot/package.mk @@ -3,8 +3,8 @@ # Copyright (C) 2019-present Team LibreELEC (https://libreelec.tv) PKG_NAME="fakeroot" -PKG_VERSION="1.25.3" -PKG_SHA256="8e903683357f7f5bcc31b879fd743391ad47691d4be33d24a76be3b6c21e956c" +PKG_VERSION="1.29" +PKG_SHA256="8fbbafb780c9173e3ace4a04afbc1d900f337f3216883939f5c7db3431be7c20" PKG_LICENSE="GPL3" PKG_SITE="https://tracker.debian.org/pkg/fakeroot" PKG_URL="http://ftp.debian.org/debian/pool/main/f/fakeroot/${PKG_NAME}_${PKG_VERSION}.orig.tar.gz" diff --git a/packages/devel/fakeroot/patches/fakeroot-002-stat-ver-undefined.patch b/packages/devel/fakeroot/patches/fakeroot-002-stat-ver-undefined.patch deleted file mode 100644 index 8a2eb9bf6..000000000 --- a/packages/devel/fakeroot/patches/fakeroot-002-stat-ver-undefined.patch +++ /dev/null @@ -1,56 +0,0 @@ -From f6ca3217ec2fad93d078fa0121aa8f88d7d12ccb Mon Sep 17 00:00:00 2001 -From: lualiliu -Date: Wed, 7 Sep 2022 10:57:49 +0800 -Subject: [PATCH] Add a patch about fakeroot(_STAT_VER undeclared) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -solve it: -libfakeroot.c:99:40: error: ‘_STAT_VER’ undeclared (first use in this -function) ---- - ...fine-_STAT_VER-if-not-already-define.patch | 34 +++++++++++++++++++ - 1 file changed, 34 insertions(+) - create mode 100644 packages/devel/fakeroot/patches/0001-libfakeroot.c-define-_STAT_VER-if-not-already-define.patch - -diff --git a/packages/devel/fakeroot/patches/0001-libfakeroot.c-define-_STAT_VER-if-not-already-define.patch b/packages/devel/fakeroot/patches/0001-libfakeroot.c-define-_STAT_VER-if-not-already-define.patch -new file mode 100644 -index 00000000..613d0c95 ---- /dev/null -+++ b/packages/devel/fakeroot/patches/0001-libfakeroot.c-define-_STAT_VER-if-not-already-define.patch -@@ -0,0 +1,34 @@ -+From ca68c7336dea4a07cf5b77c1fdc9e9aee4984ca5 Mon Sep 17 00:00:00 2001 -+From: Ilya Lipnitskiy -+Date: Thu, 11 Feb 2021 20:59:25 -0800 -+Subject: [PATCH 1/3] libfakeroot.c: define _STAT_VER if not already defined -+ -+Signed-off-by: Ilya Lipnitskiy -+--- -+ libfakeroot.c | 10 ++++++++++ -+ 1 file changed, 10 insertions(+) -+ -+diff --git a/libfakeroot.c b/libfakeroot.c -+index 3e80e38..14cdbc4 100644 -+--- a/libfakeroot.c -++++ b/libfakeroot.c -+@@ -90,6 +90,16 @@ -+ #define SEND_GET_XATTR64(a,b,c) send_get_xattr64(a,b) -+ #endif -+ -++#ifndef _STAT_VER -++ #if defined (__aarch64__) -++ #define _STAT_VER 0 -++ #elif defined (__x86_64__) -++ #define _STAT_VER 1 -++ #else -++ #define _STAT_VER 3 -++ #endif -++#endif -++ -+ /* -+ These INT_* (which stands for internal) macros should always be used when -+ the fakeroot library owns the storage of the stat variable. -+-- -+2.30.1 -+ diff --git a/packages/devel/flatbuffers/package.mk b/packages/devel/flatbuffers/package.mk index 8679e7483..4f4099df5 100644 --- a/packages/devel/flatbuffers/package.mk +++ b/packages/devel/flatbuffers/package.mk @@ -2,8 +2,8 @@ # Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) PKG_NAME="flatbuffers" -PKG_VERSION="1.12.0" -PKG_SHA256="62f2223fb9181d1d6338451375628975775f7522185266cd5296571ac152bc45" +PKG_VERSION="2.0.8" +PKG_SHA256="f97965a727d26386afaefff950badef2db3ab6af9afe23ed6d94bfb65f95f37e" PKG_LICENSE="Apache-2.0" PKG_SITE="https://github.com/google/flatbuffers" PKG_URL="https://github.com/google/flatbuffers/archive/v${PKG_VERSION}.tar.gz" @@ -23,7 +23,7 @@ PKG_CMAKE_OPTS_HOST="-DFLATBUFFERS_CODE_COVERAGE=OFF \ PKG_CMAKE_OPTS_TARGET="-DFLATBUFFERS_CODE_COVERAGE=OFF \ -DFLATBUFFERS_BUILD_TESTS=OFF \ -DFLATBUFFERS_INSTALL=ON \ - -DFLATBUFFERS_BUILD_FLATLIB=OFF \ + -DFLATBUFFERS_BUILD_FLATLIB=ON \ -DFLATBUFFERS_BUILD_FLATC=OFF \ -DFLATBUFFERS_BUILD_FLATHASH=OFF \ -DFLATBUFFERS_BUILD_GRPCTEST=OFF \ diff --git a/packages/devel/fribidi/package.mk b/packages/devel/fribidi/package.mk index 9b86b4531..7c858cc3f 100644 --- a/packages/devel/fribidi/package.mk +++ b/packages/devel/fribidi/package.mk @@ -3,14 +3,13 @@ # Copyright (C) 2019-present Team LibreELEC (https://libreelec.tv) PKG_NAME="fribidi" -PKG_VERSION="1.0.10" -PKG_SHA256="7f1c687c7831499bcacae5e8675945a39bacbad16ecaa945e9454a32df653c01" +PKG_VERSION="1.0.12" +PKG_SHA256="0cd233f97fc8c67bb3ac27ce8440def5d3ffacf516765b91c2cc654498293495" PKG_LICENSE="LGPL" PKG_SITE="http://fribidi.freedesktop.org/" PKG_URL="https://github.com/fribidi/fribidi/releases/download/v${PKG_VERSION}/${PKG_NAME}-${PKG_VERSION}.tar.xz" PKG_DEPENDS_TARGET="toolchain" PKG_LONGDESC="A bidirectional algorithm library." -PKG_TOOLCHAIN="meson" PKG_BUILD_FLAGS="+pic" PKG_MESON_OPTS_TARGET="-Ddeprecated=false \ diff --git a/packages/devel/gettext/package.mk b/packages/devel/gettext/package.mk index a3ce4ab71..fb6f5d3c5 100644 --- a/packages/devel/gettext/package.mk +++ b/packages/devel/gettext/package.mk @@ -3,11 +3,11 @@ # Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) PKG_NAME="gettext" -PKG_VERSION="0.21" -PKG_SHA256="d20fcbb537e02dcf1383197ba05bd0734ef7bf5db06bdb241eb69b7d16b73192" +PKG_VERSION="0.21.1" +PKG_SHA256="50dbc8f39797950aa2c98e939947c527e5ac9ebd2c1b99dd7b06ba33a6767ae6" PKG_LICENSE="GPL" -PKG_SITE="http://www.gnu.org/s/gettext/" -PKG_URL="http://ftp.gnu.org/pub/gnu/gettext/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_SITE="https://www.gnu.org/s/gettext/" +PKG_URL="https://ftp.gnu.org/pub/gnu/gettext/${PKG_NAME}-${PKG_VERSION}.tar.xz" PKG_DEPENDS_HOST="ccache:host" PKG_DEPENDS_TARGET="toolchain" PKG_LONGDESC="A program internationalization library and tools." diff --git a/packages/devel/glib/package.mk b/packages/devel/glib/package.mk index 120f3bb86..16fcaa16d 100644 --- a/packages/devel/glib/package.mk +++ b/packages/devel/glib/package.mk @@ -3,14 +3,14 @@ # Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) PKG_NAME="glib" -PKG_VERSION="2.71.0" +PKG_VERSION="2.74.0" +PKG_SHA256="3652c7f072d7b031a6b5edd623f77ebc5dcd2ae698598abcc89ff39ca75add30" PKG_LICENSE="LGPL" PKG_SITE="https://www.gtk.org/" PKG_URL="https://download.gnome.org/sources/glib/$(get_pkg_version_maj_min)/${PKG_NAME}-${PKG_VERSION}.tar.xz" -PKG_DEPENDS_HOST="libffi:host pcre:host Python3:host meson:host ninja:host" -PKG_DEPENDS_TARGET="toolchain pcre zlib libffi Python3:host util-linux" +PKG_DEPENDS_HOST="libffi:host pcre2:host Python3:host meson:host ninja:host" +PKG_DEPENDS_TARGET="toolchain pcre2 zlib libffi Python3:host util-linux" PKG_LONGDESC="A library which includes support routines for C such as lists, trees, hashes, memory allocation." -PKG_TOOLCHAIN="meson" PKG_MESON_OPTS_HOST="-Ddefault_library=shared \ -Dinstalled_tests=false \ diff --git a/packages/devel/glibc/package.mk b/packages/devel/glibc/package.mk index 5e5998bda..d60aee8f3 100644 --- a/packages/devel/glibc/package.mk +++ b/packages/devel/glibc/package.mk @@ -3,18 +3,18 @@ # Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) PKG_NAME="glibc" -PKG_VERSION="2.35" -PKG_SHA256="5123732f6b67ccd319305efd399971d58592122bcc2a6518a1bd2510dd0cf52e" +PKG_VERSION="2.36" +PKG_SHA256="1c959fea240906226062cb4b1e7ebce71a9f0e3c0836c09e7e3423d434fcfe75" PKG_LICENSE="GPL" PKG_SITE="https://www.gnu.org/software/libc/" PKG_URL="https://ftp.gnu.org/pub/gnu/glibc/${PKG_NAME}-${PKG_VERSION}.tar.xz" PKG_DEPENDS_TARGET="ccache:host autotools:host linux:host gcc:bootstrap pigz:host Python3:host" PKG_DEPENDS_INIT="glibc" PKG_LONGDESC="The Glibc package contains the main C library." -PKG_BUILD_FLAGS="-gold" +PKG_BUILD_FLAGS="+bfd -gold" case "${DEVICE}" in - RG351P|RG351V|RG351MP|RG503|RG353P) + RG353P|RG503|RG351P|RG351V|RG351MP) OPT_ENABLE_KERNEL=4.4.0 ;; *) @@ -98,6 +98,16 @@ EOF # binaries to install into target GLIBC_INCLUDE_BIN="getent ldd locale localedef" + + # glibc does not need / nor build successfully with _FILE_OFFSET_BITS or _TIME_BITS set + case ${ARCH} in + arm|aarch64) + export CFLAGS=$(echo ${CFLAGS} | sed -e "s|-D_FILE_OFFSET_BITS=64||g") + export CFLAGS=$(echo ${CFLAGS} | sed -e "s|-D_TIME_BITS=64||g") + export CXXFLAGS=$(echo ${CXXFLAGS} | sed -e "s|-D_FILE_OFFSET_BITS=64||g") + export CXXFLAGS=$(echo ${CXXFLAGS} | sed -e "s|-D_TIME_BITS=64||g") + ;; + esac } post_makeinstall_target() { @@ -108,9 +118,7 @@ post_makeinstall_target() { safe_remove ${INSTALL}/usr/lib/audit safe_remove ${INSTALL}/usr/lib/glibc - safe_remove ${INSTALL}/usr/lib/libc_pic safe_remove ${INSTALL}/usr/lib/*.o - safe_remove ${INSTALL}/usr/lib/*.map safe_remove ${INSTALL}/var # add UTF-8 charmap diff --git a/packages/devel/glibc/patches/arm/glibc-HACK-Don-t-check-GLIBC_ABI_DT_RELR-support-for-Chrom.patch b/packages/devel/glibc/patches/arm/glibc-HACK-Don-t-check-GLIBC_ABI_DT_RELR-support-for-Chrom.patch new file mode 100644 index 000000000..78234d8e9 --- /dev/null +++ b/packages/devel/glibc/patches/arm/glibc-HACK-Don-t-check-GLIBC_ABI_DT_RELR-support-for-Chrom.patch @@ -0,0 +1,27 @@ +From 85892fbc0d6f64f564f0d4c9514a7183ad8eb985 Mon Sep 17 00:00:00 2001 +From: alex +Date: Sun, 17 Jul 2022 12:16:20 +0200 +Subject: [PATCH] HACK: Don't check GLIBC_ABI_DT_RELR support for ChromeOS + libwidevinecdm.so + +--- + elf/dl-version.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/elf/dl-version.c b/elf/dl-version.c +index cda0889209..058394f148 100644 +--- a/elf/dl-version.c ++++ b/elf/dl-version.c +@@ -373,7 +373,8 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode) + if (d->d_tag == DT_NEEDED) + { + const char *name = strtab + d->d_un.d_val; +- if (strncmp (name, "libc.so.", 8) == 0) ++ if (strncmp (name, "libc.so.", 8) == 0 && ++ strstr (map->l_name, "libwidevinecdm.so") == NULL) + { + _dl_exception_create + (&exception, DSO_FILENAME (map->l_name), +-- +2.37.1 + diff --git a/packages/devel/glibc/patches/arm/glibc-add-support-for-SHT_RELR-sections.patch b/packages/devel/glibc/patches/arm/glibc-add-support-for-SHT_RELR-sections.patch deleted file mode 100644 index 07a0c4082..000000000 --- a/packages/devel/glibc/patches/arm/glibc-add-support-for-SHT_RELR-sections.patch +++ /dev/null @@ -1,327 +0,0 @@ -From 6676e967dba405ca31d57b63e096becd13d4a200 Mon Sep 17 00:00:00 2001 -From: Rahul Chaudhry -Date: Thu, 15 Mar 2018 14:30:17 -0700 -Subject: [PATCH 4/8] sys-libs/glibc: add support for SHT_RELR sections. - -This patch adds experimental support for SHT_RELR sections, proposed -here: https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg - -SHT_RELR sections are supported for arm, aarch64, and x86_64 targets. -To enable them, pass '--experimental-use-relr' flag to gold. - -Definitions for the new ELF section type and dynamic array tags, as well -as the encoding used in the new section are all under discussion and are -subject to change. We plan to send the patch upstream after the gABI has -been updated to include the new definitions. - -[Adrian: forward-ported to glibc 2.32] ---- - elf/do-rel.h | 41 ++++++++++++++++++++++++++++++++++-- - elf/dynamic-link.h | 15 +++++++++++++ - elf/elf.h | 15 +++++++++++-- - elf/get-dynamic-info.h | 7 ++++++ - sysdeps/aarch64/dl-machine.h | 10 +++++++++ - sysdeps/arm/dl-machine.h | 10 +++++++++ - sysdeps/i386/dl-machine.h | 10 +++++++++ - sysdeps/x86_64/dl-machine.h | 10 +++++++++ - 8 files changed, 114 insertions(+), 4 deletions(-) - ---- a/elf/do-rel.h -+++ b/elf/do-rel.h -@@ -28,6 +28,12 @@ - # define elf_machine_rel_relative elf_machine_rela_relative - #endif - -+#ifdef DO_RELR -+# define elf_dynamic_do_Rel elf_dynamic_do_Relr -+# define Rel Relr -+# define elf_machine_rel_relative elf_machine_relr_relative -+#endif -+ - #ifndef DO_ELF_MACHINE_REL_RELATIVE - # define DO_ELF_MACHINE_REL_RELATIVE(map, l_addr, relative) \ - elf_machine_rel_relative (l_addr, relative, \ -@@ -48,12 +54,12 @@ elf_dynamic_do_Rel (struct link_map *map - const ElfW(Rel) *r = (const void *) reladdr; - const ElfW(Rel) *end = (const void *) (reladdr + relsize); - ElfW(Addr) l_addr = map->l_addr; --# if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP -+# if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP && !defined DO_RELR - const ElfW(Rel) *r2 = NULL; - const ElfW(Rel) *end2 = NULL; - # endif - --#if (!defined DO_RELA || !defined ELF_MACHINE_PLT_REL) && !defined RTLD_BOOTSTRAP -+#if (!defined DO_RELA || !defined ELF_MACHINE_PLT_REL) && !defined RTLD_BOOTSTRAP && !defined DO_RELR - /* We never bind lazily during ld.so bootstrap. Unfortunately gcc is - not clever enough to see through all the function calls to realize - that. */ -@@ -82,8 +88,10 @@ elf_dynamic_do_Rel (struct link_map *map - else - #endif - { -+# if !defined DO_RELR - const ElfW(Sym) *const symtab = - (const void *) D_PTR (map, l_info[DT_SYMTAB]); -+# endif - const ElfW(Rel) *relative = r; - r += nrelative; - -@@ -110,9 +118,36 @@ elf_dynamic_do_Rel (struct link_map *map - if (l_addr != 0 || ! map->l_info[VALIDX(DT_GNU_PRELINKED)]) - # endif - #endif -+ -+#ifdef DO_RELR -+ { -+ ElfW(Addr) base = 0; -+ for (; relative < end; ++relative) -+ { -+ ElfW(Relr) entry = *relative; -+ if ((entry&1) == 0) -+ { -+ elf_machine_relr_relative (l_addr, scope, (void *) (l_addr + entry)); -+ base = entry + sizeof(ElfW(Addr)); -+ continue; -+ } -+ ElfW(Addr) offset = base; -+ while (entry != 0) -+ { -+ entry >>= 1; -+ if ((entry&1) != 0) -+ elf_machine_relr_relative (l_addr, scope, (void *) (l_addr + offset)); -+ offset += sizeof(ElfW(Addr)); -+ } -+ base += (8*sizeof(ElfW(Addr)) - 1) * sizeof(ElfW(Addr)); -+ } -+ } -+#else - for (; relative < r; ++relative) - DO_ELF_MACHINE_REL_RELATIVE (map, l_addr, relative); -+#endif - -+#if !defined DO_RELR - #ifdef RTLD_BOOTSTRAP - /* The dynamic linker always uses versioning. */ - assert (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL); -@@ -211,6 +246,7 @@ elf_dynamic_do_Rel (struct link_map *map - # endif - } - #endif -+#endif - } - } - -@@ -220,3 +256,4 @@ elf_dynamic_do_Rel (struct link_map *map - #undef elf_machine_rel_relative - #undef DO_ELF_MACHINE_REL_RELATIVE - #undef DO_RELA -+#undef DO_RELR ---- a/elf/dynamic-link.h -+++ b/elf/dynamic-link.h -@@ -50,6 +50,11 @@ static inline void __attribute__((always_i - elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, - void *const reloc_addr); - # endif -+# if ! ELF_MACHINE_NO_RELR -+static inline void __attribute__((always_inline)) -+elf_machine_relr_relative (ElfW(Addr) l_addr, struct r_scope_elem *scope[], -+ void *const reloc_addr); -+# endif - # if ELF_MACHINE_NO_RELA || defined ELF_MACHINE_PLT_REL - static inline void __attribute__((always_inline)) - elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], -@@ -146,6 +151,15 @@ elf_machine_lazy_rel (struct link_map *m - # define ELF_DYNAMIC_DO_RELA(map, scope, lazy, skip_ifunc) /* Nothing to do. */ - # endif - -+# if ! ELF_MACHINE_NO_RELR -+# define DO_RELR -+# include "do-rel.h" -+# define ELF_DYNAMIC_DO_RELR(map, scope, lazy, skip_ifunc) \ -+ _ELF_DYNAMIC_DO_RELOC (RELR, Relr, map, scope, lazy, skip_ifunc, 1) -+# else -+# define ELF_DYNAMIC_DO_RELR(map, scope, lazy, skip_ifunc) /* Nothing to do. */ -+# endif -+ - /* This can't just be an inline function because GCC is too dumb - to inline functions containing inlines themselves. */ - # define ELF_DYNAMIC_RELOCATE(map, scope, lazy, consider_profile, skip_ifunc) \ -@@ -154,6 +168,7 @@ elf_machine_lazy_rel (struct link_map *m - (consider_profile)); \ - ELF_DYNAMIC_DO_REL ((map), (scope), edr_lazy, skip_ifunc); \ - ELF_DYNAMIC_DO_RELA ((map), (scope), edr_lazy, skip_ifunc); \ -+ ELF_DYNAMIC_DO_RELR ((map), (scope), edr_lazy, skip_ifunc); \ - } while (0) - - #endif ---- a/elf/elf.h -+++ b/elf/elf.h -@@ -443,7 +443,8 @@ typedef struct - #define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ - #define SHT_GROUP 17 /* Section group */ - #define SHT_SYMTAB_SHNDX 18 /* Extended section indices */ --#define SHT_NUM 19 /* Number of defined types. */ -+#define SHT_RELR 19 /* Relative relocation, only offsets */ -+#define SHT_NUM 20 /* Number of defined types. */ - #define SHT_LOOS 0x60000000 /* Start OS-specific. */ - #define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */ - #define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */ -@@ -662,6 +663,12 @@ typedef struct - Elf64_Sxword r_addend; /* Addend */ - } Elf64_Rela; - -+/* Relocation table entry for relative (in section of type SHT_RELR). */ -+ -+typedef Elf32_Word Elf32_Relr; /* offset/bitmap for relative relocations */ -+ -+typedef Elf64_Xword Elf64_Relr; /* offset/bitmap for relative relocations */ -+ - /* How to extract and insert information held in the r_info field. */ - - #define ELF32_R_SYM(val) ((val) >> 8) -@@ -887,7 +894,10 @@ typedef struct - #define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ - #define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ - #define DT_SYMTAB_SHNDX 34 /* Address of SYMTAB_SHNDX section */ --#define DT_NUM 35 /* Number used */ -+#define DT_RELRSZ 35 -+#define DT_RELR 36 -+#define DT_RELRENT 37 -+#define DT_NUM 38 /* Number used */ - #define DT_LOOS 0x6000000d /* Start of OS-specific */ - #define DT_HIOS 0x6ffff000 /* End of OS-specific */ - #define DT_LOPROC 0x70000000 /* Start of processor-specific */ -@@ -939,6 +949,7 @@ typedef struct - GNU extension. */ - #define DT_VERSYM 0x6ffffff0 - -+#define DT_RELRCOUNT 0x6ffffff8 - #define DT_RELACOUNT 0x6ffffff9 - #define DT_RELCOUNT 0x6ffffffa - ---- a/elf/get-dynamic-info.h -+++ b/elf/get-dynamic-info.h -@@ -89,6 +89,9 @@ elf_get_dynamic_info (struct link_map *l - # if ! ELF_MACHINE_NO_REL - ADJUST_DYN_INFO (DT_REL); - # endif -+# if ! ELF_MACHINE_NO_RELR -+ ADJUST_DYN_INFO (DT_RELR); -+#endif - ADJUST_DYN_INFO (DT_JMPREL); - ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM)); - ADJUST_DYN_INFO (ADDRIDX (DT_GNU_HASH)); -@@ -113,6 +116,10 @@ elf_get_dynamic_info (struct link_map *l - if (info[DT_REL] != NULL) - assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel))); - #endif -+#if ! ELF_MACHINE_NO_RELR -+ if (info[DT_RELR] != NULL) -+ assert (info[DT_RELRENT]->d_un.d_val == sizeof (ElfW(Relr))); -+# endif - if (bootstrap || static_pie_bootstrap) - { - assert (info[DT_RUNPATH] == NULL); ---- a/sysdeps/aarch64/dl-machine.h -+++ b/sysdeps/aarch64/dl-machine.h -@@ -384,6 +385,15 @@ elf_machine_rela_relative (ElfW(Addr) l_ - } - - static inline void -+__attribute__ ((always_inline)) -+elf_machine_relr_relative (ElfW(Addr) l_addr, struct r_scope_elem *scope[], -+ void *const reloc_addr_arg) -+{ -+ ElfW(Addr) *const reloc_addr = reloc_addr_arg; -+ *reloc_addr += l_addr; -+} -+ -+static inline void - __attribute__ ((always_inline)) - elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], - ElfW(Addr) l_addr, ---- a/sysdeps/arm/dl-machine.h -+++ b/sysdeps/arm/dl-machine.h -@@ -637,6 +638,15 @@ elf_machine_rel_relative (Elf32_Addr l_a - *reloc_addr += l_addr; - } - -+static inline void -+__attribute ((always_inline)) -+elf_machine_relr_relative (ElfW(Addr) l_addr, struct r_scope_elem *scope[], -+ void *const reloc_addr_arg) -+{ -+ ElfW(Addr) *const reloc_addr = reloc_addr_arg; -+ *reloc_addr += l_addr; -+} -+ - # ifndef RTLD_BOOTSTRAP - static inline void - __attribute__ ((always_inline)) ---- a/sysdeps/i386/dl-machine.h -+++ b/sysdeps/i386/dl-machine.h -@@ -626,6 +626,15 @@ elf_machine_rel_relative (Elf32_Addr l_a - *reloc_addr += l_addr; - } - -+static inline void -+__attribute ((always_inline)) -+elf_machine_relr_relative (ElfW(Addr) l_addr, struct r_scope_elem *scope[], -+ void *const reloc_addr_arg) -+{ -+ ElfW(Addr) *const reloc_addr = reloc_addr_arg; -+ *reloc_addr += l_addr; -+} -+ - # ifndef RTLD_BOOTSTRAP - static inline void - __attribute__ ((always_inline)) ---- a/sysdeps/x86_64/dl-machine.h -+++ b/sysdeps/x86_64/dl-machine.h -@@ -545,6 +546,15 @@ elf_machine_rela_relative (ElfW(Addr) l_ - } - - static inline void -+__attribute ((always_inline)) -+elf_machine_relr_relative (ElfW(Addr) l_addr, struct r_scope_elem *scope[], -+ void *const reloc_addr_arg) -+{ -+ ElfW(Addr) *const reloc_addr = reloc_addr_arg; -+ *reloc_addr += l_addr; -+} -+ -+static inline void - __attribute ((always_inline)) - elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], - ElfW(Addr) l_addr, const ElfW(Rela) *reloc, ---- a/sysdeps/arm/dl-machine-rel.h 2022-02-03 05:27:54.000000000 +0000 -+++ b/sysdeps/arm/dl-machine-rel.h 2022-04-11 10:16:03.103743770 +0000 -@@ -23,6 +23,7 @@ - Prelinked libraries may use Elf32_Rela though. */ - #define ELF_MACHINE_NO_RELA defined RTLD_BOOTSTRAP - #define ELF_MACHINE_NO_REL 0 -+#define ELF_MACHINE_NO_RELR 0 - - /* ARM never uses Elf32_Rela relocations for the dynamic linker. - Prelinked libraries may use Elf32_Rela though. */ ---- a/sysdeps/generic/dl-machine-rel.h 2022-02-03 05:27:54.000000000 +0000 -+++ b/sysdeps/generic/dl-machine-rel.h 2022-04-11 10:28:40.996539086 +0000 -@@ -23,6 +23,7 @@ - #define ELF_MACHINE_NO_REL 1 - /* Defined if the architecture supports Elf{32,64}_Rela relocations. */ - #define ELF_MACHINE_NO_RELA 0 -+#define ELF_MACHINE_NO_RELR 0 - /* Used to calculate the index of link_map l_reloc_result. */ - #define PLTREL ElfW(Rela) - ---- a/sysdeps/i386/dl-machine-rel.h 2022-02-03 05:27:54.000000000 +0000 -+++ b/sysdeps/i386/dl-machine-rel.h 2022-04-11 10:16:17.677066810 +0000 -@@ -23,6 +23,7 @@ - Prelinked libraries may use Elf32_Rela though. */ - #define ELF_MACHINE_NO_RELA defined RTLD_BOOTSTRAP - #define ELF_MACHINE_NO_REL 0 -+#define ELF_MACHINE_NO_RELR 0 - - /* The i386 never uses Elf32_Rela relocations for the dynamic linker. - Prelinked libraries may use Elf32_Rela though. */ diff --git a/packages/devel/glibc/patches/glibc-0001-linux-fix-missing-convert-scm-timestamps-BZ-28860.patch b/packages/devel/glibc/patches/glibc-0001-linux-fix-missing-convert-scm-timestamps-BZ-28860.patch deleted file mode 100644 index e8ebe7c66..000000000 --- a/packages/devel/glibc/patches/glibc-0001-linux-fix-missing-convert-scm-timestamps-BZ-28860.patch +++ /dev/null @@ -1,31 +0,0 @@ -From patchwork Thu Feb 3 20:07:40 2022 -Subject: [COMMITTED] linux: Fix missing __convert_scm_timestamps (BZ #28860) -Date: Thu, 3 Feb 2022 17:07:40 -0300 -From: Adhemerval Zanella - -Commit 948ce73b31 made recvmsg/recvmmsg to always call -__convert_scm_timestamps for 64 bit time_t symbol, so adjust it to -always build it for __TIMESIZE != 64. - -It fixes build for architecture with 32 bit time_t support when -configured with minimum kernel of 5.1. ---- - sysdeps/unix/sysv/linux/convert_scm_timestamps.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/sysdeps/unix/sysv/linux/convert_scm_timestamps.c b/sysdeps/unix/sysv/linux/convert_scm_timestamps.c -index 82171bf325..dfc8c2beff 100644 ---- a/sysdeps/unix/sysv/linux/convert_scm_timestamps.c -+++ b/sysdeps/unix/sysv/linux/convert_scm_timestamps.c -@@ -16,9 +16,9 @@ - License along with the GNU C Library; if not, see - . */ - --#include -+#include - --#ifndef __ASSUME_TIME64_SYSCALLS -+#if __TIMESIZE != 64 - # include - # include - # include diff --git a/packages/devel/glibc/patches/glibc-fix-dns-with-broken-routers.patch b/packages/devel/glibc/patches/glibc-fix-dns-with-broken-routers.patch index 4bce31923..6e04bf149 100644 --- a/packages/devel/glibc/patches/glibc-fix-dns-with-broken-routers.patch +++ b/packages/devel/glibc/patches/glibc-fix-dns-with-broken-routers.patch @@ -9,85 +9,90 @@ Date: Tue Oct 1 12:09:07 2013 +0300 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -730,6 +730,38 @@ gaih_inet (const char *name, const struc - if (res_ctx == NULL) - no_more = 1; + if (res_ctx == NULL) + no_more = 1; -+ /* AI_ADDRCONFIG determines whether or not we should suppress any -+ * hostname lookups. If the local host has only IPv4 interfaces, -+ * then suppress lookups for IPv6 addresses, and vice versa; if -+ * the local host has only IPv6 interfaces, suppress any lookups -+ * for IPv4 addresses.. -+ * -+ * Link-local IPv6 addresses and loopback addresses of either -+ * family are ignored when determining whether or not the host has -+ * an interface of the given address family, cf. __check_pf(). -+ * -+ * This logic is only applied for AF_UNSPEC. If the caller -+ * explicitly requested an address family, give him what he asked -+ * for. -+ * -+ * If we didn't find any interfaces of either address family, -+ * we ignore AI_ADDRCONFIG and return all available resutlts. */ -+ int suppress_af = 0; -+ if (req->ai_family == AF_UNSPEC) -+ { -+ struct in6addrinfo *in6ai = NULL; -+ size_t in6ailen = 0; -+ bool seen_ipv4 = false; -+ bool seen_ipv6 = false; -+ __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen); -+ __free_in6ai (in6ai); ++ /* AI_ADDRCONFIG determines whether or not we should suppress any ++ * hostname lookups. If the local host has only IPv4 interfaces, ++ * then suppress lookups for IPv6 addresses, and vice versa; if ++ * the local host has only IPv6 interfaces, suppress any lookups ++ * for IPv4 addresses.. ++ * ++ * Link-local IPv6 addresses and loopback addresses of either ++ * family are ignored when determining whether or not the host has ++ * an interface of the given address family, cf. __check_pf(). ++ * ++ * This logic is only applied for AF_UNSPEC. If the caller ++ * explicitly requested an address family, give him what he asked ++ * for. ++ * ++ * If we didn't find any interfaces of either address family, ++ * we ignore AI_ADDRCONFIG and return all available resutlts. */ ++ int suppress_af = 0; ++ if (req->ai_family == AF_UNSPEC) ++ { ++ struct in6addrinfo *in6ai = NULL; ++ size_t in6ailen = 0; ++ bool seen_ipv4 = false; ++ bool seen_ipv6 = false; ++ __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen); ++ __free_in6ai (in6ai); + -+ if(seen_ipv4 && !seen_ipv6) -+ suppress_af = AF_INET6; -+ else if(seen_ipv6 && !seen_ipv4) -+ suppress_af = AF_INET; -+ } ++ if(seen_ipv4 && !seen_ipv6) ++ suppress_af = AF_INET6; ++ else if(seen_ipv6 && !seen_ipv4) ++ suppress_af = AF_INET; ++ } + - while (!no_more) - { - no_data = 0; + while (!no_more) + { + no_data = 0; @@ -737,7 +769,7 @@ gaih_inet (const char *name, const struc - /* gethostbyname4_r sends out parallel A and AAAA queries and - is thus only suitable for PF_UNSPEC. */ -- if (req->ai_family == PF_UNSPEC) -+ if (req->ai_family == PF_UNSPEC && !suppress_af) - fct4 = __nss_lookup_function (nip, "gethostbyname4_r"); + /* gethostbyname4_r sends out parallel A and AAAA queries and + is thus only suitable for PF_UNSPEC. */ +- if (req->ai_family == PF_UNSPEC) ++ if (req->ai_family == PF_UNSPEC && !suppress_af) + fct4 = __nss_lookup_function (nip, "gethostbyname4_r"); - if (fct4 != NULL) -@@ -826,20 +858,22 @@ gaih_inet (const char *name, const struc + if (fct4 != NULL) +@@ -826,25 +858,27 @@ gaih_inet (const char *name, const struc - if (fct != NULL) + if (fct != NULL) + { +- if (req->ai_family == AF_INET6 +- || req->ai_family == AF_UNSPEC) ++ if ((req->ai_family == AF_INET6 ++ || req->ai_family == AF_UNSPEC) ++ && suppress_af != AF_INET6) + { + if ((result = gethosts (fct, AF_INET6, name, req, tmpbuf, + res, &status, &no_data)) != 0) { -- if (req->ai_family == AF_INET6 -- || req->ai_family == AF_UNSPEC) -+ if ((req->ai_family == AF_INET6 -+ || req->ai_family == AF_UNSPEC) -+ && suppress_af != AF_INET6) - { - gethosts (AF_INET6); - no_inet6_data = no_data; - inet6_status = status; - } -- if (req->ai_family == AF_INET -- || req->ai_family == AF_UNSPEC -- || (req->ai_family == AF_INET6 -- && (req->ai_flags & AI_V4MAPPED) -- /* Avoid generating the mapped addresses if we -- know we are not going to need them. */ -- && ((req->ai_flags & AI_ALL) || !got_ipv6))) -+ if ((req->ai_family == AF_INET -+ || req->ai_family == AF_UNSPEC -+ || (req->ai_family == AF_INET6 -+ && (req->ai_flags & AI_V4MAPPED) -+ /* Avoid generating the mapped addresses if we -+ know we are not going to need them. */ -+ && ((req->ai_flags & AI_ALL) || !got_ipv6))) -+ && suppress_af != AF_INET) - { - gethosts (AF_INET); - + __resolv_context_put (res_ctx); + goto out; + } + no_inet6_data = no_data; + inet6_status = status; + } +- if (req->ai_family == AF_INET +- || req->ai_family == AF_UNSPEC +- || (req->ai_family == AF_INET6 +- && (req->ai_flags & AI_V4MAPPED) +- /* Avoid generating the mapped addresses if we +- know we are not going to need them. */ +- && ((req->ai_flags & AI_ALL) || !res->got_ipv6))) ++ if ((req->ai_family == AF_INET ++ || req->ai_family == AF_UNSPEC ++ || (req->ai_family == AF_INET6 ++ && (req->ai_flags & AI_V4MAPPED) ++ /* Avoid generating the mapped addresses if we ++ know we are not going to need them. */ ++ && ((req->ai_flags & AI_ALL) || !res->got_ipv6))) ++ && suppress_af != AF_INET) + { + if ((result = gethosts (fct, AF_INET, name, req, tmpbuf, + res, &status, &no_data)) != 0) --- a/sysdeps/unix/sysv/linux/check_pf.c +++ b/sysdeps/unix/sysv/linux/check_pf.c @@ -224,7 +224,8 @@ make_request (int fd, pid_t pid) diff --git a/packages/devel/gobject-introspection/package.mk b/packages/devel/gobject-introspection/package.mk index b6ea8375d..872e442d2 100644 --- a/packages/devel/gobject-introspection/package.mk +++ b/packages/devel/gobject-introspection/package.mk @@ -4,8 +4,8 @@ # Copyright (C) 2020-present Team CoreELEC (https://coreelec.org) PKG_NAME="gobject-introspection" -PKG_VERSION="1.72.0" -PKG_SHA256="07c30d7f465dabd861c03a950430343e976d445179ad451a4dd1b17329e1cbae" +PKG_VERSION="1.74.0" +PKG_SHA256="79ed5d764d288f046b027ff064be174d7904904565de150a94841740a2a0455d" PKG_ARCH="any" PKG_LICENSE="LGPL" PKG_SITE="http://www.gtk.org/" @@ -18,7 +18,9 @@ PKG_LONGDESC="GLib is a library which includes support routines for C such as li PKG_TOOLCHAIN="meson" pre_configure_host() { - PKG_MESON_OPTS_HOST="-Ddoctool=disabled" + PKG_MESON_OPTS_HOST=" \ + -Ddoctool=disabled \ + -Dbuild_introspection_data=false" # prevent g-ir-scanner from writing cache data to $HOME export GI_SCANNER_DISABLE_CACHE="1" diff --git a/packages/devel/gperftools/package.mk b/packages/devel/gperftools/package.mk new file mode 100644 index 000000000..7e447f7e8 --- /dev/null +++ b/packages/devel/gperftools/package.mk @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2021-present Team CoreELEC (https://coreelec.org) + +PKG_NAME="gperftools" +PKG_VERSION="2.9.1" +PKG_SHA256="484a88279d2fa5753d7e9dea5f86954b64975f20e796a6ffaf2f3426a674a06a" +PKG_LICENSE="BSD" +PKG_SITE="https://github.com/gperftools/gperftools" +PKG_URL="https://github.com/gperftools/gperftools/archive/${PKG_NAME}-${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Google Performance Tools" +PKG_TOOLCHAIN="autotools" + +PKG_CONFIGURE_OPTS_TARGET="--enable-minimal --disable-debugalloc --disable-static" diff --git a/packages/devel/json-c/package.mk b/packages/devel/json-c/package.mk new file mode 100644 index 000000000..43fa57261 --- /dev/null +++ b/packages/devel/json-c/package.mk @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2010-2011 Roman Weber (roman@openelec.tv) +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2019-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="json-c" +PKG_VERSION="0.16" +PKG_SHA256="c169436bd63a30fce4f9560befccb6bad3d375c8c7e9905ceb4e1f28f2cb24f7" +PKG_LICENSE="MIT" +PKG_SITE="https://github.com/json-c/json-c" +PKG_URL="https://github.com/json-c/json-c/archive/json-c-${PKG_VERSION%-*}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Implements a reference counting object model that allows you to easily construct JSON objects in C." diff --git a/packages/devel/libao/package.mk b/packages/devel/libao/package.mk deleted file mode 100644 index 179583dd5..000000000 --- a/packages/devel/libao/package.mk +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later -# Copyright (C) 2022-present Fewtarius - -PKG_NAME="libao" -PKG_VERSION="cafce902" -PKG_LICENSE="GPL" -PKG_SITE="https://gitlab.xiph.org/xiph/libao" -PKG_URL="${PKG_SITE}.git" -PKG_DEPENDS_TARGET="toolchain" -PKG_LONGDESC="Audio output portability library." -PKG_TOOLCHAIN="autotools" diff --git a/packages/devel/libbpf/package.mk b/packages/devel/libbpf/package.mk new file mode 100644 index 000000000..68a9d32da --- /dev/null +++ b/packages/devel/libbpf/package.mk @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2021-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="libbpf" +PKG_VERSION="0.8.1" +PKG_SHA256="7bda8187efc619d1eb20a1ba5ab949dd68d40dd44945310c91ac0f915fa4a42b" +PKG_LICENSE="LGPL-2.1" +PKG_SITE="https://github.com/libbpf/libbpf" +PKG_URL="https://github.com/libbpf/libbpf/archive/refs/tags/v${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain elfutils" +PKG_LONGDESC="libbpf supports building BPF CO-RE-enabled applications" +PKG_TOOLCHAIN="make" + +make_target() { + make BUILD_STATIC_ONLY=1 \ + PREFIX=${SYSROOT_PREFIX}/usr \ + -C src +} + +makeinstall_target() { + make BUILD_STATIC_ONLY=1 \ + PREFIX=${SYSROOT_PREFIX}/usr \ + -C src install +} diff --git a/packages/devel/libbpf/patches/libbpf-fix-crosscompile-and-sysroot.patch b/packages/devel/libbpf/patches/libbpf-fix-crosscompile-and-sysroot.patch new file mode 100644 index 000000000..8af85a283 --- /dev/null +++ b/packages/devel/libbpf/patches/libbpf-fix-crosscompile-and-sysroot.patch @@ -0,0 +1,43 @@ +diff --git a/src/Makefile b/src/Makefile +index 81ea6b8..7ab5f13 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -67,15 +67,12 @@ INSTALL = install + + DESTDIR ?= + +-ifeq ($(filter-out %64 %64be %64eb %64le %64el s390x, $(shell uname -m)),) +- LIBSUBDIR := lib64 +-else +- LIBSUBDIR := lib +-endif ++LIBSUBDIR := lib + + # By default let the pc file itself use ${prefix} in includedir/libdir so that + # the prefix can be overridden at runtime (eg: --define-prefix) + ifndef LIBDIR ++ PREFIX_PC := /usr + LIBDIR_PC := $$\{prefix\}/$(LIBSUBDIR) + else + LIBDIR_PC := $(LIBDIR) +@@ -106,7 +103,7 @@ $(OBJDIR)/libbpf.so.$(LIBBPF_VERSION): $(SHARED_OBJS) + $^ $(ALL_LDFLAGS) -o $@ + + $(OBJDIR)/libbpf.pc: force +- $(Q)sed -e "s|@PREFIX@|$(PREFIX)|" \ ++ $(Q)sed -e "s|@PREFIX@|$(PREFIX_PC)|" \ + -e "s|@LIBDIR@|$(LIBDIR_PC)|" \ + -e "s|@VERSION@|$(LIBBPF_VERSION)|" \ + < libbpf.pc.template > $@ +diff --git a/src/libbpf.pc.template b/src/libbpf.pc.template +index b45ed53..fe6ddde 100644 +--- a/src/libbpf.pc.template ++++ b/src/libbpf.pc.template +@@ -7,6 +7,6 @@ includedir=${prefix}/include + Name: libbpf + Description: BPF library + Version: @VERSION@ +-Libs: -L${libdir} -lbpf ++Libs: -L${libdir} -lbpf -lz + Requires.private: libelf zlib + Cflags: -I${includedir} diff --git a/packages/devel/libcec/package.mk b/packages/devel/libcec/package.mk index 5d079fe4a..807d7a676 100644 --- a/packages/devel/libcec/package.mk +++ b/packages/devel/libcec/package.mk @@ -3,8 +3,8 @@ # Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) PKG_NAME="libcec" -PKG_VERSION="4.0.7" -PKG_SHA256="bcd92c376993a5721d346edcc09eb17289451f9156b1d1d113c9663c2046315a" +PKG_VERSION="6.0.2" +PKG_SHA256="090696d7a4fb772d7acebbb06f91ab92e025531c7c91824046b9e4e71ecb3377" PKG_LICENSE="GPL" PKG_SITE="http://libcec.pulse-eight.com/" PKG_URL="https://github.com/Pulse-Eight/libcec/archive/libcec-${PKG_VERSION}.tar.gz" @@ -16,10 +16,19 @@ PKG_CMAKE_OPTS_TARGET="-DBUILD_SHARED_LIBS=1 \ -DCMAKE_INSTALL_LIBDIR_NOARCH:STRING=lib \ -DSKIP_PYTHON_WRAPPER=1 \ -DHAVE_IMX_API=0 \ - -DHAVE_AOCEC_API=0 -DHAVE_AMLOGIC_API=0 \ -DHAVE_GIT_BIN=0 \ -DHAVE_RPI_LIB=0" +if [ "${KODIPLAYER_DRIVER}" = "libamcodec" ]; then + if [ "${TARGET_KERNEL_ARCH}" = "arm64" ]; then + PKG_CMAKE_OPTS_TARGET="${PKG_CMAKE_OPTS_TARGET} -DHAVE_AOCEC_API=1" + else + PKG_CMAKE_OPTS_TARGET="${PKG_CMAKE_OPTS_TARGET} -DHAVE_AMLOGIC_API=1" + fi +else + PKG_CMAKE_OPTS_TARGET="${PKG_CMAKE_OPTS_TARGET} -DHAVE_AOCEC_API=0 -DHAVE_AMLOGIC_API=0" +fi + # libX11 and xrandr to read the sink's EDID, used to determine the PC's HDMI physical address if [ "${DISPLAYSERVER}" = "x11" ]; then PKG_DEPENDS_TARGET+=" libX11 libXrandr" @@ -35,7 +44,11 @@ post_makeinstall_target() { # Remove the Python3 demo - useless for us rm -f ${INSTALL}/usr/bin/pyCecClient - PYTHON_DIR=${INSTALL}/usr/lib/${PKG_PYTHON_VERSION} + # Remove the sysmlink and redirect to /var/lib so that we can change libcec versions at run time + rm -f ${INSTALL}/usr/lib/libcec.so.6 + ln -sf /var/lib/libcec.so.6 ${INSTALL}/usr/lib/libcec.so.6 + + PYTHON_DIR=${INSTALL}/usr/lib/${PKG_PYTHON_VERSION} if [ -d ${PYTHON_DIR}/dist-packages ]; then mv ${PYTHON_DIR}/dist-packages ${PYTHON_DIR}/site-packages fi diff --git a/packages/devel/libevent/package.mk b/packages/devel/libevent/package.mk new file mode 100644 index 000000000..88ca43403 --- /dev/null +++ b/packages/devel/libevent/package.mk @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2018-present Team CoreELEC (https://coreelec.org) + +PKG_NAME="libevent" +PKG_VERSION="2.1.11-stable" +PKG_SHA256="a65bac6202ea8c5609fd5c7e480e6d25de467ea1917c08290c521752f147283d" +PKG_LICENSE="BSD" +PKG_SITE="https://libevent.org" +PKG_URL="https://github.com/libevent/libevent/releases/download/release-$PKG_VERSION/$PKG_NAME-$PKG_VERSION.tar.gz" +PKG_DEPENDS_TARGET="toolchain openssl" +PKG_LONGDESC="The libevent API provides a mechanism to execute a callback function when a specific event occurs." +PKG_TOOLCHAIN="configure" + +PKG_CONFIGURE_OPTS_TARGET="--disable-static \ + --disable-libevent-regress \ + --disable-samples \ + --enable-openssl" + +post_unpack() { + # https://github.com/libevent/libevent/issues/863 + # Uninstall.cmake.in is missing from 2.1.11 release + touch $PKG_BUILD/cmake/Uninstall.cmake.in +} + +post_makeinstall_target() { + rm -f $INSTALL/usr/bin/event_rpcgen.py +} diff --git a/packages/devel/libffi/package.mk b/packages/devel/libffi/package.mk index 0c88c3c6f..d3cbcc398 100644 --- a/packages/devel/libffi/package.mk +++ b/packages/devel/libffi/package.mk @@ -14,6 +14,7 @@ PKG_LONGDESC="Foreign Function Interface Library." PKG_TOOLCHAIN="autotools" PKG_CONFIGURE_OPTS_TARGET="--disable-debug \ + --enable-static --disable-shared \ --with-pic \ --enable-structs \ --enable-raw-api \ diff --git a/packages/devel/libfmt/package.mk b/packages/devel/libfmt/package.mk index c6e7d8722..f91751073 100644 --- a/packages/devel/libfmt/package.mk +++ b/packages/devel/libfmt/package.mk @@ -2,13 +2,17 @@ # Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv) PKG_NAME="libfmt" -PKG_VERSION="5.3.0" # newer version break easyrpg! -PKG_SHA256="defa24a9af4c622a7134076602070b45721a43c51598c8456ec6f2c4dbb51c89" +PKG_VERSION="9.1.0" +PKG_SHA256="5dea48d1fcddc3ec571ce2058e13910a0d4a6bab4cc09a809d8b1dd1c88ae6f2" PKG_LICENSE="BSD" PKG_SITE="https://github.com/fmtlib/fmt" -PKG_URL="https://github.com/fmtlib/fmt/archive/$PKG_VERSION.tar.gz" +PKG_URL="https://github.com/fmtlib/fmt/archive/${PKG_VERSION}.tar.gz" PKG_DEPENDS_TARGET="toolchain" PKG_LONGDESC="fmt is an open-source formatting library for C++. It can be used as a safe alternative to printf or as a fast alternative to IOStreams." -PKG_BUILD_FLAGS="+pic" -PKG_CMAKE_OPTS_TARGET="-DFMT_DOC=OFF -DFMT_INSTALL=ON -DFMT_TEST=OFF -DFMT_USE_CPP11=ON" \ No newline at end of file +PKG_CMAKE_OPTS_TARGET="-DCMAKE_CXX_STANDARD=14 \ + -DCMAKE_CXX_EXTENSIONS:BOOL=OFF \ + -DFMT_DOC=OFF \ + -DFMT_INSTALL=ON \ + -DFMT_TEST=OFF \ + -DBUILD_SHARED_LIBS=ON" diff --git a/packages/devel/libirman/package.mk b/packages/devel/libirman/package.mk new file mode 100644 index 000000000..316e55350 --- /dev/null +++ b/packages/devel/libirman/package.mk @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2020-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="libirman" +PKG_VERSION="0.5.2" +PKG_SHA256="43e58d7cd22b3a4c4dc8dcf8542a269ebcb4d8f6ceea0577b9fc882898f09a47" +PKG_LICENSE="GPL" +PKG_SITE="https://sourceforge.net/projects/libirman" +PKG_URL="http://downloads.sourceforge.net/project/libirman/${PKG_VERSION}/${PKG_NAME}-${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain systemd lirc" +PKG_NEED_UNPACK="$(get_pkg_directory lirc)" +PKG_LONGDESC="libirman library for lircd" +PKG_TOOLCHAIN="autotools" +PKG_BUILD_FLAGS="+pic -parallel" + +PKG_CONFIGURE_OPTS_TARGET="--disable-swtest" + +post_configure_target() { + libtool_remove_rpath libtool +} + +post_makeinstall_target() { + rm -rf ${INSTALL}/usr/bin +} diff --git a/packages/devel/libirman/patches/libirman-0001-fix-poll-include.patch b/packages/devel/libirman/patches/libirman-0001-fix-poll-include.patch new file mode 100644 index 000000000..500572434 --- /dev/null +++ b/packages/devel/libirman/patches/libirman-0001-fix-poll-include.patch @@ -0,0 +1,35 @@ +diff -Naur a/config.h.in b/config.h.in +--- a/config.h.in 2016-05-18 18:19:56.000000000 +0200 ++++ b/config.h.in 2016-12-26 22:49:43.514203152 +0100 +@@ -21,6 +21,9 @@ + /* Define to 1 if you have the `mkfifo' function. */ + #undef HAVE_MKFIFO + ++/* defined if poll.h is available */ ++#undef HAVE_POLL_H ++ + /* Define to 1 if you have the `select' function. */ + #undef HAVE_SELECT + +@@ -48,6 +51,9 @@ + /* Define to 1 if you have the header file. */ + #undef HAVE_SYS_FILE_H + ++/* defined if sys/poll.h is available */ ++#undef HAVE_SYS_POLL_H ++ + /* Define to 1 if you have the header file. */ + #undef HAVE_SYS_STAT_H + +diff -Naur a/configure.ac b/configure.ac +--- a/configure.ac 2016-05-18 18:19:41.000000000 +0200 ++++ b/configure.ac 2016-12-26 22:48:40.190031280 +0100 +@@ -20,7 +20,7 @@ + + dnl Checks for header files. + AC_HEADER_STDC +-AC_CHECK_HEADERS(fcntl.h sys/time.h unistd.h termios.h memory.hi sys/file.h) ++AC_CHECK_HEADERS(fcntl.h sys/time.h unistd.h termios.h memory.hi sys/file.h poll.h sys/poll.h) + + dnl Checks for typedefs, structures, and compiler characteristics. + AC_TYPE_PID_T diff --git a/packages/devel/libplist/package.mk b/packages/devel/libplist/package.mk index 9d501fa8c..360bbf769 100644 --- a/packages/devel/libplist/package.mk +++ b/packages/devel/libplist/package.mk @@ -18,6 +18,10 @@ pre_configure_target() { export CONFIG_SHELL="/bin/bash" } +post_configure_target() { + libtool_remove_rpath libtool +} + post_makeinstall_target() { rm -rf ${INSTALL}/usr/bin } diff --git a/packages/devel/libsodium/package.mk b/packages/devel/libsodium/package.mk deleted file mode 100644 index cb9c3c1fc..000000000 --- a/packages/devel/libsodium/package.mk +++ /dev/null @@ -1,14 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later -# Copyright (C) 2020-present Fewtarius -# Sodium License: https://libsodium.gitbook.io/doc/#license - -PKG_NAME="libsodium" -PKG_VERSION="d1580db1b34b7c73abb960e5f464a87ce8b7ed7d" -PKG_SHA256="75902b344f2a2279698266dc53fb48dfa394d2f507ae81c8f935264bbed49588" -PKG_LICENSE="ISC" -PKG_SITE="https://github.com/jedisct1/libsodium" -PKG_URL="$PKG_SITE/archive/$PKG_VERSION.tar.gz" -PKG_GIT_CLONE_BRANCH="stable" -PKG_DEPENDS_HOST="toolchain" -PKG_LONGDESC="A modern, easy-to-use software library for encryption, decryption, signatures, password hashing and more." -PKG_TOOLCHAIN="autotools" diff --git a/packages/devel/make/patches/make-02-fix-large-command-line-on-POSIX-systems.patch b/packages/devel/make/patches/make-02-fix-large-command-line-on-POSIX-systems.patch new file mode 100644 index 000000000..12ac8b767 --- /dev/null +++ b/packages/devel/make/patches/make-02-fix-large-command-line-on-POSIX-systems.patch @@ -0,0 +1,170 @@ +From e249c43741779ae7dd6834f6840384257d4c3dd8 Mon Sep 17 00:00:00 2001 +From: Mike Crowe +Date: Fri, 6 Nov 2020 15:22:37 +0000 +Subject: [PATCH] [SV 45763] Fix large command line on POSIX systems + +When presented with a very long command line (as is common when linking +a large number of files with absolute paths in a deep subdirectory), +make fails to execute the command as it doesn't split the command line +to fit within the limits. + +This is based on a fix for Debian bug 688601[1] by Adam Conrad applied +by Manoj Srivastava originally applied for Debian make-dfsg 4.0-5 in +2014 but dropped in 2018 (it seems under the incorrect assumption that +it had been accepted upstream.) + +I've tweaked Adam's original patch so that it compiles successfully with +-Werror on top of current master. This required: + +* moving the eval_line declaration to the top of the block, so I moved + the macros too +* using a const variable when iterating over the shell +* adding a cast to avoid a signed/unsigned mismatch. + +As suggested in the Savannah bug report[2], I've added a test case that +fails without the rest of the patch. I'm not sure what the consequences +of running the test on non-POSIX targets would be and whether it needs +marking as an expected failure. + +* src/job.c (construct_command_argv_internal): support running commands +longer than MAX_ARG_STRLEN +* tests/scripts/features/long_command_line: add test for such a command +* configure.ac: check for now-required sys/user.h and linux/binfmts.h +headers + +[1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=688601 +[2] https://savannah.gnu.org/bugs/?45763#comment2 +--- + src/job.c | 52 +++++++++++++++++++++++- + tests/scripts/features/long_command_line | 30 ++++++++++++++ + 2 files changed, 81 insertions(+), 1 deletions(-) + create mode 100644 tests/scripts/features/long_command_line + +diff --git a/src/job.c b/src/job.c +index 3bcec38..734c591 100644 +--- a/src/job.c ++++ b/src/job.c +@@ -26,6 +26,12 @@ this program. If not, see . */ + #include "variable.h" + #include "os.h" + ++#include ++#include ++#ifndef PAGE_SIZE ++# define PAGE_SIZE (sysconf(_SC_PAGESIZE)) ++#endif ++ + /* Default shell to use. */ + #ifdef WINDOWS32 + # ifdef HAVE_STRINGS_H +@@ -3228,6 +3236,15 @@ construct_command_argv_internal (char *line, char **restp, const char *shell, + size_t sflags_len = shellflags ? strlen (shellflags) : 0; + #ifdef WINDOWS32 + char *command_ptr = NULL; /* used for batch_mode_shell mode */ ++#endif ++ char *args_ptr; ++#ifdef MAX_ARG_STRLEN ++ static char eval_line[] = "eval\\ \\\"set\\ x\\;\\ shift\\;\\ "; ++#define ARG_NUMBER_DIGITS 5 ++#define EVAL_LEN (sizeof(eval_line)-1 + shell_len + 4 \ ++ + (7 + ARG_NUMBER_DIGITS) * 2 * line_len / (MAX_ARG_STRLEN - 2)) ++#else ++#define EVAL_LEN 0 + #endif + + # ifdef __EMX__ /* is this necessary? */ +@@ -3395,7 +3412,7 @@ construct_command_argv_internal (char *line, char **restp, const char *shell, + } + + new_line = xmalloc ((shell_len*2) + 1 + sflags_len + 1 +- + (line_len*2) + 1); ++ + (line_len*2) + 1 + EVAL_LEN); + ap = new_line; + /* Copy SHELL, escaping any characters special to the shell. If + we don't escape them, construct_command_argv_internal will +@@ -3415,6 +3432,31 @@ construct_command_argv_internal (char *line, char **restp, const char *shell, + #ifdef WINDOWS32 + command_ptr = ap; + #endif ++ ++#if !defined (WINDOWS32) && defined (MAX_ARG_STRLEN) ++ if (unixy_shell && line_len > MAX_ARG_STRLEN) ++ { ++ const char *q; ++ unsigned j; ++ memcpy (ap, eval_line, sizeof (eval_line) - 1); ++ ap += sizeof (eval_line) - 1; ++ for (j = 1; j <= 2 * line_len / (MAX_ARG_STRLEN - 2); j++) ++ ap += sprintf (ap, "\\$\\{%u\\}", j); ++ *ap++ = '\\'; ++ *ap++ = '"'; ++ *ap++ = ' '; ++ /* Copy only the first word of SHELL to $0. */ ++ for (q = shell; *q != '\0'; ++q) ++ { ++ if (isspace ((unsigned char)*q)) ++ break; ++ *ap++ = *q; ++ } ++ *ap++ = ' '; ++ } ++#endif ++ args_ptr = ap; ++ + for (p = line; *p != '\0'; ++p) + { + if (restp != NULL && *p == '\n') +@@ -3462,6 +3504,14 @@ construct_command_argv_internal (char *line, char **restp, const char *shell, + } + #endif + *ap++ = *p; ++#if !defined (WINDOWS32) && defined (MAX_ARG_STRLEN) ++ if (unixy_shell && line_len > MAX_ARG_STRLEN ++ && (ap - args_ptr > (long)(MAX_ARG_STRLEN - 2))) ++ { ++ *ap++ = ' '; ++ args_ptr = ap; ++ } ++#endif + } + if (ap == new_line + shell_len + sflags_len + 2) + { +diff --git a/tests/scripts/features/long_command_line b/tests/scripts/features/long_command_line +new file mode 100644 +index 0000000..3899ac8 +--- /dev/null ++++ b/tests/scripts/features/long_command_line +@@ -0,0 +1,30 @@ ++# -*-perl-*- ++$description = "Test long command line."; ++ ++$details = ""; ++ ++# Variable names containing UTF8 characters ++run_make_test(q! ++# 49 characters ++ARGS:=one two three four five six seven eight niner ten ++# 49*4+3 = 199 characters ++ARGS:=$(ARGS) $(ARGS) $(ARGS) $(ARGS) ++# 199*4+3 = 799 characters ++ARGS:=$(ARGS) $(ARGS) $(ARGS) $(ARGS) ++# 799*4+3 = 3199 characters ++ARGS:=$(ARGS) $(ARGS) $(ARGS) $(ARGS) ++# 3199*4+3 = 12799 characters ++ARGS:=$(ARGS) $(ARGS) $(ARGS) $(ARGS) ++# 12799*4+3 = 51199 characters ++ARGS:=$(ARGS) $(ARGS) $(ARGS) $(ARGS) ++# 51199*4+3 = 204799 characters ++ARGS:=$(ARGS) $(ARGS) $(ARGS) $(ARGS) ++# 24799*2+1 = 409599 characters ++#ARGS:=$(ARGS) $(ARGS) ++ ++test: ++ @: $(ARGS) ++!, ++ '', ""); ++ ++1; +-- +2.20.1 + diff --git a/packages/devel/mimalloc/package.mk b/packages/devel/mimalloc/package.mk new file mode 100644 index 000000000..9fc139869 --- /dev/null +++ b/packages/devel/mimalloc/package.mk @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (C) 2022-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="mimalloc" +PKG_VERSION="2.0.6" +PKG_SHA256="9f05c94cc2b017ed13698834ac2a3567b6339a8bde27640df5a1581d49d05ce5" +PKG_LICENSE="MIT" +PKG_SITE="https://github.com/microsoft/mimalloc" +PKG_URL="https://github.com/microsoft/mimalloc/archive/refs/tags/v${PKG_VERSION}.tar.gz" +PKG_DEPENDS_HOST="cmake:host ninja:host" +PKG_LONGDESC="mimalloc (pronounced "me-malloc") is a general purpose allocator with excellent performance characteristics" + +PKG_CMAKE_OPTS_HOST="-DMI_SECURE=OFF \ + -DMI_DEBUG_FULL=OFF \ + -DMI_OVERRIDE=ON \ + -DMI_XMALLOC=OFF \ + -DMI_SHOW_ERRORS=OFF \ + -DMI_USE_CXX=OFF \ + -DMI_SEE_ASM=OFF \ + -DMI_LOCAL_DYNAMIC_TLS=OFF \ + -DMI_BUILD_SHARED=ON \ + -DMI_BUILD_STATIC=OFF \ + -DMI_BUILD_OBJECT=OFF \ + -DMI_BUILD_TESTS=OFF \ + -DMI_DEBUG_TSAN=OFF \ + -DMI_DEBUG_UBSAN=OFF \ + -DMI_SKIP_COLLECT_ON_EXIT=OFF" diff --git a/packages/devel/mold/package.mk b/packages/devel/mold/package.mk new file mode 100644 index 000000000..0802cea17 --- /dev/null +++ b/packages/devel/mold/package.mk @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (C) 2022-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="mold" +PKG_VERSION="1.6.0" +PKG_SHA256="59cd3ea1a2a5fb50d0d97faddd8bff4c7e71054a576c00a87b17f56ecbd88729" +PKG_LICENSE="AGPL-3.0-or-later" +PKG_SITE="https://github.com/rui314/mold" +PKG_URL="https://github.com/rui314/mold/archive/refs/tags/v${PKG_VERSION}.tar.gz" +PKG_DEPENDS_HOST="cmake:host zlib:host zstd:host openssl:host tbb:host mimalloc:host" +PKG_LONGDESC="mold is a faster drop-in replacement for existing Unix linkers" + +PKG_CMAKE_OPTS_HOST="-DCMAKE_INSTALL_LIBDIR="${TOOLCHAIN}/${TARGET_NAME}/lib" + -DCMAKE_INSTALL_BINDIR="${TARGET_NAME}/bin" \ + -DCMAKE_INSTALL_LIBEXECDIR="${TARGET_NAME}" \ + -DMOLD_LTO=ON \ + -DMOLD_MOSTLY_STATIC=ON \ + -DMOLD_USE_SYSTEM_MIMALLOC=ON \ + -DMOLD_USE_SYSTEM_TBB=ON" + +post_makeinstall_host() { + ln -sf ${TOOLCHAIN}/${TARGET_NAME}/bin/mold ${TARGET_PREFIX}ld.mold +} diff --git a/packages/devel/mold/patches/mold-999.01-PR740-allow-custom-mold-binary-install-path.patch b/packages/devel/mold/patches/mold-999.01-PR740-allow-custom-mold-binary-install-path.patch new file mode 100644 index 000000000..0ecca3b06 --- /dev/null +++ b/packages/devel/mold/patches/mold-999.01-PR740-allow-custom-mold-binary-install-path.patch @@ -0,0 +1,24 @@ +From f7f2ef6182d058f7c58401d9278aa3136cb996f5 Mon Sep 17 00:00:00 2001 +From: SupervisedThinking +Date: Thu, 29 Sep 2022 11:49:57 +0200 +Subject: [PATCH] CMakeLists: allow custom mold binary install path + +- https://cmake.org/cmake/help/latest/command/install.html +- ${CMAKE_INSTALL_BINDIR} defaults to bin if not set +--- + CMakeLists.txt | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 7136cf2b..4542f915 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -287,7 +287,7 @@ if(BUILD_TESTING) + endif() + + if(NOT CMAKE_SKIP_INSTALL_RULES) +- install(TARGETS mold RUNTIME DESTINATION bin) ++ install(TARGETS mold RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + install(FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR}) + install(FILES docs/mold.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1/) + install(CODE " diff --git a/packages/devel/mold/patches/mold-999.01-fix-strip-on-armv7.patch b/packages/devel/mold/patches/mold-999.01-fix-strip-on-armv7.patch new file mode 100644 index 000000000..8bb7c21b2 --- /dev/null +++ b/packages/devel/mold/patches/mold-999.01-fix-strip-on-armv7.patch @@ -0,0 +1,164 @@ +From 610042a8e927106cb2d852fba2a90faa0d0e050f Mon Sep 17 00:00:00 2001 +From: Rui Ueyama +Date: Fri, 21 Oct 2022 07:08:09 +0800 +Subject: [PATCH] [ELF] Set .ARM.exidx's sh_link to .text + +GNU binutil's strip command doesn't like an .ARM.exidx section with +sh_link set to 0. arm-linux-gnueabihf-strip actually crashes on my +machine when the command is run on such a file. + +https://github.com/rui314/mold/issues/801 +--- + elf/arch-arm32.cc | 56 +++++++++++++++++++++++++++++-------------- + elf/mold.h | 2 +- + elf/output-chunks.cc | 4 ++-- + elf/passes.cc | 2 +- + test/elf/exception.sh | 8 +++++++ + 5 files changed, 50 insertions(+), 22 deletions(-) + +diff --git a/elf/arch-arm32.cc b/elf/arch-arm32.cc +index 46e45d43d..bea510763 100644 +--- a/elf/arch-arm32.cc ++++ b/elf/arch-arm32.cc +@@ -552,14 +552,6 @@ void RangeExtensionThunk::copy_buf(Context &ctx) { + } + } + +-template +-static OutputSection *find_exidx_section(Context &ctx) { +- for (std::unique_ptr> &osec : ctx.output_sections) +- if (osec->shdr.sh_type == SHT_ARM_EXIDX) +- return osec.get(); +- return nullptr; +-} +- + // ARM executables use an .ARM.exidx section to look up an exception + // handling record for the current instruction pointer. The table needs + // to be sorted by their addresses. +@@ -569,13 +561,7 @@ static OutputSection *find_exidx_section(Context &ctx) { + // likely that it's due to some historical reason. + // + // This function sorts .ARM.exidx records. +-void sort_arm_exidx(Context &ctx) { +- Timer t(ctx, "sort_arm_exidx"); +- +- OutputSection *osec = find_exidx_section(ctx); +- if (!osec) +- return; +- ++static void sort_exidx(Context &ctx, OutputSection &osec) { + // .ARM.exidx records consists of a signed 31-bit relative address + // and a 32-bit value. The relative address indicates the start + // address of a function that the record covers. The value is one of +@@ -595,11 +581,11 @@ void sort_arm_exidx(Context &ctx) { + ul32 val; + }; + +- if (osec->shdr.sh_size % sizeof(Entry)) ++ if (osec.shdr.sh_size % sizeof(Entry)) + Fatal(ctx) << "invalid .ARM.exidx section size"; + +- Entry *ent = (Entry *)(ctx.buf + osec->shdr.sh_offset); +- i64 num_entries = osec->shdr.sh_size / sizeof(Entry); ++ Entry *ent = (Entry *)(ctx.buf + osec.shdr.sh_offset); ++ i64 num_entries = osec.shdr.sh_size / sizeof(Entry); + + // Entry's addresses are relative to themselves. In order to sort + // records by addresses, we first translate them so that the addresses +@@ -628,4 +614,38 @@ void sort_arm_exidx(Context &ctx) { + }); + } + ++void fixup_arm_exidx_section(Context &ctx) { ++ Timer t(ctx, "fixup_arm_exidx_section"); ++ ++ auto find_exidx = [&]() -> OutputSection * { ++ for (std::unique_ptr> &osec : ctx.output_sections) ++ if (osec->shdr.sh_type == SHT_ARM_EXIDX) ++ return osec.get(); ++ return nullptr; ++ }; ++ ++ OutputSection *exidx = find_exidx(); ++ if (!exidx) ++ return; ++ ++ // Sort .ARM.exidx contents ++ sort_exidx(ctx, *exidx); ++ ++ // .ARM.exidx's sh_link should be set to the .text section index. ++ // Runtime doesn't care about it, but the binutils's strip command does. ++ if (ctx.shdr) { ++ auto find_text = [&]() -> OutputSection * { ++ for (std::unique_ptr> &osec : ctx.output_sections) ++ if (osec->name == ".text") ++ return osec.get(); ++ return nullptr; ++ }; ++ ++ if (OutputSection *text = find_exidx()) { ++ exidx->shdr.sh_link = text->shndx; ++ ctx.shdr->copy_buf(ctx); ++ } ++ } ++} ++ + } // namespace mold::elf +diff --git a/elf/mold.h b/elf/mold.h +index 11938270e..c8bac2b4e 100644 +--- a/elf/mold.h ++++ b/elf/mold.h +@@ -1434,7 +1434,7 @@ template void write_dependency_file(Context &); + // arch-arm32.cc + // + +-void sort_arm_exidx(Context &ctx); ++void fixup_arm_exidx_section(Context &ctx); + + // + // arch-riscv64.cc +diff --git a/elf/output-chunks.cc b/elf/output-chunks.cc +index 54562feb2..0d1d0dcfd 100644 +--- a/elf/output-chunks.cc ++++ b/elf/output-chunks.cc +@@ -847,9 +847,9 @@ get_output_name(Context &ctx, std::string_view name, u64 flags) { + + if ((name == ".rodata" || name.starts_with(".rodata.")) && (flags & SHF_MERGE)) + return (flags & SHF_STRINGS) ? ".rodata.str" : ".rodata.cst"; +- if (name == ".ARM.exidx" || name.starts_with(".ARM.exidx.")) ++ if (name.starts_with(".ARM.exidx")) + return ".ARM.exidx"; +- if (name == ".ARM.extab" || name.starts_with(".ARM.extab.")) ++ if (name.starts_with(".ARM.extab")) + return ".ARM.extab"; + + if (ctx.arg.z_keep_text_section_prefix) { +diff --git a/elf/passes.cc b/elf/passes.cc +index 713a06a84..4bffc3dbd 100644 +--- a/elf/passes.cc ++++ b/elf/passes.cc +@@ -1102,7 +1102,7 @@ void copy_chunks(Context &ctx) { + report_undef_errors(ctx); + + if constexpr (std::is_same_v) +- sort_arm_exidx(ctx); ++ fixup_arm_exidx_section(ctx); + } + + template +diff --git a/test/elf/exception.sh b/test/elf/exception.sh +index 6832966f0..c584c99fa 100755 +--- a/test/elf/exception.sh ++++ b/test/elf/exception.sh +@@ -65,3 +65,11 @@ if [ $MACHINE = x86_64 -o $MACHINE = aarch64 ]; then + $CXX -B. -o $t/exe10 $t/e.o -no-pie + $QEMU $t/exe10 + fi ++ ++$CXX -B. -o $t/exe11 $t/b.o -pie ++$STRIP $t/exe11 ++$QEMU $t/exe11 ++ ++$CXX -B. -o $t/exe12 $t/c.o -no-pie ++$STRIP $t/exe12 ++$QEMU $t/exe12 diff --git a/packages/devel/pcre2/package.mk b/packages/devel/pcre2/package.mk index 5f42205f3..47b9df4a5 100644 --- a/packages/devel/pcre2/package.mk +++ b/packages/devel/pcre2/package.mk @@ -10,10 +10,11 @@ PKG_URL="https://github.com/PCRE2Project/pcre2/releases/download/pcre2-${PKG_VER PKG_DEPENDS_HOST="toolchain:host" PKG_DEPENDS_TARGET="toolchain" PKG_LONGDESC="A set of functions that implement regular expression pattern matching using the same syntax." -PKG_BUILD_FLAGS="+pic +pic:host" +PKG_BUILD_FLAGS="+pic" PKG_CMAKE_OPTS_HOST="-DBUILD_SHARED_LIBS=OFF \ -DBUILD_STATIC_LIBS=ON \ + -DPCRE2_STATIC_PIC=ON \ -DPCRE2_BUILD_PCRE2_8=ON \ -DPCRE2_BUILD_PCRE2_16=ON \ -DPCRE2_BUILD_PCRE2_32=ON \ diff --git a/packages/devel/popt/package.mk b/packages/devel/popt/package.mk index 1c0f708ca..75ba06e3b 100644 --- a/packages/devel/popt/package.mk +++ b/packages/devel/popt/package.mk @@ -3,8 +3,8 @@ # Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) PKG_NAME="popt" -PKG_VERSION="1.18" -PKG_SHA256="5159bc03a20b28ce363aa96765f37df99ea4d8850b1ece17d1e6ad5c24fdc5d1" +PKG_VERSION="1.19" +PKG_SHA256="c25a4838fc8e4c1c8aacb8bd620edb3084a3d63bf8987fdad3ca2758c63240f9" PKG_LICENSE="GPL" PKG_SITE="https://github.com/rpm-software-management/popt" PKG_URL="http://ftp.rpm.org/popt/releases/popt-1.x/${PKG_NAME}-${PKG_VERSION}.tar.gz" diff --git a/packages/devel/slang/package.mk b/packages/devel/slang/package.mk index 362d032f5..a3e93889e 100644 --- a/packages/devel/slang/package.mk +++ b/packages/devel/slang/package.mk @@ -3,12 +3,12 @@ # Copyright (C) 2016-present Team LibreELEC (https://libreelec.tv) PKG_NAME="slang" -PKG_VERSION="2.3.2" -PKG_SHA256="fc9e3b0fc4f67c3c1f6d43c90c16a5c42d117b8e28457c5b46831b8b5d3ae31a" +PKG_VERSION="2.3.3" +PKG_SHA256="f9145054ae131973c61208ea82486d5dd10e3c5cdad23b7c4a0617743c8f5a18" PKG_LICENSE="GPL" PKG_SITE="http://www.jedsoft.org/slang/" PKG_URL="https://www.jedsoft.org/releases/slang/${PKG_NAME}-${PKG_VERSION}.tar.bz2" -PKG_DEPENDS_TARGET="toolchain" +PKG_DEPENDS_TARGET="toolchain pcre" PKG_LONGDESC="A library designed to allow a developer to create robust multi-platform software." PKG_BUILD_FLAGS="-parallel" @@ -17,6 +17,7 @@ PKG_CONFIGURE_OPTS_TARGET="--without-onig" pre_configure_target() { # slang fails to build in subdirs cd ${PKG_BUILD} + sed -i 's|RPATH=".*"|RPATH=""|' configure rm -rf .${TARGET_NAME} } diff --git a/packages/devel/spdlog/package.mk b/packages/devel/spdlog/package.mk index c09b02cc8..b32c2dc9a 100644 --- a/packages/devel/spdlog/package.mk +++ b/packages/devel/spdlog/package.mk @@ -2,13 +2,17 @@ # Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv) PKG_NAME="spdlog" -PKG_VERSION="1.9.2" -PKG_SHA256="6fff9215f5cb81760be4cc16d033526d1080427d236e86d70bb02994f85e3d38" +PKG_VERSION="1.10.0" +PKG_SHA256="697f91700237dbae2326b90469be32b876b2b44888302afbc7aceb68bcfe8224" PKG_LICENSE="MIT" PKG_SITE="https://github.com/gabime/spdlog" PKG_URL="https://github.com/gabime/spdlog/archive/v${PKG_VERSION}.tar.gz" PKG_DEPENDS_TARGET="toolchain libfmt" PKG_LONGDESC="Very fast, header only, C++ logging library." -PKG_TOOLCHAIN="cmake" -PKG_CMAKE_OPTS_TARGET="-DCMAKE_CXX_STANDARD=14 -DCMAKE_CXX_EXTENSIONS:BOOL=OFF -DSPDLOG_FMT_EXTERNAL=ON -DSPDLOG_BUILD_EXAMPLE=OFF -DSPDLOG_BUILD_TESTS=OFF" +PKG_CMAKE_OPTS_TARGET="-DCMAKE_CXX_STANDARD=14 \ + -DCMAKE_CXX_EXTENSIONS:BOOL=OFF \ + -DSPDLOG_BUILD_SHARED=ON \ + -DSPDLOG_FMT_EXTERNAL=ON \ + -DSPDLOG_BUILD_EXAMPLE=OFF \ + -DSPDLOG_BUILD_TESTS=OFF" diff --git a/packages/devel/tbb/package.mk b/packages/devel/tbb/package.mk new file mode 100644 index 000000000..791b57fe3 --- /dev/null +++ b/packages/devel/tbb/package.mk @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (C) 2022-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="tbb" +PKG_VERSION="2021.7.0" +PKG_SHA256="2cae2a80cda7d45dc7c072e4295c675fff5ad8316691f26f40539f7e7e54c0cc" +PKG_LICENSE="Apache-2.0" +PKG_SITE="https://github.com/oneapi-src/oneTBB" +PKG_URL="https://github.com/oneapi-src/oneTBB/archive/refs/tags/v${PKG_VERSION}.tar.gz" +PKG_DEPENDS_HOST="cmake:host ninja:host" +PKG_LONGDESC="oneTBB is a flexible C++ library that simplifies the work of adding parallelism to complex applications" + +PKG_CMAKE_OPTS_HOST="-DTBB_TEST=OFF \ + -DTBB_EXAMPLES=OFF \ + -DTBB_STRICT=OFF \ + -DTBB4PY_BUILD=OFF \ + -DTBB_BUILD=ON \ + -DTBBMALLOC_BUILD=ON \ + -DTBBMALLOC_PROXY_BUILD=ON \ + -DTBB_CPF=OFF \ + -DTBB_FIND_PACKAGE=OFF \ + -DTBB_DISABLE_HWLOC_AUTOMATIC_SEARCH=OFF \ + -DTBB_ENABLE_IPO=ON" + +pre_configure_host() { + export CXXFLAGS+=" -D__TBB_DYNAMIC_LOAD_ENABLED=0" +} diff --git a/packages/devel/tbb/patches/tbb-999.01-PR824-retry-if-pthread_create-fails-with-EAGAIN.patch b/packages/devel/tbb/patches/tbb-999.01-PR824-retry-if-pthread_create-fails-with-EAGAIN.patch new file mode 100644 index 000000000..c97f7c7cc --- /dev/null +++ b/packages/devel/tbb/patches/tbb-999.01-PR824-retry-if-pthread_create-fails-with-EAGAIN.patch @@ -0,0 +1,168 @@ +From 3a8bc6478654afcbd219f45e7ea01353c2d57eb6 Mon Sep 17 00:00:00 2001 +From: Rui Ueyama +Date: Sat, 7 May 2022 19:55:24 +0800 +Subject: [PATCH] Retry if pthread_create fails with EAGAIN + +On many Unix-like systems, pthread_create can fail spuriously even if +the running machine has enough resources to spawn a new thread. +Therefore, if EAGAIN is returned from pthread_create, we actually have +to try again. + +I observed this issue when running the mold linker +(https://github.com/rui314/mold) under a heavy load. mold uses OneTBB +for parallelization. + +As another data point, Go has the same logic to retry on EAGAIN: +https://go-review.googlesource.com/c/go/+/33894/ + +nanosleep is defined in POSIX 2001, so I believe that all Unix-like +systems support it. + +Signed-off-by: Rui Ueyama +--- + src/tbb/rml_thread_monitor.h | 30 +++++++++++++++- + test/CMakeLists.txt | 3 ++ + test/tbb/test_pthread_create.cpp | 59 ++++++++++++++++++++++++++++++++ + 3 files changed, 91 insertions(+), 1 deletion(-) + create mode 100644 test/tbb/test_pthread_create.cpp + +diff --git a/src/tbb/rml_thread_monitor.h b/src/tbb/rml_thread_monitor.h +index 13b556380..dc046ba00 100644 + src/tbb/rml_thread_monitor.h | 19 ++++++++++++++++++- + 1 file changed, 18 insertions(+), 1 deletion(-) + +diff --git a/src/tbb/rml_thread_monitor.h b/src/tbb/rml_thread_monitor.h +index 13b556380..5b844b232 100644 +--- a/src/tbb/rml_thread_monitor.h ++++ b/src/tbb/rml_thread_monitor.h +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + #else + #error Unsupported platform + #endif +@@ -183,6 +184,32 @@ inline void thread_monitor::check( int error_code, const char* routine ) { + } + } + ++// pthread_create(2) can spuriously fail on Linux. This is a function ++// to wrap pthread_create(2) to retry if it fails with EAGAIN. ++inline void do_pthread_create(pthread_t *handle, pthread_attr_t *s, void* (*thread_routine)(void*), void* arg) { ++#ifdef __linux__ ++ int tries = 0; ++ const int max_num_tries = 20; ++ ++ for (;;) { ++ int error_code = pthread_create(handle, s, thread_routine, arg); ++ if (!error_code) ++ break; ++ if (error_code != EAGAIN || tries++ > max_num_tries) { ++ handle_perror(error_code, "pthread_create has failed"); ++ break; ++ } ++ ++ // Retry after tries * 1 millisecond. ++ struct timespec ts = {0, tries * 1000 * 1000}; ++ nanosleep(&ts, NULL); ++ } ++#else ++ if (int error_code = pthread_create(handle, s, thread_routine, arg)) ++ handle_perror(error_code, "pthread_create has failed"); ++#endif ++} ++ + inline thread_monitor::handle_type thread_monitor::launch( void* (*thread_routine)(void*), void* arg, std::size_t stack_size ) { + // FIXME - consider more graceful recovery than just exiting if a thread cannot be launched. + // Note that there are some tricky situations to deal with, such that the thread is already +@@ -191,8 +218,9 @@ inline thread_monitor::handle_type thread_monitor::launch( void* (*thread_routin + check(pthread_attr_init( &s ), "pthread_attr_init has failed"); + if( stack_size>0 ) + check(pthread_attr_setstacksize( &s, stack_size ), "pthread_attr_setstack_size has failed" ); ++ + pthread_t handle; +- check( pthread_create( &handle, &s, thread_routine, arg ), "pthread_create has failed" ); ++ do_pthread_create(&handle, &s, thread_routine, arg); + check( pthread_attr_destroy( &s ), "pthread_attr_destroy has failed" ); + return handle; + } +diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt +index f15679e83..92802b015 100644 +--- a/test/CMakeLists.txt ++++ b/test/CMakeLists.txt +@@ -373,6 +373,9 @@ if (TARGET TBB::tbb) + if (APPLE OR ANDROID_PLATFORM) + target_link_libraries(test_dynamic_link PRIVATE -rdynamic) # for the test_dynamic_link + endif() ++ if (UNIX AND NOT APPLE) ++ tbb_add_test(SUBDIR tbb NAME test_pthread_create DEPENDENCIES TBB::tbb) ++ endif() + tbb_add_test(SUBDIR tbb NAME test_collaborative_call_once DEPENDENCIES TBB::tbb) + tbb_add_test(SUBDIR tbb NAME test_concurrent_lru_cache DEPENDENCIES TBB::tbb) + tbb_add_test(SUBDIR tbb NAME test_concurrent_unordered_map DEPENDENCIES TBB::tbb) +diff --git a/test/tbb/test_pthread_create.cpp b/test/tbb/test_pthread_create.cpp +new file mode 100644 +index 000000000..4cb1f4ea5 +--- /dev/null ++++ b/test/tbb/test_pthread_create.cpp +@@ -0,0 +1,59 @@ ++/* ++ Copyright (c) 2005-2022 Intel Corporation ++ ++ Licensed under the Apache License, Version 2.0 (the "License"); ++ you may not use this file except in compliance with the License. ++ You may obtain a copy of the License at ++ ++ http://www.apache.org/licenses/LICENSE-2.0 ++ ++ Unless required by applicable law or agreed to in writing, software ++ distributed under the License is distributed on an "AS IS" BASIS, ++ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ See the License for the specific language governing permissions and ++ limitations under the License. ++*/ ++ ++#include "common/test.h" ++#include "common/utils.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++//! Test that thread pool creation won't be affected with a spurious failure of pthread_create(). ++//! \brief \ref error_guessing ++TEST_CASE("pthread_create is not affected by fork") { ++ std::atomic_bool done; ++ ++ std::thread thr([&]() { ++ while (!done) { ++ pid_t pid = fork(); ++ CHECK(pid != -1); ++ ++ if (pid == 0) { ++ // child ++ _exit(0); ++ } else { ++ int wstatus; ++ do { ++ pid_t pid2 = waitpid(pid, &wstatus, 0); ++ CHECK(pid2 != -1); ++ } while (!WIFEXITED(wstatus) && !WIFSIGNALED(wstatus)); ++ } ++ } ++ }); ++ ++ for (int i = 0; i < 50; i++) { ++ tbb::task_scheduler_handle handle{tbb::attach{}}; ++ tbb::parallel_for(0, 10000, [](int) {}); ++ tbb::finalize(handle); ++ } ++ ++ done = true; ++ thr.join(); ++} diff --git a/packages/games/emulators/PPSSPPSDL/package.mk b/packages/games/emulators/PPSSPPSDL/package.mk index fffb0b3fa..cd621a7b3 100644 --- a/packages/games/emulators/PPSSPPSDL/package.mk +++ b/packages/games/emulators/PPSSPPSDL/package.mk @@ -2,7 +2,7 @@ # Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert) # Copyright (C) 2022-present Fewtarius PKG_NAME="PPSSPPSDL" -PKG_VERSION="eb18a87eeec1827a83ac6e9b3bc0e29043616205" +PKG_VERSION="109db81eca29fcd618b4ebf7969d1f2a40918410" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPLv2" @@ -32,17 +32,16 @@ if [ "${OPENGLES_SUPPORT}" = yes ]; then -DUSING_X11_VULKAN=OFF" fi -### Vulkan is still not working for PPSSPP on the win600 yet. -#if [ "${VULKAN_SUPPORT}" = "yes" ] -#then -# PKG_DEPENDS_TARGET+=" vulkan-loader vulkan-headers" -# PKG_CMAKE_OPTS_TARGET+=" -DUSE_VULKAN_DISPLAY_KHR=ON \ -# -DVULKAN=ON \ -# -DEGL_NO_X11=1 -# -DMESA_EGL_NO_X11_HEADERS=1" -#else +if [ "${VULKAN_SUPPORT}" = "yes" ] +then + PKG_DEPENDS_TARGET+=" vulkan-loader vulkan-headers" + PKG_CMAKE_OPTS_TARGET+=" -DUSE_VULKAN_DISPLAY_KHR=ON \ + -DVULKAN=ON \ + -DEGL_NO_X11=1 + -DMESA_EGL_NO_X11_HEADERS=1" +else PKG_CMAKE_OPTS_TARGET+=" -DVULKAN=OFF" -#fi +fi if [ "${DISPLAYSERVER}" = "wl" ]; then PKG_DEPENDS_TARGET+=" wayland ${WINDOWMANAGER}" diff --git a/packages/games/emulators/amiberry/package.mk b/packages/games/emulators/amiberry/package.mk index 5683eea89..462c1e7d6 100644 --- a/packages/games/emulators/amiberry/package.mk +++ b/packages/games/emulators/amiberry/package.mk @@ -3,7 +3,7 @@ PKG_NAME="amiberry" PKG_ARCH="arm aarch64" -PKG_VERSION="d64358d725e27e7273f93ce290b31abf4ab3b4a9" +PKG_VERSION="c3d5861545af0e579ae7d7f5768166c389b4dce1" PKG_LICENSE="GPLv3" PKG_SITE="https://github.com/midwan/amiberry" PKG_URL="${PKG_SITE}.git" diff --git a/packages/games/emulators/dolphinsa/config/RG353P/WiiControllerProfiles/classic.ini b/packages/games/emulators/dolphinsa/config/RG353P/WiiControllerProfiles/classic.ini new file mode 100644 index 000000000..93256a3d6 --- /dev/null +++ b/packages/games/emulators/dolphinsa/config/RG353P/WiiControllerProfiles/classic.ini @@ -0,0 +1,27 @@ +[Wiimote1] +Device = evdev/0/retrogame_joypad +Extension = Classic +Source = 1 +Classic/Buttons/A = Button 1 +Classic/Buttons/B = Button 0 +Classic/Buttons/X = Button 2 +Classic/Buttons/Y = Button 3 +Classic/Buttons/ZL = Button 6 +Classic/Buttons/ZR = Button 7 +Classic/Buttons/- = Button 8 +Classic/Buttons/+ = Button 9 +Classic/Left Stick/Up = Axis 1- +Classic/Left Stick/Down = Axis 1+ +Classic/Left Stick/Left = Axis 0- +Classic/Left Stick/Right = Axis 0+ +Classic/Right Stick/Up = Axis 3- +Classic/Right Stick/Down = Axis 3+ +Classic/Right Stick/Left = Axis 2- +Classic/Right Stick/Right = Axis 2+ +Classic/Triggers/L = Button 4 +Classic/Triggers/R = Button 5 +Classic/D-Pad/Up = Button 13 +Classic/D-Pad/Down = Button 14 +Classic/D-Pad/Left = Button 15 +Classic/D-Pad/Right = Button 16 + diff --git a/packages/games/emulators/dolphinsa/config/RG353P/WiiControllerProfiles/nunchuck.ini b/packages/games/emulators/dolphinsa/config/RG353P/WiiControllerProfiles/nunchuck.ini new file mode 100644 index 000000000..1b40dbeaa --- /dev/null +++ b/packages/games/emulators/dolphinsa/config/RG353P/WiiControllerProfiles/nunchuck.ini @@ -0,0 +1,25 @@ +[Wiimote1] +Device = evdev/0/retrogame_joypad +Extension = Nunchuk +Buttons/A = Button 0 +Buttons/B = Button 1 +Buttons/1 = Button 3 +Buttons/2 = Button 2 +Buttons/- = Button 8 +Buttons/+ = Button 9 +D-Pad/Up = Button 13 +D-Pad/Down = Button 14 +D-Pad/Left = Button 15 +D-Pad/Right = Button 16 +Shake/X = Button 6 +Shake/Y = Button 6 +Shake/Z = Button 6 +Nunchuk/Buttons/C = Button 5 +Nunchuk/Buttons/Z = Button 4 +Nunchuk/Stick/Up = Axis 1- +Nunchuk/Stick/Down = Axis 1+ +Nunchuk/Stick/Left = Axis 0- +Nunchuk/Stick/Right = Axis 0+ +Nunchuk/Shake/X = Button 7 +Nunchuk/Shake/Y = Button 7 +Nunchuk/Shake/Z = Button 7 diff --git a/packages/games/emulators/dolphinsa/config/RG353P/WiiControllerProfiles/remote.ini b/packages/games/emulators/dolphinsa/config/RG353P/WiiControllerProfiles/remote.ini new file mode 100644 index 000000000..be1aea460 --- /dev/null +++ b/packages/games/emulators/dolphinsa/config/RG353P/WiiControllerProfiles/remote.ini @@ -0,0 +1,15 @@ +[Wiimote1] +Device = evdev/0/retrogame_joypad +Buttons/A = Button 0 +Buttons/B = Button 1 +Buttons/1 = Button 3 +Buttons/2 = Button 2 +Buttons/- = Button 8 +Buttons/+ = Button 9 +D-Pad/Up = Button 13 +D-Pad/Down = Button 14 +D-Pad/Left = Button 15 +D-Pad/Right = Button 16 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 diff --git a/packages/games/emulators/dolphinsa/config/RG552/GCPadNew.ini b/packages/games/emulators/dolphinsa/config/RG552/GCPadNew.ini index 8ebced2df..e8eccb2e0 100644 --- a/packages/games/emulators/dolphinsa/config/RG552/GCPadNew.ini +++ b/packages/games/emulators/dolphinsa/config/RG552/GCPadNew.ini @@ -1,12 +1,12 @@ [GCPad1] Device = evdev/0/retrogame_joypad -Buttons/A = Button 0 -Buttons/B = Button 1 -Buttons/Start = Button 9 -Buttons/X = Button 3 -Buttons/Y = Button 2 +Buttons/A = Button 1 +Buttons/B = Button 0 +Buttons/Start = Button 8 +Buttons/X = Button 2 +Buttons/Y = Button 3 Buttons/Z = Button 7 -Buttons/Hotkey = Button 8 +Buttons/Hotkey = Button 9 C-Stick/Dead Zone = 25.000000000000000 C-Stick/Down = Axis 3+ C-Stick/Left = Axis 2- diff --git a/packages/games/emulators/dolphinsa/config/RG552/WiiControllerProfiles/classic.ini b/packages/games/emulators/dolphinsa/config/RG552/WiiControllerProfiles/classic.ini new file mode 100644 index 000000000..93256a3d6 --- /dev/null +++ b/packages/games/emulators/dolphinsa/config/RG552/WiiControllerProfiles/classic.ini @@ -0,0 +1,27 @@ +[Wiimote1] +Device = evdev/0/retrogame_joypad +Extension = Classic +Source = 1 +Classic/Buttons/A = Button 1 +Classic/Buttons/B = Button 0 +Classic/Buttons/X = Button 2 +Classic/Buttons/Y = Button 3 +Classic/Buttons/ZL = Button 6 +Classic/Buttons/ZR = Button 7 +Classic/Buttons/- = Button 8 +Classic/Buttons/+ = Button 9 +Classic/Left Stick/Up = Axis 1- +Classic/Left Stick/Down = Axis 1+ +Classic/Left Stick/Left = Axis 0- +Classic/Left Stick/Right = Axis 0+ +Classic/Right Stick/Up = Axis 3- +Classic/Right Stick/Down = Axis 3+ +Classic/Right Stick/Left = Axis 2- +Classic/Right Stick/Right = Axis 2+ +Classic/Triggers/L = Button 4 +Classic/Triggers/R = Button 5 +Classic/D-Pad/Up = Button 13 +Classic/D-Pad/Down = Button 14 +Classic/D-Pad/Left = Button 15 +Classic/D-Pad/Right = Button 16 + diff --git a/packages/games/emulators/dolphinsa/config/RG552/WiiControllerProfiles/nunchuck.ini b/packages/games/emulators/dolphinsa/config/RG552/WiiControllerProfiles/nunchuck.ini new file mode 100644 index 000000000..1b40dbeaa --- /dev/null +++ b/packages/games/emulators/dolphinsa/config/RG552/WiiControllerProfiles/nunchuck.ini @@ -0,0 +1,25 @@ +[Wiimote1] +Device = evdev/0/retrogame_joypad +Extension = Nunchuk +Buttons/A = Button 0 +Buttons/B = Button 1 +Buttons/1 = Button 3 +Buttons/2 = Button 2 +Buttons/- = Button 8 +Buttons/+ = Button 9 +D-Pad/Up = Button 13 +D-Pad/Down = Button 14 +D-Pad/Left = Button 15 +D-Pad/Right = Button 16 +Shake/X = Button 6 +Shake/Y = Button 6 +Shake/Z = Button 6 +Nunchuk/Buttons/C = Button 5 +Nunchuk/Buttons/Z = Button 4 +Nunchuk/Stick/Up = Axis 1- +Nunchuk/Stick/Down = Axis 1+ +Nunchuk/Stick/Left = Axis 0- +Nunchuk/Stick/Right = Axis 0+ +Nunchuk/Shake/X = Button 7 +Nunchuk/Shake/Y = Button 7 +Nunchuk/Shake/Z = Button 7 diff --git a/packages/games/emulators/dolphinsa/config/RG552/WiiControllerProfiles/remote.ini b/packages/games/emulators/dolphinsa/config/RG552/WiiControllerProfiles/remote.ini new file mode 100644 index 000000000..be1aea460 --- /dev/null +++ b/packages/games/emulators/dolphinsa/config/RG552/WiiControllerProfiles/remote.ini @@ -0,0 +1,15 @@ +[Wiimote1] +Device = evdev/0/retrogame_joypad +Buttons/A = Button 0 +Buttons/B = Button 1 +Buttons/1 = Button 3 +Buttons/2 = Button 2 +Buttons/- = Button 8 +Buttons/+ = Button 9 +D-Pad/Up = Button 13 +D-Pad/Down = Button 14 +D-Pad/Left = Button 15 +D-Pad/Right = Button 16 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 diff --git a/packages/games/emulators/dolphinsa/config/handheld/Dolphin.ini b/packages/games/emulators/dolphinsa/config/handheld/Dolphin.ini index 078dd73e0..e220b8308 100644 --- a/packages/games/emulators/dolphinsa/config/handheld/Dolphin.ini +++ b/packages/games/emulators/dolphinsa/config/handheld/Dolphin.ini @@ -122,7 +122,7 @@ EmulationSpeed = 1.00000000 FrameSkip = 0x00000003 Overclock = 4.00000000 OverclockEnable = False -GFXBackend = +GFXBackend = Vulkan GPUDeterminismMode = auto PerfMapDir = [Movie] diff --git a/packages/games/emulators/dolphinsa/config/handheld/GCPadNew.ini b/packages/games/emulators/dolphinsa/config/handheld/GCPadNew.ini index 130cee4ce..22884a3fd 100644 --- a/packages/games/emulators/dolphinsa/config/handheld/GCPadNew.ini +++ b/packages/games/emulators/dolphinsa/config/handheld/GCPadNew.ini @@ -2,11 +2,11 @@ Device = evdev/0/Microsoft X-Box 360 pad Buttons/A = Button 1 Buttons/B = Button 0 -Buttons/Start = Button 7 +Buttons/Start = Button 6 Buttons/X = Button 3 Buttons/Y = Button 2 Buttons/Z = Button 5 -Buttons/Hotkey = Button 6 +Buttons/Hotkey = Button 7 C-Stick/Dead Zone = 25.000000000000000 C-Stick/Down = Axis 4+ C-Stick/Left = Axis 3- @@ -26,6 +26,4 @@ Main Stick/Modifier/Range = 50.000000000000000 Main Stick/Right = Axis 0+ Main Stick/Up = Axis 1- Triggers/L = Axis 2+ -Triggers/L = Axis 2+ -Triggers/R = Axis 5+ Triggers/R = Axis 5+ diff --git a/packages/games/emulators/dolphinsa/config/handheld/WiiControllerProfiles/classic.ini b/packages/games/emulators/dolphinsa/config/handheld/WiiControllerProfiles/classic.ini new file mode 100644 index 000000000..b9450699c --- /dev/null +++ b/packages/games/emulators/dolphinsa/config/handheld/WiiControllerProfiles/classic.ini @@ -0,0 +1,27 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Extension = Classic +Source = 1 +Classic/Buttons/A = Button 1 +Classic/Buttons/B = Button 0 +Classic/Buttons/X = Button 3 +Classic/Buttons/Y = Button 2 +Classic/Buttons/ZL = Axis 2+ +Classic/Buttons/ZR = Axis 5+ +Classic/Buttons/- = Button 6 +Classic/Buttons/+ = Button 7 +Classic/Buttons/Home = Button 8 +Classic/Left Stick/Up = Axis 1- +Classic/Left Stick/Down = Axis 1+ +Classic/Left Stick/Left = Axis 0- +Classic/Left Stick/Right = Axis 0+ +Classic/Right Stick/Up = Axis 4- +Classic/Right Stick/Down = Axis 4+ +Classic/Right Stick/Left = Axis 3- +Classic/Right Stick/Right = Axis 3+ +Classic/Triggers/L = Button 4 +Classic/Triggers/R = Button 5 +Classic/D-Pad/Up = Axis 7- +Classic/D-Pad/Down = Axis 7+ +Classic/D-Pad/Left = Axis 6- +Classic/D-Pad/Right = Axis 6+ diff --git a/packages/games/emulators/dolphinsa/config/handheld/WiiControllerProfiles/nunchuck.ini b/packages/games/emulators/dolphinsa/config/handheld/WiiControllerProfiles/nunchuck.ini new file mode 100644 index 000000000..ce65fba9b --- /dev/null +++ b/packages/games/emulators/dolphinsa/config/handheld/WiiControllerProfiles/nunchuck.ini @@ -0,0 +1,26 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Extension = Nunchuk +Buttons/A = Button 0 +Buttons/B = Button 1 +Buttons/1 = Button 2 +Buttons/2 = Button 3 +Buttons/- = Button 6 +Buttons/+ = Button 7 +D-Pad/Up = Axis 7- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +Nunchuk/Buttons/C = Button 5 +Nunchuk/Buttons/Z = Axis 5+ +Nunchuk/Stick/Up = Axis 1- +Nunchuk/Stick/Down = Axis 1+ +Nunchuk/Stick/Left = Axis 0- +Nunchuk/Stick/Right = Axis 0+ +Nunchuk/Shake/X = Axis 2+ +Nunchuk/Shake/Y = Axis 2+ +Nunchuk/Shake/Z = Axis 2+ diff --git a/packages/games/emulators/dolphinsa/config/handheld/WiiControllerProfiles/remote.ini b/packages/games/emulators/dolphinsa/config/handheld/WiiControllerProfiles/remote.ini new file mode 100644 index 000000000..29041118a --- /dev/null +++ b/packages/games/emulators/dolphinsa/config/handheld/WiiControllerProfiles/remote.ini @@ -0,0 +1,16 @@ +[Wiimote1] +Device = evdev/0/Microsoft X-Box 360 pad +Buttons/A = Button 0 +Buttons/B = Button 1 +Buttons/1 = Button 2 +Buttons/2 = Button 3 +Buttons/- = Button 6 +Buttons/+ = Button 7 +Buttons/Home = Button 8 +Shake/X = Button 4 +Shake/Y = Button 4 +Shake/Z = Button 4 +D-Pad/Up = Axis 7- +D-Pad/Down = Axis 7+ +D-Pad/Left = Axis 6- +D-Pad/Right = Axis 6+ diff --git a/packages/games/emulators/dolphinsa/package.mk b/packages/games/emulators/dolphinsa/package.mk index fade711d9..ea827bef8 100755 --- a/packages/games/emulators/dolphinsa/package.mk +++ b/packages/games/emulators/dolphinsa/package.mk @@ -3,15 +3,15 @@ PKG_NAME="dolphinsa" PKG_LICENSE="GPLv2" -PKG_DEPENDS_TARGET="toolchain libevdev libdrm ffmpeg zlib libpng lzo libusb zstd" +PKG_DEPENDS_TARGET="toolchain libevdev libdrm ffmpeg zlib libpng lzo libusb zstd ecm" PKG_LONGDESC="Dolphin is a GameCube / Wii emulator, allowing you to play games for these two platforms on PC with improvements. " case ${DEVICE} in RG552|handheld) PKG_SITE="https://github.com/dolphin-emu/dolphin" PKG_URL="${PKG_SITE}.git" - PKG_VERSION="9222956acdfb6a0526b6fdada4aeaa936de9fcd1" - PKG_PATCH_DIRS+=" new" + PKG_VERSION="c931529e7aa5926b8a21a193bf8f80244b3ae888" + PKG_PATCH_DIRS+=" wayland" ;; *) PKG_SITE="https://github.com/rtissera/dolphin" @@ -24,26 +24,26 @@ esac if [ ! "${OPENGL}" = "no" ]; then PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd" - PKG_CONFIGURE_OPTS_TARGET+=" -DENABLE_X11=OFF \ + PKG_CMAKE_OPTS_TARGET+=" -DENABLE_X11=OFF \ -DENABLE_EGL=ON" fi if [ "${OPENGLES_SUPPORT}" = yes ]; then PKG_DEPENDS_TARGET+=" ${OPENGLES}" - PKG_CONFIGURE_OPTS_TARGET+=" -DENABLE_X11=OFF \ + PKG_CMAKE_OPTS_TARGET+=" -DENABLE_X11=OFF \ -DENABLE_EGL=ON" fi if [ "${DISPLAYSERVER}" = "wl" ]; then PKG_DEPENDS_TARGET+=" wayland ${WINDOWMANAGER} xorg-server xrandr libXi" - PKG_CONFIGURE_OPTS_TARGET+=" -DENABLE_X11=ON \ - -DENABLE_EGL=ON" + PKG_CMAKE_OPTS_TARGET+=" -DENABLE_WAYLAND=ON \ + -DENABLE_X11=OFF" fi if [ "${VULKAN_SUPPORT}" = "yes" ] then PKG_DEPENDS_TARGET+=" vulkan-loader vulkan-headers" - PKG_CONFIGURE_OPTS_TARGET+=" -DENABLE_VULKAN=ON" + PKG_CMAKE_OPTS_TARGET+=" -DENABLE_VULKAN=ON" fi PKG_CMAKE_OPTS_TARGET+=" -DENABLE_HEADLESS=ON \ @@ -61,12 +61,14 @@ PKG_CMAKE_OPTS_TARGET+=" -DENABLE_HEADLESS=ON \ -DENCODE_FRAMEDUMPS=OFF \ -DENABLE_CLI_TOOL=OFF" + makeinstall_target() { mkdir -p ${INSTALL}/usr/bin cp -rf ${PKG_BUILD}/.${TARGET_NAME}/Binaries/dolphin* ${INSTALL}/usr/bin cp -rf ${PKG_DIR}/scripts/* ${INSTALL}/usr/bin - chmod +x ${INSTALL}/usr/bin/start_dolphin.sh + chmod +x ${INSTALL}/usr/bin/start_dolphin_gc.sh + chmod +x ${INSTALL}/usr/bin/start_dolphin_wii.sh mkdir -p ${INSTALL}/usr/config/dolphin-emu cp -rf ${PKG_BUILD}/Data/Sys/* ${INSTALL}/usr/config/dolphin-emu @@ -79,9 +81,12 @@ post_install() { DOLPHIN_PLATFORM="drm" ;; *) - DOLPHIN_PLATFORM="x11" + DOLPHIN_PLATFORM="wayland" ;; esac sed -e "s/@DOLPHIN_PLATFORM@/${DOLPHIN_PLATFORM}/g" \ - -i ${INSTALL}/usr/bin/start_dolphin.sh + -i ${INSTALL}/usr/bin/start_dolphin_gc.sh + sed -e "s/@DOLPHIN_PLATFORM@/${DOLPHIN_PLATFORM}/g" \ + -i ${INSTALL}/usr/bin/start_dolphin_wii.sh + } diff --git a/packages/games/emulators/dolphinsa/patches/new/002-x11-hotkeys.patch b/packages/games/emulators/dolphinsa/patches/new/002-x11-hotkeys.patch deleted file mode 100644 index 4348cb492..000000000 --- a/packages/games/emulators/dolphinsa/patches/new/002-x11-hotkeys.patch +++ /dev/null @@ -1,142 +0,0 @@ -diff --git a/Source/Core/Core/HW/GCPadEmu.h b/Source/Core/Core/HW/GCPadEmu.h -index 66a1aee4e4..a03eaebcd3 100644 ---- a/Source/Core/Core/HW/GCPadEmu.h -+++ b/Source/Core/Core/HW/GCPadEmu.h -@@ -65,6 +65,7 @@ public: - static constexpr const char* X_BUTTON = "X"; - static constexpr const char* Y_BUTTON = "Y"; - static constexpr const char* Z_BUTTON = "Z"; -+ static constexpr const char* HOTKEY_BUTTON = "Hotkey"; - static constexpr const char* START_BUTTON = "Start"; - - // i18n: The left trigger button (labeled L on real controllers) -diff --git a/Source/Core/Core/HW/GCPadEmu.cpp b/Source/Core/Core/HW/GCPadEmu.cpp -index 470d2b8c2f..97818b5b67 100644 ---- a/Source/Core/Core/HW/GCPadEmu.cpp -+++ b/Source/Core/Core/HW/GCPadEmu.cpp -@@ -25,6 +25,7 @@ static const u16 button_bitmasks[] = { - PAD_BUTTON_Y, - PAD_TRIGGER_Z, - PAD_BUTTON_START, -+ PAD_BUTTON_HOTKEY, - 0 // MIC HAX - }; - -@@ -47,6 +48,9 @@ GCPad::GCPad(const unsigned int index) : m_index(index) - // i18n: The START/PAUSE button on GameCube controllers - m_buttons->AddInput(ControllerEmu::Translate, START_BUTTON, _trans("START")); - -+ // Hotkey Button -+ m_buttons->AddInput(ControllerEmu::Translate, HOTKEY_BUTTON, _trans("HOTKEY")); -+ - // sticks - groups.emplace_back(m_main_stick = new ControllerEmu::OctagonAnalogStick( - MAIN_STICK_GROUP, _trans("Control Stick"), MAIN_STICK_GATE_RADIUS)); -diff --git a/Source/Core/DolphinNoGUI/PlatformX11.cpp b/Source/Core/DolphinNoGUI/PlatformX11.cpp -index 8dcd93bf52..5d7386da38 100644 ---- a/Source/Core/DolphinNoGUI/PlatformX11.cpp -+++ b/Source/Core/DolphinNoGUI/PlatformX11.cpp -@@ -16,6 +16,12 @@ static constexpr auto X_None = None; - #include "Core/Core.h" - #include "Core/State.h" - -+#include "Core/HW/GCPad.h" -+#include "InputCommon/GCPadStatus.h" -+#include -+#include "Core/Config/GraphicsSettings.h" -+#include "VideoCommon/VideoConfig.h" -+ - #include - #include - #include -@@ -149,11 +155,78 @@ void PlatformX11::MainLoop() - { - while (IsRunning()) - { -+ static int hotkey = 0; -+ static int slot = 0; -+ static int fps = 0; -+ static int aspect = 0; -+ - UpdateRunningFlag(); - Core::HostDispatchJobs(); - ProcessEvents(); - UpdateWindowPosition(); - -+ if(Pad::IsInitialized()) { -+ GCPadStatus x = Pad::GetStatus(0); -+ -+ if( (x.button & PAD_BUTTON_HOTKEY) == PAD_BUTTON_HOTKEY) { // hotkey pressed -+ if(hotkey == 1) { -+ hotkey = 2; -+ } -+ } else { -+ hotkey = 1; // assure hotkey is released between actions -+ } -+ -+ if(hotkey == 2) { // hotkey pressed -+ if( (x.button & PAD_BUTTON_START) == PAD_BUTTON_START) { -+ RequestShutdown(); -+ hotkey = 0; -+ } -+ -+ if( (x.button & PAD_TRIGGER_L) == PAD_TRIGGER_L) { -+ State::Load(slot); -+ hotkey = 0; -+ } -+ if( (x.button & PAD_TRIGGER_R) == PAD_TRIGGER_R) { -+ State::Save(slot); -+ hotkey = 0; -+ } -+ if( (x.button & PAD_BUTTON_DOWN) == PAD_BUTTON_DOWN) { -+ if(slot > 0) slot--; -+ Core::DisplayMessage(fmt::format("Slot {} selected", slot), 4000); -+ hotkey = 0; -+ } -+ if( (x.button & PAD_BUTTON_UP) == PAD_BUTTON_UP) { -+ if(slot < 10) slot++; -+ Core::DisplayMessage(fmt::format("Slot {} selected", slot), 4000); -+ hotkey = 0; -+ } -+ if( (x.button & PAD_BUTTON_A) == PAD_BUTTON_A) { -+ Core::SaveScreenShot(); -+ hotkey = 0; -+ } -+ if( (x.button & PAD_BUTTON_Y) == PAD_BUTTON_Y) { -+ if(fps == 0) { -+ Config::SetCurrent(Config::GFX_SHOW_FPS, True); -+ fps = 1; -+ } else { -+ Config::SetCurrent(Config::GFX_SHOW_FPS, False); -+ fps = 0; -+ } -+ hotkey = 0; -+ } -+ if( (x.button & PAD_BUTTON_X) == PAD_BUTTON_X) { -+ if(aspect == 0) { -+ Config::SetCurrent(Config::GFX_ASPECT_RATIO, AspectMode::Stretch); -+ aspect = 1; -+ } else { -+ Config::SetCurrent(Config::GFX_ASPECT_RATIO, AspectMode::Auto); -+ aspect = 0; -+ } -+ hotkey = 0; -+ } -+ } -+ } -+ - // TODO: Is this sleep appropriate? - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - } -diff --git a/Source/Core/InputCommon/GCPadStatus.h b/Source/Core/InputCommon/GCPadStatus.h -index 7da1bbd..57d294d 100644 ---- a/Source/Core/InputCommon/GCPadStatus.h -+++ b/Source/Core/InputCommon/GCPadStatus.h -@@ -27,6 +27,7 @@ enum PadButton - PAD_BUTTON_X = 0x0400, - PAD_BUTTON_Y = 0x0800, - PAD_BUTTON_START = 0x1000, -+ PAD_BUTTON_HOTKEY = 0x2000, - }; - - struct GCPadStatus diff --git a/packages/games/emulators/dolphinsa/patches/new/003-fix-x11-window.patch b/packages/games/emulators/dolphinsa/patches/new/003-fix-x11-window.patch deleted file mode 100644 index 6ad08e55b..000000000 --- a/packages/games/emulators/dolphinsa/patches/new/003-fix-x11-window.patch +++ /dev/null @@ -1,144 +0,0 @@ -diff --git a/Source/Core/DolphinNoGUI/MainNoGUI.cpp b/Source/Core/DolphinNoGUI/MainNoGUI.cpp -index 11bbf55da1..71d8960652 100644 ---- a/Source/Core/DolphinNoGUI/MainNoGUI.cpp -+++ b/Source/Core/DolphinNoGUI/MainNoGUI.cpp -@@ -251,6 +251,10 @@ int main(int argc, char* argv[]) - if (options.is_set("user")) - user_directory = static_cast(options.get("user")); - -+ UICommon::SetUserDirectory(user_directory); -+ UICommon::Init(); -+ GCAdapter::Init(); -+ - s_platform = GetPlatform(options); - if (!s_platform || !s_platform->Init()) - { -@@ -258,17 +262,6 @@ int main(int argc, char* argv[]) - return 1; - } - -- const WindowSystemInfo wsi = s_platform->GetWindowSystemInfo(); -- -- UICommon::SetUserDirectory(user_directory); -- UICommon::Init(); -- UICommon::InitControllers(wsi); -- -- Common::ScopeGuard ui_common_guard([] { -- UICommon::ShutdownControllers(); -- UICommon::Shutdown(); -- }); -- - if (save_state_path && !game_specified) - { - fprintf(stderr, "A save state cannot be loaded without specifying a game to launch.\n"); -@@ -295,7 +288,7 @@ int main(int argc, char* argv[]) - - DolphinAnalytics::Instance().ReportDolphinStart("nogui"); - -- if (!BootManager::BootCore(std::move(boot), wsi)) -+ if (!BootManager::BootCore(std::move(boot), s_platform->GetWindowSystemInfo())) - { - fprintf(stderr, "Could not boot the specified file\n"); - return 1; -@@ -310,6 +303,7 @@ int main(int argc, char* argv[]) - - Core::Shutdown(); - s_platform.reset(); -+ UICommon::Shutdown(); - - return 0; - } - -diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp -index 8a02534c57..00d8ac09e8 100644 ---- a/Source/Core/Core/Core.cpp -+++ b/Source/Core/Core/Core.cpp -@@ -470,14 +470,26 @@ static void EmuThread(std::unique_ptr boot, WindowSystemInfo wsi - DeclareAsCPUThread(); - s_frame_step = false; - -- // Switch the window used for inputs to the render window. This way, the cursor position -- // is relative to the render window, instead of the main window. -- ASSERT(g_controller_interface.IsInit()); -- g_controller_interface.ChangeWindow(wsi.render_window); -- -- Pad::LoadConfig(); -- Pad::LoadGBAConfig(); -- Keyboard::LoadConfig(); -+ // The frontend will likely have initialized the controller interface, as it needs -+ // it to provide the configuration dialogs. In this case, instead of re-initializing -+ // entirely, we switch the window used for inputs to the render window. This way, the -+ // cursor position is relative to the render window, instead of the main window. -+ bool init_controllers = false; -+ if (!g_controller_interface.IsInit()) -+ { -+ g_controller_interface.Initialize(wsi); -+ Pad::Initialize(); -+ Pad::InitializeGBA(); -+ Keyboard::Initialize(); -+ init_controllers = true; -+ } -+ else -+ { -+ g_controller_interface.ChangeWindow(wsi.render_window); -+ Pad::LoadConfig(); -+ Pad::LoadGBAConfig(); -+ Keyboard::LoadConfig(); -+ } - - BootSessionData boot_session_data = std::move(boot->boot_session_data); - const std::optional& savestate_path = boot_session_data.GetSavestatePath(); -@@ -494,13 +506,50 @@ static void EmuThread(std::unique_ptr boot, WindowSystemInfo wsi - Common::SyncSDImageToSDFolder(); - }}; - -- // Load Wiimotes - only if we are booting in Wii mode -+ // Load and Init Wiimotes - only if we are booting in Wii mode -+ bool init_wiimotes = false; - if (core_parameter.bWii && !Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_ENABLED)) - { -- Wiimote::LoadConfig(); -+ if (init_controllers) -+ { -+ Wiimote::Initialize(savestate_path ? Wiimote::InitializeMode::DO_WAIT_FOR_WIIMOTES : -+ Wiimote::InitializeMode::DO_NOT_WAIT_FOR_WIIMOTES); -+ init_wiimotes = true; -+ } -+ else -+ { -+ Wiimote::LoadConfig(); -+ } - } - -- FreeLook::LoadInputConfig(); -+ if (init_controllers) -+ { -+ FreeLook::Initialize(); -+ } -+ else -+ { -+ FreeLook::LoadInputConfig(); -+ } -+ -+ Common::ScopeGuard controller_guard{[init_controllers, init_wiimotes] { -+ if (!init_controllers) -+ return; -+ -+ if (init_wiimotes) -+ { -+ Wiimote::ResetAllWiimotes(); -+ Wiimote::Shutdown(); -+ } -+ -+ FreeLook::Shutdown(); -+ -+ ResetRumble(); -+ -+ Keyboard::Shutdown(); -+ Pad::Shutdown(); -+ Pad::ShutdownGBA(); -+ g_controller_interface.Shutdown(); -+ }}; - - Movie::Init(*boot); - Common::ScopeGuard movie_guard{&Movie::Shutdown}; diff --git a/packages/games/emulators/dolphinsa/patches/wayland/000-add-wayland.patch b/packages/games/emulators/dolphinsa/patches/wayland/000-add-wayland.patch new file mode 100644 index 000000000..ff95c8615 --- /dev/null +++ b/packages/games/emulators/dolphinsa/patches/wayland/000-add-wayland.patch @@ -0,0 +1,1373 @@ +diff --git a/CMake/FindWaylandProtocols.cmake b/CMake/FindWaylandProtocols.cmake +new file mode 100644 +index 0000000000..891903feaa +--- /dev/null ++++ b/CMake/FindWaylandProtocols.cmake +@@ -0,0 +1,28 @@ ++# from https://github.com/glfw/glfw/blob/master/CMake/modules/FindWaylandProtocols.cmake ++ ++find_package(PkgConfig) ++ ++pkg_check_modules(WaylandProtocols QUIET wayland-protocols>=${WaylandProtocols_FIND_VERSION}) ++ ++execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=pkgdatadir wayland-protocols ++ OUTPUT_VARIABLE WaylandProtocols_PKGDATADIR ++ RESULT_VARIABLE _pkgconfig_failed) ++if (_pkgconfig_failed) ++ message(FATAL_ERROR "Missing wayland-protocols pkgdatadir") ++endif() ++ ++string(REGEX REPLACE "[\r\n]" "" WaylandProtocols_PKGDATADIR "${WaylandProtocols_PKGDATADIR}") ++ ++find_package_handle_standard_args(WaylandProtocols ++ FOUND_VAR ++ WaylandProtocols_FOUND ++ REQUIRED_VARS ++ WaylandProtocols_PKGDATADIR ++ VERSION_VAR ++ WaylandProtocols_VERSION ++ HANDLE_COMPONENTS ++) ++ ++set(WAYLAND_PROTOCOLS_FOUND ${WaylandProtocols_FOUND}) ++set(WAYLAND_PROTOCOLS_PKGDATADIR ${WaylandProtocols_PKGDATADIR}) ++set(WAYLAND_PROTOCOLS_VERSION ${WaylandProtocols_VERSION}) +diff --git a/CMake/FindXKBCommon.cmake b/CMake/FindXKBCommon.cmake +new file mode 100644 +index 0000000000..3cdb40b82d +--- /dev/null ++++ b/CMake/FindXKBCommon.cmake +@@ -0,0 +1,33 @@ ++# - Try to find XKBCommon ++# Once done, this will define ++# ++# XKBCOMMON_FOUND - System has XKBCommon ++# XKBCOMMON_INCLUDE_DIRS - The XKBCommon include directories ++# XKBCOMMON_LIBRARIES - The libraries needed to use XKBCommon ++# XKBCOMMON_DEFINITIONS - Compiler switches required for using XKBCommon ++ ++find_package(PkgConfig) ++pkg_check_modules(PC_XKBCOMMON QUIET xkbcommon) ++set(XKBCOMMON_DEFINITIONS ${PC_XKBCOMMON_CFLAGS_OTHER}) ++ ++find_path(XKBCOMMON_INCLUDE_DIR ++ NAMES xkbcommon/xkbcommon.h ++ HINTS ${PC_XKBCOMMON_INCLUDE_DIR} ${PC_XKBCOMMON_INCLUDE_DIRS} ++) ++ ++find_library(XKBCOMMON_LIBRARY ++ NAMES xkbcommon ++ HINTS ${PC_XKBCOMMON_LIBRARY} ${PC_XKBCOMMON_LIBRARY_DIRS} ++) ++ ++set(XKBCOMMON_LIBRARIES ${XKBCOMMON_LIBRARY}) ++set(XKBCOMMON_LIBRARY_DIRS ${XKBCOMMON_LIBRARY_DIRS}) ++set(XKBCOMMON_INCLUDE_DIRS ${XKBCOMMON_INCLUDE_DIR}) ++ ++include(FindPackageHandleStandardArgs) ++find_package_handle_standard_args(XKBCommon DEFAULT_MSG ++ XKBCOMMON_LIBRARY ++ XKBCOMMON_INCLUDE_DIR ++) ++ ++mark_as_advanced(XKBCOMMON_LIBRARY XKBCOMMON_INCLUDE_DIR) +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 04bcdde4c2..7d7892f47c 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -43,6 +43,7 @@ set(DOLPHIN_DEFAULT_UPDATE_TRACK "" CACHE STRING "Name of the default update tra + + if(UNIX AND NOT APPLE AND NOT ANDROID) + option(ENABLE_X11 "Enables X11 Support" ON) ++ option(ENABLE_WAYLAND "Enables Wayland Support" OFF) + endif() + if(NOT WIN32 AND NOT APPLE AND NOT HAIKU) + option(ENABLE_EGL "Enables EGL OpenGL Interface" ON) +@@ -549,6 +550,17 @@ if(ENABLE_X11) + endif() + endif() + ++if(ENABLE_WAYLAND) ++ find_package(ECM REQUIRED NO_MODULE) ++ list(APPEND CMAKE_MODULE_PATH "${ECM_MODULE_PATH}") ++ find_package(Wayland REQUIRED Client Egl) ++ find_package(WaylandScanner REQUIRED) ++ find_package(WaylandProtocols 1.15 REQUIRED) ++ find_package(XKBCommon REQUIRED) ++ add_definitions(-DHAVE_WAYLAND=1) ++ message(STATUS "Wayland support enabled") ++endif() ++ + if(ENABLE_EGL) + find_package(EGL) + if(EGL_FOUND) +diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt +index 4dc764408d..98951537fe 100644 +--- a/Source/Core/Common/CMakeLists.txt ++++ b/Source/Core/Common/CMakeLists.txt +@@ -261,11 +261,20 @@ if(ENABLE_EGL AND EGL_FOUND) + GL/GLInterface/EGLAndroid.cpp + GL/GLInterface/EGLAndroid.h + ) +- elseif(ENABLE_X11 AND X11_FOUND) +- target_sources(common PRIVATE +- GL/GLInterface/EGLX11.cpp +- GL/GLInterface/EGLX11.h +- ) ++ else() ++ if(ENABLE_X11 AND X11_FOUND) ++ target_sources(common PRIVATE ++ GL/GLInterface/EGLX11.cpp ++ GL/GLInterface/EGLX11.h ++ ) ++ endif() ++ if(ENABLE_WAYLAND AND WAYLAND_FOUND) ++ target_sources(common PRIVATE ++ GL/GLInterface/EGLWayland.cpp ++ GL/GLInterface/EGLWayland.h ++ ) ++ target_link_libraries(common PRIVATE Wayland::Egl) ++ endif() + endif() + target_include_directories(common PRIVATE ${EGL_INCLUDE_DIRS}) + target_link_libraries(common PUBLIC ${EGL_LIBRARIES}) +diff --git a/Source/Core/Common/GL/GLContext.cpp b/Source/Core/Common/GL/GLContext.cpp +index f7b6ca8af8..7d07303617 100644 +--- a/Source/Core/Common/GL/GLContext.cpp ++++ b/Source/Core/Common/GL/GLContext.cpp +@@ -25,6 +25,9 @@ + #if defined(ANDROID) + #include "Common/GL/GLInterface/EGLAndroid.h" + #endif ++#if HAVE_WAYLAND ++#include "Common/GL/GLInterface/EGLWayland.h" ++#endif + #endif + + const std::array, 9> GLContext::s_desktop_opengl_versions = { +@@ -57,11 +60,11 @@ bool GLContext::ClearCurrent() + return false; + } + +-void GLContext::Update() ++void GLContext::UpdateDimensions(int window_width, int window_height) + { + } + +-void GLContext::UpdateSurface(void* window_handle) ++void GLContext::UpdateSurface(void* window_handle, int window_width, int window_height) + { + } + +@@ -113,6 +116,10 @@ std::unique_ptr GLContext::Create(const WindowSystemInfo& wsi, bool s + #endif + } + #endif ++#if HAVE_WAYLAND ++ if (wsi.type == WindowSystemType::Wayland) ++ context = std::make_unique(); ++#endif + #if HAVE_EGL + if (wsi.type == WindowSystemType::Headless || wsi.type == WindowSystemType::FBDev) + context = std::make_unique(); +diff --git a/Source/Core/Common/GL/GLContext.h b/Source/Core/Common/GL/GLContext.h +index a1d0a931bf..7ccd68e156 100644 +--- a/Source/Core/Common/GL/GLContext.h ++++ b/Source/Core/Common/GL/GLContext.h +@@ -36,8 +36,8 @@ public: + virtual bool MakeCurrent(); + virtual bool ClearCurrent(); + +- virtual void Update(); +- virtual void UpdateSurface(void* window_handle); ++ virtual void UpdateDimensions(int window_width, int window_height); ++ virtual void UpdateSurface(void* window_handle, int window_width, int window_height); + + virtual void Swap(); + virtual void SwapInterval(int interval); +diff --git a/Source/Core/Common/GL/GLInterface/AGL.h b/Source/Core/Common/GL/GLInterface/AGL.h +index dda9fee0e3..dd135087c3 100644 +--- a/Source/Core/Common/GL/GLInterface/AGL.h ++++ b/Source/Core/Common/GL/GLInterface/AGL.h +@@ -27,6 +27,8 @@ public: + + bool MakeCurrent() override; + bool ClearCurrent() override; ++ ++ void UpdateDimensions(int window_width, int window_height) override; + + void Update() override; + +diff --git a/Source/Core/Common/GL/GLInterface/AGL.mm b/Source/Core/Common/GL/GLInterface/AGL.mm +index a6fc7f0c0e..b0358a17dd 100644 +--- a/Source/Core/Common/GL/GLInterface/AGL.mm ++++ b/Source/Core/Common/GL/GLInterface/AGL.mm +@@ -144,7 +144,7 @@ bool GLContextAGL::ClearCurrent() + return true; + } + +-void GLContextAGL::Update() ++void GLContextAGL::UpdateDimensions(int window_width, int window_height) + { + if (!m_view) + return; +diff --git a/Source/Core/Common/GL/GLInterface/EGL.cpp b/Source/Core/Common/GL/GLInterface/EGL.cpp +index 30230e7d08..8fc9b339fb 100644 +--- a/Source/Core/Common/GL/GLInterface/EGL.cpp ++++ b/Source/Core/Common/GL/GLInterface/EGL.cpp +@@ -292,8 +292,8 @@ bool GLContextEGL::CreateWindowSurface() + { + if (!IsHeadless()) + { +- EGLNativeWindowType native_window = GetEGLNativeWindow(m_config); +- m_egl_surface = eglCreateWindowSurface(m_egl_display, m_config, native_window, nullptr); ++ m_native_window = GetEGLNativeWindow(m_config); ++ m_egl_surface = eglCreateWindowSurface(m_egl_display, m_config, m_native_window, nullptr); + if (!m_egl_surface) + { + INFO_LOG_FMT(VIDEO, "Error: eglCreateWindowSurface failed"); +@@ -301,15 +301,7 @@ bool GLContextEGL::CreateWindowSurface() + } + + // Get dimensions from the surface. +- EGLint surface_width = 1, surface_height = 1; +- if (!eglQuerySurface(m_egl_display, m_egl_surface, EGL_WIDTH, &surface_width) || +- !eglQuerySurface(m_egl_display, m_egl_surface, EGL_HEIGHT, &surface_height)) +- { +- WARN_LOG_FMT(VIDEO, +- "Failed to get surface dimensions via eglQuerySurface. Size may be incorrect."); +- } +- m_backbuffer_width = static_cast(surface_width); +- m_backbuffer_height = static_cast(surface_height); ++ QueryDimensions(); + } + else if (!m_supports_surfaceless) + { +@@ -347,9 +339,16 @@ bool GLContextEGL::MakeCurrent() + return eglMakeCurrent(m_egl_display, m_egl_surface, m_egl_surface, m_egl_context); + } + +-void GLContextEGL::UpdateSurface(void* window_handle) ++void GLContextEGL::UpdateDimensions(int window_width, int window_height) ++{ ++ QueryDimensions(); ++} ++ ++void GLContextEGL::UpdateSurface(void* window_handle, int window_width, int window_height) + { + m_wsi.render_surface = window_handle; ++ m_wsi.render_surface_width = window_width; ++ m_wsi.render_surface_height = window_height; + ClearCurrent(); + DestroyWindowSurface(); + CreateWindowSurface(); +@@ -376,3 +375,15 @@ void GLContextEGL::DestroyContext() + m_egl_context = EGL_NO_CONTEXT; + m_egl_display = EGL_NO_DISPLAY; + } ++ ++void GLContextEGL::QueryDimensions() ++{ ++ EGLint surface_width = 1, surface_height = 1; ++ if (!eglQuerySurface(m_egl_display, m_egl_surface, EGL_WIDTH, &surface_width) || ++ !eglQuerySurface(m_egl_display, m_egl_surface, EGL_HEIGHT, &surface_height)) ++ { ++ INFO_LOG_FMT(VIDEO, "Failed to get surface dimensions via eglQuerySurface. Size may be incorrect."); ++ } ++ m_backbuffer_width = static_cast(surface_width); ++ m_backbuffer_height = static_cast(surface_height); ++} +diff --git a/Source/Core/Common/GL/GLInterface/EGL.h b/Source/Core/Common/GL/GLInterface/EGL.h +index bed1b31ecc..5029765265 100644 +--- a/Source/Core/Common/GL/GLInterface/EGL.h ++++ b/Source/Core/Common/GL/GLInterface/EGL.h +@@ -22,7 +22,8 @@ public: + bool MakeCurrent() override; + bool ClearCurrent() override; + +- void UpdateSurface(void* window_handle) override; ++ void UpdateDimensions(int window_width, int window_height); ++ void UpdateSurface(void* window_handle, int window_width, int window_height) override; + + void Swap() override; + void SwapInterval(int interval) override; +@@ -39,9 +40,12 @@ protected: + void DestroyWindowSurface(); + void DetectMode(); + void DestroyContext(); ++ void QueryDimensions(); + + WindowSystemInfo m_wsi = {}; + ++ EGLNativeWindowType m_native_window = {}; ++ + EGLConfig m_config; + bool m_supports_surfaceless = false; + std::vector m_attribs; +diff --git a/Source/Core/Common/GL/GLInterface/EGLWayland.cpp b/Source/Core/Common/GL/GLInterface/EGLWayland.cpp +new file mode 100644 +index 0000000000..422c167a2e +--- /dev/null ++++ b/Source/Core/Common/GL/GLInterface/EGLWayland.cpp +@@ -0,0 +1,36 @@ ++// Copyright 2019 Dolphin Emulator Project ++// Licensed under GPLv2+ ++// Refer to the license.txt file included. ++ ++#include "Common/GL/GLInterface/EGLWayland.h" ++#include ++ ++GLContextEGLWayland::~GLContextEGLWayland() ++{ ++ if (m_native_window) ++ wl_egl_window_destroy(reinterpret_cast(m_native_window)); ++} ++ ++EGLDisplay GLContextEGLWayland::OpenEGLDisplay() ++{ ++ return eglGetDisplay(reinterpret_cast(m_wsi.display_connection)); ++} ++ ++void GLContextEGLWayland::UpdateDimensions(int window_width, int window_height) ++{ ++ wl_egl_window_resize(reinterpret_cast(m_native_window), window_width, ++ window_height, 0, 0); ++ m_backbuffer_width = window_width; ++ m_backbuffer_height = window_height; ++} ++ ++EGLNativeWindowType GLContextEGLWayland::GetEGLNativeWindow(EGLConfig config) ++{ ++ wl_egl_window* window = ++ wl_egl_window_create(static_cast(m_wsi.render_surface), ++ m_wsi.render_surface_width, m_wsi.render_surface_height); ++ if (!window) ++ return {}; ++ ++ return reinterpret_cast(window); ++} +diff --git a/Source/Core/Common/GL/GLInterface/EGLWayland.h b/Source/Core/Common/GL/GLInterface/EGLWayland.h +new file mode 100644 +index 0000000000..83f403a34f +--- /dev/null ++++ b/Source/Core/Common/GL/GLInterface/EGLWayland.h +@@ -0,0 +1,19 @@ ++// Copyright 2019 Dolphin Emulator Project ++// Licensed under GPLv2+ ++// Refer to the license.txt file included. ++ ++#pragma once ++ ++#include "Common/GL/GLInterface/EGL.h" ++ ++class GLContextEGLWayland : public GLContextEGL ++{ ++public: ++ ~GLContextEGLWayland(); ++ ++ void UpdateDimensions(int window_width, int window_height) override; ++ ++protected: ++ EGLDisplay OpenEGLDisplay() override; ++ EGLNativeWindowType GetEGLNativeWindow(EGLConfig config) override; ++}; +diff --git a/Source/Core/Common/GL/GLInterface/EGLX11.cpp b/Source/Core/Common/GL/GLInterface/EGLX11.cpp +index f430898361..d2496c2cf4 100644 +--- a/Source/Core/Common/GL/GLInterface/EGLX11.cpp ++++ b/Source/Core/Common/GL/GLInterface/EGLX11.cpp +@@ -11,7 +11,7 @@ GLContextEGLX11::~GLContextEGLX11() + m_render_window.reset(); + } + +-void GLContextEGLX11::Update() ++void GLContextEGLX11::UpdateDimensions(int window_width, int window_height) + { + m_render_window->UpdateDimensions(); + m_backbuffer_width = m_render_window->GetWidth(); +diff --git a/Source/Core/Common/GL/GLInterface/EGLX11.h b/Source/Core/Common/GL/GLInterface/EGLX11.h +index 6f30333341..7d7ba557e2 100644 +--- a/Source/Core/Common/GL/GLInterface/EGLX11.h ++++ b/Source/Core/Common/GL/GLInterface/EGLX11.h +@@ -13,7 +13,7 @@ class GLContextEGLX11 final : public GLContextEGL + public: + ~GLContextEGLX11() override; + +- void Update() override; ++void UpdateDimensions(int window_width, int window_height) override; + + protected: + EGLDisplay OpenEGLDisplay() override; +diff --git a/Source/Core/Common/GL/GLInterface/GLX.cpp b/Source/Core/Common/GL/GLInterface/GLX.cpp +index b04296d096..e6116bc999 100644 +--- a/Source/Core/Common/GL/GLInterface/GLX.cpp ++++ b/Source/Core/Common/GL/GLInterface/GLX.cpp +@@ -310,7 +310,7 @@ bool GLContextGLX::ClearCurrent() + return glXMakeCurrent(m_display, None, nullptr); + } + +-void GLContextGLX::Update() ++void GLContextGLX::UpdateDimensions(int window_width, int window_height) + { + m_render_window->UpdateDimensions(); + m_backbuffer_width = m_render_window->GetWidth(); +diff --git a/Source/Core/Common/GL/GLInterface/GLX.h b/Source/Core/Common/GL/GLInterface/GLX.h +index ec4bd29cb9..cf8b81a42d 100644 +--- a/Source/Core/Common/GL/GLInterface/GLX.h ++++ b/Source/Core/Common/GL/GLInterface/GLX.h +@@ -24,7 +24,7 @@ public: + bool MakeCurrent() override; + bool ClearCurrent() override; + +- void Update() override; ++ void UpdateDimensions(int window_width, int window_height) override; + + void SwapInterval(int Interval) override; + void Swap() override; +diff --git a/Source/Core/Common/GL/GLInterface/WGL.cpp b/Source/Core/Common/GL/GLInterface/WGL.cpp +index 286859daf6..cf2dbe0617 100644 +--- a/Source/Core/Common/GL/GLInterface/WGL.cpp ++++ b/Source/Core/Common/GL/GLInterface/WGL.cpp +@@ -480,7 +480,7 @@ bool GLContextWGL::ClearCurrent() + } + + // Update window width, size and etc. Called from Render.cpp +-void GLContextWGL::Update() ++void GLContextWGL::UpdateDimensions(int window_width, int window_height) + { + RECT rcWindow; + GetClientRect(m_window_handle, &rcWindow); +diff --git a/Source/Core/Common/GL/GLInterface/WGL.h b/Source/Core/Common/GL/GLInterface/WGL.h +index ad2b665028..4ee867eb03 100644 +--- a/Source/Core/Common/GL/GLInterface/WGL.h ++++ b/Source/Core/Common/GL/GLInterface/WGL.h +@@ -19,7 +19,7 @@ public: + bool MakeCurrent() override; + bool ClearCurrent() override; + +- void Update() override; ++ void UpdateDimensions(int window_width, int window_height) override; + + void Swap() override; + void SwapInterval(int interval) override; +diff --git a/Source/Core/Common/WindowSystemInfo.h b/Source/Core/Common/WindowSystemInfo.h +index 8936ad1a02..105271e290 100644 +--- a/Source/Core/Common/WindowSystemInfo.h ++++ b/Source/Core/Common/WindowSystemInfo.h +@@ -40,7 +40,11 @@ struct WindowSystemInfo + // This is kept seperate as input may require a different handle to rendering, and + // during video backend startup the surface pointer may change (MoltenVK). + void* render_surface = nullptr; +- ++ ++ // Dimensions of the render surface, if this is determined by the frontend. ++ int render_surface_width = 0; ++ int render_surface_height = 0; ++ + // Scale of the render surface. For hidpi systems, this will be >1. + float render_surface_scale = 1.0f; + }; +diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp +index 8a02534c57..9931ada05b 100644 +--- a/Source/Core/Core/Core.cpp ++++ b/Source/Core/Core/Core.cpp +@@ -474,6 +474,8 @@ static void EmuThread(std::unique_ptr boot, WindowSystemInfo wsi + // is relative to the render window, instead of the main window. + ASSERT(g_controller_interface.IsInit()); + g_controller_interface.ChangeWindow(wsi.render_window); ++ //g_controller_interface.ChangeWindow(wsi.render_surface, wsi.render_surface_width, ++ // wsi.render_surface_height); + + Pad::LoadConfig(); + Pad::LoadGBAConfig(); +diff --git a/Source/Core/Core/HW/GCPadEmu.cpp b/Source/Core/Core/HW/GCPadEmu.cpp +index 470d2b8c2f..0defa182bc 100644 +--- a/Source/Core/Core/HW/GCPadEmu.cpp ++++ b/Source/Core/Core/HW/GCPadEmu.cpp +@@ -24,6 +24,7 @@ static const u16 button_bitmasks[] = { + PAD_BUTTON_X, + PAD_BUTTON_Y, + PAD_TRIGGER_Z, ++ PAD_BUTTON_HOTKEY, + PAD_BUTTON_START, + 0 // MIC HAX + }; +@@ -47,6 +48,9 @@ GCPad::GCPad(const unsigned int index) : m_index(index) + // i18n: The START/PAUSE button on GameCube controllers + m_buttons->AddInput(ControllerEmu::Translate, START_BUTTON, _trans("START")); + ++ // Hotkey Button ++ m_buttons->AddInput(ControllerEmu::Translate, HOTKEY_BUTTON, _trans("HOTKEY")); ++ + // sticks + groups.emplace_back(m_main_stick = new ControllerEmu::OctagonAnalogStick( + MAIN_STICK_GROUP, _trans("Control Stick"), MAIN_STICK_GATE_RADIUS)); +diff --git a/Source/Core/Core/HW/GCPadEmu.h b/Source/Core/Core/HW/GCPadEmu.h +index 66a1aee4e4..a03eaebcd3 100644 +--- a/Source/Core/Core/HW/GCPadEmu.h ++++ b/Source/Core/Core/HW/GCPadEmu.h +@@ -65,6 +65,7 @@ public: + static constexpr const char* X_BUTTON = "X"; + static constexpr const char* Y_BUTTON = "Y"; + static constexpr const char* Z_BUTTON = "Z"; ++ static constexpr const char* HOTKEY_BUTTON = "Hotkey"; + static constexpr const char* START_BUTTON = "Start"; + + // i18n: The left trigger button (labeled L on real controllers) +diff --git a/Source/Core/DolphinNoGUI/CMakeLists.txt b/Source/Core/DolphinNoGUI/CMakeLists.txt +index f21955d809..c4de5e64bd 100644 +--- a/Source/Core/DolphinNoGUI/CMakeLists.txt ++++ b/Source/Core/DolphinNoGUI/CMakeLists.txt +@@ -17,6 +17,22 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + target_sources(dolphin-nogui PRIVATE PlatformFBDev.cpp) + endif() + ++if(ENABLE_WAYLAND AND WAYLAND_FOUND) ++ set(WAYLAND_PLATFORM_SRCS PlatformWayland.cpp) ++ ++ # Generate the xdg-shell and xdg-decoration protocols at build-time. ++ ecm_add_wayland_client_protocol(WAYLAND_PLATFORM_SRCS ++ PROTOCOL "${WAYLAND_PROTOCOLS_PKGDATADIR}/stable/xdg-shell/xdg-shell.xml" ++ BASENAME xdg-shell) ++ ecm_add_wayland_client_protocol(WAYLAND_PLATFORM_SRCS ++ PROTOCOL "${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml" ++ BASENAME xdg-decoration) ++ ++ target_include_directories(dolphin-nogui PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") ++ target_sources(dolphin-nogui PRIVATE "${WAYLAND_PLATFORM_SRCS}") ++ target_link_libraries(dolphin-nogui PRIVATE Wayland::Client) ++endif() ++ + set_target_properties(dolphin-nogui PROPERTIES OUTPUT_NAME dolphin-emu-nogui) + + target_link_libraries(dolphin-nogui +diff --git a/Source/Core/DolphinNoGUI/MainNoGUI.cpp b/Source/Core/DolphinNoGUI/MainNoGUI.cpp +index 11bbf55da1..7ba9111b8a 100644 +--- a/Source/Core/DolphinNoGUI/MainNoGUI.cpp ++++ b/Source/Core/DolphinNoGUI/MainNoGUI.cpp +@@ -155,6 +155,11 @@ static std::unique_ptr GetPlatform(const optparse::Values& options) + { + std::string platform_name = static_cast(options.get("platform")); + ++#if HAVE_WAYLAND ++ if (platform_name == "wayland") ++ return Platform::CreateWaylandPlatform(); ++#endif ++ + #if HAVE_X11 + if (platform_name == "x11" || platform_name.empty()) + return Platform::CreateX11Platform(); +@@ -199,6 +204,10 @@ int main(int argc, char* argv[]) + #ifdef _WIN32 + , + "win32" ++#endif ++#ifdef HAVE_WAYLAND ++ , ++ "wayland" + #endif + }); + +diff --git a/Source/Core/DolphinNoGUI/Platform.h b/Source/Core/DolphinNoGUI/Platform.h +index 24ec06e307..294f7087d8 100644 +--- a/Source/Core/DolphinNoGUI/Platform.h ++++ b/Source/Core/DolphinNoGUI/Platform.h +@@ -35,6 +35,10 @@ public: + static std::unique_ptr CreateX11Platform(); + #endif + ++#ifdef HAVE_WAYLAND ++ static std::unique_ptr CreateWaylandPlatform(); ++#endif ++ + #ifdef __linux__ + static std::unique_ptr CreateFBDevPlatform(); + #endif +diff --git a/Source/Core/DolphinNoGUI/PlatformWayland.cpp b/Source/Core/DolphinNoGUI/PlatformWayland.cpp +new file mode 100644 +index 0000000000..cebff25198 +--- /dev/null ++++ b/Source/Core/DolphinNoGUI/PlatformWayland.cpp +@@ -0,0 +1,323 @@ ++// Copyright 2018 Dolphin Emulator Project ++// Licensed under GPLv2+ ++// Refer to the license.txt file included. ++ ++#include ++ ++#include "DolphinNoGUI/Platform.h" ++ ++#include "Common/MsgHandler.h" ++#include "Core/Config/MainSettings.h" ++#include "Core/Core.h" ++#include "Core/State.h" ++ ++#include "Core/HW/GCPad.h" ++#include "InputCommon/GCPadStatus.h" ++#include ++#include "Core/Config/GraphicsSettings.h" ++#include "VideoCommon/VideoConfig.h" ++ ++#include ++#include ++#include ++ ++#include ++#include "wayland-xdg-decoration-client-protocol.h" ++#include "wayland-xdg-shell-client-protocol.h" ++ ++#include "UICommon/X11Utils.h" ++#include "VideoCommon/RenderBase.h" ++ ++namespace ++{ ++class PlatformWayland : public Platform ++{ ++public: ++ ~PlatformWayland() override; ++ ++ bool Init() override; ++ void SetTitle(const std::string& string) override; ++ void MainLoop() override; ++ ++ WindowSystemInfo GetWindowSystemInfo() const; ++ ++private: ++ void ProcessEvents(); ++ ++ static void GlobalRegistryHandler(void* data, wl_registry* registry, uint32_t id, ++ const char* interface, uint32_t version); ++ static void GlobalRegistryRemover(void* data, wl_registry* registry, uint32_t id); ++ static void XDGWMBasePing(void* data, struct xdg_wm_base* xdg_wm_base, uint32_t serial); ++ static void XDGSurfaceConfigure(void* data, struct xdg_surface* xdg_surface, uint32_t serial); ++ static void TopLevelConfigure(void* data, struct xdg_toplevel* xdg_toplevel, int32_t width, ++ int32_t height, struct wl_array* states); ++ static void TopLevelClose(void* data, struct xdg_toplevel* xdg_toplevel); ++ ++ wl_display* m_display = nullptr; ++ wl_registry* m_registry = nullptr; ++ wl_compositor* m_compositor = nullptr; ++ xdg_wm_base* m_xdg_wm_base = nullptr; ++ wl_surface* m_surface = nullptr; ++ wl_region* m_region = nullptr; ++ xdg_surface* m_xdg_surface = nullptr; ++ xdg_toplevel* m_xdg_toplevel = nullptr; ++ zxdg_decoration_manager_v1* m_decoration_manager = nullptr; ++ zxdg_toplevel_decoration_v1* m_toplevel_decoration = nullptr; ++ ++ int m_surface_width = 0; ++ int m_surface_height = 0; ++}; ++ ++PlatformWayland::~PlatformWayland() ++{ ++ if (m_xdg_toplevel) ++ xdg_toplevel_destroy(m_xdg_toplevel); ++ if (m_xdg_surface) ++ xdg_surface_destroy(m_xdg_surface); ++ if (m_surface) ++ wl_surface_destroy(m_surface); ++ if (m_region) ++ wl_region_destroy(m_region); ++ if (m_xdg_wm_base) ++ xdg_wm_base_destroy(m_xdg_wm_base); ++ if (m_compositor) ++ wl_compositor_destroy(m_compositor); ++ if (m_registry) ++ wl_registry_destroy(m_registry); ++ if (m_display) ++ wl_display_disconnect(m_display); ++} ++ ++void PlatformWayland::GlobalRegistryHandler(void* data, wl_registry* registry, uint32_t id, ++ const char* interface, uint32_t version) ++{ ++ PlatformWayland* platform = static_cast(data); ++ if (std::strcmp(interface, wl_compositor_interface.name) == 0) ++ { ++ platform->m_compositor = static_cast( ++ wl_registry_bind(platform->m_registry, id, &wl_compositor_interface, 1)); ++ } ++ else if (std::strcmp(interface, xdg_wm_base_interface.name) == 0) ++ { ++ platform->m_xdg_wm_base = static_cast( ++ wl_registry_bind(platform->m_registry, id, &xdg_wm_base_interface, 1)); ++ } ++ else if (std::strcmp(interface, zxdg_decoration_manager_v1_interface.name) == 0) ++ { ++ platform->m_decoration_manager = static_cast( ++ wl_registry_bind(platform->m_registry, id, &zxdg_decoration_manager_v1_interface, 1)); ++ } ++} ++ ++void PlatformWayland::GlobalRegistryRemover(void* data, wl_registry* registry, uint32_t id) ++{ ++} ++ ++void PlatformWayland::XDGWMBasePing(void* data, struct xdg_wm_base* xdg_wm_base, uint32_t serial) ++{ ++ xdg_wm_base_pong(xdg_wm_base, serial); ++} ++ ++void PlatformWayland::XDGSurfaceConfigure(void* data, struct xdg_surface* xdg_surface, ++ uint32_t serial) ++{ ++ xdg_surface_ack_configure(xdg_surface, serial); ++} ++ ++void PlatformWayland::TopLevelConfigure(void* data, struct xdg_toplevel* xdg_toplevel, ++ int32_t width, int32_t height, struct wl_array* states) ++{ ++ // If this is zero, it's asking us to set the size. ++ if (width == 0 || height == 0) ++ return; ++ ++ PlatformWayland* platform = static_cast(data); ++ platform->m_surface_width = width; ++ platform->m_surface_height = height; ++ if (g_renderer) ++ g_renderer->ResizeSurface(width, height); ++ //if (g_controller_interface.IsInit()) ++ //g_controller_interface.OnWindowResized(width, height); ++} ++ ++void PlatformWayland::TopLevelClose(void* data, struct xdg_toplevel* xdg_toplevel) ++{ ++ PlatformWayland* platform = static_cast(data); ++ platform->Stop(); ++} ++ ++bool PlatformWayland::Init() ++{ ++ m_display = wl_display_connect(nullptr); ++ if (!m_display) ++ { ++ //PanicAlert("Failed to connect to Wayland display."); ++ return false; ++ } ++ ++ static const wl_registry_listener registry_listener = {GlobalRegistryHandler, ++ GlobalRegistryRemover}; ++ m_registry = wl_display_get_registry(m_display); ++ wl_registry_add_listener(m_registry, ®istry_listener, this); ++ ++ // Call back to registry listener to get compositor/shell. ++ wl_display_dispatch(m_display); ++ wl_display_roundtrip(m_display); ++ ++ // We need a shell/compositor, or at least one we understand. ++ if (!m_compositor || !m_display || !m_xdg_wm_base) ++ { ++ std::fprintf(stderr, "Missing Wayland shell/compositor\n"); ++ return false; ++ } ++ ++ // Create the compositor and shell surface. ++ if (!(m_surface = wl_compositor_create_surface(m_compositor)) || ++ !(m_xdg_surface = xdg_wm_base_get_xdg_surface(m_xdg_wm_base, m_surface)) || ++ !(m_xdg_toplevel = xdg_surface_get_toplevel(m_xdg_surface))) ++ { ++ std::fprintf(stderr, "Failed to create compositor/shell surfaces\n"); ++ return false; ++ } ++ ++ static const xdg_wm_base_listener xdg_wm_base_listener = {XDGWMBasePing}; ++ xdg_wm_base_add_listener(m_xdg_wm_base, &xdg_wm_base_listener, this); ++ ++ static const xdg_surface_listener shell_surface_listener = {XDGSurfaceConfigure}; ++ xdg_surface_add_listener(m_xdg_surface, &shell_surface_listener, this); ++ ++ static const xdg_toplevel_listener toplevel_listener = {TopLevelConfigure, TopLevelClose}; ++ xdg_toplevel_add_listener(m_xdg_toplevel, &toplevel_listener, this); ++ ++ // Create region in the surface to draw into. ++ m_surface_width = Config::Get(Config::MAIN_RENDER_WINDOW_WIDTH); ++ m_surface_height = Config::Get(Config::MAIN_RENDER_WINDOW_HEIGHT); ++ m_region = wl_compositor_create_region(m_compositor); ++ wl_region_add(m_region, 0, 0, m_surface_width, m_surface_height); ++ wl_surface_set_opaque_region(m_surface, m_region); ++ wl_surface_commit(m_surface); ++ ++ // This doesn't seem to have any effect on kwin... ++ xdg_surface_set_window_geometry(m_xdg_surface, Config::Get(Config::MAIN_RENDER_WINDOW_XPOS), ++ Config::Get(Config::MAIN_RENDER_WINDOW_YPOS), ++ Config::Get(Config::MAIN_RENDER_WINDOW_WIDTH), ++ Config::Get(Config::MAIN_RENDER_WINDOW_HEIGHT)); ++ ++ if (m_decoration_manager) ++ { ++ m_toplevel_decoration = ++ zxdg_decoration_manager_v1_get_toplevel_decoration(m_decoration_manager, m_xdg_toplevel); ++ if (m_toplevel_decoration) ++ zxdg_toplevel_decoration_v1_set_mode(m_toplevel_decoration, ++ ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); ++ } ++ ++ return true; ++} ++ ++void PlatformWayland::SetTitle(const std::string& string) ++{ ++ xdg_toplevel_set_title(m_xdg_toplevel, string.c_str()); ++} ++ ++void PlatformWayland::MainLoop() ++{ ++ while (IsRunning()) ++ { ++ static int hotkey = 0; ++ static int slot = 0; ++ static int fps = 0; ++ static int aspect = 0; ++ ++ UpdateRunningFlag(); ++ Core::HostDispatchJobs(); ++ ProcessEvents(); ++ ++ if(Pad::IsInitialized()) { ++ GCPadStatus x = Pad::GetStatus(0); ++ ++ if( (x.button & PAD_BUTTON_HOTKEY) == PAD_BUTTON_HOTKEY) { // hotkey pressed ++ if(hotkey == 1) { ++ hotkey = 2; ++ } ++ } else { ++ hotkey = 1; // assure hotkey is released between actions ++ } ++ ++ if(hotkey == 2) { // hotkey pressed ++ if( (x.button & PAD_BUTTON_START) == PAD_BUTTON_START) { ++ RequestShutdown(); ++ hotkey = 0; ++ } ++ ++ if( (x.button & PAD_TRIGGER_L) == PAD_TRIGGER_L) { ++ State::Load(slot); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_TRIGGER_R) == PAD_TRIGGER_R) { ++ State::Save(slot); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_DOWN) == PAD_BUTTON_DOWN) { ++ if(slot > 0) slot--; ++ Core::DisplayMessage(fmt::format("Slot {} selected", slot), 4000); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_UP) == PAD_BUTTON_UP) { ++ if(slot < 10) slot++; ++ Core::DisplayMessage(fmt::format("Slot {} selected", slot), 4000); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_A) == PAD_BUTTON_A) { ++ Core::SaveScreenShot(); ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_Y) == PAD_BUTTON_Y) { ++ if(fps == 0) { ++ Config::SetCurrent(Config::GFX_SHOW_FPS, True); ++ fps = 1; ++ } else { ++ Config::SetCurrent(Config::GFX_SHOW_FPS, False); ++ fps = 0; ++ } ++ hotkey = 0; ++ } ++ if( (x.button & PAD_BUTTON_X) == PAD_BUTTON_X) { ++ if(aspect == 0) { ++ Config::SetCurrent(Config::GFX_ASPECT_RATIO, AspectMode::Stretch); ++ aspect = 1; ++ } else { ++ Config::SetCurrent(Config::GFX_ASPECT_RATIO, AspectMode::Auto); ++ aspect = 0; ++ } ++ hotkey = 0; ++ } ++ } ++ } ++ ++ // TODO: Is this sleep appropriate? ++ std::this_thread::sleep_for(std::chrono::milliseconds(1)); ++ } ++} ++ ++WindowSystemInfo PlatformWayland::GetWindowSystemInfo() const ++{ ++ WindowSystemInfo wsi; ++ wsi.type = WindowSystemType::Wayland; ++ wsi.display_connection = static_cast(m_display); ++ wsi.render_surface = reinterpret_cast(m_surface); ++ wsi.render_surface_width = m_surface_width; ++ wsi.render_surface_height = m_surface_height; ++ return wsi; ++} ++ ++void PlatformWayland::ProcessEvents() ++{ ++ wl_display_dispatch_pending(m_display); ++} ++} // namespace ++ ++std::unique_ptr Platform::CreateWaylandPlatform() ++{ ++ return std::make_unique(); ++} +diff --git a/Source/Core/DolphinNoGUI/PlatformX11.cpp b/Source/Core/DolphinNoGUI/PlatformX11.cpp +index 8dcd93bf52..f1a75e3b44 100644 +--- a/Source/Core/DolphinNoGUI/PlatformX11.cpp ++++ b/Source/Core/DolphinNoGUI/PlatformX11.cpp +@@ -57,8 +57,8 @@ private: + #endif + int m_window_x = Config::Get(Config::MAIN_RENDER_WINDOW_XPOS); + int m_window_y = Config::Get(Config::MAIN_RENDER_WINDOW_YPOS); +- unsigned int m_window_width = Config::Get(Config::MAIN_RENDER_WINDOW_WIDTH); +- unsigned int m_window_height = Config::Get(Config::MAIN_RENDER_WINDOW_HEIGHT); ++ int m_window_width = Config::Get(Config::MAIN_RENDER_WINDOW_WIDTH); ++ int m_window_height = Config::Get(Config::MAIN_RENDER_WINDOW_HEIGHT); + }; + + PlatformX11::~PlatformX11() +@@ -166,6 +166,8 @@ WindowSystemInfo PlatformX11::GetWindowSystemInfo() const + wsi.display_connection = static_cast(m_display); + wsi.render_window = reinterpret_cast(m_window); + wsi.render_surface = reinterpret_cast(m_window); ++ wsi.render_surface_width = m_window_width; ++ wsi.render_surface_height = m_window_height; + return wsi; + } + +@@ -176,8 +178,9 @@ void PlatformX11::UpdateWindowPosition() + + Window winDummy; + unsigned int borderDummy, depthDummy; +- XGetGeometry(m_display, m_window, &winDummy, &m_window_x, &m_window_y, &m_window_width, +- &m_window_height, &borderDummy, &depthDummy); ++ XGetGeometry(m_display, m_window, &winDummy, &m_window_x, &m_window_y, ++ reinterpret_cast(&m_window_width), ++ reinterpret_cast(&m_window_height), &borderDummy, &depthDummy); + } + + void PlatformX11::ProcessEvents() +@@ -264,7 +267,10 @@ void PlatformX11::ProcessEvents() + case ConfigureNotify: + { + if (g_renderer) +- g_renderer->ResizeSurface(); ++ { ++ UpdateWindowPosition(); ++ g_renderer->ResizeSurface(m_window_width, m_window_height); ++ } + } + break; + } +diff --git a/Source/Core/InputCommon/GCPadStatus.h b/Source/Core/InputCommon/GCPadStatus.h +index 74849e5594..029ade5824 100644 +--- a/Source/Core/InputCommon/GCPadStatus.h ++++ b/Source/Core/InputCommon/GCPadStatus.h +@@ -26,6 +26,7 @@ enum PadButton + PAD_BUTTON_X = 0x0400, + PAD_BUTTON_Y = 0x0800, + PAD_BUTTON_START = 0x1000, ++ PAD_BUTTON_HOTKEY = 0x2000, + }; + + struct GCPadStatus +diff --git a/Source/Core/VideoBackends/OGL/OGLRender.cpp b/Source/Core/VideoBackends/OGL/OGLRender.cpp +index 49400d73ff..dd812a7c87 100644 +--- a/Source/Core/VideoBackends/OGL/OGLRender.cpp ++++ b/Source/Core/VideoBackends/OGL/OGLRender.cpp +@@ -1079,7 +1079,7 @@ void Renderer::CheckForSurfaceChange() + if (!m_surface_changed.TestAndClear()) + return; + +- m_main_gl_context->UpdateSurface(m_new_surface_handle); ++ m_main_gl_context->UpdateSurface(m_new_surface_handle, m_new_surface_width, m_new_surface_height); + m_new_surface_handle = nullptr; + + // With a surface change, the window likely has new dimensions. +@@ -1093,7 +1093,7 @@ void Renderer::CheckForSurfaceResize() + if (!m_surface_resized.TestAndClear()) + return; + +- m_main_gl_context->Update(); ++ m_main_gl_context->UpdateDimensions(m_new_surface_width, m_new_surface_height); + m_backbuffer_width = m_main_gl_context->GetBackBufferWidth(); + m_backbuffer_height = m_main_gl_context->GetBackBufferHeight(); + m_system_framebuffer->UpdateDimensions(m_backbuffer_width, m_backbuffer_height); +diff --git a/Source/Core/VideoBackends/Software/SWOGLWindow.cpp b/Source/Core/VideoBackends/Software/SWOGLWindow.cpp +index a002e3e519..0d2190ea61 100644 +--- a/Source/Core/VideoBackends/Software/SWOGLWindow.cpp ++++ b/Source/Core/VideoBackends/Software/SWOGLWindow.cpp +@@ -32,6 +32,16 @@ bool SWOGLWindow::IsHeadless() const + return m_gl_context->IsHeadless(); + } + ++u32 SWOGLWindow::GetWidth() const ++{ ++ return m_gl_context->GetBackBufferWidth(); ++} ++ ++u32 SWOGLWindow::GetHeight() const ++{ ++ return m_gl_context->GetBackBufferHeight(); ++} ++ + bool SWOGLWindow::Initialize(const WindowSystemInfo& wsi) + { + m_gl_context = GLContext::Create(wsi); +@@ -84,11 +94,17 @@ bool SWOGLWindow::Initialize(const WindowSystemInfo& wsi) + return true; + } + ++ ++void SWOGLWindow::UpdateDimensions(int window_width, int window_height) ++{ ++ // just updates the render window position and the backbuffer size ++ m_gl_context->UpdateDimensions(window_width, window_height); ++} ++ + void SWOGLWindow::ShowImage(const AbstractTexture* image, + const MathUtil::Rectangle& xfb_region) + { + const SW::SWTexture* sw_image = static_cast(image); +- m_gl_context->Update(); // just updates the render window position and the backbuffer size + + GLsizei glWidth = (GLsizei)m_gl_context->GetBackBufferWidth(); + GLsizei glHeight = (GLsizei)m_gl_context->GetBackBufferHeight(); +diff --git a/Source/Core/VideoBackends/Software/SWOGLWindow.h b/Source/Core/VideoBackends/Software/SWOGLWindow.h +index 965f7f4e43..b18f8e6636 100644 +--- a/Source/Core/VideoBackends/Software/SWOGLWindow.h ++++ b/Source/Core/VideoBackends/Software/SWOGLWindow.h +@@ -20,6 +20,10 @@ public: + GLContext* GetContext() const { return m_gl_context.get(); } + bool IsHeadless() const; + ++ u32 GetWidth() const; ++ u32 GetHeight() const; ++ void UpdateDimensions(int window_width, int window_height); ++ + // Image to show, will be swapped immediately + void ShowImage(const AbstractTexture* image, const MathUtil::Rectangle& xfb_region); + +diff --git a/Source/Core/VideoBackends/Software/SWRenderer.cpp b/Source/Core/VideoBackends/Software/SWRenderer.cpp +index 76eea93068..d3ef32736e 100644 +--- a/Source/Core/VideoBackends/Software/SWRenderer.cpp ++++ b/Source/Core/VideoBackends/Software/SWRenderer.cpp +@@ -59,17 +59,17 @@ SWRenderer::CreateFramebuffer(AbstractTexture* color_attachment, AbstractTexture + static_cast(depth_attachment)); + } + +-void SWRenderer::BindBackbuffer(const ClearColor& clear_color) +-{ ++//void SWRenderer::BindBackbuffer(const ClearColor& clear_color) ++//{ + // Look for framebuffer resizes +- if (!m_surface_resized.TestAndClear()) +- return; ++ //if (!m_surface_resized.TestAndClear()) ++ //return; + +- GLContext* context = m_window->GetContext(); +- context->Update(); +- m_backbuffer_width = context->GetBackBufferWidth(); +- m_backbuffer_height = context->GetBackBufferHeight(); +-} ++ //GLContext* context = m_window->GetContext(); ++ //context->UpdateDimensions(window_width, window_height); ++ //m_backbuffer_width = context->GetBackBufferWidth(); ++ //m_backbuffer_height = context->GetBackBufferHeight(); ++//} + + class SWShader final : public AbstractShader + { +@@ -107,7 +107,7 @@ std::unique_ptr SWRenderer::CreatePipeline(const AbstractPipel + { + return std::make_unique(); + } +- ++ + // Called on the GPU thread + void SWRenderer::RenderXFBToScreen(const MathUtil::Rectangle& target_rc, + const AbstractTexture* source_texture, +@@ -117,6 +117,16 @@ void SWRenderer::RenderXFBToScreen(const MathUtil::Rectangle& target_rc, + m_window->ShowImage(source_texture, source_rc); + } + ++void SWRenderer::CheckForSurfaceResize() ++{ ++ if (!m_surface_resized.TestAndClear()) ++ return; ++ ++ m_window->UpdateDimensions(m_new_surface_width, m_new_surface_height); ++ m_backbuffer_width = static_cast(m_window->GetWidth()); ++ m_backbuffer_height = static_cast(m_window->GetHeight()); ++} ++ + u32 SWRenderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData) + { + u32 value = 0; +diff --git a/Source/Core/VideoBackends/Software/SWRenderer.h b/Source/Core/VideoBackends/Software/SWRenderer.h +index 8aa9aa4af5..7f5f98f4d3 100644 +--- a/Source/Core/VideoBackends/Software/SWRenderer.h ++++ b/Source/Core/VideoBackends/Software/SWRenderer.h +@@ -29,7 +29,7 @@ public: + std::unique_ptr + CreateFramebuffer(AbstractTexture* color_attachment, AbstractTexture* depth_attachment) override; + +- void BindBackbuffer(const ClearColor& clear_color = {}) override; ++ //void BindBackbuffer(const ClearColor& clear_color = {}) override; + + std::unique_ptr CreateShaderFromSource(ShaderStage stage, std::string_view source, + std::string_view name) override; +@@ -64,6 +64,8 @@ protected: + std::unique_ptr CreateBoundingBox() const override; + + private: ++void CheckForSurfaceResize(); ++ + std::unique_ptr m_window; + }; + } // namespace SW +diff --git a/Source/Core/VideoBackends/Vulkan/VKRenderer.cpp b/Source/Core/VideoBackends/Vulkan/VKRenderer.cpp +index 23dba4613b..5fb174b62f 100644 +--- a/Source/Core/VideoBackends/Vulkan/VKRenderer.cpp ++++ b/Source/Core/VideoBackends/Vulkan/VKRenderer.cpp +@@ -306,7 +306,7 @@ void Renderer::BindBackbuffer(const ClearColor& clear_color) + else if (res == VK_SUBOPTIMAL_KHR || res == VK_ERROR_OUT_OF_DATE_KHR) + { + INFO_LOG_FMT(VIDEO, "Resizing swap chain due to suboptimal/out-of-date"); +- m_swap_chain->ResizeSwapChain(); ++ m_swap_chain->ResizeSwapChain(m_backbuffer_width, m_backbuffer_height); + } + else + { +@@ -384,8 +384,11 @@ void Renderer::CheckForSurfaceChange() + g_command_buffer_mgr->CheckLastPresentFail(); + + // Recreate the surface. If this fails we're in trouble. +- if (!m_swap_chain->RecreateSurface(m_new_surface_handle)) ++ if (!m_swap_chain->RecreateSurface(m_new_surface_handle, m_new_surface_width, ++ m_new_surface_height)) ++ { + PanicAlertFmt("Failed to recreate Vulkan surface. Cannot continue."); ++ } + m_new_surface_handle = nullptr; + + // Handle case where the dimensions are now different. +@@ -412,7 +415,7 @@ void Renderer::CheckForSurfaceResize() + g_command_buffer_mgr->CheckLastPresentFail(); + + // Resize the swap chain. +- m_swap_chain->RecreateSwapChain(); ++ m_swap_chain->ResizeSwapChain(m_new_surface_width, m_new_surface_height); + OnSwapChainResized(); + } + +diff --git a/Source/Core/VideoBackends/Vulkan/VKSwapChain.cpp b/Source/Core/VideoBackends/Vulkan/VKSwapChain.cpp +index a7f5bb929d..bc515a6d34 100644 +--- a/Source/Core/VideoBackends/Vulkan/VKSwapChain.cpp ++++ b/Source/Core/VideoBackends/Vulkan/VKSwapChain.cpp +@@ -15,7 +15,6 @@ + #include "VideoBackends/Vulkan/ObjectCache.h" + #include "VideoBackends/Vulkan/VKTexture.h" + #include "VideoBackends/Vulkan/VulkanContext.h" +-#include "VideoCommon/RenderBase.h" + + #if defined(VK_USE_PLATFORM_XLIB_KHR) + #include +@@ -25,7 +24,8 @@ namespace Vulkan + { + SwapChain::SwapChain(const WindowSystemInfo& wsi, VkSurfaceKHR surface, bool vsync) + : m_wsi(wsi), m_surface(surface), m_vsync_enabled(vsync), +- m_fullscreen_supported(g_vulkan_context->SupportsExclusiveFullscreen(wsi, surface)) ++ m_fullscreen_supported(g_vulkan_context->SupportsExclusiveFullscreen(wsi, surface)), ++ m_width(wsi.render_surface_width), m_height(wsi.render_surface_height) + { + } + +@@ -84,6 +84,29 @@ VkSurfaceKHR SwapChain::CreateVulkanSurface(VkInstance instance, const WindowSys + } + #endif + ++#if defined(VK_USE_PLATFORM_WAYLAND_KHR) ++ if (wsi.type == WindowSystemType::Wayland) ++ { ++ VkWaylandSurfaceCreateInfoKHR surface_create_info = { ++ VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR, // VkStructureType sType ++ nullptr, // const void* pNext ++ 0, // VkWaylandSurfaceCreateFlagsKHR flags ++ static_cast(wsi.display_connection), // struct wl_display* display ++ static_cast(wsi.render_surface) // struct wl_surface* surface ++ }; ++ ++ VkSurfaceKHR surface; ++ VkResult res = vkCreateWaylandSurfaceKHR(instance, &surface_create_info, nullptr, &surface); ++ if (res != VK_SUCCESS) ++ { ++ LOG_VULKAN_ERROR(res, "vkCreateWaylandSurfaceKHR failed: "); ++ return VK_NULL_HANDLE; ++ } ++ ++ return surface; ++ } ++#endif ++ + #if defined(VK_USE_PLATFORM_ANDROID_KHR) + if (wsi.type == WindowSystemType::Android) + { +@@ -265,8 +288,8 @@ bool SwapChain::CreateSwapChain() + VkExtent2D size = surface_capabilities.currentExtent; + if (size.width == UINT32_MAX) + { +- size.width = std::max(g_renderer->GetBackbufferWidth(), 1); +- size.height = std::max(g_renderer->GetBackbufferHeight(), 1); ++ size.width = static_cast(m_wsi.render_surface_width); ++ size.height = static_cast(m_wsi.render_surface_height); + } + size.width = std::clamp(size.width, surface_capabilities.minImageExtent.width, + surface_capabilities.maxImageExtent.width); +@@ -463,9 +486,11 @@ VkResult SwapChain::AcquireNextImage() + return res; + } + +-bool SwapChain::ResizeSwapChain() ++bool SwapChain::ResizeSwapChain(int window_width, int window_height) + { + DestroySwapChainImages(); ++ m_wsi.render_surface_width = window_width; ++ m_wsi.render_surface_height = window_height; + if (!CreateSwapChain() || !SetupSwapChainImages()) + { + PanicAlertFmt("Failed to re-configure swap chain images, this is fatal (for now)"); +@@ -531,7 +556,7 @@ bool SwapChain::SetFullscreenState(bool state) + #endif + } + +-bool SwapChain::RecreateSurface(void* native_handle) ++bool SwapChain::RecreateSurface(void* native_handle, int window_width, int window_height) + { + // Destroy the old swap chain, images, and surface. + DestroySwapChainImages(); +@@ -540,6 +565,8 @@ bool SwapChain::RecreateSurface(void* native_handle) + + // Re-create the surface with the new native handle + m_wsi.render_surface = native_handle; ++ m_wsi.render_surface_width = window_width; ++ m_wsi.render_surface_height = window_height; + m_surface = CreateVulkanSurface(g_vulkan_context->GetVulkanInstance(), m_wsi); + if (m_surface == VK_NULL_HANDLE) + return false; +diff --git a/Source/Core/VideoBackends/Vulkan/VKSwapChain.h b/Source/Core/VideoBackends/Vulkan/VKSwapChain.h +index 5e67217f2d..7fb8c21f53 100644 +--- a/Source/Core/VideoBackends/Vulkan/VKSwapChain.h ++++ b/Source/Core/VideoBackends/Vulkan/VKSwapChain.h +@@ -52,8 +52,8 @@ public: + } + VkResult AcquireNextImage(); + +- bool RecreateSurface(void* native_handle); +- bool ResizeSwapChain(); ++ bool RecreateSurface(void* native_handle, int window_width, int window_height); ++ bool ResizeSwapChain(int window_width, int window_height); + bool RecreateSwapChain(); + + // Change vsync enabled state. This may fail as it causes a swapchain recreation. +diff --git a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp +index 3275cb9417..639069b0cb 100644 +--- a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp ++++ b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp +@@ -209,6 +209,13 @@ bool VulkanContext::SelectInstanceExtensions(std::vector* extension + return false; + } + #endif ++#if defined(VK_USE_PLATFORM_WAYLAND_KHR) ++ if (wstype == WindowSystemType::Wayland && ++ !AddExtension(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, true)) ++ { ++ return false; ++ } ++#endif + #if defined(VK_USE_PLATFORM_ANDROID_KHR) + if (wstype == WindowSystemType::Android && + !AddExtension(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, true)) +diff --git a/Source/Core/VideoBackends/Vulkan/VulkanEntryPoints.inl b/Source/Core/VideoBackends/Vulkan/VulkanEntryPoints.inl +index 3bb21c41e3..3ff64b524c 100644 +--- a/Source/Core/VideoBackends/Vulkan/VulkanEntryPoints.inl ++++ b/Source/Core/VideoBackends/Vulkan/VulkanEntryPoints.inl +@@ -49,6 +49,11 @@ VULKAN_INSTANCE_ENTRY_POINT(vkCreateXlibSurfaceKHR, false) + VULKAN_INSTANCE_ENTRY_POINT(vkGetPhysicalDeviceXlibPresentationSupportKHR, false) + #endif + ++#if defined(VK_USE_PLATFORM_WAYLAND_KHR) ++VULKAN_INSTANCE_ENTRY_POINT(vkCreateWaylandSurfaceKHR, false) ++VULKAN_INSTANCE_ENTRY_POINT(vkGetPhysicalDeviceWaylandPresentationSupportKHR, false) ++#endif ++ + #if defined(VK_USE_PLATFORM_ANDROID_KHR) + VULKAN_INSTANCE_ENTRY_POINT(vkCreateAndroidSurfaceKHR, false) + #endif +diff --git a/Source/Core/VideoBackends/Vulkan/VulkanLoader.h b/Source/Core/VideoBackends/Vulkan/VulkanLoader.h +index c9b92f5ac8..a728d25186 100644 +--- a/Source/Core/VideoBackends/Vulkan/VulkanLoader.h ++++ b/Source/Core/VideoBackends/Vulkan/VulkanLoader.h +@@ -13,6 +13,10 @@ + #define VK_USE_PLATFORM_XLIB_KHR + #endif + ++#if defined(HAVE_WAYLAND) ++#define VK_USE_PLATFORM_WAYLAND_KHR ++#endif ++ + #if defined(ANDROID) + #define VK_USE_PLATFORM_ANDROID_KHR + #endif +diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp +index f787ab7dab..abd50cdcca 100644 +--- a/Source/Core/VideoCommon/RenderBase.cpp ++++ b/Source/Core/VideoCommon/RenderBase.cpp +@@ -726,16 +726,20 @@ bool Renderer::IsHeadless() const + return true; + } + +-void Renderer::ChangeSurface(void* new_surface_handle) ++void Renderer::ChangeSurface(void* new_surface_handle, int new_width, int new_height) + { + std::lock_guard lock(m_swap_mutex); + m_new_surface_handle = new_surface_handle; ++ m_new_surface_width = new_width; ++ m_new_surface_height = new_height; + m_surface_changed.Set(); + } + +-void Renderer::ResizeSurface() ++void Renderer::ResizeSurface(int new_width, int new_height) + { + std::lock_guard lock(m_swap_mutex); ++ m_new_surface_width = new_width; ++ m_new_surface_height = new_height; + m_surface_resized.Set(); + } + +diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h +index 8824e6ff77..4692036a96 100644 +--- a/Source/Core/VideoCommon/RenderBase.h ++++ b/Source/Core/VideoCommon/RenderBase.h +@@ -245,8 +245,8 @@ public: + VideoCommon::PostProcessing* GetPostProcessor() const { return m_post_processor.get(); } + // Final surface changing + // This is called when the surface is resized (WX) or the window changes (Android). +- void ChangeSurface(void* new_surface_handle); +- void ResizeSurface(); ++ void ChangeSurface(void* new_surface_handle, int new_width, int new_height); ++ void ResizeSurface(int new_width, int new_height); + bool UseVertexDepthRange() const; + void DoState(PointerWrap& p); + +@@ -340,6 +340,8 @@ protected: + std::unique_ptr m_post_processor; + + void* m_new_surface_handle = nullptr; ++ int m_new_surface_width = 0; ++ int m_new_surface_height = 0; + Common::Flag m_surface_changed; + Common::Flag m_surface_resized; + std::mutex m_swap_mutex; diff --git a/packages/games/emulators/dolphinsa/patches/new/001-padorder.patch b/packages/games/emulators/dolphinsa/patches/wayland/001-padorder.patch similarity index 100% rename from packages/games/emulators/dolphinsa/patches/new/001-padorder.patch rename to packages/games/emulators/dolphinsa/patches/wayland/001-padorder.patch diff --git a/packages/games/emulators/dolphinsa/patches/new/004-git.patch b/packages/games/emulators/dolphinsa/patches/wayland/004-git.patch similarity index 100% rename from packages/games/emulators/dolphinsa/patches/new/004-git.patch rename to packages/games/emulators/dolphinsa/patches/wayland/004-git.patch diff --git a/packages/games/emulators/dolphinsa/patches/new/005-hide-osd-msg.patch b/packages/games/emulators/dolphinsa/patches/wayland/005-hide-osd-msg.patch similarity index 100% rename from packages/games/emulators/dolphinsa/patches/new/005-hide-osd-msg.patch rename to packages/games/emulators/dolphinsa/patches/wayland/005-hide-osd-msg.patch diff --git a/packages/games/emulators/dolphinsa/scripts/start_dolphin.sh b/packages/games/emulators/dolphinsa/scripts/start_dolphin.sh deleted file mode 100755 index 4a0982e09..000000000 --- a/packages/games/emulators/dolphinsa/scripts/start_dolphin.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -# SPDX-License-Identifier: GPL-2.0-or-later -# Copyright (C) 2022-present BrooksyTech (https://github.com/brooksytech) - -. /etc/profile - -if [ ! -d "/storage/.config/dolphin-emu" ]; then - mkdir -p "/storage/.config/dolphin-emu" - cp -r "/usr/config/dolphin-emu" "/storage/.config/" -fi - -if [ ! -d "/storage/.config/dolphin-emu/StateSaves" ]; then - mkdir -p "/storage/.config/dolphin-emu/StateSaves" -fi - -rm -rf /storage/.local/share/dolphin-emu - -ln -sfv /storage/.config/dolphin-emu /storage/.local/share/dolphin-emu - -/usr/bin/dolphin-emu-nogui -p @DOLPHIN_PLATFORM@ -a HLE -e "${1}" diff --git a/packages/games/emulators/dolphinsa/scripts/start_dolphin_gc.sh b/packages/games/emulators/dolphinsa/scripts/start_dolphin_gc.sh new file mode 100755 index 000000000..d1040e51e --- /dev/null +++ b/packages/games/emulators/dolphinsa/scripts/start_dolphin_gc.sh @@ -0,0 +1,145 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present BrooksyTech (https://github.com/brooksytech) + +. /etc/profile + +#Check if dolphin-emu exists in .config +if [ ! -d "/storage/.config/dolphin-emu" ]; then + mkdir -p "/storage/.config/dolphin-emu" + cp -r "/usr/config/dolphin-emu" "/storage/.config/" +fi + +#Check if GC custom controller profile exists in .config/dolphin-emu +if [ ! -f "/storage/.config/dolphin-emu/Custom_GCPadNew.ini" ]; then + cp -r "/usr/config/dolphin-emu/GCPadNew.ini" "/storage/.config/dolphin-emu/Custom_GCPadNew.ini" +fi + +#Link Save States to /roms/savestates +if [ ! -d "/storage/roms/savestates/gamecube/" ]; then + mkdir -p "/storage/roms/savestates/gamecube/" +fi + +rm -rf /storage/.config/dolphin-emu/StateSaves +ln -sf /storage/roms/savestates/gamecube /storage/.config/dolphin-emu/StateSaves + + #Emulation Station Features + GAME=$(echo "${1}"| sed "s#^/.*/##") + AA=$(get_setting anti_aliasing gamecube "${GAME}") + ASPECT=$(get_setting aspect_ratio gamecube "${GAME}") + RENDERER=$(get_setting graphics_backend gamecube "${GAME}") + IRES=$(get_setting internal_resolution gamecube "${GAME}") + FPS=$(get_setting show_fps gamecube "${GAME}") + CON=$(get_setting gamecube_controller_profile gamecube "${GAME}") + + #Anti-Aliasing + if [ "$AA" = "0" ] + then + sed -i '/MSAA/c\MSAA = 0' /storage/.config/dolphin-emu/GFX.ini + sed -i '/SSAA/c\SSAA = False' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$AA" = "2m" ] + then + sed -i '/MSAA/c\MSAA = 2' /storage/.config/dolphin-emu/GFX.ini + sed -i '/SSAA/c\SSAA = False' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$AA" = "2s" ] + then + sed -i '/MSAA/c\MSAA = 2' /storage/.config/dolphin-emu/GFX.ini + sed -i '/SSAA/c\SSAA = True' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$AA" = "4m" ] + then + sed -i '/MSAA/c\MSAA = 4' /storage/.config/dolphin-emu/GFX.ini + sed -i '/SSAA/c\SSAA = False' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$AA" = "4s" ] + then + sed -i '/MSAA/c\MSAA = 4' /storage/.config/dolphin-emu/GFX.ini + sed -i '/SSAA/c\SSAA = True' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$AA" = "8m" ] + then + sed -i '/MSAA/c\MSAA = 8' /storage/.config/dolphin-emu/GFX.ini + sed -i '/SSAA/c\SSAA = False' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$AA" = "8s" ] + then + sed -i '/MSAA/c\MSAA = 8' /storage/.config/dolphin-emu/GFX.ini + sed -i '/SSAA/c\SSAA = True' /storage/.config/dolphin-emu/GFX.ini + fi + + #Aspect Ratio + if [ "$ASPECT" = "0" ] + then + sed -i '/AspectRatio/c\AspectRatio = 0' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$ASPECT" = "1" ] + then + sed -i '/AspectRatio/c\AspectRatio = 1' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$ASPECT" = "2" ] + then + sed -i '/AspectRatio/c\AspectRatio = 2' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$ASPECT" = "3" ] + then + sed -i '/AspectRatio/c\AspectRatio = 3' /storage/.config/dolphin-emu/GFX.ini + fi + + #Video Backend + if [ "$RENDERER" = "opengl" ] + then + sed -i '/GFXBackend/c\GFXBackend = OGL' /storage/.config/dolphin-emu/Dolphin.ini + fi + + if [ "$RENDERER" = "vulkan" ] + then + sed -i '/GFXBackend/c\GFXBackend = Vulkan' /storage/.config/dolphin-emu/Dolphin.ini + fi + if [ "$RENDERER" = "software" ] + then + sed -i '/GFXBackend/c\GFXBackend = Software Renderer' /storage/.config/dolphin-emu/Dolphin.ini + fi + + #Internal Resolution + if [ "$IRES" = "1" ] + then + sed -i '/InternalResolution/c\InternalResolution = 1' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$IRES" = "2" ] + then + sed -i '/InternalResolution/c\InternalResolution = 2' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$IRES" = "3" ] + then + sed -i '/InternalResolution/c\InternalResolution = 3' /storage/.config/dolphin-emu/GFX.ini + fi + + #Show FPS + if [ "$FPS" = "false" ] + then + sed -i '/ShowFPS/c\ShowFPS = False' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$FPS" = "true" ] + then + sed -i '/ShowFPS/c\ShowFPS = true' /storage/.config/dolphin-emu/GFX.ini + fi + + #GC Controller Profile + if [ "$CON" = "default" ] + then + cp -r /usr/config/dolphin-emu/GCPadNew.ini /storage/.config/dolphin-emu/GCPadNew.ini + fi + if [ "$CON" = "custom" ] + then + cp -r /storage/.config/dolphin-emu/Custom_GCPadNew.ini /storage/.config/dolphin-emu/GCPadNew.ini + fi + +#Link .config/dolphin-emu to .local +rm -rf /storage/.local/share/dolphin-emu +ln -sf /storage/.config/dolphin-emu /storage/.local/share/dolphin-emu + +#Run Dolphin emulator +/usr/bin/dolphin-emu-nogui -p @DOLPHIN_PLATFORM@ -a HLE -e "${1}" diff --git a/packages/games/emulators/dolphinsa/scripts/start_dolphin_wii.sh b/packages/games/emulators/dolphinsa/scripts/start_dolphin_wii.sh new file mode 100755 index 000000000..37770e745 --- /dev/null +++ b/packages/games/emulators/dolphinsa/scripts/start_dolphin_wii.sh @@ -0,0 +1,156 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2022-present BrooksyTech (https://github.com/brooksytech) + +. /etc/profile + +#Check if dolphin-emu exists in .config +if [ ! -d "/storage/.config/dolphin-emu" ]; then + mkdir -p "/storage/.config/dolphin-emu" + cp -r "/usr/config/dolphin-emu" "/storage/.config/" +fi + +#Check if Wii custom controller profile exists in .config/dolphin-emu +if [ ! -f "/storage/.config/dolphin-emu/Custom_WiimoteNew.ini" ]; then + cp -r "/usr/config/dolphin-emu/WiiControllerProfiles/remote.ini" "/storage/.config/dolphin-emu/Custom_WiimoteNew.ini" +fi + +#Gamecube controller profile needed for hotkeys to work +cp -r "/usr/config/dolphin-emu/GCPadNew.ini" "/storage/.config/dolphin-emu/GCPadNew.ini" + +#Link Save States to /roms/savestates/wii +if [ ! -d "/storage/roms/savestates/wii/" ]; then + mkdir -p "/storage/roms/savestates/wii/" +fi + +rm -rf /storage/.config/dolphin-emu/StateSaves +ln -sf /storage/roms/savestates/wii /storage/.config/dolphin-emu/StateSaves + + #Emulation Station options + GAME=$(echo "${1}"| sed "s#^/.*/##") + AA=$(get_setting anti_aliasing wii "${GAME}") + ASPECT=$(get_setting aspect_ratio wii "${GAME}") + RENDERER=$(get_setting graphics_backend wii "${GAME}") + IRES=$(get_setting internal_resolution wii "${GAME}") + FPS=$(get_setting show_fps wii "${GAME}") + CON=$(get_setting wii_controller_profile wii "${GAME}") + + #Anti-Aliasing + if [ "$AA" = "0" ] + then + sed -i '/MSAA/c\MSAA = 0' /storage/.config/dolphin-emu/GFX.ini + sed -i '/SSAA/c\SSAA = False' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$AA" = "2m" ] + then + sed -i '/MSAA/c\MSAA = 2' /storage/.config/dolphin-emu/GFX.ini + sed -i '/SSAA/c\SSAA = False' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$AA" = "2s" ] + then + sed -i '/MSAA/c\MSAA = 2' /storage/.config/dolphin-emu/GFX.ini + sed -i '/SSAA/c\SSAA = True' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$AA" = "4m" ] + then + sed -i '/MSAA/c\MSAA = 4' /storage/.config/dolphin-emu/GFX.ini + sed -i '/SSAA/c\SSAA = False' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$AA" = "4s" ] + then + sed -i '/MSAA/c\MSAA = 4' /storage/.config/dolphin-emu/GFX.ini + sed -i '/SSAA/c\SSAA = True' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$AA" = "8m" ] + then + sed -i '/MSAA/c\MSAA = 8' /storage/.config/dolphin-emu/GFX.ini + sed -i '/SSAA/c\SSAA = False' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$AA" = "8s" ] + then + sed -i '/MSAA/c\MSAA = 8' /storage/.config/dolphin-emu/GFX.ini + sed -i '/SSAA/c\SSAA = True' /storage/.config/dolphin-emu/GFX.ini + fi + + #Aspect Ratio + if [ "$ASPECT" = "0" ] + then + sed -i '/AspectRatio/c\AspectRatio = 0' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$ASPECT" = "1" ] + then + sed -i '/AspectRatio/c\AspectRatio = 1' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$ASPECT" = "2" ] + then + sed -i '/AspectRatio/c\AspectRatio = 2' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$ASPECT" = "3" ] + then + sed -i '/AspectRatio/c\AspectRatio = 3' /storage/.config/dolphin-emu/GFX.ini + fi + + #Video Backend + if [ "$RENDERER" = "opengl" ] + then + sed -i '/GFXBackend/c\GFXBackend = OGL' /storage/.config/dolphin-emu/Dolphin.ini + fi + + if [ "$RENDERER" = "vulkan" ] + then + sed -i '/GFXBackend/c\GFXBackend = Vulkan' /storage/.config/dolphin-emu/Dolphin.ini + fi + if [ "$RENDERER" = "software" ] + then + sed -i '/GFXBackend/c\GFXBackend = Software Renderer' /storage/.config/dolphin-emu/Dolphin.ini + fi + + #Internal Resolution + if [ "$IRES" = "1" ] + then + sed -i '/InternalResolution/c\InternalResolution = 1' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$IRES" = "2" ] + then + sed -i '/InternalResolution/c\InternalResolution = 2' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$IRES" = "3" ] + then + sed -i '/InternalResolution/c\InternalResolution = 3' /storage/.config/dolphin-emu/GFX.ini + fi + + #Show FPS + if [ "$FPS" = "true" ] + then + sed -i '/ShowFPS/c\ShowFPS = True' /storage/.config/dolphin-emu/GFX.ini + fi + if [ "$FPS" = "false" ] + then + sed -i '/ShowFPS/c\ShowFPS = False' /storage/.config/dolphin-emu/GFX.ini + fi + + #Wii Controller Profile + if [ "$CON" = "remote" ] + then + cp -r /usr/config/dolphin-emu/WiiControllerProfiles/remote.ini /storage/.config/dolphin-emu/WiimoteNew.ini + fi + if [ "$CON" = "nunchuck" ] + then + cp -r /usr/config/dolphin-emu/WiiControllerProfiles/nunchuck.ini /storage/.config/dolphin-emu/WiimoteNew.ini + fi + if [ "$CON" = "classic" ] + then + cp -r /usr/config/dolphin-emu/WiiControllerProfiles/classic.ini /storage/.config/dolphin-emu/WiimoteNew.ini + fi + if [ "$CON" = "custom" ] + then + cp -r /storage/.config/dolphin-emu/Custom_WiimoteNew.ini /storage/.config/dolphin-emu/WiimoteNew.ini + fi + +#Link .config/dolphin-emu to .local +rm -rf /storage/.local/share/dolphin-emu +ln -sf /storage/.config/dolphin-emu /storage/.local/share/dolphin-emu + +#Run Dolphin emulator +/usr/bin/dolphin-emu-nogui -p @DOLPHIN_PLATFORM@ -a HLE -e "${1}" diff --git a/packages/games/emulators/drastic/scripts/start_drastic.sh b/packages/games/emulators/drastic/scripts/start_drastic.sh index a948c24d4..e626a38b0 100755 --- a/packages/games/emulators/drastic/scripts/start_drastic.sh +++ b/packages/games/emulators/drastic/scripts/start_drastic.sh @@ -9,7 +9,7 @@ if [ ! -d "/storage/.config/drastic/aarch64/drastic" ]; then echo -e "=> ${OS_NAME} DRASTIC INSTALLATION" echo -e "\nChecking for internet connection..." - INETUP=$(ping -c1 -w1 www.google.com >/dev/null 2>&1) + INETUP=$(/usr/bin/amionline >/dev/null 2>&1) if [ $? == 0 ] then mkdir -p "/storage/.config/drastic/aarch64" diff --git a/packages/games/emulators/duckstationsa/package.mk b/packages/games/emulators/duckstationsa/package.mk index faa6bcc98..9e01a0fa4 100644 --- a/packages/games/emulators/duckstationsa/package.mk +++ b/packages/games/emulators/duckstationsa/package.mk @@ -3,7 +3,7 @@ PKG_NAME="duckstationsa" PKG_LICENSE="GPLv3" -PKG_DEPENDS_TARGET="toolchain SDL2 nasm:host pulseaudio openssl libidn2 nghttp2 zlib curl libevdev" +PKG_DEPENDS_TARGET="toolchain SDL2 nasm:host pulseaudio openssl libidn2 nghttp2 zlib curl libevdev ecm" PKG_SITE="https://github.com/stenzek/duckstation" PKG_URL="${PKG_SITE}.git" PKG_SHORTDESC="Fast PlayStation 1 emulator for x86-64/AArch32/AArch64 " @@ -29,12 +29,18 @@ if [ "${OPENGLES_SUPPORT}" = yes ]; then PKG_CMAKE_OPTS_TARGET+=" -DUSE_X11=OFF \ -DUSE_DRMKMS=ON \ -DENABLE_EGL=ON \ - -DUSE_MALI=OFF" + -DUSE_MALI=OFF \ + -DENABLE_VULKAN=OFF" fi if [ "${DISPLAYSERVER}" = "wl" ]; then PKG_DEPENDS_TARGET+=" wayland ${WINDOWMANAGER} xorg-server xrandr libXi" - PKG_CMAKE_OPTS_TARGET+=" -DUSE_X11=ON" + PKG_CMAKE_OPTS_TARGET+=" -DUSE_X11=OFF -DUSE_WAYLAND=ON" +fi + +if [ "${VULKAN_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_TARGET+=" vulkan-loader vulkan-headers" + PKG_CMAKE_OPTS_TARGET+=" -DENABLE_VULKAN=ON" fi pre_configure_target() { @@ -47,8 +53,6 @@ pre_configure_target() { -DUSE_SDL2=ON \ -DENABLE_CHEEVOS=ON \ -DUSE_FBDEV=OFF \ - -DUSE_WAYLAND=OFF \ - -DENABLE_VULKAN=OFF -DUSE_EVDEV=ON" } diff --git a/packages/games/emulators/duckstationsa/patches/new/003-default-to-fullscreen.patch b/packages/games/emulators/duckstationsa/patches/new/003-default-to-fullscreen.patch deleted file mode 100644 index 99df30c3f..000000000 --- a/packages/games/emulators/duckstationsa/patches/new/003-default-to-fullscreen.patch +++ /dev/null @@ -1,33 +0,0 @@ -diff --git a/src/frontend-common/fullscreen_ui.cpp b/src/frontend-common/fullscreen_ui.cpp -index ce53e69f..fc0b24d5 100644 ---- a/src/frontend-common/fullscreen_ui.cpp -+++ b/src/frontend-common/fullscreen_ui.cpp -@@ -244,6 +244,7 @@ static void DoChangeDiscFromFile(); - static void DoChangeDisc(); - static void DoRequestExit(); - static void DoToggleFullscreen(); -+static void EnableDoToggleFullscreen(); - static void DoCheatsMenu(); - static void DoToggleAnalogMode(); - -@@ -1038,6 +1039,11 @@ void FullscreenUI::DoToggleFullscreen() - Host::RunOnCPUThread([]() { Host::SetFullscreen(!Host::IsFullscreen()); }); - } - -+void FullscreenUI::EnableDoToggleFullscreen() -+{ -+ Host::SetFullscreen(true); -+} -+ - ////////////////////////////////////////////////////////////////////////// - // Landing Window - ////////////////////////////////////////////////////////////////////////// -@@ -1050,6 +1056,8 @@ void FullscreenUI::SwitchToLanding() - - void FullscreenUI::DrawLandingWindow() - { -+ EnableDoToggleFullscreen(); -+ - BeginFullscreenColumns(nullptr, 0.0f, true); - - if (BeginFullscreenColumnWindow(0.0f, -710.0f, "logo", UIPrimaryDarkColor)) diff --git a/packages/games/emulators/duckstationsa/patches/new/003-fix-wayland-compile.patch b/packages/games/emulators/duckstationsa/patches/new/003-fix-wayland-compile.patch new file mode 100644 index 000000000..1412cd087 --- /dev/null +++ b/packages/games/emulators/duckstationsa/patches/new/003-fix-wayland-compile.patch @@ -0,0 +1,34 @@ +diff --git a/src/frontend-common/platform_misc_unix.cpp b/src/frontend-common/platform_misc_unix.cpp +index 1f7ae9ec..e0487476 100644 +--- a/src/frontend-common/platform_misc_unix.cpp ++++ b/src/frontend-common/platform_misc_unix.cpp +@@ -24,12 +24,12 @@ static bool SetScreensaverInhibitX11(bool inhibit, const WindowInfo& wi) + char* argv[4] = {command.GetWriteableCharArray(), operation.GetWriteableCharArray(), id.GetWriteableCharArray(), + nullptr}; + pid_t pid; +- int res = posix_spawnp(&pid, "xdg-screensaver", nullptr, nullptr, argv, environ); +- if (res != 0) +- { +- Log_ErrorPrintf("posix_spawnp() failed: %d", res); +- return false; +- } ++ //int res = posix_spawnp(&pid, "xdg-screensaver", nullptr, nullptr, argv, environ); ++ //if (res != 0) ++ //{ ++ // Log_ErrorPrintf("posix_spawnp() failed: %d", res); ++ // return false; ++ //} + + return true; + } +@@ -95,8 +95,8 @@ bool FrontendCommon::PlaySoundAsync(const char* path) + pid_t pid; + + // Since we set SA_NOCLDWAIT in Qt, we don't need to wait here. +- int res = posix_spawnp(&pid, cmdname, nullptr, nullptr, const_cast(argv), environ); +- return (res == 0); ++// int res = posix_spawnp(&pid, cmdname, nullptr, nullptr, const_cast(argv), environ); ++// return (res == 0); + #else + return false; + #endif diff --git a/packages/games/emulators/flycastsa/package.mk b/packages/games/emulators/flycastsa/package.mk index eea017a85..9f80e1a03 100644 --- a/packages/games/emulators/flycastsa/package.mk +++ b/packages/games/emulators/flycastsa/package.mk @@ -4,7 +4,7 @@ # Copyright (C) 2022-present Fewtarius PKG_NAME="flycastsa" -PKG_VERSION="092006fbbecd77c13cb3eb6545e94d7ca721575e" +PKG_VERSION="0cbf6f6601e5c0bbd849cf6cdde4ab6ae4b030ff" PKG_LICENSE="GPLv2" PKG_SITE="https://github.com/flyinghead/flycast" PKG_URL="${PKG_SITE}.git" diff --git a/packages/games/emulators/hatarisa/package.mk b/packages/games/emulators/hatarisa/package.mk index 2e962801b..c41cdb0f2 100644 --- a/packages/games/emulators/hatarisa/package.mk +++ b/packages/games/emulators/hatarisa/package.mk @@ -2,8 +2,8 @@ # Copyright (C) 2018-present 5schatten (https://github.com/5schatten) PKG_NAME="hatarisa" -PKG_VERSION="d487c2daaee8cc263a740d17ea5cd55b7435926e" -PKG_SHA256="f5f1aca4524039a37aed3a3f005b007a7d7f51cdfabfa416026d25222d6afc3e" +PKG_VERSION="68a9cc999a6167427aaf50c55f6ad6c2c5055425" +PKG_SHA256="718cb33bb67010483902a0b865e151b7069cc4658868449ffe9dadd679737299" PKG_LICENSE="GPL" PKG_SITE="https://github.com/hatari/hatari" PKG_URL="https://github.com/hatari/hatari/archive/${PKG_VERSION}.tar.gz" diff --git a/packages/games/emulators/pico-8/package.mk b/packages/games/emulators/pico-8/package.mk index 58d9e8edc..6cb985624 100644 --- a/packages/games/emulators/pico-8/package.mk +++ b/packages/games/emulators/pico-8/package.mk @@ -2,7 +2,7 @@ # Copyright (C) 2022-present Fewtarius PKG_NAME="pico-8" -PKG_VERSION="8f85d9a4fcd96e806d6c0f884ed9738c2bdf892d" +PKG_VERSION="428c14a99c6cb5c050371a88f1d22bbb7d554011" PKG_SHA256="" PKG_ARCH="any" PKG_LICENSE="GPLv2" diff --git a/packages/games/emulators/retroarch/package.mk b/packages/games/emulators/retroarch/package.mk index 55aa8e251..626c82658 100644 --- a/packages/games/emulators/retroarch/package.mk +++ b/packages/games/emulators/retroarch/package.mk @@ -2,11 +2,11 @@ # Copyright (C) 2021-present 351ELEC (https://github.com/351ELEC) PKG_NAME="retroarch" -PKG_VERSION="0cebebbfdc817757afe4dfa763dc930e9083826c" +PKG_VERSION="2e73b87328577506f0cce1b7af9045b21e74f52b" PKG_SITE="https://github.com/libretro/RetroArch" PKG_URL="${PKG_SITE}.git" PKG_LICENSE="GPLv3" -PKG_DEPENDS_TARGET="toolchain SDL2 alsa-lib openssl freetype zlib retroarch-assets core-info ffmpeg libass joyutils empty nss-mdns openal-soft libogg libvorbisidec libvorbis libvpx libpng libdrm pulseaudio miniupnpc flac" +PKG_DEPENDS_TARGET="toolchain SDL2 alsa-lib libass openssl freetype zlib retroarch-assets core-info ffmpeg libass joyutils empty nss-mdns openal-soft libogg libvorbisidec libvorbis libvpx libpng libdrm pulseaudio miniupnpc flac" PKG_LONGDESC="Reference frontend for the libretro API." GET_HANDLER_SUPPORT="git" @@ -73,6 +73,9 @@ pre_configure_target() { PKG_DEPENDS_TARGET+=" librga libgo2" PKG_CONFIGURE_OPTS_TARGET+=" --enable-odroidgo2" ;; + *) + PKG_CONFIGURE_OPTS_TARGET+=" --disable-odroidgo2" + ;; esac cd ${PKG_BUILD} diff --git a/packages/games/emulators/scummvmsa/package.mk b/packages/games/emulators/scummvmsa/package.mk index dc1f7d3d2..c0c46a9ae 100644 --- a/packages/games/emulators/scummvmsa/package.mk +++ b/packages/games/emulators/scummvmsa/package.mk @@ -3,8 +3,8 @@ # Copyright (C) 2020-present Fewtarius PKG_NAME="scummvmsa" -PKG_VERSION="ea0f0cc9ee1e089c94e1ce9fee6a587920e3147f" -PKG_SHA256="b925ddc03488bd0fb1adf79ed3f70fbeb46ccc79558b82ce8262d9f56994399b" +PKG_VERSION="35f1cecbe4400eec7f2e5bbb5a86c2bbd878cc41" +PKG_SHA256="332e50e16a82fa13647928b1dc6745129732827ac9101c4d9962c32cd336edd2" PKG_REV="1" PKG_LICENSE="GPL2" PKG_SITE="https://github.com/scummvm/scummvm" diff --git a/packages/games/emulators/yabasanshiroSA/package.mk b/packages/games/emulators/yabasanshiroSA/package.mk index 1820c1a14..cdc080a9a 100644 --- a/packages/games/emulators/yabasanshiroSA/package.mk +++ b/packages/games/emulators/yabasanshiroSA/package.mk @@ -10,7 +10,7 @@ GET_HANDLER_SUPPORT="git" PKG_BUILD_FLAGS="+speed" PKG_PATCH_DIRS+="${DEVICE}" -case ${ARCH} in +case ${TARGET_ARCH} in aarch64|arm) PKG_VERSION="c7618d2ecbf77b1e8188fa8af4fa1cfb34833a72" PKG_GIT_CLONE_BRANCH="pi4-1-9-0" @@ -53,11 +53,11 @@ pre_configure_target() { PKG_CMAKE_OPTS_TARGET="${PKG_BUILD}/yabause " if [ ! "${OPENGL}" = "no" ]; then - PKG_CMAKE_OPTS_TARGET+=" -DUSE_EGL=ON" + PKG_CMAKE_OPTS_TARGET+=" -DUSE_EGL=ON -DUSE_OPENGL=ON" fi if [ "${OPENGLES_SUPPORT}" = yes ]; then - PKG_CMAKE_OPTS_TARGET+=" -DUSE_EGL=ON" + PKG_CMAKE_OPTS_TARGET+=" -DUSE_EGL=ON -DUSE_OPENGL=OFF" fi #if [ "${VULKAN_SUPPORT}" = "yes" ] diff --git a/packages/games/libretro/core-info/package.mk b/packages/games/libretro/core-info/package.mk index cb2438efd..2c77d769f 100644 --- a/packages/games/libretro/core-info/package.mk +++ b/packages/games/libretro/core-info/package.mk @@ -20,8 +20,8 @@ ################################################################################ PKG_NAME="core-info" -PKG_VERSION="cbf7be9d90c407abbe7d3406a8aa5ed1d23a71d8" -PKG_SHA256="f66a8aa1c791ca0fa8facee95185d2928c639f97d2d84ad71e0ace51a19cd53b" +PKG_VERSION="7744a25a0e418703e24a4bd7a2208d5a12ae8a7a" +PKG_SHA256="cfcb4afc4e28910b38a7b1c96a751865808fa69b134fe2fea4ad85bbd7cde500" PKG_LICENSE="GPL" PKG_SITE="https://github.com/libretro/libretro-core-info" PKG_URL="https://github.com/libretro/libretro-core-info/archive/${PKG_VERSION}.tar.gz" diff --git a/packages/games/libretro/dosbox-pure/patches/RG351P/001-add-platform.patch b/packages/games/libretro/dosbox-pure/patches/RG351P/001-add-platform.patch index ae45a1526..759c80e60 100644 --- a/packages/games/libretro/dosbox-pure/patches/RG351P/001-add-platform.patch +++ b/packages/games/libretro/dosbox-pure/patches/RG351P/001-add-platform.patch @@ -12,9 +12,9 @@ diff -rupN dosbox-pure.orig/Makefile dosbox-pure/Makefile +CFLAGS := -DNDEBUG -O3 -fno-ident +LDFLAGS += -O3 -fno-ident + -+CPUFLAGS := -mtune=cortex-a35 -mcpu=cortex-a35 -march=armv8-a+crc+fp+simd ++CPUFLAGS := -mtune=cortex-a35 -march=armv8-a+crc+fp+simd + -+CFLAGS += $(CPUFLAGS) -fpic -fomit-frame-pointer -fno-non-call-exceptions -Wno-psabi -Wno-format ++CFLAGS += $(CPUFLAGS) -fpic -fomit-frame-pointer -fno-non-call-exceptions -Wno-psabi -Wno-format -fexceptions +LDFLAGS += $(CPUFLAGS) -lpthread -Wl,--gc-sections -shared +CXX = $(CC) +endif diff --git a/packages/games/libretro/dosbox-pure/patches/RG503/001-add-platform.patch b/packages/games/libretro/dosbox-pure/patches/RG503/001-add-platform.patch index 1096c0cf1..54706d04f 100644 --- a/packages/games/libretro/dosbox-pure/patches/RG503/001-add-platform.patch +++ b/packages/games/libretro/dosbox-pure/patches/RG503/001-add-platform.patch @@ -12,9 +12,9 @@ diff -rupN dosbox-pure.orig/Makefile dosbox-pure/Makefile +CFLAGS := -DNDEBUG -O3 -fno-ident +LDFLAGS += -O3 -fno-ident + -+CPUFLAGS := -mtune=cortex-a55 -mcpu=cortex-a55 -march=armv8-a+crc+fp+simd ++CPUFLAGS := -mtune=cortex-a55 -march=armv8-a+crc+fp+simd + -+CFLAGS += $(CPUFLAGS) -fpic -fomit-frame-pointer -fno-non-call-exceptions -Wno-psabi -Wno-format ++CFLAGS += $(CPUFLAGS) -fpic -fomit-frame-pointer -fno-non-call-exceptions -Wno-psabi -Wno-format -fexceptions +LDFLAGS += $(CPUFLAGS) -lpthread -Wl,--gc-sections -shared +CXX = $(CC) +endif diff --git a/packages/games/libretro/dosbox-pure/patches/RG552/001-add-platform.patch b/packages/games/libretro/dosbox-pure/patches/RG552/001-add-platform.patch index f44cdf742..656f55376 100644 --- a/packages/games/libretro/dosbox-pure/patches/RG552/001-add-platform.patch +++ b/packages/games/libretro/dosbox-pure/patches/RG552/001-add-platform.patch @@ -12,9 +12,9 @@ diff -rupN dosbox-pure.orig/Makefile dosbox-pure/Makefile +CFLAGS := -DNDEBUG -O3 -fno-ident +LDFLAGS += -O3 -fno-ident + -+CPUFLAGS := -mtune=cortex-a72.cortex-a53 -mcpu=cortex-a72.cortex-a53 -march=armv8-a+crc+fp+simd ++CPUFLAGS := -mtune=cortex-a72.cortex-a53 -march=armv8-a+crc+fp+simd + -+CFLAGS += $(CPUFLAGS) -fpic -fomit-frame-pointer -fno-non-call-exceptions -Wno-psabi -Wno-format ++CFLAGS += $(CPUFLAGS) -fpic -fomit-frame-pointer -fno-non-call-exceptions -Wno-psabi -Wno-format -fexceptions +LDFLAGS += $(CPUFLAGS) -lpthread -Wl,--gc-sections -shared +CXX = $(CC) +endif diff --git a/packages/games/libretro/fbneo/package.mk b/packages/games/libretro/fbneo/package.mk index 75ad42bb2..69c1baacb 100644 --- a/packages/games/libretro/fbneo/package.mk +++ b/packages/games/libretro/fbneo/package.mk @@ -3,8 +3,8 @@ # Maintenance 2020 351ELEC team (https://github.com/fewtarius/351ELEC) PKG_NAME="fbneo" -PKG_VERSION="952f22e135ed302f9d1844e9d85295b2eccb3c1b" -PKG_SHA256="1a13e7633bc503a4781718f43c11127e6e966c5455a66f3822a874465c65345a" +PKG_VERSION="0f2a0fa2086356261d01b0c89d0f1a42224daf1e" +PKG_SHA256="a99050d175389e22a815d54df9dc136e7f2c0364bae078932004469d6e20845f" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="Non-commercial" diff --git a/packages/games/libretro/flycast/package.mk b/packages/games/libretro/flycast/package.mk index 1965c84e3..e52073a8f 100644 --- a/packages/games/libretro/flycast/package.mk +++ b/packages/games/libretro/flycast/package.mk @@ -3,7 +3,7 @@ # Copyright (C) 2022-present Fewtarius PKG_NAME="flycast" -PKG_VERSION="092006fbbecd77c13cb3eb6545e94d7ca721575e" +PKG_VERSION="0cbf6f6601e5c0bbd849cf6cdde4ab6ae4b030ff" PKG_SITE="https://github.com/flyinghead/flycast" PKG_URL="${PKG_SITE}.git" PKG_DEPENDS_TARGET="toolchain libzip" diff --git a/packages/games/libretro/genesis-plus-gx/package.mk b/packages/games/libretro/genesis-plus-gx/package.mk index 2d7bd890e..329833dce 100644 --- a/packages/games/libretro/genesis-plus-gx/package.mk +++ b/packages/games/libretro/genesis-plus-gx/package.mk @@ -20,8 +20,8 @@ ################################################################################ PKG_NAME="genesis-plus-gx" -PKG_VERSION="5cdb31854074de1662266a0a675866ea7b787b42" -PKG_SHA256="0c146c9861238b361086321eb8564bb2a18181bf13383722dc9fe08ddb872dd7" +PKG_VERSION="165f0b80a0180b303de068fbb7e087d880ef2071" +PKG_SHA256="292da3f3041cb5bc2d9ce7c319b6090cb47bfd0488b6a3c61139f940dac2fbbc" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="Non-commercial" diff --git a/packages/games/libretro/libretro-database/package.mk b/packages/games/libretro/libretro-database/package.mk index 0b84fb13f..1d67b3a79 100644 --- a/packages/games/libretro/libretro-database/package.mk +++ b/packages/games/libretro/libretro-database/package.mk @@ -20,8 +20,8 @@ ################################################################################ PKG_NAME="libretro-database" -PKG_VERSION="bc488c79cdc36ea1076a2941f2e6e32365d5f53e" -PKG_SHA256="00367a61ab8014f82d1b36b72c44ed948ad7d9d6d5c6f801d178c23ea3f5d863" +PKG_VERSION="db95b0118467cddaee5eaaef5d8c46aaa4c459a4" +PKG_SHA256="697e588f4fdc036749be393edcf3542d76fd10b17fe09205973cde9d98f20567" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/games/libretro/mame/package.mk b/packages/games/libretro/mame/package.mk index 472196f9d..adfbc955f 100644 --- a/packages/games/libretro/mame/package.mk +++ b/packages/games/libretro/mame/package.mk @@ -2,8 +2,8 @@ # Copyright (C) 2019 Trond Haugland (trondah@gmail.com) PKG_NAME="mame" -PKG_VERSION="0d935696dce53a13eaf0705f4a108ee348f3c613" -PKG_SHA256="b23fa34a8fc09d55efe64992ce5af9389a20e1ef7139ee6c004b26581c7728f5" +PKG_VERSION="57622367cb780013690d6ef23b2066b500f6ce92" +PKG_SHA256="9ede7cb09cb48f721b1803a7363f79e10a87d4e7ed25b085bf1ed6c7a02bb519" PKG_ARCH="any" PKG_LICENSE="GPLv2" PKG_SITE="https://github.com/libretro/mame" @@ -14,21 +14,32 @@ PKG_SHORTDESC="MAME - Multiple Arcade Machine Emulator" PKG_TOOLCHAIN="make" PKG_BUILD_FLAGS="-lto" +case ${TARGET_ARCH} in + arm|aarch64) + MAME_PLATFORM="PLATFORM=arm64" + CROSS_BUILD="1" + PTR64=0 + ;; + *) + CROSS_BUILD="0" + PTR64=1 + ;; +esac PKG_MAKE_OPTS_TARGET="REGENIE=1 \ VERBOSE=1 \ NOWERROR=1 \ OPENMP=1 \ - CROSS_BUILD=1 \ + CROSS_BUILD=${CROSS_BUILD} \ TOOLS=0 \ RETRO=1 \ - PTR64=0 \ + PTR64=${PTR64} \ NOASM=0 \ PYTHON_EXECUTABLE=python3 \ CONFIG=libretro \ LIBRETRO_OS=unix \ LIBRETRO_CPU= \ - PLATFORM=arm64 \ + ${MAME_PLATFORM} \ ARCH= \ TARGET=mame \ SUBTARGET=mame \ @@ -46,7 +57,10 @@ make_target() { unset ARCH unset DISTRO unset PROJECT - export ARCHOPTS="-D__aarch64__ -DASMJIT_BUILD_X86" + if [ "${PLATFORM}" = "arm64" ] + then + export ARCHOPTS="-D__aarch64__ -DASMJIT_BUILD_X86" + fi make $PKG_MAKE_OPTS_TARGET OVERRIDE_CC=$CC OVERRIDE_CXX=$CXX OVERRIDE_LD=$LD AR=$AR $MAKEFLAGS } diff --git a/packages/games/libretro/mame2003-plus/package.mk b/packages/games/libretro/mame2003-plus/package.mk index af532b128..ca5265bd2 100644 --- a/packages/games/libretro/mame2003-plus/package.mk +++ b/packages/games/libretro/mame2003-plus/package.mk @@ -20,8 +20,8 @@ ################################################################################ PKG_NAME="mame2003-plus" -PKG_VERSION="d88d5c118e8d7075ec0a4e6deebb4cd3f18a8dd1" -PKG_SHA256="b63034c37e49558b085081620b7898678b8f398ebc4b62f74c62481a45d2fc4b" +PKG_VERSION="062c22a2496ff85161b91d03d3f0d9460d3e7e76" +PKG_SHA256="61dd18d9cbb33dfb14fd5a8c3b049e2347f99fe03aad4f58a465975924f21261" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="MAME" diff --git a/packages/games/libretro/mgba/package.mk b/packages/games/libretro/mgba/package.mk index 61a56d7a4..01a7a9527 100644 --- a/packages/games/libretro/mgba/package.mk +++ b/packages/games/libretro/mgba/package.mk @@ -19,8 +19,8 @@ ################################################################################ PKG_NAME="mgba" -PKG_VERSION="199a03e719436018779fe9299706c597fb2e9231" -PKG_SHA256="d7d86a0b325cbf2ae474e3a06e190102432a0414c5585cbbe7ff8d786f0f689a" +PKG_VERSION="ec5ecb26deba8d7ac830fc66ade9fac0eeaeb4ae" +PKG_SHA256="f84e8e2517352df0dd16beabdad151a66e1c04b00e52d431ca26baede93a5d86" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="MPLv2.0" diff --git a/packages/games/libretro/nxengine/package.mk b/packages/games/libretro/nxengine/package.mk index 91b65b545..940e5bfe9 100644 --- a/packages/games/libretro/nxengine/package.mk +++ b/packages/games/libretro/nxengine/package.mk @@ -19,8 +19,8 @@ ################################################################################ PKG_NAME="nxengine" -PKG_VERSION="aa32afb8df8461920037bdbbddbff00bf465c6de" -PKG_SHA256="eed9bcf7fa214c705f880622a620dbfe47058ad167a43b236da499cf79d99761" +PKG_VERSION="e271c6262d73f07e5d92d285503f1c049801c51a" +PKG_SHA256="221873fe0f8eca81100d355eea379de70030fb20c9afec35f7d675bf2840f044" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPLv3" diff --git a/packages/games/libretro/pcsx2/package.mk b/packages/games/libretro/pcsx2/package.mk index ba36aa39d..79acacec3 100644 --- a/packages/games/libretro/pcsx2/package.mk +++ b/packages/games/libretro/pcsx2/package.mk @@ -2,7 +2,7 @@ # Copyright (C) 2022-present Fewtarius PKG_NAME="pcsx2" -PKG_VERSION="ad76509" +PKG_VERSION="ad7650949e6c8c87cd2c5e278af88e3722a321bc" PKG_ARCH="any" PKG_LICENSE="GPLv2" PKG_DEPENDS_TARGET="toolchain alsa-lib freetype zlib libpng libaio libsamplerate libfmt libpcap soundtouch yamlcpp wxwidgets" diff --git a/packages/games/libretro/pcsx_rearmed/package.mk b/packages/games/libretro/pcsx_rearmed/package.mk index 7ffd3bbc7..4ac3a1a9a 100644 --- a/packages/games/libretro/pcsx_rearmed/package.mk +++ b/packages/games/libretro/pcsx_rearmed/package.mk @@ -3,8 +3,8 @@ # Copyright (C) 2022-present Fewtarius PKG_NAME="pcsx_rearmed" -PKG_VERSION="5ced3945423cda0010597b27b7da6bce77b12baa" -PKG_SHA256="65dea294c953a9e558955a266e206e705933f60a3a971cec96b9b77c1101a45b" +PKG_VERSION="fc7764f123b6445060e56dd27152fffefdec9404" +PKG_SHA256="c2734a44c48a25a014f445c97d725e40ecd9eb9a2341c314509a858006e563ff" PKG_REV="1" PKG_ARCH="arm aarch64" PKG_LICENSE="GPLv2" diff --git a/packages/games/libretro/ppsspp/package.mk b/packages/games/libretro/ppsspp/package.mk index 878f58d42..2469dd676 100644 --- a/packages/games/libretro/ppsspp/package.mk +++ b/packages/games/libretro/ppsspp/package.mk @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="ppsspp" -PKG_VERSION="eb18a87eeec1827a83ac6e9b3bc0e29043616205" +PKG_VERSION="109db81eca29fcd618b4ebf7969d1f2a40918410" PKG_LICENSE="GPLv2" PKG_SITE="https://github.com/hrydgard/ppsspp" PKG_URL="https://github.com/hrydgard/ppsspp.git" @@ -28,33 +28,67 @@ PKG_LONGDESC="A PSP emulator for Android, Windows, Mac, Linux and Blackberry 10, GET_HANDLER_SUPPORT="git" PKG_LIBNAME="ppsspp_libretro.so" -PKG_LIBPATH="lib/$PKG_LIBNAME" +PKG_LIBPATH="lib/${PKG_LIBNAME}" -pre_configure_target() { - PKG_CMAKE_OPTS_TARGET="-DLIBRETRO=ON \ - -DUSE_SYSTEM_FFMPEG=ON \ - -DUSING_X11_VULKAN=OFF" - if [ "${ARCH}" = "arm" ] && [ ! "${TARGET_CPU}" = "arm1176jzf-s" ]; then - PKG_CMAKE_OPTS_TARGET+=" -DARMV7=ON" - elif [ "${TARGET_CPU}" = "arm1176jzf-s" ]; then - PKG_CMAKE_OPTS_TARGET+=" -DARM=ON" - fi +if [ ! "${OPENGL}" = "no" ]; then + PKG_DEPENDS_TARGET+=" ${OPENGL} glu libglvnd glew" + PKG_CMAKE_OPTS_TARGET+=" -DUSING_FBDEV=OFF \ + -DUSING_GLES2=OFF" +fi - if [ "${OPENGLES_SUPPORT}" = "yes" ]; then - PKG_CMAKE_OPTS_TARGET+=" -DUSING_FBDEV=ON \ - -DUSING_EGL=ON \ - -DUSING_GLES2=ON" - fi -} +if [ "${OPENGLES_SUPPORT}" = yes ]; then + PKG_DEPENDS_TARGET+=" ${OPENGLES}" + PKG_CMAKE_OPTS_TARGET+=" -DUSING_FBDEV=ON \ + -DUSING_EGL=OFF \ + -DUSING_GLES2=ON \ + -DVULKAN=OFF \ + -DUSE_VULKAN_DISPLAY_KHR=OFF\ + -DUSING_X11_VULKAN=OFF" +fi + +### Vulkan is still not working for PPSSPP on the win600 yet. +#if [ "${VULKAN_SUPPORT}" = "yes" ] +#then +# PKG_DEPENDS_TARGET+=" vulkan-loader vulkan-headers" +# PKG_CMAKE_OPTS_TARGET+=" -DUSE_VULKAN_DISPLAY_KHR=ON \ +# -DVULKAN=ON \ +# -DEGL_NO_X11=1 +# -DMESA_EGL_NO_X11_HEADERS=1" +#else +# PKG_CMAKE_OPTS_TARGET+=" -DVULKAN=OFF" +#fi + +if [ "${DISPLAYSERVER}" = "wl" ]; then + PKG_DEPENDS_TARGET+=" wayland ${WINDOWMANAGER}" + PKG_CMAKE_OPTS_TARGET+=" -DUSE_WAYLAND_WSI=ON" +else + PKG_CMAKE_OPTS_TARGET+=" -DUSE_WAYLAND_WSI=OFF" +fi + +PKG_CMAKE_OPTS_TARGET+="${PKG_CMAKE_OPTS_TARGET} \ + -DUSE_SYSTEM_FFMPEG=OFF \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_SYSTEM_NAME=Linux \ + -DBUILD_SHARED_LIBS=OFF \ + -DANDROID=OFF \ + -DWIN32=OFF \ + -DAPPLE=OFF \ + -DLIBRETRO=ON \ + -DCMAKE_CROSSCOMPILING=ON \ + -DUSING_QT_UI=OFF \ + -DUNITTEST=OFF \ + -DSIMULATOR=OFF \ + -DHEADLESS=OFF \ + -DUSE_DISCORD=OFF" pre_make_target() { # fix cross compiling - find $PKG_BUILD -name flags.make -exec sed -i "s:isystem :I:g" \{} \; - find $PKG_BUILD -name build.ninja -exec sed -i "s:isystem :I:g" \{} \; + find ${PKG_BUILD} -name flags.make -exec sed -i "s:isystem :I:g" \{} \; + find ${PKG_BUILD} -name build.ninja -exec sed -i "s:isystem :I:g" \{} \; } makeinstall_target() { - mkdir -p $INSTALL/usr/lib/libretro - cp $PKG_LIBPATH $INSTALL/usr/lib/libretro/ + mkdir -p ${INSTALL}/usr/lib/libretro + cp ${PKG_LIBPATH} ${INSTALL}/usr/lib/libretro/ } diff --git a/packages/games/libretro/ppsspp/patches/ppsspp-x86_64-fix.patch b/packages/games/libretro/ppsspp/patches/001-x86_64-build-fix.patch similarity index 100% rename from packages/games/libretro/ppsspp/patches/ppsspp-x86_64-fix.patch rename to packages/games/libretro/ppsspp/patches/001-x86_64-build-fix.patch diff --git a/packages/games/libretro/ppsspp/patches/002-psp-path.patch b/packages/games/libretro/ppsspp/patches/002-psp-path.patch new file mode 100644 index 000000000..f9ce20c81 --- /dev/null +++ b/packages/games/libretro/ppsspp/patches/002-psp-path.patch @@ -0,0 +1,18 @@ +diff --git a/Core/System.cpp b/Core/System.cpp +index cb6fc34fa..829a5795a 100644 +--- a/Core/System.cpp ++++ b/Core/System.cpp +@@ -619,12 +619,7 @@ std::string PSP_GetLoading() { + Path GetSysDirectory(PSPDirectories directoryType) { + const Path &memStickDirectory = g_Config.memStickDirectory; + Path pspDirectory; +- if (!strcasecmp(memStickDirectory.GetFilename().c_str(), "PSP")) { +- // Let's strip this off, to easily allow choosing a root directory named "PSP" on Android. +- pspDirectory = memStickDirectory; +- } else { +- pspDirectory = memStickDirectory / "PSP"; +- } ++ pspDirectory = memStickDirectory / "PSP"; + + switch (directoryType) { + case DIRECTORY_PSP: diff --git a/packages/games/libretro/ppsspp/patches/003-libretro-path-fix.patch b/packages/games/libretro/ppsspp/patches/003-libretro-path-fix.patch new file mode 100644 index 000000000..1c4776421 --- /dev/null +++ b/packages/games/libretro/ppsspp/patches/003-libretro-path-fix.patch @@ -0,0 +1,31 @@ +diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp +index 9b4a20bd9..9a46971fd 100644 +--- a/libretro/libretro.cpp ++++ b/libretro/libretro.cpp +@@ -993,15 +993,20 @@ void retro_init(void) + + retro_base_dir /= "PPSSPP"; + +- g_Config.currentDirectory = retro_base_dir; +- g_Config.defaultCurrentDirectory = retro_base_dir; +- g_Config.memStickDirectory = retro_save_dir; +- g_Config.flash0Directory = retro_base_dir / "flash0"; +- g_Config.internalDataDirectory = retro_base_dir; ++ g_Config.defaultCurrentDirectory = Path(getenv("HOME")); ++ g_Config.memStickDirectory = g_Config.defaultCurrentDirectory / ".config/ppsspp"; ++ g_Config.flash0Directory = g_Config.memStickDirectory / "assets" / "flash0"; ++ g_Config.internalDataDirectory = g_Config.memStickDirectory; ++ ++ //g_Config.currentDirectory = retro_base_dir; ++ //g_Config.defaultCurrentDirectory = retro_base_dir; ++ //g_Config.memStickDirectory = retro_save_dir; ++ //g_Config.flash0Directory = retro_base_dir / "flash0"; ++ //g_Config.internalDataDirectory = retro_base_dir; + g_Config.bEnableNetworkChat = false; + g_Config.bDiscordPresence = false; + +- VFSRegister("", new DirectoryAssetReader(retro_base_dir)); ++ VFSRegister("", new DirectoryAssetReader(g_Config.memStickDirectory / "assets")); + + host = new LibretroHost(); + } diff --git a/packages/games/libretro/stella/package.mk b/packages/games/libretro/stella/package.mk index 1540855bd..9f8a12cce 100644 --- a/packages/games/libretro/stella/package.mk +++ b/packages/games/libretro/stella/package.mk @@ -20,8 +20,8 @@ ################################################################################ PKG_NAME="stella" -PKG_VERSION="7193c405327e0f2156d24d53836162f4b44af079" -PKG_SHA256="066b47a0d20e5993818d5447f125abac1ebcb244018e4753d16606a8a4964d9e" +PKG_VERSION="6cbb06b10ad0e065a51c847eed57b609d9021def" +PKG_SHA256="e730b8557a1b7053f0da108dc78489a4408857f900524d83a03defecacc0e524" PKG_REV="1" PKG_LICENSE="GPL2" PKG_SITE="https://github.com/stella-emu/stella" diff --git a/packages/games/libretro/swanstation/package.mk b/packages/games/libretro/swanstation/package.mk index c60c12ff7..d7f7d2215 100644 --- a/packages/games/libretro/swanstation/package.mk +++ b/packages/games/libretro/swanstation/package.mk @@ -3,8 +3,8 @@ # Maintenance 2020 351ELEC team (https://github.com/fewtarius/351ELEC) PKG_NAME="swanstation" -PKG_VERSION="ff0b451a573885a5b3a4f291f7b22f3ffc667a17" -PKG_SHA256="a4124f47173edd5f23c06d6d2c3e0483a16f08bcbe42631937738202ee00378e" +PKG_VERSION="f6fc4f2192dca855b639a642236ed878f1eb7994" +PKG_SHA256="a43d4fd6683de8427d602891655f6a99be91947d41119fce9934ab7598e10da7" PKG_ARCH="" PKG_LICENSE="GPLv3" PKG_SITE="https://github.com/libretro/swanstation" diff --git a/packages/games/tools/portmaster/package.mk b/packages/games/tools/portmaster/package.mk index 57b48b41a..04de3789e 100644 --- a/packages/games/tools/portmaster/package.mk +++ b/packages/games/tools/portmaster/package.mk @@ -18,7 +18,7 @@ case ${DEVICE} in esac pre_unpack() { - unzip sources/portmaster/portmaster-.zip -d ${PKG_BUILD} + unzip ${SOURCES}/portmaster/portmaster-.zip -d ${PKG_BUILD} } makeinstall_target() { diff --git a/packages/games/tools/retroarch-assets/package.mk b/packages/games/tools/retroarch-assets/package.mk index 5e4adf06e..285345b6c 100644 --- a/packages/games/tools/retroarch-assets/package.mk +++ b/packages/games/tools/retroarch-assets/package.mk @@ -19,8 +19,8 @@ ################################################################################ PKG_NAME="retroarch-assets" -PKG_VERSION="ee33f8ef693b42a8e23ca3fd48f43f345e7cd087" -PKG_SHA256="b110163b0898b56be5245fd77a626b69fe5624234a5bf6af22487e2c2ee50a33" +PKG_VERSION="4ec80faf1b5439d1654f407805bb66141b880826" +PKG_SHA256="1a5dfb3acb864bacd3f3fd0121c4904438ae52703187fc61d46f0d43500562aa" PKG_LICENSE="GPL" PKG_SITE="https://github.com/libretro/retroarch-assets" PKG_URL="https://github.com/libretro/retroarch-assets/archive/${PKG_VERSION}.tar.gz" diff --git a/packages/games/tools/retroarch-joypads/gamepads/device/X86_64/ THEC64 Joystick THEC64 Joystick .cfg b/packages/games/tools/retroarch-joypads/gamepads/device/X86_64/ THEC64 Joystick THEC64 Joystick .cfg new file mode 100644 index 000000000..0ec40c3ec --- /dev/null +++ b/packages/games/tools/retroarch-joypads/gamepads/device/X86_64/ THEC64 Joystick THEC64 Joystick .cfg @@ -0,0 +1,16 @@ +input_driver = "udev" +input_device = " THEC64 Joystick THEC64 Joystick " +input_vendor_id = "7257" +input_product_id = "36" +input_b_btn = "1" +input_y_btn = "4" +input_select_btn = "2" +input_start_btn = "3" +input_up_axis = "-1" +input_down_axis = "+1" +input_left_axis = "-0" +input_right_axis = "+0" +input_a_btn = "0" +input_x_btn = "7" +input_l_btn = "5" +input_r_btn = "6" diff --git a/packages/games/tools/retroarch-joypads/gamepads/device/X86_64/Core (Plus) Wired Controller.cfg b/packages/games/tools/retroarch-joypads/gamepads/device/X86_64/Core (Plus) Wired Controller.cfg new file mode 100644 index 000000000..345a0c5e6 --- /dev/null +++ b/packages/games/tools/retroarch-joypads/gamepads/device/X86_64/Core (Plus) Wired Controller.cfg @@ -0,0 +1,29 @@ +input_driver = "udev" +input_device = "Core (Plus) Wired Controller" +input_vendor_id = "8406" +input_product_id = "42769" +input_b_btn = "1" +input_y_btn = "0" +input_select_btn = "8" +input_start_btn = "9" +input_up_btn = "h0up" +input_down_btn = "h0down" +input_left_btn = "h0left" +input_right_btn = "h0right" +input_a_btn = "2" +input_x_btn = "3" +input_l_btn = "4" +input_r_btn = "5" +input_l2_btn = "6" +input_r2_btn = "7" +input_l3_btn = "10" +input_r3_btn = "11" +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" +input_r_x_plus_axis = "+2" +input_r_x_minus_axis = "-2" +input_r_y_plus_axis = "+3" +input_r_y_minus_axis = "-3" +input_gun_trigger_mbtn = "1" diff --git a/packages/games/tools/retroarch-joypads/package.mk b/packages/games/tools/retroarch-joypads/package.mk index 95d162a0e..df51a191d 100644 --- a/packages/games/tools/retroarch-joypads/package.mk +++ b/packages/games/tools/retroarch-joypads/package.mk @@ -2,7 +2,7 @@ # Copyright (C) 2020-present Fewtarius PKG_NAME="retroarch-joypads" -PKG_VERSION="a3b5067b8954f15e8e87eeed71a4262f0ea7fd1c" +PKG_VERSION="948fff0a12e487266eebef14774f17b7b881a728" PKG_LICENSE="GPL" PKG_SITE="https://github.com/libretro/retroarch-joypad-autoconfig" PKG_URL="${PKG_SITE}.git" diff --git a/packages/graphics/SDL2/package.mk b/packages/graphics/SDL2/package.mk index 7a37f141c..23b353bf0 100644 --- a/packages/graphics/SDL2/package.mk +++ b/packages/graphics/SDL2/package.mk @@ -77,6 +77,7 @@ case ${PROJECT} in esac pre_configure_target(){ + export LDFLAGS="${LDFLAGS} -ludev" PKG_CMAKE_OPTS_TARGET="-DSDL_STATIC=OFF \ -DLIBC=ON \ -DGCC_ATOMICS=ON \ diff --git a/packages/graphics/mesa/package.mk b/packages/graphics/mesa/package.mk index 65fc6a3dd..46ccf1e05 100644 --- a/packages/graphics/mesa/package.mk +++ b/packages/graphics/mesa/package.mk @@ -10,6 +10,7 @@ PKG_URL="${PKG_SITE}.git" PKG_DEPENDS_TARGET="toolchain expat libdrm Mako:host" PKG_LONGDESC="Mesa is a 3-D graphics library with an API." PKG_TOOLCHAIN="meson" +PKG_PATCH_DIRS+="${DEVICE}" get_graphicdrivers diff --git a/packages/graphics/mesa/patches/RG552/000-enable-arb-buffer-storage.patch b/packages/graphics/mesa/patches/RG552/000-enable-arb-buffer-storage.patch new file mode 100644 index 000000000..2d584d6cf --- /dev/null +++ b/packages/graphics/mesa/patches/RG552/000-enable-arb-buffer-storage.patch @@ -0,0 +1,24 @@ +diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c +index 228e4520135..f0be106ff81 100644 +--- a/src/gallium/drivers/panfrost/pan_resource.c ++++ b/src/gallium/drivers/panfrost/pan_resource.c +@@ -1010,6 +1010,7 @@ panfrost_ptr_map(struct pipe_context *pctx, + + if (!create_new_bo && + !(usage & PIPE_MAP_UNSYNCHRONIZED) && ++ !(resource->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT) && + (usage & PIPE_MAP_WRITE) && + !(resource->target == PIPE_BUFFER + && !util_ranges_intersect(&rsrc->valid_buffer_range, box->x, box->x + box->width)) && +diff --git a/src/gallium/drivers/panfrost/pan_screen.c b/src/gallium/drivers/panfrost/pan_screen.c +index f44d0fdc2ce..971b8b97163 100644 +--- a/src/gallium/drivers/panfrost/pan_screen.c ++++ b/src/gallium/drivers/panfrost/pan_screen.c +@@ -113,6 +113,7 @@ panfrost_get_param(struct pipe_screen *screen, enum pipe_cap param) + case PIPE_CAP_MIXED_COLOR_DEPTH_BITS: + case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD: + case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: ++ case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT: + case PIPE_CAP_POINT_SPRITE: + case PIPE_CAP_DEPTH_CLIP_DISABLE: + case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE: diff --git a/packages/jelos/config/system/configs/system.cfg b/packages/jelos/config/system/configs/system.cfg index 16504a94b..cecbdfd18 100644 --- a/packages/jelos/config/system/configs/system.cfg +++ b/packages/jelos/config/system/configs/system.cfg @@ -44,6 +44,7 @@ c16.integerscale=1 c16.rgascale=0 c64.integerscale=1 c64.rgascale=0 +cloud.backup=0 colecovision.integerscale=1 colecovision.ratio=4/3 colecovision.rgascale=0 @@ -256,6 +257,7 @@ virtualboy.cpugovernor=performance wifi.enabled=0 wonderswancolor.integerscale=1 wonderswan.integerscale=1 +weston.startup=/usr/bin/start_es.sh wts.enabled=1 x68000.integerscale=1 x68000.ratio=4/3 diff --git a/packages/jelos/package.mk b/packages/jelos/package.mk index 789102045..5bd6639f3 100644 --- a/packages/jelos/package.mk +++ b/packages/jelos/package.mk @@ -32,6 +32,8 @@ PKG_SOFTWARE="" PKG_COMPAT="" +PKG_MULTIMEDIA="ffmpeg mpv vlc" + PKG_TOOLS="i2c-tools rclone jslisten evtest tailscale" ### Tools for mainline devices @@ -41,9 +43,12 @@ case "${DEVICE}" in ;; esac -PKG_MULTIMEDIA="ffmpeg mpv vlc" - -PKG_EXPERIMENTAL="" +### Bluetooth support for some devices +case "${DEVICE}" in + RG503|RG353P|RG552|RG351P|RG351V|RG351MP) + PKG_TOOLS+=" pygobject" + ;; +esac ### Project specific variables case "${PROJECT}" in @@ -60,7 +65,7 @@ if [ ! -z "${BASE_ONLY}" ] then PKG_DEPENDS_TARGET+=" ${PKG_BASEOS} ${PKG_TOOLS} ${PKG_UI}" else - PKG_DEPENDS_TARGET+=" ${PKG_BASEOS} ${PKG_TOOLS} ${PKG_UI} ${PKG_COMPAT} ${PKG_MULTIMEDIA} ${PKG_SOFTWARE} ${PKG_EXPERIMENTAL}" + PKG_DEPENDS_TARGET+=" ${PKG_BASEOS} ${PKG_TOOLS} ${PKG_UI} ${PKG_COMPAT} ${PKG_MULTIMEDIA} ${PKG_SOFTWARE}" fi make_target() { @@ -180,4 +185,5 @@ EOF sed -i "s#ssh.enabled=0#ssh.enabled=1#g" ${INSTALL}/usr/config/system/configs/system.cfg fi + enable_service bluetooth-agent.service } diff --git a/packages/jelos/sources/autostart/RG351P/001-hardwareinit b/packages/jelos/sources/autostart/RG351P/001-hardwareinit old mode 100644 new mode 100755 diff --git a/packages/jelos/sources/autostart/RG503/001-hardwareinit b/packages/jelos/sources/autostart/RG503/001-hardwareinit old mode 100644 new mode 100755 diff --git a/packages/jelos/sources/autostart/RG552/001-hardwareinit b/packages/jelos/sources/autostart/RG552/001-hardwareinit old mode 100644 new mode 100755 diff --git a/packages/jelos/sources/autostart/common/004-upgrade b/packages/jelos/sources/autostart/common/004-upgrade index ec39bb30b..92ca2704e 100755 --- a/packages/jelos/sources/autostart/common/004-upgrade +++ b/packages/jelos/sources/autostart/common/004-upgrade @@ -8,7 +8,7 @@ if [ "$(cat /storage/.config/boot.hint 2>/dev/null)" = "UPDATE" ] || [ ! -e "/st then if [ -e "/usr/share/post-update" ] then - /usr/share/post-update + /usr/share/post-update >/var/log/upgrade.log 2>&1 fi rm /storage/.config/boot.hint touch /storage/.configured diff --git a/packages/jelos/sources/autostart/common/005-alsa b/packages/jelos/sources/autostart/common/005-alsa index ee6ff2e71..6111ac969 100755 --- a/packages/jelos/sources/autostart/common/005-alsa +++ b/packages/jelos/sources/autostart/common/005-alsa @@ -31,8 +31,18 @@ then cp /usr/config/asound.state /storage/.config fi -# Remove the mixer from ES -sed -i '//dev/null) + if [ ! "$?" = 0 ] + then + sed -i '/^.*AudioCard.*$/a \\t' /storage/.config/emulationstation/es_settings.cfg + fi +else + # Remove the mixer from ES + sed -i '/>${LOG} ### Rebuild the library cache rm -f /storage/.cache/ld.so.cache ldconfig -X +echo "Sync configuration files..." >>${LOG} ### Sync configurations if [ -d "/storage/.config/system/configs" ] then @@ -21,15 +25,19 @@ rsync -a --delete ${EXCLUDE} /usr/config/system/ /storage/.config/system/ rsync -a --ignore-existing /usr/config/game /storage/.config/ rsync -a /usr/config/modules /storage/.config/ +echo "Update logo..." >>${LOG} if [ ! -L "/storage/.config/emulationstation/resources/logo.png" ] then rm -f /storage/.config/emulationstation/resources/logo.png ||: ln -sf /usr/config/splash/splash.png /storage/.config/emulationstation/resources/logo.png fi +echo "Sync modules..." >>${LOG} rsync -a /usr/config/modules/* /storage/.config/modules/ cp -f /usr/config/retroarch/retroarch-core-options.cfg /storage/.config/retroarch/retroarch-core-options.cfg + +echo "Sync theme..." >>${LOG} cd /usr/share/themes for theme in * do @@ -42,16 +50,19 @@ done cd - ### Apply developer ssh keys if they exist +echo "Apply dev keys if available..." >>${LOG} if [ -e /usr/config/ssh/authorized_keys ] then cp /usr/config/ssh/authorized_keys /storage/.ssh fi ### Sync rsync configs +echo "Update rsync configuration files..." >>${LOG} rsync --ignore-existing /usr/config/rsync-rules.conf /storage/.config/ rsync --ignore-existing /usr/config/rsync.conf /storage/.config/ ### Replace es_systems and es_features with links to manage them +echo "Sync ES configuration files..." >>${LOG} for es_cfg in es_features.cfg es_systems.cfg do if [ -e "/storage/.config/emulationstation/${es_cfg}" ] @@ -62,9 +73,11 @@ do done # Default modules need to be updated to use the new stop/start ui function. +echo "Sync modules (tools)..." >>${LOG} rsync -av /usr/config/modules/* /storage/.config/modules/ # Swap es_input back to a writeable file so external controller configuration works properly. +echo "Make sure es_input isn't a link..." >>${LOG} if [ -L "/storage/.config/emulationstation/es_input.cfg" ] then rm -f /storage/.config/emulationstation/es_input.cfg @@ -74,26 +87,36 @@ fi # Disable integer scaling by default on Win600 if [[ "${HW_DEVICE}" =~ handheld ]] then + echo "No integer scaling (Win600 only)..." >>${LOG} sed -i "s#.integerscale=1#.integerscale=0#g" /storage/.config/system/configs/system.cfg fi # We don't want to use gl on the 552, switch it to glcore. if [[ "${HW_DEVICE}" =~ RG552 ]] then + echo "Switch to glcore (RG552 only)..." >>${LOG} sed -i 's#video_driver = "gl"#video_driver = "glcore"#g' /storage/.config/retroarch/retroarch.cfg fi # If smb.conf doesn't exist in ~/.config, add it. if [ ! -e "/storage/.config/smb.conf" ] then + echo "Make sure smb.conf is in .config..." >>${LOG} cp -f /usr/config/smb.conf /storage/.config fi -# Reset the retroarch hotkeys -rm -f /storage/.retroarch_controller - # Set automatic hotkey management by default. -set_setting system.autohotkeys 1 +AUTOHOTKEYS=$(get_setting system.autohotkeys) +if [ -z "${AUTOHOTKEYS}" ] +then + echo "Set up hotkey management..." >>${LOG} + set_setting system.autohotkeys 1 +fi # Set the default weston startup to ES -set_setting weston.startup "/usr/bin/start_es.sh" +WESTONSTARTUP=$(get_setting weston.startup) +if [ -z "${WESTONSTARTUP}" ] +then + echo "Make sure weston is our default." >>${LOG} + set_setting weston.startup "/usr/bin/start_es.sh" +fi diff --git a/packages/jelos/sources/scripts/amionline b/packages/jelos/sources/scripts/amionline new file mode 100755 index 000000000..bf3686e65 --- /dev/null +++ b/packages/jelos/sources/scripts/amionline @@ -0,0 +1,20 @@ +#!/bin/sh +# SPDX-License-Identifier: Apache-2.0 +# Copyright (C) 2020-present Fewtarius + +ip route | awk '/default/ {print $3}' >/dev/null 2>&1 +if [ ! $? = 0 ] +then + echo false + exit 1 +else + ping www.google.com -c1 -w1 >/dev/null 2>&1 + if [ ! $? = 0 ] + then + echo false + exit 1 + else + echo true + exit 0 + fi +fi diff --git a/packages/jelos/sources/scripts/batocera-bluetooth-agent b/packages/jelos/sources/scripts/batocera-bluetooth-agent index 20eef4f33..978234dde 100755 --- a/packages/jelos/sources/scripts/batocera-bluetooth-agent +++ b/packages/jelos/sources/scripts/batocera-bluetooth-agent @@ -442,7 +442,7 @@ if __name__ == '__main__': bus.add_signal_receiver(properties_changed, dbus_interface = "org.freedesktop.DBus.Properties", signal_name = "PropertiesChanged", arg0 = "org.bluez.Device1", path_keyword = "path") # register the agent - agentpath = "/storage/.cache/agent" + agentpath = "/storage/agent" obj = bus.get_object("org.bluez", "/org/bluez") manager = dbus.Interface(obj, "org.bluez.AgentManager1") manager.RegisterAgent(agentpath, "NoInputNoOutput") @@ -451,7 +451,7 @@ if __name__ == '__main__': logging.info("agent registered") # run the agent, allows some tries while hardware can take time to initiate - time.sleep(5) + time.sleep(2) try: do_main_loop(options.dev_id) except Exception as e: diff --git a/packages/jelos/sources/scripts/run b/packages/jelos/sources/scripts/run index b89bbde14..36dc78db2 100755 --- a/packages/jelos/sources/scripts/run +++ b/packages/jelos/sources/scripts/run @@ -4,15 +4,19 @@ . /etc/profile -RUN=$(echo ${1} | sed 's# #\\ #g') - if [ "${UI_SERVICE}" = "weston.service" ] then - weston-terminal --command="${RUN}" + if [ -f "${*}" ] + then + RUN=$(echo ${*} | sed 's# #\\ #g') + weston-terminal --command="${RUN}" + else + weston-terminal --command="${*}" + fi else systemctl stop ${UI_SERVICE} clear >/dev/console 2>&1 - $* >/dev/console 2>&1 || "$*" + $* >/dev/console 2>&1 || "$*" 2>&1 clear >/dev/console 2>&1 fi if [ ! "${UI_SERVICE}" = "weston.service" ] diff --git a/packages/jelos/sources/scripts/runemu.sh b/packages/jelos/sources/scripts/runemu.sh index 9d22a3a30..1b1bc52a2 100755 --- a/packages/jelos/sources/scripts/runemu.sh +++ b/packages/jelos/sources/scripts/runemu.sh @@ -281,13 +281,19 @@ then RUNTHIS='${TBASH} /usr/bin/start_pcsx2.sh "${ROMNAME}"' fi ;; - "gamecube"|"wii") + "gamecube") jslisten set "-9 dolphin-emu-nogui" - if [ "$EMU" = "dolphinsa" ]; then - RUNTHIS='${TBASH} /usr/bin/start_dolphin.sh "${ROMNAME}"' + if [ "$EMU" = "dolphinsa-gc" ]; then + RUNTHIS='${TBASH} /usr/bin/start_dolphin_gc.sh "${ROMNAME}"' fi ;; + "wii") + jslisten set "-9 dolphin-emu-nogui" + if [ "$EMU" = "dolphinsa-wii" ]; then + RUNTHIS='${TBASH} /usr/bin/start_dolphin_wii.sh "${ROMNAME}"' + fi + ;; "mplayer") jslisten set "mpv" RUNTHIS='${TBASH} /usr/bin/mpv_video.sh "${ROMNAME}"' @@ -477,6 +483,18 @@ then fi fi +### Backup save games +CLOUD_BACKUP=$(get_setting "cloud.backup") +if [ "${CLOUD_BACKUP}" = "1" ] +then + INETUP=$(/usr/bin/amionline >/dev/null 2>&1) + if [ $? == 0 ] + then + log "backup saves to the cloud." + run /usr/bin/cloud_backup + fi +fi + $VERBOSE && log "Checking errors: ${ret_error} " if [ "${ret_error}" == "0" ] then diff --git a/packages/jelos/sources/scripts/setsettings.sh b/packages/jelos/sources/scripts/setsettings.sh index 4aa5a1a7c..6e6f39026 100755 --- a/packages/jelos/sources/scripts/setsettings.sh +++ b/packages/jelos/sources/scripts/setsettings.sh @@ -126,9 +126,9 @@ log "Core: ${CORE}" MY_CONTROLLER=$(cat /storage/.controller) if [ "$(get_setting system.autohotkeys)" == "1" ] then - if [ -e "/usr/share/libretro/autoconfig/${MY_CONTROLLER}.cfg" ] + if [ -e "/tmp/joypads/${MY_CONTROLLER}.cfg" ] then - cp /usr/share/libretro/autoconfig/"${MY_CONTROLLER}.cfg" /tmp + cp /tmp/joypads/"${MY_CONTROLLER}.cfg" /tmp sed -i "s# = #=#g" /tmp/"${MY_CONTROLLER}.cfg" source /tmp/"${MY_CONTROLLER}.cfg" sed -i "/input_bind_hold/d" ${RACONF} diff --git a/packages/jelos/system.d/bluetooth-agent.service b/packages/jelos/system.d/bluetooth-agent.service new file mode 100644 index 000000000..dc465e214 --- /dev/null +++ b/packages/jelos/system.d/bluetooth-agent.service @@ -0,0 +1,11 @@ +[Unit] +Description=Start bluetooth agent +After=bluetooth.service +PartOf=bluetooth.service + +[Service] +Type=simple +ExecStart=/usr/bin/batocera-bluetooth-agent + +[Install] +WantedBy=bluetooth.service diff --git a/packages/kernel/linux-drivers/RTL8188FU/package.mk b/packages/kernel/linux-drivers/RTL8188FU/package.mk index b36552212..064b22aff 100644 --- a/packages/kernel/linux-drivers/RTL8188FU/package.mk +++ b/packages/kernel/linux-drivers/RTL8188FU/package.mk @@ -1,5 +1,5 @@ PKG_NAME="RTL8188FU" -PKG_VERSION="dfe0a50" +PKG_VERSION="751882b3d8925b72ed796f40e38c0232ccc24785" PKG_LICENSE="GPL" PKG_SITE="https://github.com/kelebek333/rtl8188fu" PKG_URL="${PKG_SITE}.git" diff --git a/packages/kernel/linux-firmware/RTL8821CS-prebuilt-firmware/package.mk b/packages/kernel/linux-firmware/RTL8821CS-prebuilt-firmware/package.mk new file mode 100644 index 000000000..885147c49 --- /dev/null +++ b/packages/kernel/linux-firmware/RTL8821CS-prebuilt-firmware/package.mk @@ -0,0 +1,13 @@ +PKG_NAME="RTL8821CS-prebuilt-firmware" +PKG_LICENSE="Apache-2.0" +PKG_SITE="www.jelos.org" +PKG_SECTION="virtual" +PKG_LONGDESC="Realtek RTL8821CS Linux firmware" +PKG_DEPENDS_TARGET="linux" + +post_install() { + cp -v $(get_build_dir linux)/wifibt/rtk_hciattach $INSTALL/usr/bin + cp -v $(get_build_dir linux)/wifibt/rtl8821c_fw $INSTALL/$(get_full_firmware_dir) + cp -v $(get_build_dir linux)/wifibt/rtl8821cs_config $INSTALL/$(get_full_firmware_dir)/rtl8821c_config + enable_service hciattach-realtek.service +} \ No newline at end of file diff --git a/packages/kernel/linux-firmware/RTL8821CS-prebuilt-firmware/system.d/hciattach-realtek.service b/packages/kernel/linux-firmware/RTL8821CS-prebuilt-firmware/system.d/hciattach-realtek.service new file mode 100644 index 000000000..c48dad498 --- /dev/null +++ b/packages/kernel/linux-firmware/RTL8821CS-prebuilt-firmware/system.d/hciattach-realtek.service @@ -0,0 +1,13 @@ +[Unit] +Description=Attach /dev/ttyS1 to BlueZ stack +Before=bluetooth-agent.service +PartOf=bluetooth.service + +[Service] +Type=simple +ExecStartPre=/usr/sbin/rfkill unblock bluetooth +ExecStart=/usr/bin/rtk_hciattach -n /dev/ttyS1 rtk_h5 115200 +ExecStopPost=/usr/sbin/rfkill block bluetooth + +[Install] +WantedBy=bluetooth.service diff --git a/packages/kernel/linux/package.mk b/packages/kernel/linux/package.mk index fbe521a03..fdeb092b6 100644 --- a/packages/kernel/linux/package.mk +++ b/packages/kernel/linux/package.mk @@ -4,8 +4,8 @@ PKG_NAME="linux" PKG_LICENSE="GPL" -PKG_VERSION="5.19.16" -PKG_URL="https://www.kernel.org/pub/linux/kernel/v5.x/${PKG_NAME}-${PKG_VERSION}.tar.xz" +PKG_VERSION="6.0.6" +PKG_URL="https://www.kernel.org/pub/linux/kernel/v6.x/${PKG_NAME}-${PKG_VERSION}.tar.xz" PKG_SITE="http://www.kernel.org" PKG_DEPENDS_HOST="ccache:host rsync:host openssl:host" PKG_DEPENDS_TARGET="toolchain linux:host kmod:host cpio:host xz:host keyutils ncurses openssl:host ${KERNEL_EXTRA_DEPENDS_TARGET}" @@ -19,8 +19,8 @@ PKG_PATCH_DIRS+="${LINUX} ${DEVICE} default" PKG_KERNEL_CFG_FILE=$(kernel_config_path) || die if [ -n "${KERNEL_TOOLCHAIN}" ]; then - PKG_DEPENDS_HOST="${PKG_DEPENDS_HOST} gcc-arm-${KERNEL_TOOLCHAIN}:host" - PKG_DEPENDS_TARGET="${PKG_DEPENDS_TARGET} gcc-arm-${KERNEL_TOOLCHAIN}:host" + PKG_DEPENDS_HOST="${PKG_DEPENDS_HOST} gcc-${KERNEL_TOOLCHAIN}:host" + PKG_DEPENDS_TARGET="${PKG_DEPENDS_TARGET} gcc-${KERNEL_TOOLCHAIN}:host" HEADERS_ARCH=${TARGET_ARCH} fi @@ -175,7 +175,7 @@ pre_make_target() { ${PKG_BUILD}/scripts/config --set-str CONFIG_EXTRA_FIRMWARE_DIR "external-firmware" fi - kernel_make oldconfig + yes "" | kernel_make oldconfig if [ -f "${ROOT}/${DISTRO}/kernel_options" ]; then while read OPTION; do diff --git a/packages/kernel/linux/patches/X86_64/001-ayaneo-air.patch b/packages/kernel/linux/patches/X86_64/001-ayaneo-air.patch deleted file mode 100644 index 2d4732788..000000000 --- a/packages/kernel/linux/patches/X86_64/001-ayaneo-air.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 1fa1da0a951b32aada6f924b71a4417f101b2ed0 Mon Sep 17 00:00:00 2001 -From: Maya Matuszczyk -Date: Thu, 25 Aug 2022 20:58:34 +0200 -Subject: [PATCH] drm: panel-orientation-quirks: Add quirk for Aya Neo Air - -Yet another x86 gaming handheld. - -This one has many SKUs with quite a few of DMI strings, -so let's just use a catchall, just as with Aya Neo Next. - -Signed-off-by: Maya Matuszczyk ---- - drivers/gpu/drm/drm_panel_orientation_quirks.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c -index fc1728d46ac2..842d974a95c3 100644 ---- a/drivers/gpu/drm/drm_panel_orientation_quirks.c -+++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c -@@ -103,6 +103,12 @@ static const struct drm_dmi_panel_orientation_data lcd800x1280_rightside_up = { - .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, - }; - -+static const struct drm_dmi_panel_orientation_data lcd1080x1920_leftside_up = { -+ .width = 1080, -+ .height = 1920, -+ .orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP, -+}; -+ - static const struct drm_dmi_panel_orientation_data lcd1200x1920_rightside_up = { - .width = 1200, - .height = 1920, -@@ -152,6 +158,12 @@ static const struct dmi_system_id orientation_data[] = { - DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "AYA NEO 2021"), - }, - .driver_data = (void *)&lcd800x1280_rightside_up, -+ }, { /* AYA NEO AIR */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYANEO"), -+ DMI_MATCH(DMI_BOARD_NAME, "AIR"), -+ }, -+ .driver_data = (void *)&lcd1080x1920_leftside_up, - }, { /* AYA NEO NEXT */ - .matches = { - DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AYANEO"), --- -2.37.2 diff --git a/packages/kernel/linux/patches/X86_64/001-win600-panel.patch b/packages/kernel/linux/patches/X86_64/001-win600-panel.patch deleted file mode 100644 index 770aed292..000000000 --- a/packages/kernel/linux/patches/X86_64/001-win600-panel.patch +++ /dev/null @@ -1,32 +0,0 @@ -diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c -index 4e853acfd1e8..14b162167436 100644 ---- a/drivers/gpu/drm/drm_panel_orientation_quirks.c -+++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c -@@ -121,6 +121,12 @@ static const struct drm_dmi_panel_orientation_data lcd1600x2560_leftside_up = { - .orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP, - }; - -+static const struct drm_dmi_panel_orientation_data win600 = { -+ .width = 720, -+ .height = 1280, -+ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, -+}; -+ - static const struct dmi_system_id orientation_data[] = { - { /* Acer One 10 (S1003) */ - .matches = { -@@ -311,7 +317,13 @@ static const struct dmi_system_id orientation_data[] = { - DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"), - DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LTH17"), - }, -- .driver_data = (void *)&lcd800x1280_rightside_up, -+ .driver_data = (void *)&lcd720x1280_rightside_up, -+ }, { /* Anbernic Win600 */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Anbernic"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Win600"), -+ }, -+ .driver_data = (void *)&win600, - }, - {} - }; diff --git a/packages/kernel/linux/patches/X86_64/patch-5.19-rt10.patch b/packages/kernel/linux/patches/X86_64/patch-5.19-rt10.patch deleted file mode 100644 index d4c2a238c..000000000 --- a/packages/kernel/linux/patches/X86_64/patch-5.19-rt10.patch +++ /dev/null @@ -1,5198 +0,0 @@ -diff -rupN linux-5.19.16.orig/arch/arm/include/asm/thread_info.h linux-5.19.16/arch/arm/include/asm/thread_info.h ---- linux-5.19.16.orig/arch/arm/include/asm/thread_info.h 2022-10-18 17:21:09.088513860 -0400 -+++ linux-5.19.16/arch/arm/include/asm/thread_info.h 2022-10-18 17:21:17.796446755 -0400 -@@ -62,6 +62,7 @@ struct cpu_context_save { - struct thread_info { - unsigned long flags; /* low level flags */ - int preempt_count; /* 0 => preemptable, <0 => bug */ -+ int preempt_lazy_count; /* 0 => preemptable, <0 => bug */ - __u32 cpu; /* cpu */ - __u32 cpu_domain; /* cpu domain */ - struct cpu_context_save cpu_context; /* cpu context */ -@@ -133,6 +134,7 @@ extern int vfp_restore_user_hwstate(stru - #define TIF_SYSCALL_TRACEPOINT 6 /* syscall tracepoint instrumentation */ - #define TIF_SECCOMP 7 /* seccomp syscall filtering active */ - #define TIF_NOTIFY_SIGNAL 8 /* signal notifications exist */ -+#define TIF_NEED_RESCHED_LAZY 9 - - #define TIF_USING_IWMMXT 17 - #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ -@@ -147,6 +149,7 @@ extern int vfp_restore_user_hwstate(stru - #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) - #define _TIF_SECCOMP (1 << TIF_SECCOMP) - #define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL) -+#define _TIF_NEED_RESCHED_LAZY (1 << TIF_NEED_RESCHED_LAZY) - #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) - - /* Checks for any syscall work in entry-common.S */ -@@ -156,7 +159,8 @@ extern int vfp_restore_user_hwstate(stru - /* - * Change these and you break ASM code in entry-common.S - */ --#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ -+#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY | \ -+ _TIF_SIGPENDING | \ - _TIF_NOTIFY_RESUME | _TIF_UPROBE | \ - _TIF_NOTIFY_SIGNAL) - -diff -rupN linux-5.19.16.orig/arch/arm/Kconfig linux-5.19.16/arch/arm/Kconfig ---- linux-5.19.16.orig/arch/arm/Kconfig 2022-10-18 17:21:09.020514385 -0400 -+++ linux-5.19.16/arch/arm/Kconfig 2022-10-18 17:21:17.796446755 -0400 -@@ -34,6 +34,7 @@ config ARM - select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT if CPU_V7 - select ARCH_SUPPORTS_ATOMIC_RMW - select ARCH_SUPPORTS_HUGETLBFS if ARM_LPAE -+ select ARCH_SUPPORTS_RT if HAVE_POSIX_CPU_TIMERS_TASK_WORK - select ARCH_USE_BUILTIN_BSWAP - select ARCH_USE_CMPXCHG_LOCKREF - select ARCH_USE_MEMTEST -@@ -71,7 +72,7 @@ config ARM - select HARDIRQS_SW_RESEND - select HAVE_ARCH_AUDITSYSCALL if AEABI && !OABI_COMPAT - select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6 -- select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU -+ select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU && !PREEMPT_RT - select HAVE_ARCH_KFENCE if MMU && !XIP_KERNEL - select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU - select HAVE_ARCH_KASAN if MMU && !XIP_KERNEL -@@ -113,6 +114,7 @@ config ARM - select HAVE_PERF_EVENTS - select HAVE_PERF_REGS - select HAVE_PERF_USER_STACK_DUMP -+ select HAVE_PREEMPT_LAZY - select MMU_GATHER_RCU_TABLE_FREE if SMP && ARM_LPAE - select HAVE_REGS_AND_STACK_ACCESS_API - select HAVE_RSEQ -@@ -128,6 +130,7 @@ config ARM - select OLD_SIGSUSPEND3 - select PCI_SYSCALL if PCI - select PERF_USE_VMALLOC -+ select HAVE_POSIX_CPU_TIMERS_TASK_WORK if !KVM - select RTC_LIB - select SYS_SUPPORTS_APM_EMULATION - select THREAD_INFO_IN_TASK -diff -rupN linux-5.19.16.orig/arch/arm/kernel/asm-offsets.c linux-5.19.16/arch/arm/kernel/asm-offsets.c ---- linux-5.19.16.orig/arch/arm/kernel/asm-offsets.c 2022-10-18 17:21:09.092513830 -0400 -+++ linux-5.19.16/arch/arm/kernel/asm-offsets.c 2022-10-18 17:21:17.796446755 -0400 -@@ -43,6 +43,7 @@ int main(void) - BLANK(); - DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); - DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); -+ DEFINE(TI_PREEMPT_LAZY, offsetof(struct thread_info, preempt_lazy_count)); - DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); - DEFINE(TI_CPU_DOMAIN, offsetof(struct thread_info, cpu_domain)); - DEFINE(TI_CPU_SAVE, offsetof(struct thread_info, cpu_context)); -diff -rupN linux-5.19.16.orig/arch/arm/kernel/entry-armv.S linux-5.19.16/arch/arm/kernel/entry-armv.S ---- linux-5.19.16.orig/arch/arm/kernel/entry-armv.S 2022-10-18 17:21:09.092513830 -0400 -+++ linux-5.19.16/arch/arm/kernel/entry-armv.S 2022-10-18 17:21:17.796446755 -0400 -@@ -222,11 +222,18 @@ __irq_svc: - - #ifdef CONFIG_PREEMPTION - ldr r8, [tsk, #TI_PREEMPT] @ get preempt count -- ldr r0, [tsk, #TI_FLAGS] @ get flags - teq r8, #0 @ if preempt count != 0 -+ bne 1f @ return from exeption -+ ldr r0, [tsk, #TI_FLAGS] @ get flags -+ tst r0, #_TIF_NEED_RESCHED @ if NEED_RESCHED is set -+ blne svc_preempt @ preempt! -+ -+ ldr r8, [tsk, #TI_PREEMPT_LAZY] @ get preempt lazy count -+ teq r8, #0 @ if preempt lazy count != 0 - movne r0, #0 @ force flags to 0 -- tst r0, #_TIF_NEED_RESCHED -+ tst r0, #_TIF_NEED_RESCHED_LAZY - blne svc_preempt -+1: - #endif - - svc_exit r5, irq = 1 @ return from exception -@@ -241,8 +248,14 @@ svc_preempt: - 1: bl preempt_schedule_irq @ irq en/disable is done inside - ldr r0, [tsk, #TI_FLAGS] @ get new tasks TI_FLAGS - tst r0, #_TIF_NEED_RESCHED -+ bne 1b -+ tst r0, #_TIF_NEED_RESCHED_LAZY - reteq r8 @ go again -- b 1b -+ ldr r0, [tsk, #TI_PREEMPT_LAZY] @ get preempt lazy count -+ teq r0, #0 @ if preempt lazy count != 0 -+ beq 1b -+ ret r8 @ go again -+ - #endif - - __und_fault: -diff -rupN linux-5.19.16.orig/arch/arm/kernel/irq.c linux-5.19.16/arch/arm/kernel/irq.c ---- linux-5.19.16.orig/arch/arm/kernel/irq.c 2022-10-18 17:21:09.092513830 -0400 -+++ linux-5.19.16/arch/arm/kernel/irq.c 2022-10-18 17:21:17.796446755 -0400 -@@ -70,6 +70,7 @@ static void __init init_irq_stacks(void) - } - } - -+#ifndef CONFIG_PREEMPT_RT - static void ____do_softirq(void *arg) - { - __do_softirq(); -@@ -80,7 +81,7 @@ void do_softirq_own_stack(void) - call_with_stack(____do_softirq, NULL, - __this_cpu_read(irq_stack_ptr)); - } -- -+#endif - #endif - - int arch_show_interrupts(struct seq_file *p, int prec) -diff -rupN linux-5.19.16.orig/arch/arm/kernel/signal.c linux-5.19.16/arch/arm/kernel/signal.c ---- linux-5.19.16.orig/arch/arm/kernel/signal.c 2022-10-18 17:21:09.092513830 -0400 -+++ linux-5.19.16/arch/arm/kernel/signal.c 2022-10-18 17:21:17.796446755 -0400 -@@ -607,7 +607,8 @@ do_work_pending(struct pt_regs *regs, un - */ - trace_hardirqs_off(); - do { -- if (likely(thread_flags & _TIF_NEED_RESCHED)) { -+ if (likely(thread_flags & (_TIF_NEED_RESCHED | -+ _TIF_NEED_RESCHED_LAZY))) { - schedule(); - } else { - if (unlikely(!user_mode(regs))) -diff -rupN linux-5.19.16.orig/arch/arm/mm/fault.c linux-5.19.16/arch/arm/mm/fault.c ---- linux-5.19.16.orig/arch/arm/mm/fault.c 2022-10-18 17:21:09.124513584 -0400 -+++ linux-5.19.16/arch/arm/mm/fault.c 2022-10-18 17:21:17.796446755 -0400 -@@ -417,6 +417,9 @@ do_translation_fault(unsigned long addr, - if (addr < TASK_SIZE) - return do_page_fault(addr, fsr, regs); - -+ if (interrupts_enabled(regs)) -+ local_irq_enable(); -+ - if (user_mode(regs)) - goto bad_area; - -@@ -487,6 +490,9 @@ do_translation_fault(unsigned long addr, - static int - do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) - { -+ if (interrupts_enabled(regs)) -+ local_irq_enable(); -+ - do_bad_area(addr, fsr, regs); - return 0; - } -diff -rupN linux-5.19.16.orig/arch/arm64/include/asm/preempt.h linux-5.19.16/arch/arm64/include/asm/preempt.h ---- linux-5.19.16.orig/arch/arm64/include/asm/preempt.h 2022-10-18 17:21:09.164513276 -0400 -+++ linux-5.19.16/arch/arm64/include/asm/preempt.h 2022-10-18 17:21:17.796446755 -0400 -@@ -71,13 +71,36 @@ static inline bool __preempt_count_dec_a - * interrupt occurring between the non-atomic READ_ONCE/WRITE_ONCE - * pair. - */ -- return !pc || !READ_ONCE(ti->preempt_count); -+ if (!pc || !READ_ONCE(ti->preempt_count)) -+ return true; -+#ifdef CONFIG_PREEMPT_LAZY -+ if ((pc & ~PREEMPT_NEED_RESCHED)) -+ return false; -+ if (current_thread_info()->preempt_lazy_count) -+ return false; -+ return test_thread_flag(TIF_NEED_RESCHED_LAZY); -+#else -+ return false; -+#endif - } - - static inline bool should_resched(int preempt_offset) - { -+#ifdef CONFIG_PREEMPT_LAZY -+ u64 pc = READ_ONCE(current_thread_info()->preempt_count); -+ if (pc == preempt_offset) -+ return true; -+ -+ if ((pc & ~PREEMPT_NEED_RESCHED) != preempt_offset) -+ return false; -+ -+ if (current_thread_info()->preempt_lazy_count) -+ return false; -+ return test_thread_flag(TIF_NEED_RESCHED_LAZY); -+#else - u64 pc = READ_ONCE(current_thread_info()->preempt_count); - return pc == preempt_offset; -+#endif - } - - #ifdef CONFIG_PREEMPTION -diff -rupN linux-5.19.16.orig/arch/arm64/include/asm/thread_info.h linux-5.19.16/arch/arm64/include/asm/thread_info.h ---- linux-5.19.16.orig/arch/arm64/include/asm/thread_info.h 2022-10-18 17:21:09.164513276 -0400 -+++ linux-5.19.16/arch/arm64/include/asm/thread_info.h 2022-10-18 17:21:17.796446755 -0400 -@@ -26,6 +26,7 @@ struct thread_info { - #ifdef CONFIG_ARM64_SW_TTBR0_PAN - u64 ttbr0; /* saved TTBR0_EL1 */ - #endif -+ int preempt_lazy_count; /* 0 => preemptable, <0 => bug */ - union { - u64 preempt_count; /* 0 => preemptible, <0 => bug */ - struct { -@@ -68,6 +69,7 @@ int arch_dup_task_struct(struct task_str - #define TIF_UPROBE 4 /* uprobe breakpoint or singlestep */ - #define TIF_MTE_ASYNC_FAULT 5 /* MTE Asynchronous Tag Check Fault */ - #define TIF_NOTIFY_SIGNAL 6 /* signal notifications exist */ -+#define TIF_NEED_RESCHED_LAZY 7 - #define TIF_SYSCALL_TRACE 8 /* syscall trace active */ - #define TIF_SYSCALL_AUDIT 9 /* syscall auditing */ - #define TIF_SYSCALL_TRACEPOINT 10 /* syscall tracepoint for ftrace */ -@@ -100,8 +102,10 @@ int arch_dup_task_struct(struct task_str - #define _TIF_SVE (1 << TIF_SVE) - #define _TIF_MTE_ASYNC_FAULT (1 << TIF_MTE_ASYNC_FAULT) - #define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL) -+#define _TIF_NEED_RESCHED_LAZY (1 << TIF_NEED_RESCHED_LAZY) - --#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ -+#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY | \ -+ _TIF_SIGPENDING | \ - _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \ - _TIF_UPROBE | _TIF_MTE_ASYNC_FAULT | \ - _TIF_NOTIFY_SIGNAL) -@@ -110,6 +114,8 @@ int arch_dup_task_struct(struct task_str - _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \ - _TIF_SYSCALL_EMU) - -+#define _TIF_NEED_RESCHED_MASK (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY) -+ - #ifdef CONFIG_SHADOW_CALL_STACK - #define INIT_SCS \ - .scs_base = init_shadow_call_stack, \ -diff -rupN linux-5.19.16.orig/arch/arm64/Kconfig linux-5.19.16/arch/arm64/Kconfig ---- linux-5.19.16.orig/arch/arm64/Kconfig 2022-10-18 17:21:09.128513553 -0400 -+++ linux-5.19.16/arch/arm64/Kconfig 2022-10-18 17:21:17.796446755 -0400 -@@ -93,6 +93,7 @@ config ARM64 - select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 - select ARCH_SUPPORTS_NUMA_BALANCING - select ARCH_SUPPORTS_PAGE_TABLE_CHECK -+ select ARCH_SUPPORTS_RT - select ARCH_WANT_COMPAT_IPC_PARSE_VERSION if COMPAT - select ARCH_WANT_DEFAULT_BPF_JIT - select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT -@@ -197,6 +198,7 @@ config ARM64 - select HAVE_PERF_USER_STACK_DUMP - select HAVE_PREEMPT_DYNAMIC_KEY - select HAVE_REGS_AND_STACK_ACCESS_API -+ select HAVE_PREEMPT_LAZY - select HAVE_POSIX_CPU_TIMERS_TASK_WORK - select HAVE_FUNCTION_ARG_ACCESS_API - select MMU_GATHER_RCU_TABLE_FREE -diff -rupN linux-5.19.16.orig/arch/arm64/kernel/asm-offsets.c linux-5.19.16/arch/arm64/kernel/asm-offsets.c ---- linux-5.19.16.orig/arch/arm64/kernel/asm-offsets.c 2022-10-18 17:21:09.164513276 -0400 -+++ linux-5.19.16/arch/arm64/kernel/asm-offsets.c 2022-10-18 17:21:17.796446755 -0400 -@@ -32,6 +32,7 @@ int main(void) - DEFINE(TSK_TI_CPU, offsetof(struct task_struct, thread_info.cpu)); - DEFINE(TSK_TI_FLAGS, offsetof(struct task_struct, thread_info.flags)); - DEFINE(TSK_TI_PREEMPT, offsetof(struct task_struct, thread_info.preempt_count)); -+ DEFINE(TSK_TI_PREEMPT_LAZY, offsetof(struct task_struct, thread_info.preempt_lazy_count)); - #ifdef CONFIG_ARM64_SW_TTBR0_PAN - DEFINE(TSK_TI_TTBR0, offsetof(struct task_struct, thread_info.ttbr0)); - #endif -diff -rupN linux-5.19.16.orig/arch/arm64/kernel/signal.c linux-5.19.16/arch/arm64/kernel/signal.c ---- linux-5.19.16.orig/arch/arm64/kernel/signal.c 2022-10-18 17:21:09.168513245 -0400 -+++ linux-5.19.16/arch/arm64/kernel/signal.c 2022-10-18 17:21:17.796446755 -0400 -@@ -1099,7 +1099,7 @@ static void do_signal(struct pt_regs *re - void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags) - { - do { -- if (thread_flags & _TIF_NEED_RESCHED) { -+ if (thread_flags & _TIF_NEED_RESCHED_MASK) { - /* Unmask Debug and SError for the next task */ - local_daif_restore(DAIF_PROCCTX_NOIRQ); - -diff -rupN linux-5.19.16.orig/arch/parisc/kernel/irq.c linux-5.19.16/arch/parisc/kernel/irq.c ---- linux-5.19.16.orig/arch/parisc/kernel/irq.c 2022-10-18 17:21:09.252512598 -0400 -+++ linux-5.19.16/arch/parisc/kernel/irq.c 2022-10-18 17:21:17.796446755 -0400 -@@ -480,10 +480,12 @@ static void execute_on_irq_stack(void *f - *irq_stack_in_use = 1; - } - -+#ifndef CONFIG_PREEMPT_RT - void do_softirq_own_stack(void) - { - execute_on_irq_stack(__do_softirq, 0); - } -+#endif - #endif /* CONFIG_IRQSTACKS */ - - /* ONLY called from entry.S:intr_extint() */ -diff -rupN linux-5.19.16.orig/arch/powerpc/include/asm/stackprotector.h linux-5.19.16/arch/powerpc/include/asm/stackprotector.h ---- linux-5.19.16.orig/arch/powerpc/include/asm/stackprotector.h 2022-10-18 17:21:09.272512444 -0400 -+++ linux-5.19.16/arch/powerpc/include/asm/stackprotector.h 2022-10-18 17:21:17.796446755 -0400 -@@ -24,7 +24,11 @@ static __always_inline void boot_init_st - unsigned long canary; - - /* Try to get a semi random initial value. */ -+#ifdef CONFIG_PREEMPT_RT -+ canary = (unsigned long)&canary; -+#else - canary = get_random_canary(); -+#endif - canary ^= mftb(); - canary ^= LINUX_VERSION_CODE; - canary &= CANARY_MASK; -diff -rupN linux-5.19.16.orig/arch/powerpc/include/asm/thread_info.h linux-5.19.16/arch/powerpc/include/asm/thread_info.h ---- linux-5.19.16.orig/arch/powerpc/include/asm/thread_info.h 2022-10-18 17:21:09.276512413 -0400 -+++ linux-5.19.16/arch/powerpc/include/asm/thread_info.h 2022-10-18 17:21:17.796446755 -0400 -@@ -53,6 +53,8 @@ - struct thread_info { - int preempt_count; /* 0 => preemptable, - <0 => BUG */ -+ int preempt_lazy_count; /* 0 => preemptable, -+ <0 => BUG */ - #ifdef CONFIG_SMP - unsigned int cpu; - #endif -@@ -77,6 +79,7 @@ struct thread_info { - #define INIT_THREAD_INFO(tsk) \ - { \ - .preempt_count = INIT_PREEMPT_COUNT, \ -+ .preempt_lazy_count = 0, \ - .flags = 0, \ - } - -@@ -102,6 +105,7 @@ void arch_setup_new_exec(void); - #define TIF_PATCH_PENDING 6 /* pending live patching update */ - #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ - #define TIF_SINGLESTEP 8 /* singlestepping active */ -+#define TIF_NEED_RESCHED_LAZY 9 /* lazy rescheduling necessary */ - #define TIF_SECCOMP 10 /* secure computing */ - #define TIF_RESTOREALL 11 /* Restore all regs (implies NOERROR) */ - #define TIF_NOERROR 12 /* Force successful syscall return */ -@@ -117,6 +121,7 @@ void arch_setup_new_exec(void); - #define TIF_POLLING_NRFLAG 19 /* true if poll_idle() is polling TIF_NEED_RESCHED */ - #define TIF_32BIT 20 /* 32 bit binary */ - -+ - /* as above, but as bit values */ - #define _TIF_SYSCALL_TRACE (1<msr & MSR_EE)); - again: -- if (IS_ENABLED(CONFIG_PREEMPT)) { -+ if (IS_ENABLED(CONFIG_PREEMPTION)) { - /* Return to preemptible kernel context */ - if (unlikely(read_thread_flags() & _TIF_NEED_RESCHED)) { - if (preempt_count() == 0) - preempt_schedule_irq(); -+ } else if (unlikely(current_thread_info()->flags & _TIF_NEED_RESCHED_LAZY)) { -+ if ((preempt_count() == 0) && -+ (current_thread_info()->preempt_lazy_count == 0)) -+ preempt_schedule_irq(); - } - } - -diff -rupN linux-5.19.16.orig/arch/powerpc/kernel/irq.c linux-5.19.16/arch/powerpc/kernel/irq.c ---- linux-5.19.16.orig/arch/powerpc/kernel/irq.c 2022-10-18 17:21:09.280512382 -0400 -+++ linux-5.19.16/arch/powerpc/kernel/irq.c 2022-10-18 17:21:17.796446755 -0400 -@@ -611,6 +611,7 @@ static inline void check_stack_overflow( - } - } - -+#ifndef CONFIG_PREEMPT_RT - static __always_inline void call_do_softirq(const void *sp) - { - /* Temporarily switch r1 to sp, call __do_softirq() then restore r1. */ -@@ -629,6 +630,7 @@ static __always_inline void call_do_soft - "r11", "r12" - ); - } -+#endif - - static __always_inline void call_do_irq(struct pt_regs *regs, void *sp) - { -@@ -747,10 +749,12 @@ void *mcheckirq_ctx[NR_CPUS] __read_most - void *softirq_ctx[NR_CPUS] __read_mostly; - void *hardirq_ctx[NR_CPUS] __read_mostly; - -+#ifndef CONFIG_PREEMPT_RT - void do_softirq_own_stack(void) - { - call_do_softirq(softirq_ctx[smp_processor_id()]); - } -+#endif - - irq_hw_number_t virq_to_hw(unsigned int virq) - { -diff -rupN linux-5.19.16.orig/arch/powerpc/kernel/traps.c linux-5.19.16/arch/powerpc/kernel/traps.c ---- linux-5.19.16.orig/arch/powerpc/kernel/traps.c 2022-10-18 17:21:09.280512382 -0400 -+++ linux-5.19.16/arch/powerpc/kernel/traps.c 2022-10-18 17:21:17.796446755 -0400 -@@ -260,12 +260,17 @@ static char *get_mmu_str(void) - - static int __die(const char *str, struct pt_regs *regs, long err) - { -+ const char *pr = ""; -+ - printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); - -+ if (IS_ENABLED(CONFIG_PREEMPTION)) -+ pr = IS_ENABLED(CONFIG_PREEMPT_RT) ? " PREEMPT_RT" : " PREEMPT"; -+ - printk("%s PAGE_SIZE=%luK%s%s%s%s%s%s %s\n", - IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN) ? "LE" : "BE", - PAGE_SIZE / 1024, get_mmu_str(), -- IS_ENABLED(CONFIG_PREEMPT) ? " PREEMPT" : "", -+ pr, - IS_ENABLED(CONFIG_SMP) ? " SMP" : "", - IS_ENABLED(CONFIG_SMP) ? (" NR_CPUS=" __stringify(NR_CPUS)) : "", - debug_pagealloc_enabled() ? " DEBUG_PAGEALLOC" : "", -diff -rupN linux-5.19.16.orig/arch/powerpc/kvm/Kconfig linux-5.19.16/arch/powerpc/kvm/Kconfig ---- linux-5.19.16.orig/arch/powerpc/kvm/Kconfig 2022-10-18 17:21:09.284512352 -0400 -+++ linux-5.19.16/arch/powerpc/kvm/Kconfig 2022-10-18 17:21:17.796446755 -0400 -@@ -204,6 +204,7 @@ config KVM_E500MC - config KVM_MPIC - bool "KVM in-kernel MPIC emulation" - depends on KVM && E500 -+ depends on !PREEMPT_RT - select HAVE_KVM_IRQCHIP - select HAVE_KVM_IRQFD - select HAVE_KVM_IRQ_ROUTING -diff -rupN linux-5.19.16.orig/arch/powerpc/platforms/pseries/iommu.c linux-5.19.16/arch/powerpc/platforms/pseries/iommu.c ---- linux-5.19.16.orig/arch/powerpc/platforms/pseries/iommu.c 2022-10-18 17:21:09.296512259 -0400 -+++ linux-5.19.16/arch/powerpc/platforms/pseries/iommu.c 2022-10-18 17:21:17.796446755 -0400 -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -195,7 +196,13 @@ static int tce_build_pSeriesLP(unsigned - return ret; - } - --static DEFINE_PER_CPU(__be64 *, tce_page); -+struct tce_page { -+ __be64 * page; -+ local_lock_t lock; -+}; -+static DEFINE_PER_CPU(struct tce_page, tce_page) = { -+ .lock = INIT_LOCAL_LOCK(lock), -+}; - - static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, - long npages, unsigned long uaddr, -@@ -218,9 +225,10 @@ static int tce_buildmulti_pSeriesLP(stru - direction, attrs); - } - -- local_irq_save(flags); /* to protect tcep and the page behind it */ -+ /* to protect tcep and the page behind it */ -+ local_lock_irqsave(&tce_page.lock, flags); - -- tcep = __this_cpu_read(tce_page); -+ tcep = __this_cpu_read(tce_page.page); - - /* This is safe to do since interrupts are off when we're called - * from iommu_alloc{,_sg}() -@@ -229,12 +237,12 @@ static int tce_buildmulti_pSeriesLP(stru - tcep = (__be64 *)__get_free_page(GFP_ATOMIC); - /* If allocation fails, fall back to the loop implementation */ - if (!tcep) { -- local_irq_restore(flags); -+ local_unlock_irqrestore(&tce_page.lock, flags); - return tce_build_pSeriesLP(tbl->it_index, tcenum, - tceshift, - npages, uaddr, direction, attrs); - } -- __this_cpu_write(tce_page, tcep); -+ __this_cpu_write(tce_page.page, tcep); - } - - rpn = __pa(uaddr) >> tceshift; -@@ -264,7 +272,7 @@ static int tce_buildmulti_pSeriesLP(stru - tcenum += limit; - } while (npages > 0 && !rc); - -- local_irq_restore(flags); -+ local_unlock_irqrestore(&tce_page.lock, flags); - - if (unlikely(rc == H_NOT_ENOUGH_RESOURCES)) { - ret = (int)rc; -@@ -440,16 +448,17 @@ static int tce_setrange_multi_pSeriesLP( - DMA_BIDIRECTIONAL, 0); - } - -- local_irq_disable(); /* to protect tcep and the page behind it */ -- tcep = __this_cpu_read(tce_page); -+ /* to protect tcep and the page behind it */ -+ local_lock_irq(&tce_page.lock); -+ tcep = __this_cpu_read(tce_page.page); - - if (!tcep) { - tcep = (__be64 *)__get_free_page(GFP_ATOMIC); - if (!tcep) { -- local_irq_enable(); -+ local_unlock_irq(&tce_page.lock); - return -ENOMEM; - } -- __this_cpu_write(tce_page, tcep); -+ __this_cpu_write(tce_page.page, tcep); - } - - proto_tce = TCE_PCI_READ | TCE_PCI_WRITE; -@@ -492,7 +501,7 @@ static int tce_setrange_multi_pSeriesLP( - - /* error cleanup: caller will clear whole range */ - -- local_irq_enable(); -+ local_unlock_irq(&tce_page.lock); - return rc; - } - -diff -rupN linux-5.19.16.orig/arch/s390/include/asm/softirq_stack.h linux-5.19.16/arch/s390/include/asm/softirq_stack.h ---- linux-5.19.16.orig/arch/s390/include/asm/softirq_stack.h 2022-10-18 17:21:09.312512136 -0400 -+++ linux-5.19.16/arch/s390/include/asm/softirq_stack.h 2022-10-18 17:21:17.796446755 -0400 -@@ -5,9 +5,10 @@ - #include - #include - -+#ifndef CONFIG_PREEMPT_RT - static inline void do_softirq_own_stack(void) - { - call_on_stack(0, S390_lowcore.async_stack, void, __do_softirq); - } -- -+#endif - #endif /* __ASM_S390_SOFTIRQ_STACK_H */ -diff -rupN linux-5.19.16.orig/arch/sh/kernel/irq.c linux-5.19.16/arch/sh/kernel/irq.c ---- linux-5.19.16.orig/arch/sh/kernel/irq.c 2022-10-18 17:21:09.328512013 -0400 -+++ linux-5.19.16/arch/sh/kernel/irq.c 2022-10-18 17:21:17.796446755 -0400 -@@ -149,6 +149,7 @@ void irq_ctx_exit(int cpu) - hardirq_ctx[cpu] = NULL; - } - -+#ifndef CONFIG_PREEMPT_RT - void do_softirq_own_stack(void) - { - struct thread_info *curctx; -@@ -176,6 +177,7 @@ void do_softirq_own_stack(void) - "r5", "r6", "r7", "r8", "r9", "r15", "t", "pr" - ); - } -+#endif - #else - static inline void handle_one_irq(unsigned int irq) - { -diff -rupN linux-5.19.16.orig/arch/sparc/kernel/irq_64.c linux-5.19.16/arch/sparc/kernel/irq_64.c ---- linux-5.19.16.orig/arch/sparc/kernel/irq_64.c 2022-10-18 17:21:09.344511889 -0400 -+++ linux-5.19.16/arch/sparc/kernel/irq_64.c 2022-10-18 17:21:17.800446725 -0400 -@@ -855,6 +855,7 @@ void __irq_entry handler_irq(int pil, st - set_irq_regs(old_regs); - } - -+#ifndef CONFIG_PREEMPT_RT - void do_softirq_own_stack(void) - { - void *orig_sp, *sp = softirq_stack[smp_processor_id()]; -@@ -869,6 +870,7 @@ void do_softirq_own_stack(void) - __asm__ __volatile__("mov %0, %%sp" - : : "r" (orig_sp)); - } -+#endif - - #ifdef CONFIG_HOTPLUG_CPU - void fixup_irqs(void) -diff -rupN linux-5.19.16.orig/arch/x86/include/asm/preempt.h linux-5.19.16/arch/x86/include/asm/preempt.h ---- linux-5.19.16.orig/arch/x86/include/asm/preempt.h 2022-10-18 17:21:09.364511736 -0400 -+++ linux-5.19.16/arch/x86/include/asm/preempt.h 2022-10-18 17:21:17.800446725 -0400 -@@ -90,17 +90,48 @@ static __always_inline void __preempt_co - * a decrement which hits zero means we have no preempt_count and should - * reschedule. - */ --static __always_inline bool __preempt_count_dec_and_test(void) -+static __always_inline bool ____preempt_count_dec_and_test(void) - { - return GEN_UNARY_RMWcc("decl", __preempt_count, e, __percpu_arg([var])); - } - -+static __always_inline bool __preempt_count_dec_and_test(void) -+{ -+ if (____preempt_count_dec_and_test()) -+ return true; -+#ifdef CONFIG_PREEMPT_LAZY -+ if (preempt_count()) -+ return false; -+ if (current_thread_info()->preempt_lazy_count) -+ return false; -+ return test_thread_flag(TIF_NEED_RESCHED_LAZY); -+#else -+ return false; -+#endif -+} -+ - /* - * Returns true when we need to resched and can (barring IRQ state). - */ - static __always_inline bool should_resched(int preempt_offset) - { -+#ifdef CONFIG_PREEMPT_LAZY -+ u32 tmp; -+ tmp = raw_cpu_read_4(__preempt_count); -+ if (tmp == preempt_offset) -+ return true; -+ -+ /* preempt count == 0 ? */ -+ tmp &= ~PREEMPT_NEED_RESCHED; -+ if (tmp != preempt_offset) -+ return false; -+ /* XXX PREEMPT_LOCK_OFFSET */ -+ if (current_thread_info()->preempt_lazy_count) -+ return false; -+ return test_thread_flag(TIF_NEED_RESCHED_LAZY); -+#else - return unlikely(raw_cpu_read_4(__preempt_count) == preempt_offset); -+#endif - } - - #ifdef CONFIG_PREEMPTION -diff -rupN linux-5.19.16.orig/arch/x86/include/asm/thread_info.h linux-5.19.16/arch/x86/include/asm/thread_info.h ---- linux-5.19.16.orig/arch/x86/include/asm/thread_info.h 2022-10-18 17:21:09.368511705 -0400 -+++ linux-5.19.16/arch/x86/include/asm/thread_info.h 2022-10-18 17:21:17.800446725 -0400 -@@ -57,6 +57,8 @@ struct thread_info { - unsigned long flags; /* low level flags */ - unsigned long syscall_work; /* SYSCALL_WORK_ flags */ - u32 status; /* thread synchronous flags */ -+ int preempt_lazy_count; /* 0 => lazy preemptable -+ <0 => BUG */ - #ifdef CONFIG_SMP - u32 cpu; /* current CPU */ - #endif -@@ -65,6 +67,7 @@ struct thread_info { - #define INIT_THREAD_INFO(tsk) \ - { \ - .flags = 0, \ -+ .preempt_lazy_count = 0, \ - } - - #else /* !__ASSEMBLY__ */ -@@ -92,6 +95,7 @@ struct thread_info { - #define TIF_NOCPUID 15 /* CPUID is not accessible in userland */ - #define TIF_NOTSC 16 /* TSC is not accessible in userland */ - #define TIF_NOTIFY_SIGNAL 17 /* signal notifications exist */ -+#define TIF_NEED_RESCHED_LAZY 19 /* lazy rescheduling necessary */ - #define TIF_MEMDIE 20 /* is terminating due to OOM killer */ - #define TIF_POLLING_NRFLAG 21 /* idle is polling for TIF_NEED_RESCHED */ - #define TIF_IO_BITMAP 22 /* uses I/O bitmap */ -@@ -115,6 +119,7 @@ struct thread_info { - #define _TIF_NOCPUID (1 << TIF_NOCPUID) - #define _TIF_NOTSC (1 << TIF_NOTSC) - #define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL) -+#define _TIF_NEED_RESCHED_LAZY (1 << TIF_NEED_RESCHED_LAZY) - #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) - #define _TIF_IO_BITMAP (1 << TIF_IO_BITMAP) - #define _TIF_SPEC_FORCE_UPDATE (1 << TIF_SPEC_FORCE_UPDATE) -diff -rupN linux-5.19.16.orig/arch/x86/Kconfig linux-5.19.16/arch/x86/Kconfig ---- linux-5.19.16.orig/arch/x86/Kconfig 2022-10-18 17:21:09.352511828 -0400 -+++ linux-5.19.16/arch/x86/Kconfig 2022-10-18 17:21:17.800446725 -0400 -@@ -110,6 +110,7 @@ config X86 - select ARCH_SUPPORTS_KMAP_LOCAL_FORCE_MAP if NR_CPUS <= 4096 - select ARCH_SUPPORTS_LTO_CLANG - select ARCH_SUPPORTS_LTO_CLANG_THIN -+ select ARCH_SUPPORTS_RT - select ARCH_USE_BUILTIN_BSWAP - select ARCH_USE_MEMTEST - select ARCH_USE_QUEUED_RWLOCKS -@@ -244,6 +245,7 @@ config X86 - select HAVE_PCI - select HAVE_PERF_REGS - select HAVE_PERF_USER_STACK_DUMP -+ select HAVE_PREEMPT_LAZY - select MMU_GATHER_RCU_TABLE_FREE if PARAVIRT - select MMU_GATHER_MERGE_VMAS - select HAVE_POSIX_CPU_TIMERS_TASK_WORK -diff -rupN linux-5.19.16.orig/block/blk-mq.c linux-5.19.16/block/blk-mq.c ---- linux-5.19.16.orig/block/blk-mq.c 2022-10-18 17:21:09.396511489 -0400 -+++ linux-5.19.16/block/blk-mq.c 2022-10-18 17:21:17.800446725 -0400 -@@ -2086,14 +2086,10 @@ static void __blk_mq_delay_run_hw_queue( - return; - - if (!async && !(hctx->flags & BLK_MQ_F_BLOCKING)) { -- int cpu = get_cpu(); -- if (cpumask_test_cpu(cpu, hctx->cpumask)) { -+ if (cpumask_test_cpu(raw_smp_processor_id(), hctx->cpumask)) { - __blk_mq_run_hw_queue(hctx); -- put_cpu(); - return; - } -- -- put_cpu(); - } - - kblockd_mod_delayed_work_on(blk_mq_hctx_next_cpu(hctx), &hctx->run_work, -diff -rupN linux-5.19.16.orig/drivers/bcma/driver_gpio.c linux-5.19.16/drivers/bcma/driver_gpio.c ---- linux-5.19.16.orig/drivers/bcma/driver_gpio.c 2022-10-18 17:21:09.432511212 -0400 -+++ linux-5.19.16/drivers/bcma/driver_gpio.c 2022-10-18 17:21:17.800446725 -0400 -@@ -115,7 +115,7 @@ static irqreturn_t bcma_gpio_irq_handler - return IRQ_NONE; - - for_each_set_bit(gpio, &irqs, gc->ngpio) -- generic_handle_irq(irq_find_mapping(gc->irq.domain, gpio)); -+ generic_handle_domain_irq_safe(gc->irq.domain, gpio); - bcma_chipco_gpio_polarity(cc, irqs, val & irqs); - - return IRQ_HANDLED; -diff -rupN linux-5.19.16.orig/drivers/block/zram/zram_drv.c linux-5.19.16/drivers/block/zram/zram_drv.c ---- linux-5.19.16.orig/drivers/block/zram/zram_drv.c 2022-10-18 17:21:09.436511181 -0400 -+++ linux-5.19.16/drivers/block/zram/zram_drv.c 2022-10-18 17:21:17.800446725 -0400 -@@ -58,6 +58,40 @@ static void zram_free_page(struct zram * - static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, - u32 index, int offset, struct bio *bio); - -+#ifdef CONFIG_PREEMPT_RT -+static void zram_meta_init_table_locks(struct zram *zram, size_t num_pages) -+{ -+ size_t index; -+ -+ for (index = 0; index < num_pages; index++) -+ spin_lock_init(&zram->table[index].lock); -+} -+ -+static int zram_slot_trylock(struct zram *zram, u32 index) -+{ -+ int ret; -+ -+ ret = spin_trylock(&zram->table[index].lock); -+ if (ret) -+ __set_bit(ZRAM_LOCK, &zram->table[index].flags); -+ return ret; -+} -+ -+static void zram_slot_lock(struct zram *zram, u32 index) -+{ -+ spin_lock(&zram->table[index].lock); -+ __set_bit(ZRAM_LOCK, &zram->table[index].flags); -+} -+ -+static void zram_slot_unlock(struct zram *zram, u32 index) -+{ -+ __clear_bit(ZRAM_LOCK, &zram->table[index].flags); -+ spin_unlock(&zram->table[index].lock); -+} -+ -+#else -+ -+static void zram_meta_init_table_locks(struct zram *zram, size_t num_pages) { } - - static int zram_slot_trylock(struct zram *zram, u32 index) - { -@@ -73,6 +107,7 @@ static void zram_slot_unlock(struct zram - { - bit_spin_unlock(ZRAM_LOCK, &zram->table[index].flags); - } -+#endif - - static inline bool init_done(struct zram *zram) - { -@@ -1196,6 +1231,7 @@ static bool zram_meta_alloc(struct zram - - if (!huge_class_size) - huge_class_size = zs_huge_class_size(zram->mem_pool); -+ zram_meta_init_table_locks(zram, num_pages); - return true; - } - -diff -rupN linux-5.19.16.orig/drivers/block/zram/zram_drv.h linux-5.19.16/drivers/block/zram/zram_drv.h ---- linux-5.19.16.orig/drivers/block/zram/zram_drv.h 2022-10-18 17:21:09.436511181 -0400 -+++ linux-5.19.16/drivers/block/zram/zram_drv.h 2022-10-18 17:21:17.800446725 -0400 -@@ -63,6 +63,9 @@ struct zram_table_entry { - unsigned long element; - }; - unsigned long flags; -+#ifdef CONFIG_PREEMPT_RT -+ spinlock_t lock; -+#endif - #ifdef CONFIG_ZRAM_MEMORY_TRACKING - ktime_t ac_time; - #endif -diff -rupN linux-5.19.16.orig/drivers/char/tpm/tpm_tis.c linux-5.19.16/drivers/char/tpm/tpm_tis.c ---- linux-5.19.16.orig/drivers/char/tpm/tpm_tis.c 2022-10-18 17:21:09.444511120 -0400 -+++ linux-5.19.16/drivers/char/tpm/tpm_tis.c 2022-10-18 17:21:17.800446725 -0400 -@@ -50,6 +50,31 @@ static inline struct tpm_tis_tcg_phy *to - return container_of(data, struct tpm_tis_tcg_phy, priv); - } - -+#ifdef CONFIG_PREEMPT_RT -+/* -+ * Flushes previous write operations to chip so that a subsequent -+ * ioread*()s won't stall a cpu. -+ */ -+static inline void tpm_tis_flush(void __iomem *iobase) -+{ -+ ioread8(iobase + TPM_ACCESS(0)); -+} -+#else -+#define tpm_tis_flush(iobase) do { } while (0) -+#endif -+ -+static inline void tpm_tis_iowrite8(u8 b, void __iomem *iobase, u32 addr) -+{ -+ iowrite8(b, iobase + addr); -+ tpm_tis_flush(iobase); -+} -+ -+static inline void tpm_tis_iowrite32(u32 b, void __iomem *iobase, u32 addr) -+{ -+ iowrite32(b, iobase + addr); -+ tpm_tis_flush(iobase); -+} -+ - static int interrupts = -1; - module_param(interrupts, int, 0444); - MODULE_PARM_DESC(interrupts, "Enable interrupts"); -@@ -185,12 +210,12 @@ static int tpm_tcg_write_bytes(struct tp - switch (io_mode) { - case TPM_TIS_PHYS_8: - while (len--) -- iowrite8(*value++, phy->iobase + addr); -+ tpm_tis_iowrite8(*value++, phy->iobase, addr); - break; - case TPM_TIS_PHYS_16: - return -EINVAL; - case TPM_TIS_PHYS_32: -- iowrite32(le32_to_cpu(*((__le32 *)value)), phy->iobase + addr); -+ tpm_tis_iowrite32(le32_to_cpu(*((__le32 *)value)), phy->iobase, addr); - break; - } - -diff -rupN linux-5.19.16.orig/drivers/gpio/gpio-mlxbf2.c linux-5.19.16/drivers/gpio/gpio-mlxbf2.c ---- linux-5.19.16.orig/drivers/gpio/gpio-mlxbf2.c 2022-10-18 17:21:09.528510473 -0400 -+++ linux-5.19.16/drivers/gpio/gpio-mlxbf2.c 2022-10-18 17:21:17.800446725 -0400 -@@ -273,10 +273,8 @@ static irqreturn_t mlxbf2_gpio_irq_handl - pending = readl(gs->gpio_io + YU_GPIO_CAUSE_OR_CAUSE_EVTEN0); - writel(pending, gs->gpio_io + YU_GPIO_CAUSE_OR_CLRCAUSE); - -- for_each_set_bit(level, &pending, gc->ngpio) { -- int gpio_irq = irq_find_mapping(gc->irq.domain, level); -- generic_handle_irq(gpio_irq); -- } -+ for_each_set_bit(level, &pending, gc->ngpio) -+ generic_handle_domain_irq_safe(gc->irq.domain, level); - - return IRQ_RETVAL(pending); - } -diff -rupN linux-5.19.16.orig/drivers/gpu/drm/i915/display/intel_crtc.c linux-5.19.16/drivers/gpu/drm/i915/display/intel_crtc.c ---- linux-5.19.16.orig/drivers/gpu/drm/i915/display/intel_crtc.c 2022-10-18 17:21:09.804508347 -0400 -+++ linux-5.19.16/drivers/gpu/drm/i915/display/intel_crtc.c 2022-10-18 17:21:17.800446725 -0400 -@@ -522,7 +522,8 @@ void intel_pipe_update_start(struct inte - */ - intel_psr_wait_for_idle_locked(new_crtc_state); - -- local_irq_disable(); -+ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) -+ local_irq_disable(); - - crtc->debug.min_vbl = min; - crtc->debug.max_vbl = max; -@@ -547,11 +548,13 @@ void intel_pipe_update_start(struct inte - break; - } - -- local_irq_enable(); -+ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) -+ local_irq_enable(); - - timeout = schedule_timeout(timeout); - -- local_irq_disable(); -+ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) -+ local_irq_disable(); - } - - finish_wait(wq, &wait); -@@ -584,7 +587,8 @@ void intel_pipe_update_start(struct inte - return; - - irq_disable: -- local_irq_disable(); -+ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) -+ local_irq_disable(); - } - - #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_VBLANK_EVADE) -@@ -685,7 +689,8 @@ void intel_pipe_update_end(struct intel_ - */ - intel_vrr_send_push(new_crtc_state); - -- local_irq_enable(); -+ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) -+ local_irq_enable(); - - if (intel_vgpu_active(dev_priv)) - return; -diff -rupN linux-5.19.16.orig/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c linux-5.19.16/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c ---- linux-5.19.16.orig/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c 2022-10-18 17:21:09.812508286 -0400 -+++ linux-5.19.16/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c 2022-10-18 17:21:17.800446725 -0400 -@@ -312,10 +312,9 @@ void __intel_breadcrumbs_park(struct int - /* Kick the work once more to drain the signalers, and disarm the irq */ - irq_work_sync(&b->irq_work); - while (READ_ONCE(b->irq_armed) && !atomic_read(&b->active)) { -- local_irq_disable(); -- signal_irq_work(&b->irq_work); -- local_irq_enable(); -+ irq_work_queue(&b->irq_work); - cond_resched(); -+ irq_work_sync(&b->irq_work); - } - } - -diff -rupN linux-5.19.16.orig/drivers/gpu/drm/i915/gt/intel_execlists_submission.c linux-5.19.16/drivers/gpu/drm/i915/gt/intel_execlists_submission.c ---- linux-5.19.16.orig/drivers/gpu/drm/i915/gt/intel_execlists_submission.c 2022-10-18 17:21:09.812508286 -0400 -+++ linux-5.19.16/drivers/gpu/drm/i915/gt/intel_execlists_submission.c 2022-10-18 17:21:17.800446725 -0400 -@@ -1302,7 +1302,7 @@ static void execlists_dequeue(struct int - * and context switches) submission. - */ - -- spin_lock(&sched_engine->lock); -+ spin_lock_irq(&sched_engine->lock); - - /* - * If the queue is higher priority than the last -@@ -1402,7 +1402,7 @@ static void execlists_dequeue(struct int - * Even if ELSP[1] is occupied and not worthy - * of timeslices, our queue might be. - */ -- spin_unlock(&sched_engine->lock); -+ spin_unlock_irq(&sched_engine->lock); - return; - } - } -@@ -1428,7 +1428,7 @@ static void execlists_dequeue(struct int - - if (last && !can_merge_rq(last, rq)) { - spin_unlock(&ve->base.sched_engine->lock); -- spin_unlock(&engine->sched_engine->lock); -+ spin_unlock_irq(&engine->sched_engine->lock); - return; /* leave this for another sibling */ - } - -@@ -1590,7 +1590,7 @@ done: - */ - sched_engine->queue_priority_hint = queue_prio(sched_engine); - i915_sched_engine_reset_on_empty(sched_engine); -- spin_unlock(&sched_engine->lock); -+ spin_unlock_irq(&sched_engine->lock); - - /* - * We can skip poking the HW if we ended up with exactly the same set -@@ -1616,13 +1616,6 @@ done: - } - } - --static void execlists_dequeue_irq(struct intel_engine_cs *engine) --{ -- local_irq_disable(); /* Suspend interrupts across request submission */ -- execlists_dequeue(engine); -- local_irq_enable(); /* flush irq_work (e.g. breadcrumb enabling) */ --} -- - static void clear_ports(struct i915_request **ports, int count) - { - memset_p((void **)ports, NULL, count); -@@ -2468,7 +2461,7 @@ static void execlists_submission_tasklet - } - - if (!engine->execlists.pending[0]) { -- execlists_dequeue_irq(engine); -+ execlists_dequeue(engine); - start_timeslice(engine); - } - -diff -rupN linux-5.19.16.orig/drivers/gpu/drm/i915/i915_irq.c linux-5.19.16/drivers/gpu/drm/i915/i915_irq.c ---- linux-5.19.16.orig/drivers/gpu/drm/i915/i915_irq.c 2022-10-18 17:21:09.820508224 -0400 -+++ linux-5.19.16/drivers/gpu/drm/i915/i915_irq.c 2022-10-18 17:21:17.800446725 -0400 -@@ -917,7 +917,8 @@ static bool i915_get_crtc_scanoutpos(str - */ - spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); - -- /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ -+ if (IS_ENABLED(CONFIG_PREEMPT_RT)) -+ preempt_disable(); - - /* Get optional system timestamp before query. */ - if (stime) -@@ -981,7 +982,8 @@ static bool i915_get_crtc_scanoutpos(str - if (etime) - *etime = ktime_get(); - -- /* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */ -+ if (IS_ENABLED(CONFIG_PREEMPT_RT)) -+ preempt_enable(); - - spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); - -diff -rupN linux-5.19.16.orig/drivers/gpu/drm/i915/i915_request.c linux-5.19.16/drivers/gpu/drm/i915/i915_request.c ---- linux-5.19.16.orig/drivers/gpu/drm/i915/i915_request.c 2022-10-18 17:21:09.820508224 -0400 -+++ linux-5.19.16/drivers/gpu/drm/i915/i915_request.c 2022-10-18 17:21:17.800446725 -0400 -@@ -587,7 +587,6 @@ bool __i915_request_submit(struct i915_r - - RQ_TRACE(request, "\n"); - -- GEM_BUG_ON(!irqs_disabled()); - lockdep_assert_held(&engine->sched_engine->lock); - - /* -@@ -696,7 +695,6 @@ void __i915_request_unsubmit(struct i915 - */ - RQ_TRACE(request, "\n"); - -- GEM_BUG_ON(!irqs_disabled()); - lockdep_assert_held(&engine->sched_engine->lock); - - /* -diff -rupN linux-5.19.16.orig/drivers/gpu/drm/i915/i915_trace.h linux-5.19.16/drivers/gpu/drm/i915/i915_trace.h ---- linux-5.19.16.orig/drivers/gpu/drm/i915/i915_trace.h 2022-10-18 17:21:09.820508224 -0400 -+++ linux-5.19.16/drivers/gpu/drm/i915/i915_trace.h 2022-10-18 17:21:17.800446725 -0400 -@@ -6,6 +6,10 @@ - #if !defined(_I915_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) - #define _I915_TRACE_H_ - -+#ifdef CONFIG_PREEMPT_RT -+#define NOTRACE -+#endif -+ - #include - #include - #include -@@ -323,7 +327,7 @@ DEFINE_EVENT(i915_request, i915_request_ - TP_ARGS(rq) - ); - --#if defined(CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS) -+#if defined(CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS) && !defined(NOTRACE) - DEFINE_EVENT(i915_request, i915_request_guc_submit, - TP_PROTO(struct i915_request *rq), - TP_ARGS(rq) -diff -rupN linux-5.19.16.orig/drivers/gpu/drm/i915/i915_utils.h linux-5.19.16/drivers/gpu/drm/i915/i915_utils.h ---- linux-5.19.16.orig/drivers/gpu/drm/i915/i915_utils.h 2022-10-18 17:21:09.820508224 -0400 -+++ linux-5.19.16/drivers/gpu/drm/i915/i915_utils.h 2022-10-18 17:21:17.800446725 -0400 -@@ -334,7 +334,7 @@ wait_remaining_ms_from_jiffies(unsigned - #define wait_for(COND, MS) _wait_for((COND), (MS) * 1000, 10, 1000) - - /* If CONFIG_PREEMPT_COUNT is disabled, in_atomic() always reports false. */ --#if defined(CONFIG_DRM_I915_DEBUG) && defined(CONFIG_PREEMPT_COUNT) -+#if defined(CONFIG_DRM_I915_DEBUG) && defined(CONFIG_PREEMPT_COUNT) && !defined(CONFIG_PREEMPT_RT) - # define _WAIT_FOR_ATOMIC_CHECK(ATOMIC) WARN_ON_ONCE((ATOMIC) && !in_atomic()) - #else - # define _WAIT_FOR_ATOMIC_CHECK(ATOMIC) do { } while (0) -diff -rupN linux-5.19.16.orig/drivers/gpu/drm/i915/Kconfig linux-5.19.16/drivers/gpu/drm/i915/Kconfig ---- linux-5.19.16.orig/drivers/gpu/drm/i915/Kconfig 2022-10-18 17:21:09.804508347 -0400 -+++ linux-5.19.16/drivers/gpu/drm/i915/Kconfig 2022-10-18 17:21:17.800446725 -0400 -@@ -3,7 +3,6 @@ config DRM_I915 - tristate "Intel 8xx/9xx/G3x/G4x/HD Graphics" - depends on DRM - depends on X86 && PCI -- depends on !PREEMPT_RT - select INTEL_GTT if X86 - select INTERVAL_TREE - # we need shmfs for the swappable backing store, and in particular -diff -rupN linux-5.19.16.orig/drivers/iio/adc/stm32-adc-core.c linux-5.19.16/drivers/iio/adc/stm32-adc-core.c ---- linux-5.19.16.orig/drivers/iio/adc/stm32-adc-core.c 2022-10-18 17:21:09.956507177 -0400 -+++ linux-5.19.16/drivers/iio/adc/stm32-adc-core.c 2022-10-18 17:21:17.800446725 -0400 -@@ -358,7 +358,7 @@ static void stm32_adc_irq_handler(struct - if ((status & priv->cfg->regs->eoc_msk[i] && - stm32_adc_eoc_enabled(priv, i)) || - (status & priv->cfg->regs->ovr_msk[i])) -- generic_handle_irq(irq_find_mapping(priv->domain, i)); -+ generic_handle_domain_irq(priv->domain, i); - } - - chained_irq_exit(chip, desc); -diff -rupN linux-5.19.16.orig/drivers/pinctrl/pinctrl-amd.c linux-5.19.16/drivers/pinctrl/pinctrl-amd.c ---- linux-5.19.16.orig/drivers/pinctrl/pinctrl-amd.c 2022-10-18 17:21:10.508502926 -0400 -+++ linux-5.19.16/drivers/pinctrl/pinctrl-amd.c 2022-10-18 17:21:17.800446725 -0400 -@@ -643,7 +643,7 @@ static bool do_amd_gpio_irq_handler(int - if (!(regval & PIN_IRQ_PENDING) || - !(regval & BIT(INTERRUPT_MASK_OFF))) - continue; -- generic_handle_domain_irq(gc->irq.domain, irqnr + i); -+ generic_handle_domain_irq_safe(gc->irq.domain, irqnr + i); - - /* Clear interrupt. - * We must read the pin register again, in case the -diff -rupN linux-5.19.16.orig/drivers/platform/x86/intel/int0002_vgpio.c linux-5.19.16/drivers/platform/x86/intel/int0002_vgpio.c ---- linux-5.19.16.orig/drivers/platform/x86/intel/int0002_vgpio.c 2022-10-18 17:21:10.532502741 -0400 -+++ linux-5.19.16/drivers/platform/x86/intel/int0002_vgpio.c 2022-10-18 17:21:17.800446725 -0400 -@@ -125,8 +125,7 @@ static irqreturn_t int0002_irq(int irq, - if (!(gpe_sts_reg & GPE0A_PME_B0_STS_BIT)) - return IRQ_NONE; - -- generic_handle_irq(irq_find_mapping(chip->irq.domain, -- GPE0A_PME_B0_VIRT_GPIO_PIN)); -+ generic_handle_domain_irq_safe(chip->irq.domain, GPE0A_PME_B0_VIRT_GPIO_PIN); - - pm_wakeup_hard_event(chip->parent); - -diff -rupN linux-5.19.16.orig/drivers/ssb/driver_gpio.c linux-5.19.16/drivers/ssb/driver_gpio.c ---- linux-5.19.16.orig/drivers/ssb/driver_gpio.c 2022-10-18 17:21:10.612502125 -0400 -+++ linux-5.19.16/drivers/ssb/driver_gpio.c 2022-10-18 17:21:17.800446725 -0400 -@@ -132,7 +132,8 @@ static irqreturn_t ssb_gpio_irq_chipco_h - return IRQ_NONE; - - for_each_set_bit(gpio, &irqs, bus->gpio.ngpio) -- generic_handle_irq(ssb_gpio_to_irq(&bus->gpio, gpio)); -+ generic_handle_domain_irq_safe(bus->irq_domain, gpio); -+ - ssb_chipco_gpio_polarity(chipco, irqs, val & irqs); - - return IRQ_HANDLED; -@@ -330,7 +331,8 @@ static irqreturn_t ssb_gpio_irq_extif_ha - return IRQ_NONE; - - for_each_set_bit(gpio, &irqs, bus->gpio.ngpio) -- generic_handle_irq(ssb_gpio_to_irq(&bus->gpio, gpio)); -+ generic_handle_domain_irq_safe(bus->irq_domain, gpio); -+ - ssb_extif_gpio_polarity(extif, irqs, val & irqs); - - return IRQ_HANDLED; -diff -rupN linux-5.19.16.orig/drivers/tty/serial/8250/8250_aspeed_vuart.c linux-5.19.16/drivers/tty/serial/8250/8250_aspeed_vuart.c ---- linux-5.19.16.orig/drivers/tty/serial/8250/8250_aspeed_vuart.c 2022-10-18 17:21:10.672501663 -0400 -+++ linux-5.19.16/drivers/tty/serial/8250/8250_aspeed_vuart.c 2022-10-18 17:21:17.800446725 -0400 -@@ -278,7 +278,7 @@ static void __aspeed_vuart_set_throttle( - up->ier &= ~irqs; - if (!throttle) - up->ier |= irqs; -- serial_out(up, UART_IER, up->ier); -+ serial8250_set_IER(up, up->ier); - } - static void aspeed_vuart_set_throttle(struct uart_port *port, bool throttle) - { -diff -rupN linux-5.19.16.orig/drivers/tty/serial/8250/8250_bcm7271.c linux-5.19.16/drivers/tty/serial/8250/8250_bcm7271.c ---- linux-5.19.16.orig/drivers/tty/serial/8250/8250_bcm7271.c 2022-10-18 17:21:10.672501663 -0400 -+++ linux-5.19.16/drivers/tty/serial/8250/8250_bcm7271.c 2022-10-18 17:21:17.804446694 -0400 -@@ -609,7 +609,7 @@ static int brcmuart_startup(struct uart_ - * will handle this. - */ - up->ier &= ~UART_IER_RDI; -- serial_port_out(port, UART_IER, up->ier); -+ serial8250_set_IER(up, up->ier); - - priv->tx_running = false; - priv->dma.rx_dma = NULL; -@@ -775,10 +775,12 @@ static int brcmuart_handle_irq(struct ua - unsigned int iir = serial_port_in(p, UART_IIR); - struct brcmuart_priv *priv = p->private_data; - struct uart_8250_port *up = up_to_u8250p(p); -+ unsigned long cs_flags; - unsigned int status; - unsigned long flags; - unsigned int ier; - unsigned int mcr; -+ bool is_console; - int handled = 0; - - /* -@@ -789,6 +791,10 @@ static int brcmuart_handle_irq(struct ua - spin_lock_irqsave(&p->lock, flags); - status = serial_port_in(p, UART_LSR); - if ((status & UART_LSR_DR) == 0) { -+ is_console = uart_console(p); -+ -+ if (is_console) -+ printk_cpu_sync_get_irqsave(cs_flags); - - ier = serial_port_in(p, UART_IER); - /* -@@ -809,6 +815,9 @@ static int brcmuart_handle_irq(struct ua - serial_port_in(p, UART_RX); - } - -+ if (is_console) -+ printk_cpu_sync_put_irqrestore(cs_flags); -+ - handled = 1; - } - spin_unlock_irqrestore(&p->lock, flags); -@@ -823,8 +832,10 @@ static enum hrtimer_restart brcmuart_hrt - struct brcmuart_priv *priv = container_of(t, struct brcmuart_priv, hrt); - struct uart_port *p = priv->up; - struct uart_8250_port *up = up_to_u8250p(p); -+ unsigned long cs_flags; - unsigned int status; - unsigned long flags; -+ bool is_console; - - if (priv->shutdown) - return HRTIMER_NORESTART; -@@ -846,12 +857,20 @@ static enum hrtimer_restart brcmuart_hrt - /* re-enable receive unless upper layer has disabled it */ - if ((up->ier & (UART_IER_RLSI | UART_IER_RDI)) == - (UART_IER_RLSI | UART_IER_RDI)) { -+ is_console = uart_console(p); -+ -+ if (is_console) -+ printk_cpu_sync_get_irqsave(cs_flags); -+ - status = serial_port_in(p, UART_IER); - status |= (UART_IER_RLSI | UART_IER_RDI); - serial_port_out(p, UART_IER, status); - status = serial_port_in(p, UART_MCR); - status |= UART_MCR_RTS; - serial_port_out(p, UART_MCR, status); -+ -+ if (is_console) -+ printk_cpu_sync_put_irqrestore(cs_flags); - } - spin_unlock_irqrestore(&p->lock, flags); - return HRTIMER_NORESTART; -diff -rupN linux-5.19.16.orig/drivers/tty/serial/8250/8250_core.c linux-5.19.16/drivers/tty/serial/8250/8250_core.c ---- linux-5.19.16.orig/drivers/tty/serial/8250/8250_core.c 2022-10-18 17:21:10.672501663 -0400 -+++ linux-5.19.16/drivers/tty/serial/8250/8250_core.c 2022-10-18 17:21:17.804446694 -0400 -@@ -255,8 +255,11 @@ static void serial8250_timeout(struct ti - static void serial8250_backup_timeout(struct timer_list *t) - { - struct uart_8250_port *up = from_timer(up, t, timer); -+ struct uart_port *port = &up->port; - unsigned int iir, ier = 0, lsr; -+ unsigned long cs_flags; - unsigned long flags; -+ bool is_console; - - spin_lock_irqsave(&up->port.lock, flags); - -@@ -265,8 +268,16 @@ static void serial8250_backup_timeout(st - * based handler. - */ - if (up->port.irq) { -+ is_console = uart_console(port); -+ -+ if (is_console) -+ printk_cpu_sync_get_irqsave(cs_flags); -+ - ier = serial_in(up, UART_IER); - serial_out(up, UART_IER, 0); -+ -+ if (is_console) -+ printk_cpu_sync_put_irqrestore(cs_flags); - } - - iir = serial_in(up, UART_IIR); -@@ -289,7 +300,7 @@ static void serial8250_backup_timeout(st - serial8250_tx_chars(up); - - if (up->port.irq) -- serial_out(up, UART_IER, ier); -+ serial8250_set_IER(up, ier); - - spin_unlock_irqrestore(&up->port.lock, flags); - -@@ -569,6 +580,14 @@ serial8250_register_ports(struct uart_dr - - #ifdef CONFIG_SERIAL_8250_CONSOLE - -+static void univ8250_console_write_atomic(struct console *co, const char *s, -+ unsigned int count) -+{ -+ struct uart_8250_port *up = &serial8250_ports[co->index]; -+ -+ serial8250_console_write_atomic(up, s, count); -+} -+ - static void univ8250_console_write(struct console *co, const char *s, - unsigned int count) - { -@@ -662,6 +681,7 @@ static int univ8250_console_match(struct - - static struct console univ8250_console = { - .name = "ttyS", -+ .write_atomic = univ8250_console_write_atomic, - .write = univ8250_console_write, - .device = uart_console_device, - .setup = univ8250_console_setup, -@@ -955,7 +975,7 @@ static void serial_8250_overrun_backoff_ - spin_lock_irqsave(&port->lock, flags); - up->ier |= UART_IER_RLSI | UART_IER_RDI; - up->port.read_status_mask |= UART_LSR_DR; -- serial_out(up, UART_IER, up->ier); -+ serial8250_set_IER(up, up->ier); - spin_unlock_irqrestore(&port->lock, flags); - } - -diff -rupN linux-5.19.16.orig/drivers/tty/serial/8250/8250_exar.c linux-5.19.16/drivers/tty/serial/8250/8250_exar.c ---- linux-5.19.16.orig/drivers/tty/serial/8250/8250_exar.c 2022-10-18 17:21:10.672501663 -0400 -+++ linux-5.19.16/drivers/tty/serial/8250/8250_exar.c 2022-10-18 17:21:17.804446694 -0400 -@@ -177,6 +177,8 @@ static void xr17v35x_set_divisor(struct - - static int xr17v35x_startup(struct uart_port *port) - { -+ struct uart_8250_port *up = up_to_u8250p(port); -+ - /* - * First enable access to IER [7:5], ISR [5:4], FCR [5:4], - * MCR [7:5] and MSR [7:0] -@@ -187,7 +189,7 @@ static int xr17v35x_startup(struct uart_ - * Make sure all interrups are masked until initialization is - * complete and the FIFOs are cleared - */ -- serial_port_out(port, UART_IER, 0); -+ serial8250_set_IER(up, 0); - - return serial8250_do_startup(port); - } -diff -rupN linux-5.19.16.orig/drivers/tty/serial/8250/8250_fsl.c linux-5.19.16/drivers/tty/serial/8250/8250_fsl.c ---- linux-5.19.16.orig/drivers/tty/serial/8250/8250_fsl.c 2022-10-18 17:21:10.672501663 -0400 -+++ linux-5.19.16/drivers/tty/serial/8250/8250_fsl.c 2022-10-18 17:21:17.804446694 -0400 -@@ -58,7 +58,8 @@ int fsl8250_handle_irq(struct uart_port - if ((orig_lsr & UART_LSR_OE) && (up->overrun_backoff_time_ms > 0)) { - unsigned long delay; - -- up->ier = port->serial_in(port, UART_IER); -+ up->ier = serial8250_in_IER(up); -+ - if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) { - port->ops->stop_rx(port); - } else { -diff -rupN linux-5.19.16.orig/drivers/tty/serial/8250/8250.h linux-5.19.16/drivers/tty/serial/8250/8250.h ---- linux-5.19.16.orig/drivers/tty/serial/8250/8250.h 2022-10-18 17:21:10.672501663 -0400 -+++ linux-5.19.16/drivers/tty/serial/8250/8250.h 2022-10-18 17:21:17.800446725 -0400 -@@ -177,12 +177,74 @@ static inline void serial_dl_write(struc - up->dl_write(up, value); - } - -+static inline int serial8250_in_IER(struct uart_8250_port *up) -+{ -+ struct uart_port *port = &up->port; -+ unsigned long flags; -+ bool is_console; -+ int ier; -+ -+ is_console = uart_console(port); -+ -+ if (is_console) -+ printk_cpu_sync_get_irqsave(flags); -+ -+ ier = serial_in(up, UART_IER); -+ -+ if (is_console) -+ printk_cpu_sync_put_irqrestore(flags); -+ -+ return ier; -+} -+ -+static inline void serial8250_set_IER(struct uart_8250_port *up, int ier) -+{ -+ struct uart_port *port = &up->port; -+ unsigned long flags; -+ bool is_console; -+ -+ is_console = uart_console(port); -+ -+ if (is_console) -+ printk_cpu_sync_get_irqsave(flags); -+ -+ serial_out(up, UART_IER, ier); -+ -+ if (is_console) -+ printk_cpu_sync_put_irqrestore(flags); -+} -+ -+static inline int serial8250_clear_IER(struct uart_8250_port *up) -+{ -+ struct uart_port *port = &up->port; -+ unsigned int clearval = 0; -+ unsigned long flags; -+ bool is_console; -+ int prior; -+ -+ is_console = uart_console(port); -+ -+ if (up->capabilities & UART_CAP_UUE) -+ clearval = UART_IER_UUE; -+ -+ if (is_console) -+ printk_cpu_sync_get_irqsave(flags); -+ -+ prior = serial_in(up, UART_IER); -+ serial_out(up, UART_IER, clearval); -+ -+ if (is_console) -+ printk_cpu_sync_put_irqrestore(flags); -+ -+ return prior; -+} -+ - static inline bool serial8250_set_THRI(struct uart_8250_port *up) - { - if (up->ier & UART_IER_THRI) - return false; - up->ier |= UART_IER_THRI; -- serial_out(up, UART_IER, up->ier); -+ serial8250_set_IER(up, up->ier); - return true; - } - -@@ -191,7 +253,7 @@ static inline bool serial8250_clear_THRI - if (!(up->ier & UART_IER_THRI)) - return false; - up->ier &= ~UART_IER_THRI; -- serial_out(up, UART_IER, up->ier); -+ serial8250_set_IER(up, up->ier); - return true; - } - -diff -rupN linux-5.19.16.orig/drivers/tty/serial/8250/8250_ingenic.c linux-5.19.16/drivers/tty/serial/8250/8250_ingenic.c ---- linux-5.19.16.orig/drivers/tty/serial/8250/8250_ingenic.c 2022-10-18 17:21:10.672501663 -0400 -+++ linux-5.19.16/drivers/tty/serial/8250/8250_ingenic.c 2022-10-18 17:21:17.804446694 -0400 -@@ -146,6 +146,7 @@ OF_EARLYCON_DECLARE(x1000_uart, "ingenic - - static void ingenic_uart_serial_out(struct uart_port *p, int offset, int value) - { -+ struct uart_8250_port *up = up_to_u8250p(p); - int ier; - - switch (offset) { -@@ -167,7 +168,7 @@ static void ingenic_uart_serial_out(stru - * If we have enabled modem status IRQs we should enable - * modem mode. - */ -- ier = p->serial_in(p, UART_IER); -+ ier = serial8250_in_IER(up); - - if (ier & UART_IER_MSI) - value |= UART_MCR_MDCE | UART_MCR_FCM; -diff -rupN linux-5.19.16.orig/drivers/tty/serial/8250/8250_mtk.c linux-5.19.16/drivers/tty/serial/8250/8250_mtk.c ---- linux-5.19.16.orig/drivers/tty/serial/8250/8250_mtk.c 2022-10-18 17:21:10.672501663 -0400 -+++ linux-5.19.16/drivers/tty/serial/8250/8250_mtk.c 2022-10-18 17:21:17.804446694 -0400 -@@ -222,12 +222,40 @@ static void mtk8250_shutdown(struct uart - - static void mtk8250_disable_intrs(struct uart_8250_port *up, int mask) - { -- serial_out(up, UART_IER, serial_in(up, UART_IER) & (~mask)); -+ struct uart_port *port = &up->port; -+ unsigned long flags; -+ bool is_console; -+ int ier; -+ -+ is_console = uart_console(port); -+ -+ if (is_console) -+ printk_cpu_sync_get_irqsave(flags); -+ -+ ier = serial_in(up, UART_IER); -+ serial_out(up, UART_IER, ier & (~mask)); -+ -+ if (is_console) -+ printk_cpu_sync_put_irqrestore(flags); - } - - static void mtk8250_enable_intrs(struct uart_8250_port *up, int mask) - { -- serial_out(up, UART_IER, serial_in(up, UART_IER) | mask); -+ struct uart_port *port = &up->port; -+ unsigned long flags; -+ bool is_console; -+ int ier; -+ -+ is_console = uart_console(port); -+ -+ if (is_console) -+ printk_cpu_sync_get_irqsave(flags); -+ -+ ier = serial_in(up, UART_IER); -+ serial_out(up, UART_IER, ier | mask); -+ -+ if (is_console) -+ printk_cpu_sync_put_irqrestore(flags); - } - - static void mtk8250_set_flow_ctrl(struct uart_8250_port *up, int mode) -diff -rupN linux-5.19.16.orig/drivers/tty/serial/8250/8250_omap.c linux-5.19.16/drivers/tty/serial/8250/8250_omap.c ---- linux-5.19.16.orig/drivers/tty/serial/8250/8250_omap.c 2022-10-18 17:21:10.672501663 -0400 -+++ linux-5.19.16/drivers/tty/serial/8250/8250_omap.c 2022-10-18 17:21:17.804446694 -0400 -@@ -325,7 +325,7 @@ static void omap8250_restore_regs(struct - - /* drop TCR + TLR access, we setup XON/XOFF later */ - serial8250_out_MCR(up, up->mcr); -- serial_out(up, UART_IER, up->ier); -+ serial8250_set_IER(up, up->ier); - - serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); - serial_dl_write(up, priv->quot); -@@ -512,7 +512,7 @@ static void omap_8250_pm(struct uart_por - serial_out(up, UART_EFR, efr | UART_EFR_ECB); - serial_out(up, UART_LCR, 0); - -- serial_out(up, UART_IER, (state != 0) ? UART_IERX_SLEEP : 0); -+ serial8250_set_IER(up, (state != 0) ? UART_IERX_SLEEP : 0); - serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); - serial_out(up, UART_EFR, efr); - serial_out(up, UART_LCR, 0); -@@ -633,7 +633,7 @@ static irqreturn_t omap8250_irq(int irq, - if ((lsr & UART_LSR_OE) && up->overrun_backoff_time_ms > 0) { - unsigned long delay; - -- up->ier = port->serial_in(port, UART_IER); -+ up->ier = serial8250_in_IER(up); - if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) { - port->ops->stop_rx(port); - } else { -@@ -693,7 +693,7 @@ static int omap_8250_startup(struct uart - goto err; - - up->ier = UART_IER_RLSI | UART_IER_RDI; -- serial_out(up, UART_IER, up->ier); -+ serial8250_set_IER(up, up->ier); - - #ifdef CONFIG_PM - up->capabilities |= UART_CAP_RPM; -@@ -734,7 +734,7 @@ static void omap_8250_shutdown(struct ua - serial_out(up, UART_OMAP_EFR2, 0x0); - - up->ier = 0; -- serial_out(up, UART_IER, 0); -+ serial8250_set_IER(up, 0); - - if (up->dma) - serial8250_release_dma(up); -@@ -782,7 +782,7 @@ static void omap_8250_unthrottle(struct - up->dma->rx_dma(up); - up->ier |= UART_IER_RLSI | UART_IER_RDI; - port->read_status_mask |= UART_LSR_DR; -- serial_out(up, UART_IER, up->ier); -+ serial8250_set_IER(up, up->ier); - spin_unlock_irqrestore(&port->lock, flags); - - pm_runtime_mark_last_busy(port->dev); -@@ -873,7 +873,7 @@ static void __dma_rx_complete(void *para - __dma_rx_do_complete(p); - if (!priv->throttled) { - p->ier |= UART_IER_RLSI | UART_IER_RDI; -- serial_out(p, UART_IER, p->ier); -+ serial8250_set_IER(p, p->ier); - if (!(priv->habit & UART_HAS_EFR2)) - omap_8250_rx_dma(p); - } -@@ -930,7 +930,7 @@ static int omap_8250_rx_dma(struct uart_ - * callback to run. - */ - p->ier &= ~(UART_IER_RLSI | UART_IER_RDI); -- serial_out(p, UART_IER, p->ier); -+ serial8250_set_IER(p, p->ier); - } - goto out; - } -@@ -1146,12 +1146,12 @@ static void am654_8250_handle_rx_dma(str - * periodic timeouts, re-enable interrupts. - */ - up->ier &= ~(UART_IER_RLSI | UART_IER_RDI); -- serial_out(up, UART_IER, up->ier); -+ serial8250_set_IER(up, up->ier); - omap_8250_rx_dma_flush(up); - serial_in(up, UART_IIR); - serial_out(up, UART_OMAP_EFR2, 0x0); - up->ier |= UART_IER_RLSI | UART_IER_RDI; -- serial_out(up, UART_IER, up->ier); -+ serial8250_set_IER(up, up->ier); - } - } - -diff -rupN linux-5.19.16.orig/drivers/tty/serial/8250/8250_port.c linux-5.19.16/drivers/tty/serial/8250/8250_port.c ---- linux-5.19.16.orig/drivers/tty/serial/8250/8250_port.c 2022-10-18 17:21:10.672501663 -0400 -+++ linux-5.19.16/drivers/tty/serial/8250/8250_port.c 2022-10-18 17:21:17.804446694 -0400 -@@ -749,7 +749,7 @@ static void serial8250_set_sleep(struct - serial_out(p, UART_EFR, UART_EFR_ECB); - serial_out(p, UART_LCR, 0); - } -- serial_out(p, UART_IER, sleep ? UART_IERX_SLEEP : 0); -+ serial8250_set_IER(p, sleep ? UART_IERX_SLEEP : 0); - if (p->capabilities & UART_CAP_EFR) { - serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); - serial_out(p, UART_EFR, efr); -@@ -1023,8 +1023,11 @@ static int broken_efr(struct uart_8250_p - */ - static void autoconfig_16550a(struct uart_8250_port *up) - { -+ struct uart_port *port = &up->port; - unsigned char status1, status2; - unsigned int iersave; -+ unsigned long flags; -+ bool is_console; - - up->port.type = PORT_16550A; - up->capabilities |= UART_CAP_FIFO; -@@ -1135,6 +1138,11 @@ static void autoconfig_16550a(struct uar - return; - } - -+ is_console = uart_console(port); -+ -+ if (is_console) -+ printk_cpu_sync_get_irqsave(flags); -+ - /* - * Try writing and reading the UART_IER_UUE bit (b6). - * If it works, this is probably one of the Xscale platform's -@@ -1170,6 +1178,9 @@ static void autoconfig_16550a(struct uar - } - serial_out(up, UART_IER, iersave); - -+ if (is_console) -+ printk_cpu_sync_put_irqrestore(flags); -+ - /* - * We distinguish between 16550A and U6 16550A by counting - * how many bytes are in the FIFO. -@@ -1192,8 +1203,10 @@ static void autoconfig(struct uart_8250_ - unsigned char status1, scratch, scratch2, scratch3; - unsigned char save_lcr, save_mcr; - struct uart_port *port = &up->port; -+ unsigned long cs_flags; - unsigned long flags; - unsigned int old_capabilities; -+ bool is_console; - - if (!port->iobase && !port->mapbase && !port->membase) - return; -@@ -1211,6 +1224,11 @@ static void autoconfig(struct uart_8250_ - up->bugs = 0; - - if (!(port->flags & UPF_BUGGY_UART)) { -+ is_console = uart_console(port); -+ -+ if (is_console) -+ printk_cpu_sync_get_irqsave(cs_flags); -+ - /* - * Do a simple existence test first; if we fail this, - * there's no point trying anything else. -@@ -1240,6 +1258,10 @@ static void autoconfig(struct uart_8250_ - #endif - scratch3 = serial_in(up, UART_IER) & 0x0f; - serial_out(up, UART_IER, scratch); -+ -+ if (is_console) -+ printk_cpu_sync_put_irqrestore(cs_flags); -+ - if (scratch2 != 0 || scratch3 != 0x0F) { - /* - * We failed; there's nothing here -@@ -1337,10 +1359,7 @@ static void autoconfig(struct uart_8250_ - serial8250_out_MCR(up, save_mcr); - serial8250_clear_fifos(up); - serial_in(up, UART_RX); -- if (up->capabilities & UART_CAP_UUE) -- serial_out(up, UART_IER, UART_IER_UUE); -- else -- serial_out(up, UART_IER, 0); -+ serial8250_clear_IER(up); - - out_unlock: - spin_unlock_irqrestore(&port->lock, flags); -@@ -1366,7 +1385,9 @@ static void autoconfig_irq(struct uart_8 - unsigned char save_mcr, save_ier; - unsigned char save_ICP = 0; - unsigned int ICP = 0; -+ unsigned long flags; - unsigned long irqs; -+ bool is_console; - int irq; - - if (port->flags & UPF_FOURPORT) { -@@ -1376,8 +1397,12 @@ static void autoconfig_irq(struct uart_8 - inb_p(ICP); - } - -- if (uart_console(port)) -+ is_console = uart_console(port); -+ -+ if (is_console) { - console_lock(); -+ printk_cpu_sync_get_irqsave(flags); -+ } - - /* forget possible initially masked and pending IRQ */ - probe_irq_off(probe_irq_on()); -@@ -1409,8 +1434,10 @@ static void autoconfig_irq(struct uart_8 - if (port->flags & UPF_FOURPORT) - outb_p(save_ICP, ICP); - -- if (uart_console(port)) -+ if (is_console) { -+ printk_cpu_sync_put_irqrestore(flags); - console_unlock(); -+ } - - port->irq = (irq > 0) ? irq : 0; - } -@@ -1423,7 +1450,7 @@ static void serial8250_stop_rx(struct ua - - up->ier &= ~(UART_IER_RLSI | UART_IER_RDI); - up->port.read_status_mask &= ~UART_LSR_DR; -- serial_port_out(port, UART_IER, up->ier); -+ serial8250_set_IER(up, up->ier); - - serial8250_rpm_put(up); - } -@@ -1453,7 +1480,7 @@ void serial8250_em485_stop_tx(struct uar - serial8250_clear_and_reinit_fifos(p); - - p->ier |= UART_IER_RLSI | UART_IER_RDI; -- serial_port_out(&p->port, UART_IER, p->ier); -+ serial8250_set_IER(p, p->ier); - } - } - EXPORT_SYMBOL_GPL(serial8250_em485_stop_tx); -@@ -1705,7 +1732,7 @@ static void serial8250_disable_ms(struct - mctrl_gpio_disable_ms(up->gpios); - - up->ier &= ~UART_IER_MSI; -- serial_port_out(port, UART_IER, up->ier); -+ serial8250_set_IER(up, up->ier); - } - - static void serial8250_enable_ms(struct uart_port *port) -@@ -1721,7 +1748,7 @@ static void serial8250_enable_ms(struct - up->ier |= UART_IER_MSI; - - serial8250_rpm_get(up); -- serial_port_out(port, UART_IER, up->ier); -+ serial8250_set_IER(up, up->ier); - serial8250_rpm_put(up); - } - -@@ -2147,14 +2174,7 @@ static void serial8250_put_poll_char(str - struct uart_8250_port *up = up_to_u8250p(port); - - serial8250_rpm_get(up); -- /* -- * First save the IER then disable the interrupts -- */ -- ier = serial_port_in(port, UART_IER); -- if (up->capabilities & UART_CAP_UUE) -- serial_port_out(port, UART_IER, UART_IER_UUE); -- else -- serial_port_out(port, UART_IER, 0); -+ ier = serial8250_clear_IER(up); - - wait_for_xmitr(up, BOTH_EMPTY); - /* -@@ -2167,7 +2187,7 @@ static void serial8250_put_poll_char(str - * and restore the IER - */ - wait_for_xmitr(up, BOTH_EMPTY); -- serial_port_out(port, UART_IER, ier); -+ serial8250_set_IER(up, ier); - serial8250_rpm_put(up); - } - -@@ -2176,8 +2196,10 @@ static void serial8250_put_poll_char(str - int serial8250_do_startup(struct uart_port *port) - { - struct uart_8250_port *up = up_to_u8250p(port); -+ unsigned long cs_flags; - unsigned long flags; - unsigned char lsr, iir; -+ bool is_console; - int retval; - - if (!port->fifosize) -@@ -2197,7 +2219,7 @@ int serial8250_do_startup(struct uart_po - up->acr = 0; - serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); - serial_port_out(port, UART_EFR, UART_EFR_ECB); -- serial_port_out(port, UART_IER, 0); -+ serial8250_set_IER(up, 0); - serial_port_out(port, UART_LCR, 0); - serial_icr_write(up, UART_CSR, 0); /* Reset the UART */ - serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); -@@ -2207,7 +2229,7 @@ int serial8250_do_startup(struct uart_po - - if (port->type == PORT_DA830) { - /* Reset the port */ -- serial_port_out(port, UART_IER, 0); -+ serial8250_set_IER(up, 0); - serial_port_out(port, UART_DA830_PWREMU_MGMT, 0); - mdelay(10); - -@@ -2302,6 +2324,8 @@ int serial8250_do_startup(struct uart_po - if (port->irq && (up->port.flags & UPF_SHARE_IRQ)) - up->port.irqflags |= IRQF_SHARED; - -+ is_console = uart_console(port); -+ - if (port->irq && !(up->port.flags & UPF_NO_THRE_TEST)) { - unsigned char iir1; - -@@ -2318,6 +2342,9 @@ int serial8250_do_startup(struct uart_po - */ - spin_lock_irqsave(&port->lock, flags); - -+ if (is_console) -+ printk_cpu_sync_get_irqsave(cs_flags); -+ - wait_for_xmitr(up, UART_LSR_THRE); - serial_port_out_sync(port, UART_IER, UART_IER_THRI); - udelay(1); /* allow THRE to set */ -@@ -2328,6 +2355,9 @@ int serial8250_do_startup(struct uart_po - iir = serial_port_in(port, UART_IIR); - serial_port_out(port, UART_IER, 0); - -+ if (is_console) -+ printk_cpu_sync_put_irqrestore(cs_flags); -+ - spin_unlock_irqrestore(&port->lock, flags); - - if (port->irqflags & IRQF_SHARED) -@@ -2384,10 +2414,14 @@ int serial8250_do_startup(struct uart_po - * Do a quick test to see if we receive an interrupt when we enable - * the TX irq. - */ -+ if (is_console) -+ printk_cpu_sync_get_irqsave(cs_flags); - serial_port_out(port, UART_IER, UART_IER_THRI); - lsr = serial_port_in(port, UART_LSR); - iir = serial_port_in(port, UART_IIR); - serial_port_out(port, UART_IER, 0); -+ if (is_console) -+ printk_cpu_sync_put_irqrestore(cs_flags); - - if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) { - if (!(up->bugs & UART_BUG_TXEN)) { -@@ -2419,7 +2453,7 @@ dont_test_tx_en: - if (up->dma) { - const char *msg = NULL; - -- if (uart_console(port)) -+ if (is_console) - msg = "forbid DMA for kernel console"; - else if (serial8250_request_dma(up)) - msg = "failed to request DMA"; -@@ -2470,7 +2504,7 @@ void serial8250_do_shutdown(struct uart_ - */ - spin_lock_irqsave(&port->lock, flags); - up->ier = 0; -- serial_port_out(port, UART_IER, 0); -+ serial8250_set_IER(up, 0); - spin_unlock_irqrestore(&port->lock, flags); - - synchronize_irq(port->irq); -@@ -2836,7 +2870,7 @@ serial8250_do_set_termios(struct uart_po - if (up->capabilities & UART_CAP_RTOIE) - up->ier |= UART_IER_RTOIE; - -- serial_port_out(port, UART_IER, up->ier); -+ serial8250_set_IER(up, up->ier); - - if (up->capabilities & UART_CAP_EFR) { - unsigned char efr = 0; -@@ -3304,7 +3338,7 @@ EXPORT_SYMBOL_GPL(serial8250_set_default - - #ifdef CONFIG_SERIAL_8250_CONSOLE - --static void serial8250_console_putchar(struct uart_port *port, unsigned char ch) -+static void serial8250_console_putchar_locked(struct uart_port *port, unsigned char ch) - { - struct uart_8250_port *up = up_to_u8250p(port); - -@@ -3312,6 +3346,18 @@ static void serial8250_console_putchar(s - serial_port_out(port, UART_TX, ch); - } - -+static void serial8250_console_putchar(struct uart_port *port, unsigned char ch) -+{ -+ struct uart_8250_port *up = up_to_u8250p(port); -+ unsigned long flags; -+ -+ wait_for_xmitr(up, UART_LSR_THRE); -+ -+ printk_cpu_sync_get_irqsave(flags); -+ serial8250_console_putchar_locked(port, ch); -+ printk_cpu_sync_put_irqrestore(flags); -+} -+ - /* - * Restore serial console when h/w power-off detected - */ -@@ -3333,6 +3379,32 @@ static void serial8250_console_restore(s - serial8250_out_MCR(up, up->mcr | UART_MCR_DTR | UART_MCR_RTS); - } - -+void serial8250_console_write_atomic(struct uart_8250_port *up, -+ const char *s, unsigned int count) -+{ -+ struct uart_port *port = &up->port; -+ unsigned long flags; -+ unsigned int ier; -+ -+ printk_cpu_sync_get_irqsave(flags); -+ -+ touch_nmi_watchdog(); -+ -+ ier = serial8250_clear_IER(up); -+ -+ if (atomic_fetch_inc(&up->console_printing)) { -+ uart_console_write(port, "\n", 1, -+ serial8250_console_putchar_locked); -+ } -+ uart_console_write(port, s, count, serial8250_console_putchar_locked); -+ atomic_dec(&up->console_printing); -+ -+ wait_for_xmitr(up, BOTH_EMPTY); -+ serial8250_set_IER(up, ier); -+ -+ printk_cpu_sync_put_irqrestore(flags); -+} -+ - /* - * Print a string to the serial port using the device FIFO - * -@@ -3378,24 +3450,12 @@ void serial8250_console_write(struct uar - struct uart_port *port = &up->port; - unsigned long flags; - unsigned int ier, use_fifo; -- int locked = 1; - - touch_nmi_watchdog(); - -- if (oops_in_progress) -- locked = spin_trylock_irqsave(&port->lock, flags); -- else -- spin_lock_irqsave(&port->lock, flags); -- -- /* -- * First save the IER then disable the interrupts -- */ -- ier = serial_port_in(port, UART_IER); -+ spin_lock_irqsave(&port->lock, flags); - -- if (up->capabilities & UART_CAP_UUE) -- serial_port_out(port, UART_IER, UART_IER_UUE); -- else -- serial_port_out(port, UART_IER, 0); -+ ier = serial8250_clear_IER(up); - - /* check scratch reg to see if port powered off during system sleep */ - if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) { -@@ -3429,10 +3489,12 @@ void serial8250_console_write(struct uar - */ - !(up->port.flags & UPF_CONS_FLOW); - -+ atomic_inc(&up->console_printing); - if (likely(use_fifo)) - serial8250_console_fifo_write(up, s, count); - else - uart_console_write(port, s, count, serial8250_console_putchar); -+ atomic_dec(&up->console_printing); - - /* - * Finally, wait for transmitter to become empty -@@ -3445,8 +3507,7 @@ void serial8250_console_write(struct uar - if (em485->tx_stopped) - up->rs485_stop_tx(up); - } -- -- serial_port_out(port, UART_IER, ier); -+ serial8250_set_IER(up, ier); - - /* - * The receive handling will happen properly because the -@@ -3458,8 +3519,7 @@ void serial8250_console_write(struct uar - if (up->msr_saved_flags) - serial8250_modem_status(up); - -- if (locked) -- spin_unlock_irqrestore(&port->lock, flags); -+ spin_unlock_irqrestore(&port->lock, flags); - } - - static unsigned int probe_baud(struct uart_port *port) -@@ -3479,6 +3539,7 @@ static unsigned int probe_baud(struct ua - - int serial8250_console_setup(struct uart_port *port, char *options, bool probe) - { -+ struct uart_8250_port *up = up_to_u8250p(port); - int baud = 9600; - int bits = 8; - int parity = 'n'; -@@ -3488,6 +3549,8 @@ int serial8250_console_setup(struct uart - if (!port->iobase && !port->membase) - return -ENODEV; - -+ atomic_set(&up->console_printing, 0); -+ - if (options) - uart_parse_options(options, &baud, &parity, &bits, &flow); - else if (probe) -diff -rupN linux-5.19.16.orig/drivers/tty/serial/8250/Kconfig linux-5.19.16/drivers/tty/serial/8250/Kconfig ---- linux-5.19.16.orig/drivers/tty/serial/8250/Kconfig 2022-10-18 17:21:10.672501663 -0400 -+++ linux-5.19.16/drivers/tty/serial/8250/Kconfig 2022-10-18 17:21:17.804446694 -0400 -@@ -9,6 +9,7 @@ config SERIAL_8250 - depends on !S390 - select SERIAL_CORE - select SERIAL_MCTRL_GPIO if GPIOLIB -+ select HAVE_ATOMIC_CONSOLE - help - This selects whether you want to include the driver for the standard - serial ports. The standard answer is Y. People who might say N -diff -rupN linux-5.19.16.orig/drivers/tty/serial/amba-pl011.c linux-5.19.16/drivers/tty/serial/amba-pl011.c ---- linux-5.19.16.orig/drivers/tty/serial/amba-pl011.c 2022-10-18 17:21:10.672501663 -0400 -+++ linux-5.19.16/drivers/tty/serial/amba-pl011.c 2022-10-18 17:21:17.804446694 -0400 -@@ -2308,18 +2308,24 @@ pl011_console_write(struct console *co, - { - struct uart_amba_port *uap = amba_ports[co->index]; - unsigned int old_cr = 0, new_cr; -- unsigned long flags; -+ unsigned long flags = 0; - int locked = 1; - - clk_enable(uap->clk); - -- local_irq_save(flags); -+ /* -+ * local_irq_save(flags); -+ * -+ * This local_irq_save() is nonsense. If we come in via sysrq -+ * handling then interrupts are already disabled. Aside of -+ * that the port.sysrq check is racy on SMP regardless. -+ */ - if (uap->port.sysrq) - locked = 0; - else if (oops_in_progress) -- locked = spin_trylock(&uap->port.lock); -+ locked = spin_trylock_irqsave(&uap->port.lock, flags); - else -- spin_lock(&uap->port.lock); -+ spin_lock_irqsave(&uap->port.lock, flags); - - /* - * First save the CR then disable the interrupts -@@ -2345,8 +2351,7 @@ pl011_console_write(struct console *co, - pl011_write(old_cr, uap, REG_CR); - - if (locked) -- spin_unlock(&uap->port.lock); -- local_irq_restore(flags); -+ spin_unlock_irqrestore(&uap->port.lock, flags); - - clk_disable(uap->clk); - } -diff -rupN linux-5.19.16.orig/drivers/tty/serial/omap-serial.c linux-5.19.16/drivers/tty/serial/omap-serial.c ---- linux-5.19.16.orig/drivers/tty/serial/omap-serial.c 2022-10-18 17:21:10.672501663 -0400 -+++ linux-5.19.16/drivers/tty/serial/omap-serial.c 2022-10-18 17:21:17.804446694 -0400 -@@ -1241,13 +1241,10 @@ serial_omap_console_write(struct console - unsigned int ier; - int locked = 1; - -- local_irq_save(flags); -- if (up->port.sysrq) -- locked = 0; -- else if (oops_in_progress) -- locked = spin_trylock(&up->port.lock); -+ if (up->port.sysrq || oops_in_progress) -+ locked = spin_trylock_irqsave(&up->port.lock, flags); - else -- spin_lock(&up->port.lock); -+ spin_lock_irqsave(&up->port.lock, flags); - - /* - * First save the IER then disable the interrupts -@@ -1274,8 +1271,7 @@ serial_omap_console_write(struct console - check_modem_status(up); - - if (locked) -- spin_unlock(&up->port.lock); -- local_irq_restore(flags); -+ spin_unlock_irqrestore(&up->port.lock, flags); - } - - static int __init -diff -rupN linux-5.19.16.orig/drivers/tty/sysrq.c linux-5.19.16/drivers/tty/sysrq.c ---- linux-5.19.16.orig/drivers/tty/sysrq.c 2022-10-18 17:21:10.676501631 -0400 -+++ linux-5.19.16/drivers/tty/sysrq.c 2022-10-18 17:21:17.804446694 -0400 -@@ -581,6 +581,7 @@ void __handle_sysrq(int key, bool check_ - - rcu_sysrq_start(); - rcu_read_lock(); -+ printk_prefer_direct_enter(); - /* - * Raise the apparent loglevel to maximum so that the sysrq header - * is shown to provide the user with positive feedback. We do not -@@ -622,6 +623,7 @@ void __handle_sysrq(int key, bool check_ - pr_cont("\n"); - console_loglevel = orig_log_level; - } -+ printk_prefer_direct_exit(); - rcu_read_unlock(); - rcu_sysrq_end(); - -diff -rupN linux-5.19.16.orig/fs/dcache.c linux-5.19.16/fs/dcache.c ---- linux-5.19.16.orig/fs/dcache.c 2022-10-18 17:21:10.732501201 -0400 -+++ linux-5.19.16/fs/dcache.c 2022-10-18 17:21:17.804446694 -0400 -@@ -2239,6 +2239,7 @@ struct dentry *d_add_ci(struct dentry *d - } - } - res = d_splice_alias(inode, found); -+ d_lookup_done(found); - if (res) { - dput(found); - return res; -@@ -2563,7 +2564,15 @@ EXPORT_SYMBOL(d_rehash); - - static inline unsigned start_dir_add(struct inode *dir) - { -- -+ /* -+ * The caller holds a spinlock (dentry::d_lock). On !PREEMPT_RT -+ * kernels spin_lock() implicitly disables preemption, but not on -+ * PREEMPT_RT. So for RT it has to be done explicitly to protect -+ * the sequence count write side critical section against a reader -+ * or another writer preempting, which would result in a live lock. -+ */ -+ if (IS_ENABLED(CONFIG_PREEMPT_RT)) -+ preempt_disable(); - for (;;) { - unsigned n = dir->i_dir_seq; - if (!(n & 1) && cmpxchg(&dir->i_dir_seq, n, n + 1) == n) -@@ -2572,9 +2581,13 @@ static inline unsigned start_dir_add(str - } - } - --static inline void end_dir_add(struct inode *dir, unsigned n) -+static inline void end_dir_add(struct inode *dir, unsigned int n, -+ wait_queue_head_t *d_wait) - { - smp_store_release(&dir->i_dir_seq, n + 2); -+ if (IS_ENABLED(CONFIG_PREEMPT_RT)) -+ preempt_enable(); -+ wake_up_all(d_wait); - } - - static void d_wait_lookup(struct dentry *dentry) -@@ -2701,32 +2714,50 @@ mismatch: - } - EXPORT_SYMBOL(d_alloc_parallel); - --void __d_lookup_done(struct dentry *dentry) -+/* -+ * - Unhash the dentry -+ * - Retrieve and clear the waitqueue head in dentry -+ * - Return the waitqueue head -+ */ -+static wait_queue_head_t *__d_lookup_unhash(struct dentry *dentry) - { -- struct hlist_bl_head *b = in_lookup_hash(dentry->d_parent, -- dentry->d_name.hash); -+ wait_queue_head_t *d_wait; -+ struct hlist_bl_head *b; -+ -+ lockdep_assert_held(&dentry->d_lock); -+ -+ b = in_lookup_hash(dentry->d_parent, dentry->d_name.hash); - hlist_bl_lock(b); - dentry->d_flags &= ~DCACHE_PAR_LOOKUP; - __hlist_bl_del(&dentry->d_u.d_in_lookup_hash); -- wake_up_all(dentry->d_wait); -+ d_wait = dentry->d_wait; - dentry->d_wait = NULL; - hlist_bl_unlock(b); - INIT_HLIST_NODE(&dentry->d_u.d_alias); - INIT_LIST_HEAD(&dentry->d_lru); -+ return d_wait; -+} -+ -+void __d_lookup_unhash_wake(struct dentry *dentry) -+{ -+ spin_lock(&dentry->d_lock); -+ wake_up_all(__d_lookup_unhash(dentry)); -+ spin_unlock(&dentry->d_lock); - } --EXPORT_SYMBOL(__d_lookup_done); -+EXPORT_SYMBOL(__d_lookup_unhash_wake); - - /* inode->i_lock held if inode is non-NULL */ - - static inline void __d_add(struct dentry *dentry, struct inode *inode) - { -+ wait_queue_head_t *d_wait; - struct inode *dir = NULL; - unsigned n; - spin_lock(&dentry->d_lock); - if (unlikely(d_in_lookup(dentry))) { - dir = dentry->d_parent->d_inode; - n = start_dir_add(dir); -- __d_lookup_done(dentry); -+ d_wait = __d_lookup_unhash(dentry); - } - if (inode) { - unsigned add_flags = d_flags_for_inode(inode); -@@ -2738,7 +2769,7 @@ static inline void __d_add(struct dentry - } - __d_rehash(dentry); - if (dir) -- end_dir_add(dir, n); -+ end_dir_add(dir, n, d_wait); - spin_unlock(&dentry->d_lock); - if (inode) - spin_unlock(&inode->i_lock); -@@ -2885,6 +2916,7 @@ static void __d_move(struct dentry *dent - bool exchange) - { - struct dentry *old_parent, *p; -+ wait_queue_head_t *d_wait; - struct inode *dir = NULL; - unsigned n; - -@@ -2915,7 +2947,7 @@ static void __d_move(struct dentry *dent - if (unlikely(d_in_lookup(target))) { - dir = target->d_parent->d_inode; - n = start_dir_add(dir); -- __d_lookup_done(target); -+ d_wait = __d_lookup_unhash(target); - } - - write_seqcount_begin(&dentry->d_seq); -@@ -2951,7 +2983,7 @@ static void __d_move(struct dentry *dent - write_seqcount_end(&dentry->d_seq); - - if (dir) -- end_dir_add(dir, n); -+ end_dir_add(dir, n, d_wait); - - if (dentry->d_parent != old_parent) - spin_unlock(&dentry->d_parent->d_lock); -diff -rupN linux-5.19.16.orig/include/asm-generic/softirq_stack.h linux-5.19.16/include/asm-generic/softirq_stack.h ---- linux-5.19.16.orig/include/asm-generic/softirq_stack.h 2022-10-18 17:21:10.800500677 -0400 -+++ linux-5.19.16/include/asm-generic/softirq_stack.h 2022-10-18 17:21:17.804446694 -0400 -@@ -2,7 +2,7 @@ - #ifndef __ASM_GENERIC_SOFTIRQ_STACK_H - #define __ASM_GENERIC_SOFTIRQ_STACK_H - --#ifdef CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK -+#if defined(CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK) && !defined(CONFIG_PREEMPT_RT) - void do_softirq_own_stack(void); - #else - static inline void do_softirq_own_stack(void) -diff -rupN linux-5.19.16.orig/include/linux/console.h linux-5.19.16/include/linux/console.h ---- linux-5.19.16.orig/include/linux/console.h 2022-10-18 17:21:10.828500461 -0400 -+++ linux-5.19.16/include/linux/console.h 2022-10-18 17:21:17.804446694 -0400 -@@ -16,6 +16,7 @@ - - #include - #include -+#include - - struct vc_data; - struct console_font_op; -@@ -137,9 +138,19 @@ static inline int con_debug_leave(void) - #define CON_BRL (32) /* Used for a braille device */ - #define CON_EXTENDED (64) /* Use the extended output format a la /dev/kmsg */ - -+#ifdef CONFIG_HAVE_ATOMIC_CONSOLE -+struct console_atomic_data { -+ u64 seq; -+ char *text; -+ char *ext_text; -+ char *dropped_text; -+}; -+#endif -+ - struct console { - char name[16]; - void (*write)(struct console *, const char *, unsigned); -+ void (*write_atomic)(struct console *, const char *, unsigned); - int (*read)(struct console *, char *, unsigned); - struct tty_driver *(*device)(struct console *, int *); - void (*unblank)(void); -@@ -152,7 +163,26 @@ struct console { - uint ispeed; - uint ospeed; - u64 seq; -- unsigned long dropped; -+ atomic_long_t dropped; -+#ifdef CONFIG_HAVE_ATOMIC_CONSOLE -+ struct console_atomic_data *atomic_data; -+#endif -+ struct task_struct *thread; -+ bool blocked; -+ -+ /* -+ * The per-console lock is used by printing kthreads to synchronize -+ * this console with callers of console_lock(). This is necessary in -+ * order to allow printing kthreads to run in parallel to each other, -+ * while each safely accessing the @blocked field and synchronizing -+ * against direct printing via console_lock/console_unlock. -+ * -+ * Note: For synchronizing against direct printing via -+ * console_trylock/console_unlock, see the static global -+ * variable @console_kthreads_active. -+ */ -+ struct mutex lock; -+ - void *data; - struct console *next; - }; -@@ -167,6 +197,7 @@ extern int console_set_on_cmdline; - extern struct console *early_console; - - enum con_flush_mode { -+ CONSOLE_ATOMIC_FLUSH_PENDING, - CONSOLE_FLUSH_PENDING, - CONSOLE_REPLAY_ALL, - }; -diff -rupN linux-5.19.16.orig/include/linux/dcache.h linux-5.19.16/include/linux/dcache.h ---- linux-5.19.16.orig/include/linux/dcache.h 2022-10-18 17:21:10.828500461 -0400 -+++ linux-5.19.16/include/linux/dcache.h 2022-10-18 17:21:17.804446694 -0400 -@@ -349,7 +349,7 @@ static inline void dont_mount(struct den - spin_unlock(&dentry->d_lock); - } - --extern void __d_lookup_done(struct dentry *); -+extern void __d_lookup_unhash_wake(struct dentry *dentry); - - static inline int d_in_lookup(const struct dentry *dentry) - { -@@ -358,11 +358,8 @@ static inline int d_in_lookup(const stru - - static inline void d_lookup_done(struct dentry *dentry) - { -- if (unlikely(d_in_lookup(dentry))) { -- spin_lock(&dentry->d_lock); -- __d_lookup_done(dentry); -- spin_unlock(&dentry->d_lock); -- } -+ if (unlikely(d_in_lookup(dentry))) -+ __d_lookup_unhash_wake(dentry); - } - - extern void dput(struct dentry *); -diff -rupN linux-5.19.16.orig/include/linux/entry-common.h linux-5.19.16/include/linux/entry-common.h ---- linux-5.19.16.orig/include/linux/entry-common.h 2022-10-18 17:21:10.832500430 -0400 -+++ linux-5.19.16/include/linux/entry-common.h 2022-10-18 17:21:17.804446694 -0400 -@@ -57,9 +57,15 @@ - # define ARCH_EXIT_TO_USER_MODE_WORK (0) - #endif - -+#ifdef CONFIG_PREEMPT_LAZY -+# define _TIF_NEED_RESCHED_MASK (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY) -+#else -+# define _TIF_NEED_RESCHED_MASK (_TIF_NEED_RESCHED) -+#endif -+ - #define EXIT_TO_USER_MODE_WORK \ - (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_UPROBE | \ -- _TIF_NEED_RESCHED | _TIF_PATCH_PENDING | _TIF_NOTIFY_SIGNAL | \ -+ _TIF_NEED_RESCHED_MASK | _TIF_PATCH_PENDING | _TIF_NOTIFY_SIGNAL | \ - ARCH_EXIT_TO_USER_MODE_WORK) - - /** -diff -rupN linux-5.19.16.orig/include/linux/interrupt.h linux-5.19.16/include/linux/interrupt.h ---- linux-5.19.16.orig/include/linux/interrupt.h 2022-10-18 17:21:10.836500399 -0400 -+++ linux-5.19.16/include/linux/interrupt.h 2022-10-18 17:21:17.804446694 -0400 -@@ -605,6 +605,35 @@ extern void __raise_softirq_irqoff(unsig - extern void raise_softirq_irqoff(unsigned int nr); - extern void raise_softirq(unsigned int nr); - -+#ifdef CONFIG_PREEMPT_RT -+DECLARE_PER_CPU(struct task_struct *, timersd); -+DECLARE_PER_CPU(unsigned long, pending_timer_softirq); -+ -+extern void raise_timer_softirq(void); -+extern void raise_hrtimer_softirq(void); -+ -+static inline unsigned int local_pending_timers(void) -+{ -+ return __this_cpu_read(pending_timer_softirq); -+} -+ -+#else -+static inline void raise_timer_softirq(void) -+{ -+ raise_softirq(TIMER_SOFTIRQ); -+} -+ -+static inline void raise_hrtimer_softirq(void) -+{ -+ raise_softirq_irqoff(HRTIMER_SOFTIRQ); -+} -+ -+static inline unsigned int local_pending_timers(void) -+{ -+ return local_softirq_pending(); -+} -+#endif -+ - DECLARE_PER_CPU(struct task_struct *, ksoftirqd); - - static inline struct task_struct *this_cpu_ksoftirqd(void) -diff -rupN linux-5.19.16.orig/include/linux/irqdesc.h linux-5.19.16/include/linux/irqdesc.h ---- linux-5.19.16.orig/include/linux/irqdesc.h 2022-10-18 17:21:10.840500369 -0400 -+++ linux-5.19.16/include/linux/irqdesc.h 2022-10-18 17:21:17.804446694 -0400 -@@ -169,6 +169,7 @@ int generic_handle_irq_safe(unsigned int - * conversion failed. - */ - int generic_handle_domain_irq(struct irq_domain *domain, unsigned int hwirq); -+int generic_handle_domain_irq_safe(struct irq_domain *domain, unsigned int hwirq); - int generic_handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq); - #endif - -diff -rupN linux-5.19.16.orig/include/linux/lockdep.h linux-5.19.16/include/linux/lockdep.h ---- linux-5.19.16.orig/include/linux/lockdep.h 2022-10-18 17:21:10.840500369 -0400 -+++ linux-5.19.16/include/linux/lockdep.h 2022-10-18 17:21:17.804446694 -0400 -@@ -435,7 +435,6 @@ enum xhlock_context_t { - XHLOCK_CTX_NR, - }; - --#define lockdep_init_map_crosslock(m, n, k, s) do {} while (0) - /* - * To initialize a lockdep_map statically use this macro. - * Note that _name must not be NULL. -diff -rupN linux-5.19.16.orig/include/linux/preempt.h linux-5.19.16/include/linux/preempt.h ---- linux-5.19.16.orig/include/linux/preempt.h 2022-10-18 17:21:10.848500307 -0400 -+++ linux-5.19.16/include/linux/preempt.h 2022-10-18 17:21:17.804446694 -0400 -@@ -196,6 +196,20 @@ extern void preempt_count_sub(int val); - #define preempt_count_inc() preempt_count_add(1) - #define preempt_count_dec() preempt_count_sub(1) - -+#ifdef CONFIG_PREEMPT_LAZY -+#define add_preempt_lazy_count(val) do { preempt_lazy_count() += (val); } while (0) -+#define sub_preempt_lazy_count(val) do { preempt_lazy_count() -= (val); } while (0) -+#define inc_preempt_lazy_count() add_preempt_lazy_count(1) -+#define dec_preempt_lazy_count() sub_preempt_lazy_count(1) -+#define preempt_lazy_count() (current_thread_info()->preempt_lazy_count) -+#else -+#define add_preempt_lazy_count(val) do { } while (0) -+#define sub_preempt_lazy_count(val) do { } while (0) -+#define inc_preempt_lazy_count() do { } while (0) -+#define dec_preempt_lazy_count() do { } while (0) -+#define preempt_lazy_count() (0) -+#endif -+ - #ifdef CONFIG_PREEMPT_COUNT - - #define preempt_disable() \ -@@ -204,6 +218,12 @@ do { \ - barrier(); \ - } while (0) - -+#define preempt_lazy_disable() \ -+do { \ -+ inc_preempt_lazy_count(); \ -+ barrier(); \ -+} while (0) -+ - #define sched_preempt_enable_no_resched() \ - do { \ - barrier(); \ -@@ -235,6 +255,18 @@ do { \ - __preempt_schedule(); \ - } while (0) - -+/* -+ * open code preempt_check_resched() because it is not exported to modules and -+ * used by local_unlock() or bpf_enable_instrumentation(). -+ */ -+#define preempt_lazy_enable() \ -+do { \ -+ dec_preempt_lazy_count(); \ -+ barrier(); \ -+ if (should_resched(0)) \ -+ __preempt_schedule(); \ -+} while (0) -+ - #else /* !CONFIG_PREEMPTION */ - #define preempt_enable() \ - do { \ -@@ -242,6 +274,12 @@ do { \ - preempt_count_dec(); \ - } while (0) - -+#define preempt_lazy_enable() \ -+do { \ -+ dec_preempt_lazy_count(); \ -+ barrier(); \ -+} while (0) -+ - #define preempt_enable_notrace() \ - do { \ - barrier(); \ -@@ -282,6 +320,9 @@ do { \ - #define preempt_enable_notrace() barrier() - #define preemptible() 0 - -+#define preempt_lazy_disable() barrier() -+#define preempt_lazy_enable() barrier() -+ - #endif /* CONFIG_PREEMPT_COUNT */ - - #ifdef MODULE -@@ -300,7 +341,7 @@ do { \ - } while (0) - #define preempt_fold_need_resched() \ - do { \ -- if (tif_need_resched()) \ -+ if (tif_need_resched_now()) \ - set_preempt_need_resched(); \ - } while (0) - -@@ -416,8 +457,15 @@ extern void migrate_enable(void); - - #else - --static inline void migrate_disable(void) { } --static inline void migrate_enable(void) { } -+static inline void migrate_disable(void) -+{ -+ preempt_lazy_disable(); -+} -+ -+static inline void migrate_enable(void) -+{ -+ preempt_lazy_enable(); -+} - - #endif /* CONFIG_SMP */ - -diff -rupN linux-5.19.16.orig/include/linux/printk.h linux-5.19.16/include/linux/printk.h ---- linux-5.19.16.orig/include/linux/printk.h 2022-10-18 17:21:10.848500307 -0400 -+++ linux-5.19.16/include/linux/printk.h 2022-10-18 17:21:17.804446694 -0400 -@@ -169,7 +169,11 @@ extern void __printk_safe_exit(void); - #define printk_deferred_enter __printk_safe_enter - #define printk_deferred_exit __printk_safe_exit - -+extern void printk_prefer_direct_enter(void); -+extern void printk_prefer_direct_exit(void); -+ - extern bool pr_flush(int timeout_ms, bool reset_on_progress); -+extern void try_block_console_kthreads(int timeout_ms); - - /* - * Please don't use printk_ratelimit(), because it shares ratelimiting state -@@ -221,11 +225,23 @@ static inline void printk_deferred_exit( - { - } - -+static inline void printk_prefer_direct_enter(void) -+{ -+} -+ -+static inline void printk_prefer_direct_exit(void) -+{ -+} -+ - static inline bool pr_flush(int timeout_ms, bool reset_on_progress) - { - return true; - } - -+static inline void try_block_console_kthreads(int timeout_ms) -+{ -+} -+ - static inline int printk_ratelimit(void) - { - return 0; -diff -rupN linux-5.19.16.orig/include/linux/sched.h linux-5.19.16/include/linux/sched.h ---- linux-5.19.16.orig/include/linux/sched.h 2022-10-18 17:21:10.852500276 -0400 -+++ linux-5.19.16/include/linux/sched.h 2022-10-18 17:21:17.804446694 -0400 -@@ -2026,6 +2026,43 @@ static inline int test_tsk_need_resched( - return unlikely(test_tsk_thread_flag(tsk,TIF_NEED_RESCHED)); - } - -+#ifdef CONFIG_PREEMPT_LAZY -+static inline void set_tsk_need_resched_lazy(struct task_struct *tsk) -+{ -+ set_tsk_thread_flag(tsk,TIF_NEED_RESCHED_LAZY); -+} -+ -+static inline void clear_tsk_need_resched_lazy(struct task_struct *tsk) -+{ -+ clear_tsk_thread_flag(tsk,TIF_NEED_RESCHED_LAZY); -+} -+ -+static inline int test_tsk_need_resched_lazy(struct task_struct *tsk) -+{ -+ return unlikely(test_tsk_thread_flag(tsk,TIF_NEED_RESCHED_LAZY)); -+} -+ -+static inline int need_resched_lazy(void) -+{ -+ return test_thread_flag(TIF_NEED_RESCHED_LAZY); -+} -+ -+static inline int need_resched_now(void) -+{ -+ return test_thread_flag(TIF_NEED_RESCHED); -+} -+ -+#else -+static inline void clear_tsk_need_resched_lazy(struct task_struct *tsk) { } -+static inline int need_resched_lazy(void) { return 0; } -+ -+static inline int need_resched_now(void) -+{ -+ return test_thread_flag(TIF_NEED_RESCHED); -+} -+ -+#endif -+ - /* - * cond_resched() and cond_resched_lock(): latency reduction via - * explicit rescheduling in places that are safe. The return -diff -rupN linux-5.19.16.orig/include/linux/serial_8250.h linux-5.19.16/include/linux/serial_8250.h ---- linux-5.19.16.orig/include/linux/serial_8250.h 2022-10-18 17:21:10.852500276 -0400 -+++ linux-5.19.16/include/linux/serial_8250.h 2022-10-18 17:21:17.804446694 -0400 -@@ -7,6 +7,7 @@ - #ifndef _LINUX_SERIAL_8250_H - #define _LINUX_SERIAL_8250_H - -+#include - #include - #include - #include -@@ -123,6 +124,8 @@ struct uart_8250_port { - #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA - unsigned char msr_saved_flags; - -+ atomic_t console_printing; -+ - struct uart_8250_dma *dma; - const struct uart_8250_ops *ops; - -@@ -178,6 +181,8 @@ void serial8250_init_port(struct uart_82 - void serial8250_set_defaults(struct uart_8250_port *up); - void serial8250_console_write(struct uart_8250_port *up, const char *s, - unsigned int count); -+void serial8250_console_write_atomic(struct uart_8250_port *up, const char *s, -+ unsigned int count); - int serial8250_console_setup(struct uart_port *port, char *options, bool probe); - int serial8250_console_exit(struct uart_port *port); - -diff -rupN linux-5.19.16.orig/include/linux/thread_info.h linux-5.19.16/include/linux/thread_info.h ---- linux-5.19.16.orig/include/linux/thread_info.h 2022-10-18 17:21:10.892499968 -0400 -+++ linux-5.19.16/include/linux/thread_info.h 2022-10-18 17:21:17.804446694 -0400 -@@ -177,7 +177,17 @@ static __always_inline unsigned long rea - clear_ti_thread_flag(task_thread_info(t), TIF_##fl) - #endif /* !CONFIG_GENERIC_ENTRY */ - --#define tif_need_resched() test_thread_flag(TIF_NEED_RESCHED) -+#ifdef CONFIG_PREEMPT_LAZY -+#define tif_need_resched() (test_thread_flag(TIF_NEED_RESCHED) || \ -+ test_thread_flag(TIF_NEED_RESCHED_LAZY)) -+#define tif_need_resched_now() (test_thread_flag(TIF_NEED_RESCHED)) -+#define tif_need_resched_lazy() test_thread_flag(TIF_NEED_RESCHED_LAZY) -+ -+#else -+#define tif_need_resched() test_thread_flag(TIF_NEED_RESCHED) -+#define tif_need_resched_now() test_thread_flag(TIF_NEED_RESCHED) -+#define tif_need_resched_lazy() 0 -+#endif - - #ifndef CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES - static inline int arch_within_stack_frames(const void * const stack, -diff -rupN linux-5.19.16.orig/include/linux/trace_events.h linux-5.19.16/include/linux/trace_events.h ---- linux-5.19.16.orig/include/linux/trace_events.h 2022-10-18 17:21:10.892499968 -0400 -+++ linux-5.19.16/include/linux/trace_events.h 2022-10-18 17:21:17.804446694 -0400 -@@ -70,6 +70,7 @@ struct trace_entry { - unsigned char flags; - unsigned char preempt_count; - int pid; -+ unsigned char preempt_lazy_count; - }; - - #define TRACE_EVENT_TYPE_MAX \ -@@ -158,9 +159,10 @@ static inline void tracing_generic_entry - unsigned int trace_ctx) - { - entry->preempt_count = trace_ctx & 0xff; -+ entry->preempt_lazy_count = (trace_ctx >> 16) & 0xff; - entry->pid = current->pid; - entry->type = type; -- entry->flags = trace_ctx >> 16; -+ entry->flags = trace_ctx >> 24; - } - - unsigned int tracing_gen_ctx_irq_test(unsigned int irqs_status); -@@ -171,7 +173,13 @@ enum trace_flag_type { - TRACE_FLAG_NEED_RESCHED = 0x04, - TRACE_FLAG_HARDIRQ = 0x08, - TRACE_FLAG_SOFTIRQ = 0x10, -+#ifdef CONFIG_PREEMPT_LAZY -+ TRACE_FLAG_PREEMPT_RESCHED = 0x00, -+ TRACE_FLAG_NEED_RESCHED_LAZY = 0x20, -+#else -+ TRACE_FLAG_NEED_RESCHED_LAZY = 0x00, - TRACE_FLAG_PREEMPT_RESCHED = 0x20, -+#endif - TRACE_FLAG_NMI = 0x40, - TRACE_FLAG_BH_OFF = 0x80, - }; -diff -rupN linux-5.19.16.orig/init/Kconfig linux-5.19.16/init/Kconfig ---- linux-5.19.16.orig/init/Kconfig 2022-10-18 17:21:10.948499537 -0400 -+++ linux-5.19.16/init/Kconfig 2022-10-18 17:21:17.808446663 -0400 -@@ -1574,6 +1574,10 @@ config PRINTK - very difficult to diagnose system problems, saying N here is - strongly discouraged. - -+config HAVE_ATOMIC_CONSOLE -+ bool -+ default n -+ - config BUG - bool "BUG() support" if EXPERT - default y -diff -rupN linux-5.19.16.orig/kernel/entry/common.c linux-5.19.16/kernel/entry/common.c ---- linux-5.19.16.orig/kernel/entry/common.c 2022-10-18 17:21:10.956499475 -0400 -+++ linux-5.19.16/kernel/entry/common.c 2022-10-18 17:21:17.808446663 -0400 -@@ -153,7 +153,7 @@ static unsigned long exit_to_user_mode_l - - local_irq_enable_exit_to_user(ti_work); - -- if (ti_work & _TIF_NEED_RESCHED) -+ if (ti_work & _TIF_NEED_RESCHED_MASK) - schedule(); - - if (ti_work & _TIF_UPROBE) -@@ -381,7 +381,7 @@ void raw_irqentry_exit_cond_resched(void - rcu_irq_exit_check_preempt(); - if (IS_ENABLED(CONFIG_DEBUG_ENTRY)) - WARN_ON_ONCE(!on_thread_stack()); -- if (need_resched()) -+ if (should_resched(0)) - preempt_schedule_irq(); - } - } -diff -rupN linux-5.19.16.orig/kernel/hung_task.c linux-5.19.16/kernel/hung_task.c ---- linux-5.19.16.orig/kernel/hung_task.c 2022-10-18 17:21:10.952499506 -0400 -+++ linux-5.19.16/kernel/hung_task.c 2022-10-18 17:21:17.808446663 -0400 -@@ -127,6 +127,8 @@ static void check_hung_task(struct task_ - * complain: - */ - if (sysctl_hung_task_warnings) { -+ printk_prefer_direct_enter(); -+ - if (sysctl_hung_task_warnings > 0) - sysctl_hung_task_warnings--; - pr_err("INFO: task %s:%d blocked for more than %ld seconds.\n", -@@ -142,6 +144,8 @@ static void check_hung_task(struct task_ - - if (sysctl_hung_task_all_cpu_backtrace) - hung_task_show_all_bt = true; -+ -+ printk_prefer_direct_exit(); - } - - touch_nmi_watchdog(); -@@ -204,12 +208,17 @@ static void check_hung_uninterruptible_t - } - unlock: - rcu_read_unlock(); -- if (hung_task_show_lock) -+ if (hung_task_show_lock) { -+ printk_prefer_direct_enter(); - debug_show_all_locks(); -+ printk_prefer_direct_exit(); -+ } - - if (hung_task_show_all_bt) { - hung_task_show_all_bt = false; -+ printk_prefer_direct_enter(); - trigger_all_cpu_backtrace(); -+ printk_prefer_direct_exit(); - } - - if (hung_task_call_panic) -diff -rupN linux-5.19.16.orig/kernel/irq/irqdesc.c linux-5.19.16/kernel/irq/irqdesc.c ---- linux-5.19.16.orig/kernel/irq/irqdesc.c 2022-10-18 17:21:10.960499444 -0400 -+++ linux-5.19.16/kernel/irq/irqdesc.c 2022-10-18 17:21:17.808446663 -0400 -@@ -705,6 +705,30 @@ int generic_handle_domain_irq(struct irq - } - EXPORT_SYMBOL_GPL(generic_handle_domain_irq); - -+ /** -+ * generic_handle_irq_safe - Invoke the handler for a HW irq belonging -+ * to a domain from any context. -+ * @domain: The domain where to perform the lookup -+ * @hwirq: The HW irq number to convert to a logical one -+ * -+ * Returns: 0 on success, a negative value on error. -+ * -+ * This function can be called from any context (IRQ or process context). It -+ * will report an error if not invoked from IRQ context and the irq has been -+ * marked to enforce IRQ-context only. -+ */ -+int generic_handle_domain_irq_safe(struct irq_domain *domain, unsigned int hwirq) -+{ -+ unsigned long flags; -+ int ret; -+ -+ local_irq_save(flags); -+ ret = handle_irq_desc(irq_resolve_mapping(domain, hwirq)); -+ local_irq_restore(flags); -+ return ret; -+} -+EXPORT_SYMBOL_GPL(generic_handle_domain_irq_safe); -+ - /** - * generic_handle_domain_nmi - Invoke the handler for a HW nmi belonging - * to a domain. -diff -rupN linux-5.19.16.orig/kernel/Kconfig.preempt linux-5.19.16/kernel/Kconfig.preempt ---- linux-5.19.16.orig/kernel/Kconfig.preempt 2022-10-18 17:21:10.952499506 -0400 -+++ linux-5.19.16/kernel/Kconfig.preempt 2022-10-18 17:21:17.808446663 -0400 -@@ -1,5 +1,11 @@ - # SPDX-License-Identifier: GPL-2.0-only - -+config HAVE_PREEMPT_LAZY -+ bool -+ -+config PREEMPT_LAZY -+ def_bool y if HAVE_PREEMPT_LAZY && PREEMPT_RT -+ - config PREEMPT_NONE_BUILD - bool - -diff -rupN linux-5.19.16.orig/kernel/ksysfs.c linux-5.19.16/kernel/ksysfs.c ---- linux-5.19.16.orig/kernel/ksysfs.c 2022-10-18 17:21:10.952499506 -0400 -+++ linux-5.19.16/kernel/ksysfs.c 2022-10-18 17:21:17.808446663 -0400 -@@ -137,6 +137,15 @@ KERNEL_ATTR_RO(vmcoreinfo); - - #endif /* CONFIG_CRASH_CORE */ - -+#if defined(CONFIG_PREEMPT_RT) -+static ssize_t realtime_show(struct kobject *kobj, -+ struct kobj_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "%d\n", 1); -+} -+KERNEL_ATTR_RO(realtime); -+#endif -+ - /* whether file capabilities are enabled */ - static ssize_t fscaps_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -@@ -228,6 +237,9 @@ static struct attribute * kernel_attrs[] - &rcu_expedited_attr.attr, - &rcu_normal_attr.attr, - #endif -+#ifdef CONFIG_PREEMPT_RT -+ &realtime_attr.attr, -+#endif - NULL - }; - -diff -rupN linux-5.19.16.orig/kernel/panic.c linux-5.19.16/kernel/panic.c ---- linux-5.19.16.orig/kernel/panic.c 2022-10-18 17:21:10.952499506 -0400 -+++ linux-5.19.16/kernel/panic.c 2022-10-18 17:21:17.808446663 -0400 -@@ -257,7 +257,6 @@ void panic(const char *fmt, ...) - panic_smp_self_stop(); - - console_verbose(); -- bust_spinlocks(1); - va_start(args, fmt); - len = vscnprintf(buf, sizeof(buf), fmt, args); - va_end(args); -@@ -274,6 +273,11 @@ void panic(const char *fmt, ...) - dump_stack(); - #endif - -+ /* If atomic consoles are available, flush the kernel log. */ -+ console_flush_on_panic(CONSOLE_ATOMIC_FLUSH_PENDING); -+ -+ bust_spinlocks(1); -+ - /* - * If kgdb is enabled, give it a chance to run before we stop all - * the other CPUs or else we won't be able to debug processes left -@@ -297,6 +301,7 @@ void panic(const char *fmt, ...) - * unfortunately means it may not be hardened to work in a - * panic situation. - */ -+ try_block_console_kthreads(10000); - smp_send_stop(); - } else { - /* -@@ -304,6 +309,7 @@ void panic(const char *fmt, ...) - * kmsg_dump, we will need architecture dependent extra - * works in addition to stopping other CPUs. - */ -+ try_block_console_kthreads(10000); - crash_smp_send_stop(); - } - -@@ -603,6 +609,8 @@ void __warn(const char *file, int line, - { - disable_trace_on_warning(); - -+ printk_prefer_direct_enter(); -+ - if (file) - pr_warn("WARNING: CPU: %d PID: %d at %s:%d %pS\n", - raw_smp_processor_id(), current->pid, file, line, -@@ -632,6 +640,8 @@ void __warn(const char *file, int line, - - /* Just a warning, don't kill lockdep. */ - add_taint(taint, LOCKDEP_STILL_OK); -+ -+ printk_prefer_direct_exit(); - } - - #ifndef __WARN_FLAGS -diff -rupN linux-5.19.16.orig/kernel/printk/internal.h linux-5.19.16/kernel/printk/internal.h ---- linux-5.19.16.orig/kernel/printk/internal.h 2022-10-18 17:21:10.960499444 -0400 -+++ linux-5.19.16/kernel/printk/internal.h 2022-10-18 17:21:17.808446663 -0400 -@@ -20,6 +20,8 @@ enum printk_info_flags { - LOG_CONT = 8, /* text is a fragment of a continuation line */ - }; - -+extern bool block_console_kthreads; -+ - __printf(4, 0) - int vprintk_store(int facility, int level, - const struct dev_printk_info *dev_info, -diff -rupN linux-5.19.16.orig/kernel/printk/printk.c linux-5.19.16/kernel/printk/printk.c ---- linux-5.19.16.orig/kernel/printk/printk.c 2022-10-18 17:21:10.960499444 -0400 -+++ linux-5.19.16/kernel/printk/printk.c 2022-10-18 17:21:17.808446663 -0400 -@@ -44,6 +44,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -224,6 +225,36 @@ int devkmsg_sysctl_set_loglvl(struct ctl - static int nr_ext_console_drivers; - - /* -+ * Used to synchronize printing kthreads against direct printing via -+ * console_trylock/console_unlock. -+ * -+ * Values: -+ * -1 = console kthreads atomically blocked (via global trylock) -+ * 0 = no kthread printing, console not locked (via trylock) -+ * >0 = kthread(s) actively printing -+ * -+ * Note: For synchronizing against direct printing via -+ * console_lock/console_unlock, see the @lock variable in -+ * struct console. -+ */ -+static atomic_t console_kthreads_active = ATOMIC_INIT(0); -+ -+#define console_kthreads_atomic_tryblock() \ -+ (atomic_cmpxchg(&console_kthreads_active, 0, -1) == 0) -+#define console_kthreads_atomic_unblock() \ -+ atomic_cmpxchg(&console_kthreads_active, -1, 0) -+#define console_kthreads_atomically_blocked() \ -+ (atomic_read(&console_kthreads_active) == -1) -+ -+#define console_kthread_printing_tryenter() \ -+ atomic_inc_unless_negative(&console_kthreads_active) -+#define console_kthread_printing_exit() \ -+ atomic_dec(&console_kthreads_active) -+ -+/* Block console kthreads to avoid processing new messages. */ -+bool block_console_kthreads; -+ -+/* - * Helper macros to handle lockdep when locking/unlocking console_sem. We use - * macros instead of functions so that _RET_IP_ contains useful information. - */ -@@ -271,14 +302,49 @@ static bool panic_in_progress(void) - } - - /* -- * This is used for debugging the mess that is the VT code by -- * keeping track if we have the console semaphore held. It's -- * definitely not the perfect debug tool (we don't know if _WE_ -- * hold it and are racing, but it helps tracking those weird code -- * paths in the console code where we end up in places I want -- * locked without the console semaphore held). -+ * Tracks whether kthread printers are all blocked. A value of true implies -+ * that the console is locked via console_lock() or the console is suspended. -+ * Writing to this variable requires holding @console_sem. -+ */ -+static bool console_kthreads_blocked; -+ -+/* -+ * Block all kthread printers from a schedulable context. -+ * -+ * Requires holding @console_sem. - */ --static int console_locked, console_suspended; -+static void console_kthreads_block(void) -+{ -+ struct console *con; -+ -+ for_each_console(con) { -+ mutex_lock(&con->lock); -+ con->blocked = true; -+ mutex_unlock(&con->lock); -+ } -+ -+ console_kthreads_blocked = true; -+} -+ -+/* -+ * Unblock all kthread printers from a schedulable context. -+ * -+ * Requires holding @console_sem. -+ */ -+static void console_kthreads_unblock(void) -+{ -+ struct console *con; -+ -+ for_each_console(con) { -+ mutex_lock(&con->lock); -+ con->blocked = false; -+ mutex_unlock(&con->lock); -+ } -+ -+ console_kthreads_blocked = false; -+} -+ -+static int console_suspended; - - /* - * Array of consoles built from command line options (console=) -@@ -361,7 +427,75 @@ static int console_msg_format = MSG_FORM - /* syslog_lock protects syslog_* variables and write access to clear_seq. */ - static DEFINE_MUTEX(syslog_lock); - -+/* -+ * A flag to signify if printk_activate_kthreads() has already started the -+ * kthread printers. If true, any later registered consoles must start their -+ * own kthread directly. The flag is write protected by the console_lock. -+ */ -+static bool printk_kthreads_available; -+ - #ifdef CONFIG_PRINTK -+static atomic_t printk_prefer_direct = ATOMIC_INIT(0); -+ -+/** -+ * printk_prefer_direct_enter - cause printk() calls to attempt direct -+ * printing to all enabled consoles -+ * -+ * Since it is not possible to call into the console printing code from any -+ * context, there is no guarantee that direct printing will occur. -+ * -+ * This globally effects all printk() callers. -+ * -+ * Context: Any context. -+ */ -+void printk_prefer_direct_enter(void) -+{ -+ atomic_inc(&printk_prefer_direct); -+} -+ -+/** -+ * printk_prefer_direct_exit - restore printk() behavior -+ * -+ * Context: Any context. -+ */ -+void printk_prefer_direct_exit(void) -+{ -+ WARN_ON(atomic_dec_if_positive(&printk_prefer_direct) < 0); -+} -+ -+/* -+ * Calling printk() always wakes kthread printers so that they can -+ * flush the new message to their respective consoles. Also, if direct -+ * printing is allowed, printk() tries to flush the messages directly. -+ * -+ * Direct printing is allowed in situations when the kthreads -+ * are not available or the system is in a problematic state. -+ * -+ * See the implementation about possible races. -+ */ -+static inline bool allow_direct_printing(void) -+{ -+ /* -+ * Checking kthread availability is a possible race because the -+ * kthread printers can become permanently disabled during runtime. -+ * However, doing that requires holding the console_lock, so any -+ * pending messages will be direct printed by console_unlock(). -+ */ -+ if (!printk_kthreads_available) -+ return true; -+ -+ /* -+ * Prefer direct printing when the system is in a problematic state. -+ * The context that sets this state will always see the updated value. -+ * The other contexts do not care. Anyway, direct printing is just a -+ * best effort. The direct output is only possible when console_lock -+ * is not already taken and no kthread printers are actively printing. -+ */ -+ return (system_state > SYSTEM_RUNNING || -+ oops_in_progress || -+ atomic_read(&printk_prefer_direct)); -+} -+ - DECLARE_WAIT_QUEUE_HEAD(log_wait); - /* All 3 protected by @syslog_lock. */ - /* the next printk record to read by syslog(READ) or /proc/kmsg */ -@@ -1850,6 +1984,7 @@ static int console_lock_spinning_disable - return 1; - } - -+#if !IS_ENABLED(CONFIG_PREEMPT_RT) - /** - * console_trylock_spinning - try to get console_lock by busy waiting - * -@@ -1923,6 +2058,7 @@ static int console_trylock_spinning(void - - return 1; - } -+#endif /* CONFIG_PREEMPT_RT */ - - /* - * Call the specified console driver, asking it to write out the specified -@@ -1930,19 +2066,28 @@ static int console_trylock_spinning(void - * dropped, a dropped message will be written out first. - */ - static void call_console_driver(struct console *con, const char *text, size_t len, -- char *dropped_text) -+ char *dropped_text, bool atomic_printing) - { -+ unsigned long dropped = 0; - size_t dropped_len; - -- if (con->dropped && dropped_text) { -+ if (dropped_text) -+ dropped = atomic_long_xchg_relaxed(&con->dropped, 0); -+ -+ if (dropped) { - dropped_len = snprintf(dropped_text, DROPPED_TEXT_MAX, - "** %lu printk messages dropped **\n", -- con->dropped); -- con->dropped = 0; -- con->write(con, dropped_text, dropped_len); -+ dropped); -+ if (atomic_printing) -+ con->write_atomic(con, dropped_text, dropped_len); -+ else -+ con->write(con, dropped_text, dropped_len); - } - -- con->write(con, text, len); -+ if (atomic_printing) -+ con->write_atomic(con, text, len); -+ else -+ con->write(con, text, len); - } - - /* -@@ -2252,10 +2397,22 @@ asmlinkage int vprintk_emit(int facility - printed_len = vprintk_store(facility, level, dev_info, fmt, args); - - /* If called from the scheduler, we can not call up(). */ -- if (!in_sched) { -+ if (!in_sched && allow_direct_printing()) { -+#if IS_ENABLED(CONFIG_PREEMPT_RT) -+ /* -+ * Use the non-spinning trylock since PREEMPT_RT does not -+ * support console lock handovers. -+ * -+ * Direct printing will most likely involve taking spinlocks. -+ * For PREEMPT_RT, this is only allowed if in a preemptible -+ * context. -+ */ -+ if (preemptible() && console_trylock()) -+ console_unlock(); -+#else - /* - * The caller may be holding system-critical or -- * timing-sensitive locks. Disable preemption during -+ * timing-sensitive locks. Disable preemption during direct - * printing of all remaining records to all consoles so that - * this context can return as soon as possible. Hopefully - * another printk() caller will take over the printing. -@@ -2270,6 +2427,7 @@ asmlinkage int vprintk_emit(int facility - if (console_trylock_spinning()) - console_unlock(); - preempt_enable(); -+#endif - } - - wake_up_klogd(); -@@ -2296,8 +2454,80 @@ asmlinkage __visible int _printk(const c - } - EXPORT_SYMBOL(_printk); - -+#ifdef CONFIG_HAVE_ATOMIC_CONSOLE -+static void __free_atomic_data(struct console_atomic_data *d) -+{ -+ kfree(d->text); -+ kfree(d->ext_text); -+ kfree(d->dropped_text); -+} -+ -+static void free_atomic_data(struct console_atomic_data *d) -+{ -+ int count = 1; -+ int i; -+ -+ if (!d) -+ return; -+ -+#ifdef CONFIG_HAVE_NMI -+ count = 2; -+#endif -+ -+ for (i = 0; i < count; i++) -+ __free_atomic_data(&d[i]); -+ kfree(d); -+} -+ -+static int __alloc_atomic_data(struct console_atomic_data *d, short flags) -+{ -+ d->text = kmalloc(CONSOLE_LOG_MAX, GFP_KERNEL); -+ if (!d->text) -+ return -1; -+ -+ if (flags & CON_EXTENDED) { -+ d->ext_text = kmalloc(CONSOLE_EXT_LOG_MAX, GFP_KERNEL); -+ if (!d->ext_text) -+ return -1; -+ } else { -+ d->dropped_text = kmalloc(DROPPED_TEXT_MAX, GFP_KERNEL); -+ if (!d->dropped_text) -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static struct console_atomic_data *alloc_atomic_data(short flags) -+{ -+ struct console_atomic_data *d; -+ int count = 1; -+ int i; -+ -+#ifdef CONFIG_HAVE_NMI -+ count = 2; -+#endif -+ -+ d = kzalloc(sizeof(*d) * count, GFP_KERNEL); -+ if (!d) -+ goto err_out; -+ -+ for (i = 0; i < count; i++) { -+ if (__alloc_atomic_data(&d[i], flags) != 0) -+ goto err_out; -+ } -+ -+ return d; -+err_out: -+ free_atomic_data(d); -+ return NULL; -+} -+#endif /* CONFIG_HAVE_ATOMIC_CONSOLE */ -+ - static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progress); - -+static void printk_start_kthread(struct console *con); -+ - #else /* CONFIG_PRINTK */ - - #define CONSOLE_LOG_MAX 0 -@@ -2308,6 +2538,8 @@ static bool __pr_flush(struct console *c - #define prb_first_valid_seq(rb) 0 - #define prb_next_seq(rb) 0 - -+#define free_atomic_data(d) -+ - static u64 syslog_seq; - - static size_t record_print_text(const struct printk_record *r, -@@ -2326,11 +2558,13 @@ static ssize_t msg_print_ext_body(char * - static void console_lock_spinning_enable(void) { } - static int console_lock_spinning_disable_and_check(void) { return 0; } - static void call_console_driver(struct console *con, const char *text, size_t len, -- char *dropped_text) -+ char *dropped_text, bool atomic_printing) - { - } - static bool suppress_message_printing(int level) { return false; } - static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progress) { return true; } -+static void printk_start_kthread(struct console *con) { } -+static bool allow_direct_printing(void) { return true; } - - #endif /* CONFIG_PRINTK */ - -@@ -2549,6 +2783,14 @@ static int console_cpu_notify(unsigned i - /* If trylock fails, someone else is doing the printing */ - if (console_trylock()) - console_unlock(); -+ else { -+ /* -+ * If a new CPU comes online, the conditions for -+ * printer_should_wake() may have changed for some -+ * kthread printer with !CON_ANYTIME. -+ */ -+ wake_up_klogd(); -+ } - } - return 0; - } -@@ -2568,7 +2810,7 @@ void console_lock(void) - down_console_sem(); - if (console_suspended) - return; -- console_locked = 1; -+ console_kthreads_block(); - console_may_schedule = 1; - } - EXPORT_SYMBOL(console_lock); -@@ -2589,15 +2831,30 @@ int console_trylock(void) - up_console_sem(); - return 0; - } -- console_locked = 1; -+ if (!console_kthreads_atomic_tryblock()) { -+ up_console_sem(); -+ return 0; -+ } - console_may_schedule = 0; - return 1; - } - EXPORT_SYMBOL(console_trylock); - -+/* -+ * This is used to help to make sure that certain paths within the VT code are -+ * running with the console lock held. It is definitely not the perfect debug -+ * tool (it is not known if the VT code is the task holding the console lock), -+ * but it helps tracking those weird code paths in the console code such as -+ * when the console is suspended: where the console is not locked but no -+ * console printing may occur. -+ * -+ * Note: This returns true when the console is suspended but is not locked. -+ * This is intentional because the VT code must consider that situation -+ * the same as if the console was locked. -+ */ - int is_console_locked(void) - { -- return console_locked; -+ return (console_kthreads_blocked || atomic_read(&console_kthreads_active)); - } - EXPORT_SYMBOL(is_console_locked); - -@@ -2620,18 +2877,9 @@ static bool abandon_console_lock_in_pani - return atomic_read(&panic_cpu) != raw_smp_processor_id(); - } - --/* -- * Check if the given console is currently capable and allowed to print -- * records. -- * -- * Requires the console_lock. -- */ --static inline bool console_is_usable(struct console *con) -+static inline bool __console_is_usable(short flags) - { -- if (!(con->flags & CON_ENABLED)) -- return false; -- -- if (!con->write) -+ if (!(flags & CON_ENABLED)) - return false; - - /* -@@ -2640,18 +2888,116 @@ static inline bool console_is_usable(str - * cope (CON_ANYTIME) don't call them until this CPU is officially up. - */ - if (!cpu_online(raw_smp_processor_id()) && -- !(con->flags & CON_ANYTIME)) -+ !(flags & CON_ANYTIME)) - return false; - - return true; - } - -+/* -+ * Check if the given console is currently capable and allowed to print -+ * records. -+ * -+ * Requires holding the console_lock. -+ */ -+static inline bool console_is_usable(struct console *con, bool atomic_printing) -+{ -+ if (atomic_printing) { -+#ifdef CONFIG_HAVE_ATOMIC_CONSOLE -+ if (!con->write_atomic) -+ return false; -+ if (!con->atomic_data) -+ return false; -+#else -+ return false; -+#endif -+ } else if (!con->write) { -+ return false; -+ } -+ -+ return __console_is_usable(con->flags); -+} -+ - static void __console_unlock(void) - { -- console_locked = 0; -+ /* -+ * Depending on whether console_lock() or console_trylock() was used, -+ * appropriately allow the kthread printers to continue. -+ */ -+ if (console_kthreads_blocked) -+ console_kthreads_unblock(); -+ else -+ console_kthreads_atomic_unblock(); -+ -+ /* -+ * New records may have arrived while the console was locked. -+ * Wake the kthread printers to print them. -+ */ -+ wake_up_klogd(); -+ - up_console_sem(); - } - -+static u64 read_console_seq(struct console *con) -+{ -+#ifdef CONFIG_HAVE_ATOMIC_CONSOLE -+ unsigned long flags; -+ u64 seq2; -+ u64 seq; -+ -+ if (!con->atomic_data) -+ return con->seq; -+ -+ printk_cpu_sync_get_irqsave(flags); -+ -+ seq = con->seq; -+ seq2 = con->atomic_data[0].seq; -+ if (seq2 > seq) -+ seq = seq2; -+#ifdef CONFIG_HAVE_NMI -+ seq2 = con->atomic_data[1].seq; -+ if (seq2 > seq) -+ seq = seq2; -+#endif -+ -+ printk_cpu_sync_put_irqrestore(flags); -+ -+ return seq; -+#else /* CONFIG_HAVE_ATOMIC_CONSOLE */ -+ return con->seq; -+#endif -+} -+ -+static void write_console_seq(struct console *con, u64 val, bool atomic_printing) -+{ -+#ifdef CONFIG_HAVE_ATOMIC_CONSOLE -+ unsigned long flags; -+ u64 *seq; -+ -+ if (!con->atomic_data) { -+ con->seq = val; -+ return; -+ } -+ -+ printk_cpu_sync_get_irqsave(flags); -+ -+ if (atomic_printing) { -+ seq = &con->atomic_data[0].seq; -+#ifdef CONFIG_HAVE_NMI -+ if (in_nmi()) -+ seq = &con->atomic_data[1].seq; -+#endif -+ } else { -+ seq = &con->seq; -+ } -+ *seq = val; -+ -+ printk_cpu_sync_put_irqrestore(flags); -+#else /* CONFIG_HAVE_ATOMIC_CONSOLE */ -+ con->seq = val; -+#endif -+} -+ - /* - * Print one record for the given console. The record printed is whatever - * record is the next available record for the given console. -@@ -2664,36 +3010,47 @@ static void __console_unlock(void) - * If dropped messages should be printed, @dropped_text is a buffer of size - * DROPPED_TEXT_MAX. Otherwise @dropped_text must be NULL. - * -+ * @atomic_printing specifies if atomic printing should be used. -+ * - * @handover will be set to true if a printk waiter has taken over the - * console_lock, in which case the caller is no longer holding the -- * console_lock. Otherwise it is set to false. -+ * console_lock. Otherwise it is set to false. A NULL pointer may be provided -+ * to disable allowing the console_lock to be taken over by a printk waiter. - * - * Returns false if the given console has no next record to print, otherwise - * true. - * -- * Requires the console_lock. -+ * Requires the console_lock if @handover is non-NULL. -+ * Requires con->lock otherwise. - */ --static bool console_emit_next_record(struct console *con, char *text, char *ext_text, -- char *dropped_text, bool *handover) -+static bool __console_emit_next_record(struct console *con, char *text, char *ext_text, -+ char *dropped_text, bool atomic_printing, -+ bool *handover) - { -- static int panic_console_dropped; -+ static atomic_t panic_console_dropped = ATOMIC_INIT(0); - struct printk_info info; - struct printk_record r; - unsigned long flags; - char *write_text; - size_t len; -+ u64 seq; - - prb_rec_init_rd(&r, &info, text, CONSOLE_LOG_MAX); - -- *handover = false; -+ if (handover) -+ *handover = false; - -- if (!prb_read_valid(prb, con->seq, &r)) -+ seq = read_console_seq(con); -+ -+ if (!prb_read_valid(prb, seq, &r)) - return false; - -- if (con->seq != r.info->seq) { -- con->dropped += r.info->seq - con->seq; -- con->seq = r.info->seq; -- if (panic_in_progress() && panic_console_dropped++ > 10) { -+ if (seq != r.info->seq) { -+ atomic_long_add((unsigned long)(r.info->seq - seq), &con->dropped); -+ write_console_seq(con, r.info->seq, atomic_printing); -+ seq = r.info->seq; -+ if (panic_in_progress() && -+ atomic_fetch_inc_relaxed(&panic_console_dropped) > 10) { - suppress_panic_printk = 1; - pr_warn_once("Too many dropped messages. Suppress messages on non-panic CPUs to prevent livelock.\n"); - } -@@ -2701,7 +3058,7 @@ static bool console_emit_next_record(str - - /* Skip record that has level above the console loglevel. */ - if (suppress_message_printing(r.info->level)) { -- con->seq++; -+ write_console_seq(con, seq + 1, atomic_printing); - goto skip; - } - -@@ -2715,32 +3072,66 @@ static bool console_emit_next_record(str - len = record_print_text(&r, console_msg_format & MSG_FORMAT_SYSLOG, printk_time); - } - -- /* -- * While actively printing out messages, if another printk() -- * were to occur on another CPU, it may wait for this one to -- * finish. This task can not be preempted if there is a -- * waiter waiting to take over. -- * -- * Interrupts are disabled because the hand over to a waiter -- * must not be interrupted until the hand over is completed -- * (@console_waiter is cleared). -- */ -- printk_safe_enter_irqsave(flags); -- console_lock_spinning_enable(); -+ if (handover) { -+ /* -+ * While actively printing out messages, if another printk() -+ * were to occur on another CPU, it may wait for this one to -+ * finish. This task can not be preempted if there is a -+ * waiter waiting to take over. -+ * -+ * Interrupts are disabled because the hand over to a waiter -+ * must not be interrupted until the hand over is completed -+ * (@console_waiter is cleared). -+ */ -+ printk_safe_enter_irqsave(flags); -+ console_lock_spinning_enable(); - -- stop_critical_timings(); /* don't trace print latency */ -- call_console_driver(con, write_text, len, dropped_text); -- start_critical_timings(); -+ /* don't trace irqsoff print latency */ -+ stop_critical_timings(); -+ } - -- con->seq++; -+ call_console_driver(con, write_text, len, dropped_text, atomic_printing); - -- *handover = console_lock_spinning_disable_and_check(); -- printk_safe_exit_irqrestore(flags); -+ write_console_seq(con, seq + 1, atomic_printing); -+ -+ if (handover) { -+ start_critical_timings(); -+ *handover = console_lock_spinning_disable_and_check(); -+ printk_safe_exit_irqrestore(flags); -+ } - skip: - return true; - } - - /* -+ * Print a record for a given console, but allow another printk() caller to -+ * take over the console_lock and continue printing. -+ * -+ * Requires the console_lock, but depending on @handover after the call, the -+ * caller may no longer have the console_lock. -+ * -+ * See __console_emit_next_record() for argument and return details. -+ */ -+static bool console_emit_next_record_transferable(struct console *con, char *text, char *ext_text, -+ char *dropped_text, bool *handover) -+{ -+ /* -+ * Handovers are only supported if threaded printers are atomically -+ * blocked. The context taking over the console_lock may be atomic. -+ * -+ * PREEMPT_RT also does not support handovers because the spinning -+ * waiter can cause large latencies. -+ */ -+ if (!console_kthreads_atomically_blocked() || -+ IS_ENABLED(CONFIG_PREEMPT_RT)) { -+ *handover = false; -+ handover = NULL; -+ } -+ -+ return __console_emit_next_record(con, text, ext_text, dropped_text, false, handover); -+} -+ -+/* - * Print out all remaining records to all consoles. - * - * @do_cond_resched is set by the caller. It can be true only in schedulable -@@ -2758,8 +3149,8 @@ skip: - * were flushed to all usable consoles. A returned false informs the caller - * that everything was not flushed (either there were no usable consoles or - * another context has taken over printing or it is a panic situation and this -- * is not the panic CPU). Regardless the reason, the caller should assume it -- * is not useful to immediately try again. -+ * is not the panic CPU or direct printing is not preferred). Regardless the -+ * reason, the caller should assume it is not useful to immediately try again. - * - * Requires the console_lock. - */ -@@ -2776,24 +3167,26 @@ static bool console_flush_all(bool do_co - *handover = false; - - do { -+ /* Let the kthread printers do the work if they can. */ -+ if (!allow_direct_printing()) -+ return false; -+ - any_progress = false; - - for_each_console(con) { - bool progress; - -- if (!console_is_usable(con)) -+ if (!console_is_usable(con, false)) - continue; - any_usable = true; - - if (con->flags & CON_EXTENDED) { - /* Extended consoles do not print "dropped messages". */ -- progress = console_emit_next_record(con, &text[0], -- &ext_text[0], NULL, -- handover); -+ progress = console_emit_next_record_transferable(con, &text[0], -+ &ext_text[0], NULL, handover); - } else { -- progress = console_emit_next_record(con, &text[0], -- NULL, &dropped_text[0], -- handover); -+ progress = console_emit_next_record_transferable(con, &text[0], -+ NULL, &dropped_text[0], handover); - } - if (*handover) - return false; -@@ -2818,6 +3211,68 @@ static bool console_flush_all(bool do_co - return any_usable; - } - -+#if defined(CONFIG_HAVE_ATOMIC_CONSOLE) && defined(CONFIG_PRINTK) -+static bool console_emit_next_record(struct console *con, char *text, char *ext_text, -+ char *dropped_text, bool atomic_printing); -+ -+static void atomic_console_flush_all(void) -+{ -+ unsigned long flags; -+ struct console *con; -+ bool any_progress; -+ int index = 0; -+ -+ if (console_suspended) -+ return; -+ -+#ifdef CONFIG_HAVE_NMI -+ if (in_nmi()) -+ index = 1; -+#endif -+ -+ printk_cpu_sync_get_irqsave(flags); -+ -+ do { -+ any_progress = false; -+ -+ for_each_console(con) { -+ bool progress; -+ -+ if (!console_is_usable(con, true)) -+ continue; -+ -+ if (con->flags & CON_EXTENDED) { -+ /* Extended consoles do not print "dropped messages". */ -+ progress = console_emit_next_record(con, -+ &con->atomic_data->text[index], -+ &con->atomic_data->ext_text[index], -+ NULL, -+ true); -+ } else { -+ progress = console_emit_next_record(con, -+ &con->atomic_data->text[index], -+ NULL, -+ &con->atomic_data->dropped_text[index], -+ true); -+ } -+ -+ if (!progress) -+ continue; -+ any_progress = true; -+ -+ touch_softlockup_watchdog_sync(); -+ clocksource_touch_watchdog(); -+ rcu_cpu_stall_reset(); -+ touch_nmi_watchdog(); -+ } -+ } while (any_progress); -+ -+ printk_cpu_sync_put_irqrestore(flags); -+} -+#else /* CONFIG_HAVE_ATOMIC_CONSOLE && CONFIG_PRINTK */ -+#define atomic_console_flush_all() -+#endif -+ - /** - * console_unlock - unlock the console system - * -@@ -2908,10 +3363,13 @@ void console_unblank(void) - if (oops_in_progress) { - if (down_trylock_console_sem() != 0) - return; -+ if (!console_kthreads_atomic_tryblock()) { -+ up_console_sem(); -+ return; -+ } - } else - console_lock(); - -- console_locked = 1; - console_may_schedule = 0; - for_each_console(c) - if ((c->flags & CON_ENABLED) && c->unblank) -@@ -2930,6 +3388,11 @@ void console_unblank(void) - */ - void console_flush_on_panic(enum con_flush_mode mode) - { -+ if (mode == CONSOLE_ATOMIC_FLUSH_PENDING) { -+ atomic_console_flush_all(); -+ return; -+ } -+ - /* - * If someone else is holding the console lock, trylock will fail - * and may_schedule may be set. Ignore and proceed to unlock so -@@ -2946,7 +3409,7 @@ void console_flush_on_panic(enum con_flu - - seq = prb_first_valid_seq(prb); - for_each_console(c) -- c->seq = seq; -+ write_console_seq(c, seq, false); - } - console_unlock(); - } -@@ -3189,16 +3652,27 @@ void register_console(struct console *ne - if (newcon->flags & CON_EXTENDED) - nr_ext_console_drivers++; - -- newcon->dropped = 0; -+ atomic_long_set(&newcon->dropped, 0); -+ newcon->thread = NULL; -+ newcon->blocked = true; -+ mutex_init(&newcon->lock); -+#ifdef CONFIG_HAVE_ATOMIC_CONSOLE -+ newcon->atomic_data = NULL; -+#endif -+ - if (newcon->flags & CON_PRINTBUFFER) { - /* Get a consistent copy of @syslog_seq. */ - mutex_lock(&syslog_lock); -- newcon->seq = syslog_seq; -+ write_console_seq(newcon, syslog_seq, false); - mutex_unlock(&syslog_lock); - } else { - /* Begin with next message. */ -- newcon->seq = prb_next_seq(prb); -+ write_console_seq(newcon, prb_next_seq(prb), false); - } -+ -+ if (printk_kthreads_available) -+ printk_start_kthread(newcon); -+ - console_unlock(); - console_sysfs_notify(); - -@@ -3225,6 +3699,7 @@ EXPORT_SYMBOL(register_console); - - int unregister_console(struct console *console) - { -+ struct task_struct *thd; - struct console *con; - int res; - -@@ -3265,9 +3740,26 @@ int unregister_console(struct console *c - console_drivers->flags |= CON_CONSDEV; - - console->flags &= ~CON_ENABLED; -+ -+ /* -+ * console->thread can only be cleared under the console lock. But -+ * stopping the thread must be done without the console lock. The -+ * task that clears @thread is the task that stops the kthread. -+ */ -+ thd = console->thread; -+ console->thread = NULL; -+ - console_unlock(); -+ -+ if (thd) -+ kthread_stop(thd); -+ - console_sysfs_notify(); - -+#ifdef CONFIG_HAVE_ATOMIC_CONSOLE -+ free_atomic_data(console->atomic_data); -+#endif -+ - if (console->exit) - res = console->exit(console); - -@@ -3361,6 +3853,20 @@ static int __init printk_late_init(void) - } - late_initcall(printk_late_init); - -+static int __init printk_activate_kthreads(void) -+{ -+ struct console *con; -+ -+ console_lock(); -+ printk_kthreads_available = true; -+ for_each_console(con) -+ printk_start_kthread(con); -+ console_unlock(); -+ -+ return 0; -+} -+early_initcall(printk_activate_kthreads); -+ - #if defined CONFIG_PRINTK - /* If @con is specified, only wait for that console. Otherwise wait for all. */ - static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progress) -@@ -3384,7 +3890,7 @@ static bool __pr_flush(struct console *c - for_each_console(c) { - if (con && con != c) - continue; -- if (!console_is_usable(c)) -+ if (!console_is_usable(c, false)) - continue; - printk_seq = c->seq; - if (printk_seq < seq) -@@ -3444,11 +3950,215 @@ bool pr_flush(int timeout_ms, bool reset - } - EXPORT_SYMBOL(pr_flush); - -+static void __printk_fallback_preferred_direct(void) -+{ -+ printk_prefer_direct_enter(); -+ pr_err("falling back to preferred direct printing\n"); -+ printk_kthreads_available = false; -+} -+ -+/* -+ * Enter preferred direct printing, but never exit. Mark console threads as -+ * unavailable. The system is then forever in preferred direct printing and -+ * any printing threads will exit. -+ * -+ * Must *not* be called under console_lock. Use -+ * __printk_fallback_preferred_direct() if already holding console_lock. -+ */ -+static void printk_fallback_preferred_direct(void) -+{ -+ console_lock(); -+ __printk_fallback_preferred_direct(); -+ console_unlock(); -+} -+ -+/* -+ * Print a record for a given console, not allowing another printk() caller -+ * to take over. This is appropriate for contexts that do not have the -+ * console_lock. -+ * -+ * See __console_emit_next_record() for argument and return details. -+ */ -+static bool console_emit_next_record(struct console *con, char *text, char *ext_text, -+ char *dropped_text, bool atomic_printing) -+{ -+ return __console_emit_next_record(con, text, ext_text, dropped_text, -+ atomic_printing, NULL); -+} -+ -+static bool printer_should_wake(struct console *con, u64 seq) -+{ -+ short flags; -+ -+ if (kthread_should_stop() || !printk_kthreads_available) -+ return true; -+ -+ if (con->blocked || -+ console_kthreads_atomically_blocked() || -+ block_console_kthreads || -+ system_state > SYSTEM_RUNNING || -+ oops_in_progress) { -+ return false; -+ } -+ -+ /* -+ * This is an unsafe read from con->flags, but a false positive is -+ * not a problem. Worst case it would allow the printer to wake up -+ * although it is disabled. But the printer will notice that when -+ * attempting to print and instead go back to sleep. -+ */ -+ flags = data_race(READ_ONCE(con->flags)); -+ -+ if (!__console_is_usable(flags)) -+ return false; -+ -+ return prb_read_valid(prb, seq, NULL); -+} -+ -+static int printk_kthread_func(void *data) -+{ -+ struct console *con = data; -+ char *dropped_text = NULL; -+ char *ext_text = NULL; -+ u64 seq = 0; -+ char *text; -+ int error; -+ -+#ifdef CONFIG_HAVE_ATOMIC_CONSOLE -+ if (con->write_atomic) -+ con->atomic_data = alloc_atomic_data(con->flags); -+#endif -+ -+ text = kmalloc(CONSOLE_LOG_MAX, GFP_KERNEL); -+ if (!text) { -+ con_printk(KERN_ERR, con, "failed to allocate text buffer\n"); -+ printk_fallback_preferred_direct(); -+ goto out; -+ } -+ -+ if (con->flags & CON_EXTENDED) { -+ ext_text = kmalloc(CONSOLE_EXT_LOG_MAX, GFP_KERNEL); -+ if (!ext_text) { -+ con_printk(KERN_ERR, con, "failed to allocate ext_text buffer\n"); -+ printk_fallback_preferred_direct(); -+ goto out; -+ } -+ } else { -+ dropped_text = kmalloc(DROPPED_TEXT_MAX, GFP_KERNEL); -+ if (!dropped_text) { -+ con_printk(KERN_ERR, con, "failed to allocate dropped_text buffer\n"); -+ printk_fallback_preferred_direct(); -+ goto out; -+ } -+ } -+ -+ con_printk(KERN_INFO, con, "printing thread started\n"); -+ -+ for (;;) { -+ /* -+ * Guarantee this task is visible on the waitqueue before -+ * checking the wake condition. -+ * -+ * The full memory barrier within set_current_state() of -+ * prepare_to_wait_event() pairs with the full memory barrier -+ * within wq_has_sleeper(). -+ * -+ * This pairs with __wake_up_klogd:A. -+ */ -+ error = wait_event_interruptible(log_wait, -+ printer_should_wake(con, seq)); /* LMM(printk_kthread_func:A) */ -+ -+ if (kthread_should_stop() || !printk_kthreads_available) -+ break; -+ -+ if (error) -+ continue; -+ -+ error = mutex_lock_interruptible(&con->lock); -+ if (error) -+ continue; -+ -+ if (con->blocked || -+ !console_kthread_printing_tryenter()) { -+ /* Another context has locked the console_lock. */ -+ mutex_unlock(&con->lock); -+ continue; -+ } -+ -+ /* -+ * Although this context has not locked the console_lock, it -+ * is known that the console_lock is not locked and it is not -+ * possible for any other context to lock the console_lock. -+ * Therefore it is safe to read con->flags. -+ */ -+ -+ if (!__console_is_usable(con->flags)) { -+ console_kthread_printing_exit(); -+ mutex_unlock(&con->lock); -+ continue; -+ } -+ -+ /* -+ * Even though the printk kthread is always preemptible, it is -+ * still not allowed to call cond_resched() from within -+ * console drivers. The task may become non-preemptible in the -+ * console driver call chain. For example, vt_console_print() -+ * takes a spinlock and then can call into fbcon_redraw(), -+ * which can conditionally invoke cond_resched(). -+ */ -+ console_may_schedule = 0; -+ console_emit_next_record(con, text, ext_text, dropped_text, false); -+ -+ seq = con->seq; -+ -+ console_kthread_printing_exit(); -+ -+ mutex_unlock(&con->lock); -+ } -+ -+ con_printk(KERN_INFO, con, "printing thread stopped\n"); -+out: -+ kfree(dropped_text); -+ kfree(ext_text); -+ kfree(text); -+ -+ console_lock(); -+ /* -+ * If this kthread is being stopped by another task, con->thread will -+ * already be NULL. That is fine. The important thing is that it is -+ * NULL after the kthread exits. -+ */ -+ con->thread = NULL; -+ console_unlock(); -+ -+ return 0; -+} -+ -+/* Must be called under console_lock. */ -+static void printk_start_kthread(struct console *con) -+{ -+ /* -+ * Do not start a kthread if there is no write() callback. The -+ * kthreads assume the write() callback exists. -+ */ -+ if (!con->write) -+ return; -+ -+ con->thread = kthread_run(printk_kthread_func, con, -+ "pr/%s%d", con->name, con->index); -+ if (IS_ERR(con->thread)) { -+ con->thread = NULL; -+ con_printk(KERN_ERR, con, "unable to start printing thread\n"); -+ __printk_fallback_preferred_direct(); -+ return; -+ } -+} -+ - /* - * Delayed printk version, for scheduler-internal messages: - */ --#define PRINTK_PENDING_WAKEUP 0x01 --#define PRINTK_PENDING_OUTPUT 0x02 -+#define PRINTK_PENDING_WAKEUP 0x01 -+#define PRINTK_PENDING_DIRECT_OUTPUT 0x02 - - static DEFINE_PER_CPU(int, printk_pending); - -@@ -3456,10 +4166,14 @@ static void wake_up_klogd_work_func(stru - { - int pending = this_cpu_xchg(printk_pending, 0); - -- if (pending & PRINTK_PENDING_OUTPUT) { -+ if (pending & PRINTK_PENDING_DIRECT_OUTPUT) { -+ printk_prefer_direct_enter(); -+ - /* If trylock fails, someone else is doing the printing */ - if (console_trylock()) - console_unlock(); -+ -+ printk_prefer_direct_exit(); - } - - if (pending & PRINTK_PENDING_WAKEUP) -@@ -3484,10 +4198,11 @@ static void __wake_up_klogd(int val) - * prepare_to_wait_event(), which is called after ___wait_event() adds - * the waiter but before it has checked the wait condition. - * -- * This pairs with devkmsg_read:A and syslog_print:A. -+ * This pairs with devkmsg_read:A, syslog_print:A, and -+ * printk_kthread_func:A. - */ - if (wq_has_sleeper(&log_wait) || /* LMM(__wake_up_klogd:A) */ -- (val & PRINTK_PENDING_OUTPUT)) { -+ (val & PRINTK_PENDING_DIRECT_OUTPUT)) { - this_cpu_or(printk_pending, val); - irq_work_queue(this_cpu_ptr(&wake_up_klogd_work)); - } -@@ -3505,7 +4220,17 @@ void defer_console_output(void) - * New messages may have been added directly to the ringbuffer - * using vprintk_store(), so wake any waiters as well. - */ -- __wake_up_klogd(PRINTK_PENDING_WAKEUP | PRINTK_PENDING_OUTPUT); -+ int val = PRINTK_PENDING_WAKEUP; -+ -+ /* -+ * Make sure that some context will print the messages when direct -+ * printing is allowed. This happens in situations when the kthreads -+ * may not be as reliable or perhaps unusable. -+ */ -+ if (allow_direct_printing()) -+ val |= PRINTK_PENDING_DIRECT_OUTPUT; -+ -+ __wake_up_klogd(val); - } - - void printk_trigger_flush(void) -diff -rupN linux-5.19.16.orig/kernel/printk/printk_safe.c linux-5.19.16/kernel/printk/printk_safe.c ---- linux-5.19.16.orig/kernel/printk/printk_safe.c 2022-10-18 17:21:10.960499444 -0400 -+++ linux-5.19.16/kernel/printk/printk_safe.c 2022-10-18 17:21:17.808446663 -0400 -@@ -8,7 +8,9 @@ - #include - #include - #include -+#include - #include -+#include - - #include "internal.h" - -@@ -50,3 +52,33 @@ asmlinkage int vprintk(const char *fmt, - return vprintk_default(fmt, args); - } - EXPORT_SYMBOL(vprintk); -+ -+/** -+ * try_block_console_kthreads() - Try to block console kthreads and -+ * make the global console_lock() avaialble -+ * -+ * @timeout_ms: The maximum time (in ms) to wait. -+ * -+ * Prevent console kthreads from starting processing new messages. Wait -+ * until the global console_lock() become available. -+ * -+ * Context: Can be called in any context. -+ */ -+void try_block_console_kthreads(int timeout_ms) -+{ -+ block_console_kthreads = true; -+ -+ /* Do not wait when the console lock could not be safely taken. */ -+ if (this_cpu_read(printk_context) || in_nmi()) -+ return; -+ -+ while (timeout_ms > 0) { -+ if (console_trylock()) { -+ console_unlock(); -+ return; -+ } -+ -+ udelay(1000); -+ timeout_ms -= 1; -+ } -+} -diff -rupN linux-5.19.16.orig/kernel/rcu/rcutorture.c linux-5.19.16/kernel/rcu/rcutorture.c ---- linux-5.19.16.orig/kernel/rcu/rcutorture.c 2022-10-18 17:21:10.960499444 -0400 -+++ linux-5.19.16/kernel/rcu/rcutorture.c 2022-10-18 17:22:27.075909103 -0400 -@@ -2086,6 +2086,12 @@ static int rcutorture_booster_init(unsig - WARN_ON_ONCE(!t); - sp.sched_priority = 2; - sched_setscheduler_nocheck(t, SCHED_FIFO, &sp); -+#ifdef CONFIG_PREEMPT_RT -+ t = per_cpu(timersd, cpu); -+ WARN_ON_ONCE(!t); -+ sp.sched_priority = 2; -+ sched_setscheduler_nocheck(t, SCHED_FIFO, &sp); -+#endif - } - - /* Don't allow time recalculation while creating a new task. */ -Binary files linux-5.19.16.orig/kernel/rcu/.rcutorture.c.rej.swp and linux-5.19.16/kernel/rcu/.rcutorture.c.rej.swp differ -diff -rupN linux-5.19.16.orig/kernel/rcu/tree_stall.h linux-5.19.16/kernel/rcu/tree_stall.h ---- linux-5.19.16.orig/kernel/rcu/tree_stall.h 2022-10-18 17:21:10.960499444 -0400 -+++ linux-5.19.16/kernel/rcu/tree_stall.h 2022-10-18 17:21:17.808446663 -0400 -@@ -647,6 +647,7 @@ static void print_cpu_stall(unsigned lon - * See Documentation/RCU/stallwarn.rst for info on how to debug - * RCU CPU stall warnings. - */ -+ printk_prefer_direct_enter(); - trace_rcu_stall_warning(rcu_state.name, TPS("SelfDetected")); - pr_err("INFO: %s self-detected stall on CPU\n", rcu_state.name); - raw_spin_lock_irqsave_rcu_node(rdp->mynode, flags); -@@ -684,6 +685,7 @@ static void print_cpu_stall(unsigned lon - */ - set_tsk_need_resched(current); - set_preempt_need_resched(); -+ printk_prefer_direct_exit(); - } - - static void check_cpu_stall(struct rcu_data *rdp) -diff -rupN linux-5.19.16.orig/kernel/reboot.c linux-5.19.16/kernel/reboot.c ---- linux-5.19.16.orig/kernel/reboot.c 2022-10-18 17:21:10.952499506 -0400 -+++ linux-5.19.16/kernel/reboot.c 2022-10-18 17:21:17.808446663 -0400 -@@ -82,6 +82,7 @@ void kernel_restart_prepare(char *cmd) - { - blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); - system_state = SYSTEM_RESTART; -+ try_block_console_kthreads(10000); - usermodehelper_disable(); - device_shutdown(); - } -@@ -270,6 +271,7 @@ static void kernel_shutdown_prepare(enum - blocking_notifier_call_chain(&reboot_notifier_list, - (state == SYSTEM_HALT) ? SYS_HALT : SYS_POWER_OFF, NULL); - system_state = state; -+ try_block_console_kthreads(10000); - usermodehelper_disable(); - device_shutdown(); - } -@@ -819,9 +821,11 @@ static int __orderly_reboot(void) - ret = run_cmd(reboot_cmd); - - if (ret) { -+ printk_prefer_direct_enter(); - pr_warn("Failed to start orderly reboot: forcing the issue\n"); - emergency_sync(); - kernel_restart(NULL); -+ printk_prefer_direct_exit(); - } - - return ret; -@@ -834,6 +838,7 @@ static int __orderly_poweroff(bool force - ret = run_cmd(poweroff_cmd); - - if (ret && force) { -+ printk_prefer_direct_enter(); - pr_warn("Failed to start orderly shutdown: forcing the issue\n"); - - /* -@@ -843,6 +848,7 @@ static int __orderly_poweroff(bool force - */ - emergency_sync(); - kernel_power_off(); -+ printk_prefer_direct_exit(); - } - - return ret; -@@ -900,6 +906,8 @@ EXPORT_SYMBOL_GPL(orderly_reboot); - */ - static void hw_failure_emergency_poweroff_func(struct work_struct *work) - { -+ printk_prefer_direct_enter(); -+ - /* - * We have reached here after the emergency shutdown waiting period has - * expired. This means orderly_poweroff has not been able to shut off -@@ -916,6 +924,8 @@ static void hw_failure_emergency_powerof - */ - pr_emerg("Hardware protection shutdown failed. Trying emergency restart\n"); - emergency_restart(); -+ -+ printk_prefer_direct_exit(); - } - - static DECLARE_DELAYED_WORK(hw_failure_emergency_poweroff_work, -@@ -954,11 +964,13 @@ void hw_protection_shutdown(const char * - { - static atomic_t allow_proceed = ATOMIC_INIT(1); - -+ printk_prefer_direct_enter(); -+ - pr_emerg("HARDWARE PROTECTION shutdown (%s)\n", reason); - - /* Shutdown should be initiated only once. */ - if (!atomic_dec_and_test(&allow_proceed)) -- return; -+ goto out; - - /* - * Queue a backup emergency shutdown in the event of -@@ -966,6 +978,8 @@ void hw_protection_shutdown(const char * - */ - hw_failure_emergency_poweroff(ms_until_forced); - orderly_poweroff(true); -+out: -+ printk_prefer_direct_exit(); - } - EXPORT_SYMBOL_GPL(hw_protection_shutdown); - -diff -rupN linux-5.19.16.orig/kernel/sched/core.c linux-5.19.16/kernel/sched/core.c ---- linux-5.19.16.orig/kernel/sched/core.c 2022-10-18 17:21:10.964499413 -0400 -+++ linux-5.19.16/kernel/sched/core.c 2022-10-18 17:21:17.808446663 -0400 -@@ -1052,6 +1052,46 @@ void resched_curr(struct rq *rq) - trace_sched_wake_idle_without_ipi(cpu); - } - -+#ifdef CONFIG_PREEMPT_LAZY -+ -+static int tsk_is_polling(struct task_struct *p) -+{ -+#ifdef TIF_POLLING_NRFLAG -+ return test_tsk_thread_flag(p, TIF_POLLING_NRFLAG); -+#else -+ return 0; -+#endif -+} -+ -+void resched_curr_lazy(struct rq *rq) -+{ -+ struct task_struct *curr = rq->curr; -+ int cpu; -+ -+ if (!sched_feat(PREEMPT_LAZY)) { -+ resched_curr(rq); -+ return; -+ } -+ -+ if (test_tsk_need_resched(curr)) -+ return; -+ -+ if (test_tsk_need_resched_lazy(curr)) -+ return; -+ -+ set_tsk_need_resched_lazy(curr); -+ -+ cpu = cpu_of(rq); -+ if (cpu == smp_processor_id()) -+ return; -+ -+ /* NEED_RESCHED_LAZY must be visible before we test polling */ -+ smp_mb(); -+ if (!tsk_is_polling(curr)) -+ smp_send_reschedule(cpu); -+} -+#endif -+ - void resched_cpu(int cpu) - { - struct rq *rq = cpu_rq(cpu); -@@ -2233,6 +2273,7 @@ void migrate_disable(void) - preempt_disable(); - this_rq()->nr_pinned++; - p->migration_disabled = 1; -+ preempt_lazy_disable(); - preempt_enable(); - } - EXPORT_SYMBOL_GPL(migrate_disable); -@@ -2264,6 +2305,7 @@ void migrate_enable(void) - barrier(); - p->migration_disabled = 0; - this_rq()->nr_pinned--; -+ preempt_lazy_enable(); - preempt_enable(); - } - EXPORT_SYMBOL_GPL(migrate_enable); -@@ -3257,6 +3299,70 @@ out: - } - #endif /* CONFIG_NUMA_BALANCING */ - -+#ifdef CONFIG_PREEMPT_RT -+ -+/* -+ * Consider: -+ * -+ * set_special_state(X); -+ * -+ * do_things() -+ * // Somewhere in there is an rtlock that can be contended: -+ * current_save_and_set_rtlock_wait_state(); -+ * [...] -+ * schedule_rtlock(); (A) -+ * [...] -+ * current_restore_rtlock_saved_state(); -+ * -+ * schedule(); (B) -+ * -+ * If p->saved_state is anything else than TASK_RUNNING, then p blocked on an -+ * rtlock (A) *before* voluntarily calling into schedule() (B) after setting its -+ * state to X. For things like ptrace (X=TASK_TRACED), the task could have more -+ * work to do upon acquiring the lock in do_things() before whoever called -+ * wait_task_inactive() should return. IOW, we have to wait for: -+ * -+ * p.saved_state = TASK_RUNNING -+ * p.__state = X -+ * -+ * which implies the task isn't blocked on an RT lock and got to schedule() (B). -+ * -+ * Also see comments in ttwu_state_match(). -+ */ -+ -+static __always_inline bool state_mismatch(struct task_struct *p, unsigned int match_state) -+{ -+ unsigned long flags; -+ bool mismatch; -+ -+ raw_spin_lock_irqsave(&p->pi_lock, flags); -+ mismatch = READ_ONCE(p->__state) != match_state && -+ READ_ONCE(p->saved_state) != match_state; -+ raw_spin_unlock_irqrestore(&p->pi_lock, flags); -+ return mismatch; -+} -+static __always_inline bool state_match(struct task_struct *p, unsigned int match_state, -+ bool *wait) -+{ -+ if (READ_ONCE(p->__state) == match_state) -+ return true; -+ if (READ_ONCE(p->saved_state) != match_state) -+ return false; -+ *wait = true; -+ return true; -+} -+#else -+static __always_inline bool state_mismatch(struct task_struct *p, unsigned int match_state) -+{ -+ return READ_ONCE(p->__state) != match_state; -+} -+static __always_inline bool state_match(struct task_struct *p, unsigned int match_state, -+ bool *wait) -+{ -+ return READ_ONCE(p->__state) == match_state; -+} -+#endif -+ - /* - * wait_task_inactive - wait for a thread to unschedule. - * -@@ -3275,7 +3381,7 @@ out: - */ - unsigned long wait_task_inactive(struct task_struct *p, unsigned int match_state) - { -- int running, queued; -+ bool running, wait; - struct rq_flags rf; - unsigned long ncsw; - struct rq *rq; -@@ -3301,7 +3407,7 @@ unsigned long wait_task_inactive(struct - * is actually now running somewhere else! - */ - while (task_running(rq, p)) { -- if (match_state && unlikely(READ_ONCE(p->__state) != match_state)) -+ if (match_state && state_mismatch(p, match_state)) - return 0; - cpu_relax(); - } -@@ -3314,10 +3420,12 @@ unsigned long wait_task_inactive(struct - rq = task_rq_lock(p, &rf); - trace_sched_wait_task(p); - running = task_running(rq, p); -- queued = task_on_rq_queued(p); -+ wait = task_on_rq_queued(p); - ncsw = 0; -- if (!match_state || READ_ONCE(p->__state) == match_state) -+ -+ if (!match_state || state_match(p, match_state, &wait)) - ncsw = p->nvcsw | LONG_MIN; /* sets MSB */ -+ - task_rq_unlock(rq, p, &rf); - - /* -@@ -3346,7 +3454,7 @@ unsigned long wait_task_inactive(struct - * running right now), it's preempted, and we should - * yield - it could be a while. - */ -- if (unlikely(queued)) { -+ if (unlikely(wait)) { - ktime_t to = NSEC_PER_SEC / HZ; - - set_current_state(TASK_UNINTERRUPTIBLE); -@@ -4563,6 +4671,9 @@ int sched_fork(unsigned long clone_flags - p->on_cpu = 0; - #endif - init_task_preempt_count(p); -+#ifdef CONFIG_HAVE_PREEMPT_LAZY -+ task_thread_info(p)->preempt_lazy_count = 0; -+#endif - #ifdef CONFIG_SMP - plist_node_init(&p->pushable_tasks, MAX_PRIO); - RB_CLEAR_NODE(&p->pushable_dl_tasks); -@@ -6431,6 +6542,7 @@ static void __sched notrace __schedule(u - - next = pick_next_task(rq, prev, &rf); - clear_tsk_need_resched(prev); -+ clear_tsk_need_resched_lazy(prev); - clear_preempt_need_resched(); - #ifdef CONFIG_SCHED_DEBUG - rq->last_seen_need_resched_ns = 0; -@@ -6645,6 +6757,30 @@ static void __sched notrace preempt_sche - } while (need_resched()); - } - -+#ifdef CONFIG_PREEMPT_LAZY -+/* -+ * If TIF_NEED_RESCHED is then we allow to be scheduled away since this is -+ * set by a RT task. Oterwise we try to avoid beeing scheduled out as long as -+ * preempt_lazy_count counter >0. -+ */ -+static __always_inline int preemptible_lazy(void) -+{ -+ if (test_thread_flag(TIF_NEED_RESCHED)) -+ return 1; -+ if (current_thread_info()->preempt_lazy_count) -+ return 0; -+ return 1; -+} -+ -+#else -+ -+static inline int preemptible_lazy(void) -+{ -+ return 1; -+} -+ -+#endif -+ - #ifdef CONFIG_PREEMPTION - /* - * This is the entry point to schedule() from in-kernel preemption -@@ -6658,6 +6794,8 @@ asmlinkage __visible void __sched notrac - */ - if (likely(!preemptible())) - return; -+ if (!preemptible_lazy()) -+ return; - preempt_schedule_common(); - } - NOKPROBE_SYMBOL(preempt_schedule); -@@ -6705,6 +6843,9 @@ asmlinkage __visible void __sched notrac - if (likely(!preemptible())) - return; - -+ if (!preemptible_lazy()) -+ return; -+ - do { - /* - * Because the function tracer can trace preempt_count_sub() -@@ -8961,7 +9102,9 @@ void __init init_idle(struct task_struct - - /* Set the preempt count _outside_ the spinlocks! */ - init_idle_preempt_count(idle, cpu); -- -+#ifdef CONFIG_HAVE_PREEMPT_LAZY -+ task_thread_info(idle)->preempt_lazy_count = 0; -+#endif - /* - * The idle tasks have their own, simple scheduling class: - */ -diff -rupN linux-5.19.16.orig/kernel/sched/fair.c linux-5.19.16/kernel/sched/fair.c ---- linux-5.19.16.orig/kernel/sched/fair.c 2022-10-18 17:21:10.964499413 -0400 -+++ linux-5.19.16/kernel/sched/fair.c 2022-10-18 17:21:17.812446632 -0400 -@@ -4493,7 +4493,7 @@ check_preempt_tick(struct cfs_rq *cfs_rq - ideal_runtime = sched_slice(cfs_rq, curr); - delta_exec = curr->sum_exec_runtime - curr->prev_sum_exec_runtime; - if (delta_exec > ideal_runtime) { -- resched_curr(rq_of(cfs_rq)); -+ resched_curr_lazy(rq_of(cfs_rq)); - /* - * The current task ran long enough, ensure it doesn't get - * re-elected due to buddy favours. -@@ -4517,7 +4517,7 @@ check_preempt_tick(struct cfs_rq *cfs_rq - return; - - if (delta > ideal_runtime) -- resched_curr(rq_of(cfs_rq)); -+ resched_curr_lazy(rq_of(cfs_rq)); - } - - static void -@@ -4663,7 +4663,7 @@ entity_tick(struct cfs_rq *cfs_rq, struc - * validating it and just reschedule. - */ - if (queued) { -- resched_curr(rq_of(cfs_rq)); -+ resched_curr_lazy(rq_of(cfs_rq)); - return; - } - /* -@@ -4812,7 +4812,7 @@ static void __account_cfs_rq_runtime(str - * hierarchy can be throttled - */ - if (!assign_cfs_rq_runtime(cfs_rq) && likely(cfs_rq->curr)) -- resched_curr(rq_of(cfs_rq)); -+ resched_curr_lazy(rq_of(cfs_rq)); - } - - static __always_inline -@@ -5575,7 +5575,7 @@ static void hrtick_start_fair(struct rq - - if (delta < 0) { - if (task_current(rq, p)) -- resched_curr(rq); -+ resched_curr_lazy(rq); - return; - } - hrtick_start(rq, delta); -@@ -7194,7 +7194,7 @@ static void check_preempt_wakeup(struct - return; - - preempt: -- resched_curr(rq); -+ resched_curr_lazy(rq); - /* - * Only set the backward buddy when the current task is still - * on the rq. This can happen when a wakeup gets interleaved -@@ -11338,7 +11338,7 @@ static void task_fork_fair(struct task_s - * 'current' within the tree based on its new key value. - */ - swap(curr->vruntime, se->vruntime); -- resched_curr(rq); -+ resched_curr_lazy(rq); - } - - se->vruntime -= cfs_rq->min_vruntime; -@@ -11365,7 +11365,7 @@ prio_changed_fair(struct rq *rq, struct - */ - if (task_current(rq, p)) { - if (p->prio > oldprio) -- resched_curr(rq); -+ resched_curr_lazy(rq); - } else - check_preempt_curr(rq, p, 0); - } -diff -rupN linux-5.19.16.orig/kernel/sched/features.h linux-5.19.16/kernel/sched/features.h ---- linux-5.19.16.orig/kernel/sched/features.h 2022-10-18 17:21:10.964499413 -0400 -+++ linux-5.19.16/kernel/sched/features.h 2022-10-18 17:21:17.812446632 -0400 -@@ -48,6 +48,9 @@ SCHED_FEAT(NONTASK_CAPACITY, true) - - #ifdef CONFIG_PREEMPT_RT - SCHED_FEAT(TTWU_QUEUE, false) -+# ifdef CONFIG_PREEMPT_LAZY -+SCHED_FEAT(PREEMPT_LAZY, true) -+# endif - #else - - /* -diff -rupN linux-5.19.16.orig/kernel/sched/sched.h linux-5.19.16/kernel/sched/sched.h ---- linux-5.19.16.orig/kernel/sched/sched.h 2022-10-18 17:21:10.964499413 -0400 -+++ linux-5.19.16/kernel/sched/sched.h 2022-10-18 17:21:17.812446632 -0400 -@@ -2314,6 +2314,15 @@ extern void reweight_task(struct task_st - extern void resched_curr(struct rq *rq); - extern void resched_cpu(int cpu); - -+#ifdef CONFIG_PREEMPT_LAZY -+extern void resched_curr_lazy(struct rq *rq); -+#else -+static inline void resched_curr_lazy(struct rq *rq) -+{ -+ resched_curr(rq); -+} -+#endif -+ - extern struct rt_bandwidth def_rt_bandwidth; - extern void init_rt_bandwidth(struct rt_bandwidth *rt_b, u64 period, u64 runtime); - extern bool sched_rt_bandwidth_account(struct rt_rq *rt_rq); -diff -rupN linux-5.19.16.orig/kernel/signal.c linux-5.19.16/kernel/signal.c ---- linux-5.19.16.orig/kernel/signal.c 2022-10-18 17:21:10.952499506 -0400 -+++ linux-5.19.16/kernel/signal.c 2022-10-18 17:21:17.812446632 -0400 -@@ -2297,13 +2297,13 @@ static int ptrace_stop(int exit_code, in - /* - * Don't want to allow preemption here, because - * sys_ptrace() needs this task to be inactive. -- * -- * XXX: implement read_unlock_no_resched(). - */ -- preempt_disable(); -+ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) -+ preempt_disable(); - read_unlock(&tasklist_lock); - cgroup_enter_frozen(); -- preempt_enable_no_resched(); -+ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) -+ preempt_enable_no_resched(); - freezable_schedule(); - cgroup_leave_frozen(true); - -diff -rupN linux-5.19.16.orig/kernel/softirq.c linux-5.19.16/kernel/softirq.c ---- linux-5.19.16.orig/kernel/softirq.c 2022-10-18 17:21:10.952499506 -0400 -+++ linux-5.19.16/kernel/softirq.c 2022-10-18 17:21:17.812446632 -0400 -@@ -637,6 +637,17 @@ static inline void tick_irq_exit(void) - #endif - } - -+DEFINE_PER_CPU(struct task_struct *, timersd); -+DEFINE_PER_CPU(unsigned long, pending_timer_softirq); -+ -+static void wake_timersd(void) -+{ -+ struct task_struct *tsk = __this_cpu_read(timersd); -+ -+ if (tsk) -+ wake_up_process(tsk); -+} -+ - static inline void __irq_exit_rcu(void) - { - #ifndef __ARCH_IRQ_EXIT_IRQS_DISABLED -@@ -648,6 +659,8 @@ static inline void __irq_exit_rcu(void) - preempt_count_sub(HARDIRQ_OFFSET); - if (!in_interrupt() && local_softirq_pending()) - invoke_softirq(); -+ if (IS_ENABLED(CONFIG_PREEMPT_RT) && !in_interrupt() && local_pending_timers()) -+ wake_timersd(); - - tick_irq_exit(); - } -@@ -976,11 +989,69 @@ static struct smp_hotplug_thread softirq - .thread_comm = "ksoftirqd/%u", - }; - -+static void timersd_setup(unsigned int cpu) -+{ -+ sched_set_fifo_low(current); -+} -+ -+static int timersd_should_run(unsigned int cpu) -+{ -+ return local_pending_timers(); -+} -+ -+static void run_timersd(unsigned int cpu) -+{ -+ unsigned int timer_si; -+ -+ ksoftirqd_run_begin(); -+ -+ timer_si = local_pending_timers(); -+ __this_cpu_write(pending_timer_softirq, 0); -+ or_softirq_pending(timer_si); -+ -+ __do_softirq(); -+ -+ ksoftirqd_run_end(); -+} -+ -+#ifdef CONFIG_PREEMPT_RT -+static void raise_ktimers_thread(unsigned int nr) -+{ -+ trace_softirq_raise(nr); -+ __this_cpu_or(pending_timer_softirq, 1 << nr); -+} -+ -+void raise_hrtimer_softirq(void) -+{ -+ raise_ktimers_thread(HRTIMER_SOFTIRQ); -+} -+ -+void raise_timer_softirq(void) -+{ -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ raise_ktimers_thread(TIMER_SOFTIRQ); -+ wake_timersd(); -+ local_irq_restore(flags); -+} -+#endif -+ -+static struct smp_hotplug_thread timer_threads = { -+ .store = &timersd, -+ .setup = timersd_setup, -+ .thread_should_run = timersd_should_run, -+ .thread_fn = run_timersd, -+ .thread_comm = "ktimers/%u", -+}; -+ - static __init int spawn_ksoftirqd(void) - { - cpuhp_setup_state_nocalls(CPUHP_SOFTIRQ_DEAD, "softirq:dead", NULL, - takeover_tasklets); - BUG_ON(smpboot_register_percpu_thread(&softirq_threads)); -+ if (IS_ENABLED(CONFIG_PREEMPT_RT)) -+ BUG_ON(smpboot_register_percpu_thread(&timer_threads)); - - return 0; - } -diff -rupN linux-5.19.16.orig/kernel/time/hrtimer.c linux-5.19.16/kernel/time/hrtimer.c ---- linux-5.19.16.orig/kernel/time/hrtimer.c 2022-10-18 17:21:10.964499413 -0400 -+++ linux-5.19.16/kernel/time/hrtimer.c 2022-10-18 17:21:17.812446632 -0400 -@@ -1805,7 +1805,7 @@ retry: - if (!ktime_before(now, cpu_base->softirq_expires_next)) { - cpu_base->softirq_expires_next = KTIME_MAX; - cpu_base->softirq_activated = 1; -- raise_softirq_irqoff(HRTIMER_SOFTIRQ); -+ raise_hrtimer_softirq(); - } - - __hrtimer_run_queues(cpu_base, now, flags, HRTIMER_ACTIVE_HARD); -@@ -1918,7 +1918,7 @@ void hrtimer_run_queues(void) - if (!ktime_before(now, cpu_base->softirq_expires_next)) { - cpu_base->softirq_expires_next = KTIME_MAX; - cpu_base->softirq_activated = 1; -- raise_softirq_irqoff(HRTIMER_SOFTIRQ); -+ raise_hrtimer_softirq(); - } - - __hrtimer_run_queues(cpu_base, now, flags, HRTIMER_ACTIVE_HARD); -diff -rupN linux-5.19.16.orig/kernel/time/tick-sched.c linux-5.19.16/kernel/time/tick-sched.c ---- linux-5.19.16.orig/kernel/time/tick-sched.c 2022-10-18 17:21:10.964499413 -0400 -+++ linux-5.19.16/kernel/time/tick-sched.c 2022-10-18 17:21:17.812446632 -0400 -@@ -779,7 +779,7 @@ static void tick_nohz_restart(struct tic - - static inline bool local_timer_softirq_pending(void) - { -- return local_softirq_pending() & BIT(TIMER_SOFTIRQ); -+ return local_pending_timers() & BIT(TIMER_SOFTIRQ); - } - - static ktime_t tick_nohz_next_event(struct tick_sched *ts, int cpu) -diff -rupN linux-5.19.16.orig/kernel/time/timer.c linux-5.19.16/kernel/time/timer.c ---- linux-5.19.16.orig/kernel/time/timer.c 2022-10-18 17:21:10.964499413 -0400 -+++ linux-5.19.16/kernel/time/timer.c 2022-10-18 17:21:17.812446632 -0400 -@@ -1822,7 +1822,7 @@ static void run_local_timers(void) - if (time_before(jiffies, base->next_expiry)) - return; - } -- raise_softirq(TIMER_SOFTIRQ); -+ raise_timer_softirq(); - } - - /* -diff -rupN linux-5.19.16.orig/kernel/trace/trace.c linux-5.19.16/kernel/trace/trace.c ---- linux-5.19.16.orig/kernel/trace/trace.c 2022-10-18 17:21:10.964499413 -0400 -+++ linux-5.19.16/kernel/trace/trace.c 2022-10-18 17:21:17.812446632 -0400 -@@ -2625,11 +2625,19 @@ unsigned int tracing_gen_ctx_irq_test(un - if (softirq_count() >> (SOFTIRQ_SHIFT + 1)) - trace_flags |= TRACE_FLAG_BH_OFF; - -- if (tif_need_resched()) -+ if (tif_need_resched_now()) - trace_flags |= TRACE_FLAG_NEED_RESCHED; -+#ifdef CONFIG_PREEMPT_LAZY -+ /* Run out of bits. Share the LAZY and PREEMPT_RESCHED */ -+ if (need_resched_lazy()) -+ trace_flags |= TRACE_FLAG_NEED_RESCHED_LAZY; -+#else - if (test_preempt_need_resched()) - trace_flags |= TRACE_FLAG_PREEMPT_RESCHED; -- return (trace_flags << 16) | (min_t(unsigned int, pc & 0xff, 0xf)) | -+#endif -+ -+ return (trace_flags << 24) | (min_t(unsigned int, pc & 0xff, 0xf)) | -+ (preempt_lazy_count() & 0xff) << 16 | - (min_t(unsigned int, migration_disable_value(), 0xf)) << 4; - } - -@@ -4215,15 +4223,17 @@ unsigned long trace_total_entries(struct - - static void print_lat_help_header(struct seq_file *m) - { -- seq_puts(m, "# _------=> CPU# \n" -- "# / _-----=> irqs-off/BH-disabled\n" -- "# | / _----=> need-resched \n" -- "# || / _---=> hardirq/softirq \n" -- "# ||| / _--=> preempt-depth \n" -- "# |||| / _-=> migrate-disable \n" -- "# ||||| / delay \n" -- "# cmd pid |||||| time | caller \n" -- "# \\ / |||||| \\ | / \n"); -+ seq_puts(m, "# _--------=> CPU# \n" -+ "# / _-------=> irqs-off/BH-disabled\n" -+ "# | / _------=> need-resched \n" -+ "# || / _-----=> need-resched-lazy\n" -+ "# ||| / _----=> hardirq/softirq \n" -+ "# |||| / _---=> preempt-depth \n" -+ "# ||||| / _--=> preempt-lazy-depth\n" -+ "# |||||| / _-=> migrate-disable \n" -+ "# ||||||| / delay \n" -+ "# cmd pid |||||||| time | caller \n" -+ "# \\ / |||||||| \\ | / \n"); - } - - static void print_event_info(struct array_buffer *buf, struct seq_file *m) -@@ -4257,14 +4267,16 @@ static void print_func_help_header_irq(s - - print_event_info(buf, m); - -- seq_printf(m, "# %.*s _-----=> irqs-off/BH-disabled\n", prec, space); -- seq_printf(m, "# %.*s / _----=> need-resched\n", prec, space); -- seq_printf(m, "# %.*s| / _---=> hardirq/softirq\n", prec, space); -- seq_printf(m, "# %.*s|| / _--=> preempt-depth\n", prec, space); -- seq_printf(m, "# %.*s||| / _-=> migrate-disable\n", prec, space); -- seq_printf(m, "# %.*s|||| / delay\n", prec, space); -- seq_printf(m, "# TASK-PID %.*s CPU# ||||| TIMESTAMP FUNCTION\n", prec, " TGID "); -- seq_printf(m, "# | | %.*s | ||||| | |\n", prec, " | "); -+ seq_printf(m, "# %.*s _-------=> irqs-off/BH-disabled\n", prec, space); -+ seq_printf(m, "# %.*s / _------=> need-resched\n", prec, space); -+ seq_printf(m, "# %.*s| / _-----=> need-resched-lazy\n", prec, space); -+ seq_printf(m, "# %.*s|| / _----=> hardirq/softirq\n", prec, space); -+ seq_printf(m, "# %.*s||| / _---=> preempt-depth\n", prec, space); -+ seq_printf(m, "# %.*s|||| / _--=> preempt-lazy-depth\n", prec, space); -+ seq_printf(m, "# %.*s||||| / _-=> migrate-disable\n", prec, space); -+ seq_printf(m, "# %.*s|||||| / delay\n", prec, space); -+ seq_printf(m, "# TASK-PID %.*s CPU# ||||||| TIMESTAMP FUNCTION\n", prec, " TGID "); -+ seq_printf(m, "# | | %.*s | ||||||| | |\n", prec, " | "); - } - - void -diff -rupN linux-5.19.16.orig/kernel/trace/trace_events.c linux-5.19.16/kernel/trace/trace_events.c ---- linux-5.19.16.orig/kernel/trace/trace_events.c 2022-10-18 17:21:10.964499413 -0400 -+++ linux-5.19.16/kernel/trace/trace_events.c 2022-10-18 17:21:17.812446632 -0400 -@@ -193,6 +193,7 @@ static int trace_define_common_fields(vo - /* Holds both preempt_count and migrate_disable */ - __common_field(unsigned char, preempt_count); - __common_field(int, pid); -+ __common_field(unsigned char, preempt_lazy_count); - - return ret; - } -diff -rupN linux-5.19.16.orig/kernel/trace/trace_output.c linux-5.19.16/kernel/trace/trace_output.c ---- linux-5.19.16.orig/kernel/trace/trace_output.c 2022-10-18 17:21:10.968499383 -0400 -+++ linux-5.19.16/kernel/trace/trace_output.c 2022-10-18 17:21:17.812446632 -0400 -@@ -442,6 +442,7 @@ int trace_print_lat_fmt(struct trace_seq - { - char hardsoft_irq; - char need_resched; -+ char need_resched_lazy; - char irqs_off; - int hardirq; - int softirq; -@@ -462,20 +463,27 @@ int trace_print_lat_fmt(struct trace_seq - - switch (entry->flags & (TRACE_FLAG_NEED_RESCHED | - TRACE_FLAG_PREEMPT_RESCHED)) { -+#ifndef CONFIG_PREEMPT_LAZY - case TRACE_FLAG_NEED_RESCHED | TRACE_FLAG_PREEMPT_RESCHED: - need_resched = 'N'; - break; -+#endif - case TRACE_FLAG_NEED_RESCHED: - need_resched = 'n'; - break; -+#ifndef CONFIG_PREEMPT_LAZY - case TRACE_FLAG_PREEMPT_RESCHED: - need_resched = 'p'; - break; -+#endif - default: - need_resched = '.'; - break; - } - -+ need_resched_lazy = -+ (entry->flags & TRACE_FLAG_NEED_RESCHED_LAZY) ? 'L' : '.'; -+ - hardsoft_irq = - (nmi && hardirq) ? 'Z' : - nmi ? 'z' : -@@ -484,14 +492,20 @@ int trace_print_lat_fmt(struct trace_seq - softirq ? 's' : - '.' ; - -- trace_seq_printf(s, "%c%c%c", -- irqs_off, need_resched, hardsoft_irq); -+ trace_seq_printf(s, "%c%c%c%c", -+ irqs_off, need_resched, need_resched_lazy, -+ hardsoft_irq); - - if (entry->preempt_count & 0xf) - trace_seq_printf(s, "%x", entry->preempt_count & 0xf); - else - trace_seq_putc(s, '.'); - -+ if (entry->preempt_lazy_count) -+ trace_seq_printf(s, "%x", entry->preempt_lazy_count); -+ else -+ trace_seq_putc(s, '.'); -+ - if (entry->preempt_count & 0xf0) - trace_seq_printf(s, "%x", entry->preempt_count >> 4); - else -diff -rupN linux-5.19.16.orig/kernel/watchdog.c linux-5.19.16/kernel/watchdog.c ---- linux-5.19.16.orig/kernel/watchdog.c 2022-10-18 17:21:10.952499506 -0400 -+++ linux-5.19.16/kernel/watchdog.c 2022-10-18 17:21:17.812446632 -0400 -@@ -424,6 +424,8 @@ static enum hrtimer_restart watchdog_tim - /* Start period for the next softlockup warning. */ - update_report_ts(); - -+ printk_prefer_direct_enter(); -+ - pr_emerg("BUG: soft lockup - CPU#%d stuck for %us! [%s:%d]\n", - smp_processor_id(), duration, - current->comm, task_pid_nr(current)); -@@ -442,6 +444,8 @@ static enum hrtimer_restart watchdog_tim - add_taint(TAINT_SOFTLOCKUP, LOCKDEP_STILL_OK); - if (softlockup_panic) - panic("softlockup: hung tasks"); -+ -+ printk_prefer_direct_exit(); - } - - return HRTIMER_RESTART; -diff -rupN linux-5.19.16.orig/kernel/watchdog_hld.c linux-5.19.16/kernel/watchdog_hld.c ---- linux-5.19.16.orig/kernel/watchdog_hld.c 2022-10-18 17:21:10.952499506 -0400 -+++ linux-5.19.16/kernel/watchdog_hld.c 2022-10-18 17:21:17.812446632 -0400 -@@ -135,6 +135,8 @@ static void watchdog_overflow_callback(s - if (__this_cpu_read(hard_watchdog_warn) == true) - return; - -+ printk_prefer_direct_enter(); -+ - pr_emerg("Watchdog detected hard LOCKUP on cpu %d\n", - this_cpu); - print_modules(); -@@ -155,6 +157,8 @@ static void watchdog_overflow_callback(s - if (hardlockup_panic) - nmi_panic(regs, "Hard LOCKUP"); - -+ printk_prefer_direct_exit(); -+ - __this_cpu_write(hard_watchdog_warn, true); - return; - } -diff -rupN linux-5.19.16.orig/lib/vsprintf.c linux-5.19.16/lib/vsprintf.c ---- linux-5.19.16.orig/lib/vsprintf.c 2022-10-18 17:21:10.972499352 -0400 -+++ linux-5.19.16/lib/vsprintf.c 2022-10-18 17:21:17.812446632 -0400 -@@ -750,37 +750,40 @@ static int __init debug_boot_weak_hash_e - } - early_param("debug_boot_weak_hash", debug_boot_weak_hash_enable); - --static DEFINE_STATIC_KEY_FALSE(filled_random_ptr_key); -+static bool filled_random_ptr_key; -+static siphash_key_t ptr_key __read_mostly; - --static void enable_ptr_key_workfn(struct work_struct *work) -+static void fill_ptr_key_workfn(struct work_struct *work) - { -- static_branch_enable(&filled_random_ptr_key); -+ int ret; -+ -+ ret = get_random_bytes_wait(&ptr_key, sizeof(ptr_key)); -+ if (WARN_ON(ret < 0)) -+ return; -+ /* Pairs with smp_rmb() before reading ptr_key. */ -+ smp_wmb(); -+ WRITE_ONCE(filled_random_ptr_key, true); -+} -+ -+static int vsprintf_init_hashval(void) -+{ -+ static DECLARE_WORK(fill_ptr_key_work, fill_ptr_key_workfn); -+ -+ queue_work(system_unbound_wq, &fill_ptr_key_work); -+ return 0; - } -+subsys_initcall(vsprintf_init_hashval) - - /* Maps a pointer to a 32 bit unique identifier. */ - static inline int __ptr_to_hashval(const void *ptr, unsigned long *hashval_out) - { -- static siphash_key_t ptr_key __read_mostly; - unsigned long hashval; - -- if (!static_branch_likely(&filled_random_ptr_key)) { -- static bool filled = false; -- static DEFINE_SPINLOCK(filling); -- static DECLARE_WORK(enable_ptr_key_work, enable_ptr_key_workfn); -- unsigned long flags; -- -- if (!system_unbound_wq || !rng_is_initialized() || -- !spin_trylock_irqsave(&filling, flags)) -- return -EAGAIN; -- -- if (!filled) { -- get_random_bytes(&ptr_key, sizeof(ptr_key)); -- queue_work(system_unbound_wq, &enable_ptr_key_work); -- filled = true; -- } -- spin_unlock_irqrestore(&filling, flags); -- } -+ if (!READ_ONCE(filled_random_ptr_key)) -+ return -EBUSY; - -+ /* Pairs with smp_wmb() after writing ptr_key. */ -+ smp_rmb(); - - #ifdef CONFIG_64BIT - hashval = (unsigned long)siphash_1u64((u64)ptr, &ptr_key); -diff -rupN linux-5.19.16.orig/localversion-rt linux-5.19.16/localversion-rt ---- linux-5.19.16.orig/localversion-rt 1969-12-31 19:00:00.000000000 -0500 -+++ linux-5.19.16/localversion-rt 2022-10-18 17:21:17.816446601 -0400 -@@ -0,0 +1 @@ -+-rt10 diff --git a/packages/kernel/linux/patches/X86_64/patch-6.0.5-rt14.patch b/packages/kernel/linux/patches/X86_64/patch-6.0.5-rt14.patch new file mode 100644 index 000000000..c0c976eb9 --- /dev/null +++ b/packages/kernel/linux/patches/X86_64/patch-6.0.5-rt14.patch @@ -0,0 +1,8997 @@ +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index 11ecf09aadc86..98aa5a478719c 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -33,6 +33,7 @@ config ARM + select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT if CPU_V7 + select ARCH_SUPPORTS_ATOMIC_RMW + select ARCH_SUPPORTS_HUGETLBFS if ARM_LPAE ++ select ARCH_SUPPORTS_RT if HAVE_POSIX_CPU_TIMERS_TASK_WORK + select ARCH_USE_BUILTIN_BSWAP + select ARCH_USE_CMPXCHG_LOCKREF + select ARCH_USE_MEMTEST +@@ -70,7 +71,7 @@ config ARM + select HARDIRQS_SW_RESEND + select HAVE_ARCH_AUDITSYSCALL if AEABI && !OABI_COMPAT + select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6 +- select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU ++ select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU && !PREEMPT_RT + select HAVE_ARCH_KFENCE if MMU && !XIP_KERNEL + select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU + select HAVE_ARCH_KASAN if MMU && !XIP_KERNEL +@@ -113,6 +114,7 @@ config ARM + select HAVE_PERF_EVENTS + select HAVE_PERF_REGS + select HAVE_PERF_USER_STACK_DUMP ++ select HAVE_PREEMPT_LAZY + select MMU_GATHER_RCU_TABLE_FREE if SMP && ARM_LPAE + select HAVE_REGS_AND_STACK_ACCESS_API + select HAVE_RSEQ +@@ -128,6 +130,7 @@ config ARM + select OLD_SIGSUSPEND3 + select PCI_SYSCALL if PCI + select PERF_USE_VMALLOC ++ select HAVE_POSIX_CPU_TIMERS_TASK_WORK if !KVM + select RTC_LIB + select SYS_SUPPORTS_APM_EMULATION + select THREAD_INFO_IN_TASK +diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h +index aecc403b28804..1b56e56f8f415 100644 +--- a/arch/arm/include/asm/thread_info.h ++++ b/arch/arm/include/asm/thread_info.h +@@ -62,6 +62,7 @@ struct cpu_context_save { + struct thread_info { + unsigned long flags; /* low level flags */ + int preempt_count; /* 0 => preemptable, <0 => bug */ ++ int preempt_lazy_count; /* 0 => preemptable, <0 => bug */ + __u32 cpu; /* cpu */ + __u32 cpu_domain; /* cpu domain */ + struct cpu_context_save cpu_context; /* cpu context */ +@@ -133,6 +134,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp *, + #define TIF_SYSCALL_TRACEPOINT 6 /* syscall tracepoint instrumentation */ + #define TIF_SECCOMP 7 /* seccomp syscall filtering active */ + #define TIF_NOTIFY_SIGNAL 8 /* signal notifications exist */ ++#define TIF_NEED_RESCHED_LAZY 9 + + #define TIF_USING_IWMMXT 17 + #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ +@@ -147,6 +149,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp *, + #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) + #define _TIF_SECCOMP (1 << TIF_SECCOMP) + #define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL) ++#define _TIF_NEED_RESCHED_LAZY (1 << TIF_NEED_RESCHED_LAZY) + #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) + + /* Checks for any syscall work in entry-common.S */ +@@ -156,7 +159,8 @@ extern int vfp_restore_user_hwstate(struct user_vfp *, + /* + * Change these and you break ASM code in entry-common.S + */ +-#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ ++#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY | \ ++ _TIF_SIGPENDING | \ + _TIF_NOTIFY_RESUME | _TIF_UPROBE | \ + _TIF_NOTIFY_SIGNAL) + +diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c +index 2c8d76fd7c662..c3bdec7d2df9c 100644 +--- a/arch/arm/kernel/asm-offsets.c ++++ b/arch/arm/kernel/asm-offsets.c +@@ -43,6 +43,7 @@ int main(void) + BLANK(); + DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); + DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); ++ DEFINE(TI_PREEMPT_LAZY, offsetof(struct thread_info, preempt_lazy_count)); + DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); + DEFINE(TI_CPU_DOMAIN, offsetof(struct thread_info, cpu_domain)); + DEFINE(TI_CPU_SAVE, offsetof(struct thread_info, cpu_context)); +diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S +index c39303e5c2347..cfb4660e9feab 100644 +--- a/arch/arm/kernel/entry-armv.S ++++ b/arch/arm/kernel/entry-armv.S +@@ -222,11 +222,18 @@ ENDPROC(__dabt_svc) + + #ifdef CONFIG_PREEMPTION + ldr r8, [tsk, #TI_PREEMPT] @ get preempt count +- ldr r0, [tsk, #TI_FLAGS] @ get flags + teq r8, #0 @ if preempt count != 0 ++ bne 1f @ return from exeption ++ ldr r0, [tsk, #TI_FLAGS] @ get flags ++ tst r0, #_TIF_NEED_RESCHED @ if NEED_RESCHED is set ++ blne svc_preempt @ preempt! ++ ++ ldr r8, [tsk, #TI_PREEMPT_LAZY] @ get preempt lazy count ++ teq r8, #0 @ if preempt lazy count != 0 + movne r0, #0 @ force flags to 0 +- tst r0, #_TIF_NEED_RESCHED ++ tst r0, #_TIF_NEED_RESCHED_LAZY + blne svc_preempt ++1: + #endif + + svc_exit r5, irq = 1 @ return from exception +@@ -241,8 +248,14 @@ ENDPROC(__irq_svc) + 1: bl preempt_schedule_irq @ irq en/disable is done inside + ldr r0, [tsk, #TI_FLAGS] @ get new tasks TI_FLAGS + tst r0, #_TIF_NEED_RESCHED ++ bne 1b ++ tst r0, #_TIF_NEED_RESCHED_LAZY + reteq r8 @ go again +- b 1b ++ ldr r0, [tsk, #TI_PREEMPT_LAZY] @ get preempt lazy count ++ teq r0, #0 @ if preempt lazy count != 0 ++ beq 1b ++ ret r8 @ go again ++ + #endif + + __und_fault: +diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c +index ea128e32e8ca8..3671a4214d6f4 100644 +--- a/arch/arm/kernel/signal.c ++++ b/arch/arm/kernel/signal.c +@@ -607,7 +607,8 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall) + */ + trace_hardirqs_off(); + do { +- if (likely(thread_flags & _TIF_NEED_RESCHED)) { ++ if (likely(thread_flags & (_TIF_NEED_RESCHED | ++ _TIF_NEED_RESCHED_LAZY))) { + schedule(); + } else { + if (unlikely(!user_mode(regs))) +diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c +index 46cccd6bf705a..480a1976a9dce 100644 +--- a/arch/arm/mm/fault.c ++++ b/arch/arm/mm/fault.c +@@ -421,6 +421,9 @@ do_translation_fault(unsigned long addr, unsigned int fsr, + if (addr < TASK_SIZE) + return do_page_fault(addr, fsr, regs); + ++ if (interrupts_enabled(regs)) ++ local_irq_enable(); ++ + if (user_mode(regs)) + goto bad_area; + +@@ -491,6 +494,9 @@ do_translation_fault(unsigned long addr, unsigned int fsr, + static int + do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) + { ++ if (interrupts_enabled(regs)) ++ local_irq_enable(); ++ + do_bad_area(addr, fsr, regs); + return 0; + } +diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig +index 3795eb5ba1cdd..6922949e61b71 100644 +--- a/arch/arm64/Kconfig ++++ b/arch/arm64/Kconfig +@@ -93,6 +93,7 @@ config ARM64 + select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 + select ARCH_SUPPORTS_NUMA_BALANCING + select ARCH_SUPPORTS_PAGE_TABLE_CHECK ++ select ARCH_SUPPORTS_RT + select ARCH_WANT_COMPAT_IPC_PARSE_VERSION if COMPAT + select ARCH_WANT_DEFAULT_BPF_JIT + select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT +@@ -200,6 +201,7 @@ config ARM64 + select HAVE_PERF_USER_STACK_DUMP + select HAVE_PREEMPT_DYNAMIC_KEY + select HAVE_REGS_AND_STACK_ACCESS_API ++ select HAVE_PREEMPT_LAZY + select HAVE_POSIX_CPU_TIMERS_TASK_WORK + select HAVE_FUNCTION_ARG_ACCESS_API + select MMU_GATHER_RCU_TABLE_FREE +diff --git a/arch/arm64/include/asm/preempt.h b/arch/arm64/include/asm/preempt.h +index 0159b625cc7f0..a5486918e5eeb 100644 +--- a/arch/arm64/include/asm/preempt.h ++++ b/arch/arm64/include/asm/preempt.h +@@ -71,13 +71,36 @@ static inline bool __preempt_count_dec_and_test(void) + * interrupt occurring between the non-atomic READ_ONCE/WRITE_ONCE + * pair. + */ +- return !pc || !READ_ONCE(ti->preempt_count); ++ if (!pc || !READ_ONCE(ti->preempt_count)) ++ return true; ++#ifdef CONFIG_PREEMPT_LAZY ++ if ((pc & ~PREEMPT_NEED_RESCHED)) ++ return false; ++ if (current_thread_info()->preempt_lazy_count) ++ return false; ++ return test_thread_flag(TIF_NEED_RESCHED_LAZY); ++#else ++ return false; ++#endif + } + + static inline bool should_resched(int preempt_offset) + { ++#ifdef CONFIG_PREEMPT_LAZY ++ u64 pc = READ_ONCE(current_thread_info()->preempt_count); ++ if (pc == preempt_offset) ++ return true; ++ ++ if ((pc & ~PREEMPT_NEED_RESCHED) != preempt_offset) ++ return false; ++ ++ if (current_thread_info()->preempt_lazy_count) ++ return false; ++ return test_thread_flag(TIF_NEED_RESCHED_LAZY); ++#else + u64 pc = READ_ONCE(current_thread_info()->preempt_count); + return pc == preempt_offset; ++#endif + } + + #ifdef CONFIG_PREEMPTION +diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h +index 848739c15de82..4b7148fd5551f 100644 +--- a/arch/arm64/include/asm/thread_info.h ++++ b/arch/arm64/include/asm/thread_info.h +@@ -26,6 +26,7 @@ struct thread_info { + #ifdef CONFIG_ARM64_SW_TTBR0_PAN + u64 ttbr0; /* saved TTBR0_EL1 */ + #endif ++ int preempt_lazy_count; /* 0 => preemptable, <0 => bug */ + union { + u64 preempt_count; /* 0 => preemptible, <0 => bug */ + struct { +@@ -68,6 +69,7 @@ int arch_dup_task_struct(struct task_struct *dst, + #define TIF_UPROBE 4 /* uprobe breakpoint or singlestep */ + #define TIF_MTE_ASYNC_FAULT 5 /* MTE Asynchronous Tag Check Fault */ + #define TIF_NOTIFY_SIGNAL 6 /* signal notifications exist */ ++#define TIF_NEED_RESCHED_LAZY 7 + #define TIF_SYSCALL_TRACE 8 /* syscall trace active */ + #define TIF_SYSCALL_AUDIT 9 /* syscall auditing */ + #define TIF_SYSCALL_TRACEPOINT 10 /* syscall tracepoint for ftrace */ +@@ -100,8 +102,10 @@ int arch_dup_task_struct(struct task_struct *dst, + #define _TIF_SVE (1 << TIF_SVE) + #define _TIF_MTE_ASYNC_FAULT (1 << TIF_MTE_ASYNC_FAULT) + #define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL) ++#define _TIF_NEED_RESCHED_LAZY (1 << TIF_NEED_RESCHED_LAZY) + +-#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ ++#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY | \ ++ _TIF_SIGPENDING | \ + _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \ + _TIF_UPROBE | _TIF_MTE_ASYNC_FAULT | \ + _TIF_NOTIFY_SIGNAL) +@@ -110,6 +114,8 @@ int arch_dup_task_struct(struct task_struct *dst, + _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \ + _TIF_SYSCALL_EMU) + ++#define _TIF_NEED_RESCHED_MASK (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY) ++ + #ifdef CONFIG_SHADOW_CALL_STACK + #define INIT_SCS \ + .scs_base = init_shadow_call_stack, \ +diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c +index 1197e7679882e..e74c0415f67ea 100644 +--- a/arch/arm64/kernel/asm-offsets.c ++++ b/arch/arm64/kernel/asm-offsets.c +@@ -32,6 +32,7 @@ int main(void) + DEFINE(TSK_TI_CPU, offsetof(struct task_struct, thread_info.cpu)); + DEFINE(TSK_TI_FLAGS, offsetof(struct task_struct, thread_info.flags)); + DEFINE(TSK_TI_PREEMPT, offsetof(struct task_struct, thread_info.preempt_count)); ++ DEFINE(TSK_TI_PREEMPT_LAZY, offsetof(struct task_struct, thread_info.preempt_lazy_count)); + #ifdef CONFIG_ARM64_SW_TTBR0_PAN + DEFINE(TSK_TI_TTBR0, offsetof(struct task_struct, thread_info.ttbr0)); + #endif +diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c +index 9ad911f1647c8..545c41a84411e 100644 +--- a/arch/arm64/kernel/signal.c ++++ b/arch/arm64/kernel/signal.c +@@ -1103,7 +1103,7 @@ static void do_signal(struct pt_regs *regs) + void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags) + { + do { +- if (thread_flags & _TIF_NEED_RESCHED) { ++ if (thread_flags & _TIF_NEED_RESCHED_MASK) { + /* Unmask Debug and SError for the next task */ + local_daif_restore(DAIF_PROCCTX_NOIRQ); + +diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig +index cbe7bb029aec8..ad5bcc255f4e3 100644 +--- a/arch/powerpc/Kconfig ++++ b/arch/powerpc/Kconfig +@@ -149,6 +149,7 @@ config PPC + select ARCH_STACKWALK + select ARCH_SUPPORTS_ATOMIC_RMW + select ARCH_SUPPORTS_DEBUG_PAGEALLOC if PPC_BOOK3S || PPC_8xx || 40x ++ select ARCH_SUPPORTS_RT if HAVE_POSIX_CPU_TIMERS_TASK_WORK + select ARCH_USE_BUILTIN_BSWAP + select ARCH_USE_CMPXCHG_LOCKREF if PPC64 + select ARCH_USE_MEMTEST +@@ -241,8 +242,10 @@ config PPC + select HAVE_PERF_EVENTS_NMI if PPC64 + select HAVE_PERF_REGS + select HAVE_PERF_USER_STACK_DUMP ++ select HAVE_PREEMPT_LAZY + select HAVE_REGS_AND_STACK_ACCESS_API + select HAVE_RELIABLE_STACKTRACE ++ select HAVE_POSIX_CPU_TIMERS_TASK_WORK if !KVM + select HAVE_RSEQ + select HAVE_SETUP_PER_CPU_AREA if PPC64 + select HAVE_SOFTIRQ_ON_OWN_STACK +diff --git a/arch/powerpc/include/asm/stackprotector.h b/arch/powerpc/include/asm/stackprotector.h +index 1c8460e235838..b1653c160bab9 100644 +--- a/arch/powerpc/include/asm/stackprotector.h ++++ b/arch/powerpc/include/asm/stackprotector.h +@@ -24,7 +24,11 @@ static __always_inline void boot_init_stack_canary(void) + unsigned long canary; + + /* Try to get a semi random initial value. */ ++#ifdef CONFIG_PREEMPT_RT ++ canary = (unsigned long)&canary; ++#else + canary = get_random_canary(); ++#endif + canary ^= mftb(); + canary ^= LINUX_VERSION_CODE; + canary &= CANARY_MASK; +diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h +index af58f1ed3952e..520864de8bb27 100644 +--- a/arch/powerpc/include/asm/thread_info.h ++++ b/arch/powerpc/include/asm/thread_info.h +@@ -53,6 +53,8 @@ + struct thread_info { + int preempt_count; /* 0 => preemptable, + <0 => BUG */ ++ int preempt_lazy_count; /* 0 => preemptable, ++ <0 => BUG */ + #ifdef CONFIG_SMP + unsigned int cpu; + #endif +@@ -77,6 +79,7 @@ struct thread_info { + #define INIT_THREAD_INFO(tsk) \ + { \ + .preempt_count = INIT_PREEMPT_COUNT, \ ++ .preempt_lazy_count = 0, \ + .flags = 0, \ + } + +@@ -102,6 +105,7 @@ void arch_setup_new_exec(void); + #define TIF_PATCH_PENDING 6 /* pending live patching update */ + #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ + #define TIF_SINGLESTEP 8 /* singlestepping active */ ++#define TIF_NEED_RESCHED_LAZY 9 /* lazy rescheduling necessary */ + #define TIF_SECCOMP 10 /* secure computing */ + #define TIF_RESTOREALL 11 /* Restore all regs (implies NOERROR) */ + #define TIF_NOERROR 12 /* Force successful syscall return */ +@@ -117,6 +121,7 @@ void arch_setup_new_exec(void); + #define TIF_POLLING_NRFLAG 19 /* true if poll_idle() is polling TIF_NEED_RESCHED */ + #define TIF_32BIT 20 /* 32 bit binary */ + ++ + /* as above, but as bit values */ + #define _TIF_SYSCALL_TRACE (1<msr & MSR_EE)); + again: +- if (IS_ENABLED(CONFIG_PREEMPT)) { ++ if (IS_ENABLED(CONFIG_PREEMPTION)) { + /* Return to preemptible kernel context */ + if (unlikely(read_thread_flags() & _TIF_NEED_RESCHED)) { + if (preempt_count() == 0) + preempt_schedule_irq(); ++ } else if (unlikely(current_thread_info()->flags & _TIF_NEED_RESCHED_LAZY)) { ++ if ((preempt_count() == 0) && ++ (current_thread_info()->preempt_lazy_count == 0)) ++ preempt_schedule_irq(); + } + } + +diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c +index dadfcef5d6db4..3bfe55d82b042 100644 +--- a/arch/powerpc/kernel/traps.c ++++ b/arch/powerpc/kernel/traps.c +@@ -260,12 +260,17 @@ static char *get_mmu_str(void) + + static int __die(const char *str, struct pt_regs *regs, long err) + { ++ const char *pr = ""; ++ + printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); + ++ if (IS_ENABLED(CONFIG_PREEMPTION)) ++ pr = IS_ENABLED(CONFIG_PREEMPT_RT) ? " PREEMPT_RT" : " PREEMPT"; ++ + printk("%s PAGE_SIZE=%luK%s%s%s%s%s%s %s\n", + IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN) ? "LE" : "BE", + PAGE_SIZE / 1024, get_mmu_str(), +- IS_ENABLED(CONFIG_PREEMPT) ? " PREEMPT" : "", ++ pr, + IS_ENABLED(CONFIG_SMP) ? " SMP" : "", + IS_ENABLED(CONFIG_SMP) ? (" NR_CPUS=" __stringify(NR_CPUS)) : "", + debug_pagealloc_enabled() ? " DEBUG_PAGEALLOC" : "", +diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig +index dcb398d5e0093..2cfa432afdb12 100644 +--- a/arch/powerpc/kvm/Kconfig ++++ b/arch/powerpc/kvm/Kconfig +@@ -221,6 +221,7 @@ config KVM_E500MC + config KVM_MPIC + bool "KVM in-kernel MPIC emulation" + depends on KVM && E500 ++ depends on !PREEMPT_RT + select HAVE_KVM_IRQCHIP + select HAVE_KVM_IRQFD + select HAVE_KVM_IRQ_ROUTING +diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c +index 561adac690229..61c4c0610aa6a 100644 +--- a/arch/powerpc/platforms/pseries/iommu.c ++++ b/arch/powerpc/platforms/pseries/iommu.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -195,7 +196,13 @@ static int tce_build_pSeriesLP(unsigned long liobn, long tcenum, long tceshift, + return ret; + } + +-static DEFINE_PER_CPU(__be64 *, tce_page); ++struct tce_page { ++ __be64 * page; ++ local_lock_t lock; ++}; ++static DEFINE_PER_CPU(struct tce_page, tce_page) = { ++ .lock = INIT_LOCAL_LOCK(lock), ++}; + + static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, + long npages, unsigned long uaddr, +@@ -218,9 +225,10 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, + direction, attrs); + } + +- local_irq_save(flags); /* to protect tcep and the page behind it */ ++ /* to protect tcep and the page behind it */ ++ local_lock_irqsave(&tce_page.lock, flags); + +- tcep = __this_cpu_read(tce_page); ++ tcep = __this_cpu_read(tce_page.page); + + /* This is safe to do since interrupts are off when we're called + * from iommu_alloc{,_sg}() +@@ -229,12 +237,12 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, + tcep = (__be64 *)__get_free_page(GFP_ATOMIC); + /* If allocation fails, fall back to the loop implementation */ + if (!tcep) { +- local_irq_restore(flags); ++ local_unlock_irqrestore(&tce_page.lock, flags); + return tce_build_pSeriesLP(tbl->it_index, tcenum, + tceshift, + npages, uaddr, direction, attrs); + } +- __this_cpu_write(tce_page, tcep); ++ __this_cpu_write(tce_page.page, tcep); + } + + rpn = __pa(uaddr) >> tceshift; +@@ -264,7 +272,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, + tcenum += limit; + } while (npages > 0 && !rc); + +- local_irq_restore(flags); ++ local_unlock_irqrestore(&tce_page.lock, flags); + + if (unlikely(rc == H_NOT_ENOUGH_RESOURCES)) { + ret = (int)rc; +@@ -440,16 +448,17 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn, + DMA_BIDIRECTIONAL, 0); + } + +- local_irq_disable(); /* to protect tcep and the page behind it */ +- tcep = __this_cpu_read(tce_page); ++ /* to protect tcep and the page behind it */ ++ local_lock_irq(&tce_page.lock); ++ tcep = __this_cpu_read(tce_page.page); + + if (!tcep) { + tcep = (__be64 *)__get_free_page(GFP_ATOMIC); + if (!tcep) { +- local_irq_enable(); ++ local_unlock_irq(&tce_page.lock); + return -ENOMEM; + } +- __this_cpu_write(tce_page, tcep); ++ __this_cpu_write(tce_page.page, tcep); + } + + proto_tce = TCE_PCI_READ | TCE_PCI_WRITE; +@@ -492,7 +501,7 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn, + + /* error cleanup: caller will clear whole range */ + +- local_irq_enable(); ++ local_unlock_irq(&tce_page.lock); + return rc; + } + +diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig +index 159c025ebb03e..4d62ceece1bb0 100644 +--- a/arch/x86/Kconfig ++++ b/arch/x86/Kconfig +@@ -109,6 +109,7 @@ config X86 + select ARCH_SUPPORTS_KMAP_LOCAL_FORCE_MAP if NR_CPUS <= 4096 + select ARCH_SUPPORTS_LTO_CLANG + select ARCH_SUPPORTS_LTO_CLANG_THIN ++ select ARCH_SUPPORTS_RT + select ARCH_USE_BUILTIN_BSWAP + select ARCH_USE_MEMTEST + select ARCH_USE_QUEUED_RWLOCKS +@@ -243,6 +244,7 @@ config X86 + select HAVE_PCI + select HAVE_PERF_REGS + select HAVE_PERF_USER_STACK_DUMP ++ select HAVE_PREEMPT_LAZY + select MMU_GATHER_RCU_TABLE_FREE if PARAVIRT + select MMU_GATHER_MERGE_VMAS + select HAVE_POSIX_CPU_TIMERS_TASK_WORK +diff --git a/arch/x86/include/asm/preempt.h b/arch/x86/include/asm/preempt.h +index 5f6daea1ee248..cd20b4a5719a4 100644 +--- a/arch/x86/include/asm/preempt.h ++++ b/arch/x86/include/asm/preempt.h +@@ -90,17 +90,48 @@ static __always_inline void __preempt_count_sub(int val) + * a decrement which hits zero means we have no preempt_count and should + * reschedule. + */ +-static __always_inline bool __preempt_count_dec_and_test(void) ++static __always_inline bool ____preempt_count_dec_and_test(void) + { + return GEN_UNARY_RMWcc("decl", __preempt_count, e, __percpu_arg([var])); + } + ++static __always_inline bool __preempt_count_dec_and_test(void) ++{ ++ if (____preempt_count_dec_and_test()) ++ return true; ++#ifdef CONFIG_PREEMPT_LAZY ++ if (preempt_count()) ++ return false; ++ if (current_thread_info()->preempt_lazy_count) ++ return false; ++ return test_thread_flag(TIF_NEED_RESCHED_LAZY); ++#else ++ return false; ++#endif ++} ++ + /* + * Returns true when we need to resched and can (barring IRQ state). + */ + static __always_inline bool should_resched(int preempt_offset) + { ++#ifdef CONFIG_PREEMPT_LAZY ++ u32 tmp; ++ tmp = raw_cpu_read_4(__preempt_count); ++ if (tmp == preempt_offset) ++ return true; ++ ++ /* preempt count == 0 ? */ ++ tmp &= ~PREEMPT_NEED_RESCHED; ++ if (tmp != preempt_offset) ++ return false; ++ /* XXX PREEMPT_LOCK_OFFSET */ ++ if (current_thread_info()->preempt_lazy_count) ++ return false; ++ return test_thread_flag(TIF_NEED_RESCHED_LAZY); ++#else + return unlikely(raw_cpu_read_4(__preempt_count) == preempt_offset); ++#endif + } + + #ifdef CONFIG_PREEMPTION +diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h +index f0cb881c1d690..fd8fb76f324fc 100644 +--- a/arch/x86/include/asm/thread_info.h ++++ b/arch/x86/include/asm/thread_info.h +@@ -57,6 +57,8 @@ struct thread_info { + unsigned long flags; /* low level flags */ + unsigned long syscall_work; /* SYSCALL_WORK_ flags */ + u32 status; /* thread synchronous flags */ ++ int preempt_lazy_count; /* 0 => lazy preemptable ++ <0 => BUG */ + #ifdef CONFIG_SMP + u32 cpu; /* current CPU */ + #endif +@@ -65,6 +67,7 @@ struct thread_info { + #define INIT_THREAD_INFO(tsk) \ + { \ + .flags = 0, \ ++ .preempt_lazy_count = 0, \ + } + + #else /* !__ASSEMBLY__ */ +@@ -92,6 +95,7 @@ struct thread_info { + #define TIF_NOCPUID 15 /* CPUID is not accessible in userland */ + #define TIF_NOTSC 16 /* TSC is not accessible in userland */ + #define TIF_NOTIFY_SIGNAL 17 /* signal notifications exist */ ++#define TIF_NEED_RESCHED_LAZY 19 /* lazy rescheduling necessary */ + #define TIF_MEMDIE 20 /* is terminating due to OOM killer */ + #define TIF_POLLING_NRFLAG 21 /* idle is polling for TIF_NEED_RESCHED */ + #define TIF_IO_BITMAP 22 /* uses I/O bitmap */ +@@ -115,6 +119,7 @@ struct thread_info { + #define _TIF_NOCPUID (1 << TIF_NOCPUID) + #define _TIF_NOTSC (1 << TIF_NOTSC) + #define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL) ++#define _TIF_NEED_RESCHED_LAZY (1 << TIF_NEED_RESCHED_LAZY) + #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) + #define _TIF_IO_BITMAP (1 << TIF_IO_BITMAP) + #define _TIF_SPEC_FORCE_UPDATE (1 << TIF_SPEC_FORCE_UPDATE) +diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c +index fac8ff983aec8..65fb9bad1577a 100644 +--- a/drivers/bcma/driver_gpio.c ++++ b/drivers/bcma/driver_gpio.c +@@ -115,7 +115,7 @@ static irqreturn_t bcma_gpio_irq_handler(int irq, void *dev_id) + return IRQ_NONE; + + for_each_set_bit(gpio, &irqs, gc->ngpio) +- generic_handle_irq(irq_find_mapping(gc->irq.domain, gpio)); ++ generic_handle_domain_irq_safe(gc->irq.domain, gpio); + bcma_chipco_gpio_polarity(cc, irqs, val & irqs); + + return IRQ_HANDLED; +diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c +index 226ea76cc8197..4043d909d41bf 100644 +--- a/drivers/block/zram/zram_drv.c ++++ b/drivers/block/zram/zram_drv.c +@@ -60,6 +60,40 @@ static void zram_free_page(struct zram *zram, size_t index); + static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, + u32 index, int offset, struct bio *bio); + ++#ifdef CONFIG_PREEMPT_RT ++static void zram_meta_init_table_locks(struct zram *zram, size_t num_pages) ++{ ++ size_t index; ++ ++ for (index = 0; index < num_pages; index++) ++ spin_lock_init(&zram->table[index].lock); ++} ++ ++static int zram_slot_trylock(struct zram *zram, u32 index) ++{ ++ int ret; ++ ++ ret = spin_trylock(&zram->table[index].lock); ++ if (ret) ++ __set_bit(ZRAM_LOCK, &zram->table[index].flags); ++ return ret; ++} ++ ++static void zram_slot_lock(struct zram *zram, u32 index) ++{ ++ spin_lock(&zram->table[index].lock); ++ __set_bit(ZRAM_LOCK, &zram->table[index].flags); ++} ++ ++static void zram_slot_unlock(struct zram *zram, u32 index) ++{ ++ __clear_bit(ZRAM_LOCK, &zram->table[index].flags); ++ spin_unlock(&zram->table[index].lock); ++} ++ ++#else ++ ++static void zram_meta_init_table_locks(struct zram *zram, size_t num_pages) { } + + static int zram_slot_trylock(struct zram *zram, u32 index) + { +@@ -75,6 +109,7 @@ static void zram_slot_unlock(struct zram *zram, u32 index) + { + bit_spin_unlock(ZRAM_LOCK, &zram->table[index].flags); + } ++#endif + + static inline bool init_done(struct zram *zram) + { +@@ -1198,6 +1233,7 @@ static bool zram_meta_alloc(struct zram *zram, u64 disksize) + + if (!huge_class_size) + huge_class_size = zs_huge_class_size(zram->mem_pool); ++ zram_meta_init_table_locks(zram, num_pages); + return true; + } + +diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h +index 80c3b43b4828f..ff021a9728d1e 100644 +--- a/drivers/block/zram/zram_drv.h ++++ b/drivers/block/zram/zram_drv.h +@@ -63,6 +63,9 @@ struct zram_table_entry { + unsigned long element; + }; + unsigned long flags; ++#ifdef CONFIG_PREEMPT_RT ++ spinlock_t lock; ++#endif + #ifdef CONFIG_ZRAM_MEMORY_TRACKING + ktime_t ac_time; + #endif +diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c +index bcff6429e0b4f..4a9ae338a2bdf 100644 +--- a/drivers/char/tpm/tpm_tis.c ++++ b/drivers/char/tpm/tpm_tis.c +@@ -50,6 +50,31 @@ static inline struct tpm_tis_tcg_phy *to_tpm_tis_tcg_phy(struct tpm_tis_data *da + return container_of(data, struct tpm_tis_tcg_phy, priv); + } + ++#ifdef CONFIG_PREEMPT_RT ++/* ++ * Flushes previous write operations to chip so that a subsequent ++ * ioread*()s won't stall a cpu. ++ */ ++static inline void tpm_tis_flush(void __iomem *iobase) ++{ ++ ioread8(iobase + TPM_ACCESS(0)); ++} ++#else ++#define tpm_tis_flush(iobase) do { } while (0) ++#endif ++ ++static inline void tpm_tis_iowrite8(u8 b, void __iomem *iobase, u32 addr) ++{ ++ iowrite8(b, iobase + addr); ++ tpm_tis_flush(iobase); ++} ++ ++static inline void tpm_tis_iowrite32(u32 b, void __iomem *iobase, u32 addr) ++{ ++ iowrite32(b, iobase + addr); ++ tpm_tis_flush(iobase); ++} ++ + static int interrupts = -1; + module_param(interrupts, int, 0444); + MODULE_PARM_DESC(interrupts, "Enable interrupts"); +@@ -185,12 +210,12 @@ static int tpm_tcg_write_bytes(struct tpm_tis_data *data, u32 addr, u16 len, + switch (io_mode) { + case TPM_TIS_PHYS_8: + while (len--) +- iowrite8(*value++, phy->iobase + addr); ++ tpm_tis_iowrite8(*value++, phy->iobase, addr); + break; + case TPM_TIS_PHYS_16: + return -EINVAL; + case TPM_TIS_PHYS_32: +- iowrite32(le32_to_cpu(*((__le32 *)value)), phy->iobase + addr); ++ tpm_tis_iowrite32(le32_to_cpu(*((__le32 *)value)), phy->iobase, addr); + break; + } + +diff --git a/drivers/gpio/gpio-mlxbf2.c b/drivers/gpio/gpio-mlxbf2.c +index 64cb060d9d753..77a41151c921b 100644 +--- a/drivers/gpio/gpio-mlxbf2.c ++++ b/drivers/gpio/gpio-mlxbf2.c +@@ -273,10 +273,8 @@ static irqreturn_t mlxbf2_gpio_irq_handler(int irq, void *ptr) + pending = readl(gs->gpio_io + YU_GPIO_CAUSE_OR_CAUSE_EVTEN0); + writel(pending, gs->gpio_io + YU_GPIO_CAUSE_OR_CLRCAUSE); + +- for_each_set_bit(level, &pending, gc->ngpio) { +- int gpio_irq = irq_find_mapping(gc->irq.domain, level); +- generic_handle_irq(gpio_irq); +- } ++ for_each_set_bit(level, &pending, gc->ngpio) ++ generic_handle_domain_irq_safe(gc->irq.domain, level); + + return IRQ_RETVAL(pending); + } +diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig +index 7ae3b7d67fcfc..844f54f1daea9 100644 +--- a/drivers/gpu/drm/i915/Kconfig ++++ b/drivers/gpu/drm/i915/Kconfig +@@ -3,7 +3,6 @@ config DRM_I915 + tristate "Intel 8xx/9xx/G3x/G4x/HD Graphics" + depends on DRM + depends on X86 && PCI +- depends on !PREEMPT_RT + select INTEL_GTT if X86 + select INTERVAL_TREE + # we need shmfs for the swappable backing store, and in particular +diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c +index 4442aa355f868..23085e82c3ed5 100644 +--- a/drivers/gpu/drm/i915/display/intel_crtc.c ++++ b/drivers/gpu/drm/i915/display/intel_crtc.c +@@ -522,7 +522,8 @@ void intel_pipe_update_start(struct intel_crtc_state *new_crtc_state) + */ + intel_psr_wait_for_idle_locked(new_crtc_state); + +- local_irq_disable(); ++ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) ++ local_irq_disable(); + + crtc->debug.min_vbl = min; + crtc->debug.max_vbl = max; +@@ -547,11 +548,13 @@ void intel_pipe_update_start(struct intel_crtc_state *new_crtc_state) + break; + } + +- local_irq_enable(); ++ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) ++ local_irq_enable(); + + timeout = schedule_timeout(timeout); + +- local_irq_disable(); ++ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) ++ local_irq_disable(); + } + + finish_wait(wq, &wait); +@@ -584,7 +587,8 @@ void intel_pipe_update_start(struct intel_crtc_state *new_crtc_state) + return; + + irq_disable: +- local_irq_disable(); ++ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) ++ local_irq_disable(); + } + + #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_VBLANK_EVADE) +@@ -685,7 +689,8 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) + */ + intel_vrr_send_push(new_crtc_state); + +- local_irq_enable(); ++ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) ++ local_irq_enable(); + + if (intel_vgpu_active(dev_priv)) + return; +diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c +index ecc990ec1b952..8d04b10681f0d 100644 +--- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c ++++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c +@@ -312,10 +312,9 @@ void __intel_breadcrumbs_park(struct intel_breadcrumbs *b) + /* Kick the work once more to drain the signalers, and disarm the irq */ + irq_work_sync(&b->irq_work); + while (READ_ONCE(b->irq_armed) && !atomic_read(&b->active)) { +- local_irq_disable(); +- signal_irq_work(&b->irq_work); +- local_irq_enable(); ++ irq_work_queue(&b->irq_work); + cond_resched(); ++ irq_work_sync(&b->irq_work); + } + } + +diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c +index c718e6dc40b51..0e592999b7d60 100644 +--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c ++++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c +@@ -1302,7 +1302,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) + * and context switches) submission. + */ + +- spin_lock(&sched_engine->lock); ++ spin_lock_irq(&sched_engine->lock); + + /* + * If the queue is higher priority than the last +@@ -1402,7 +1402,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) + * Even if ELSP[1] is occupied and not worthy + * of timeslices, our queue might be. + */ +- spin_unlock(&sched_engine->lock); ++ spin_unlock_irq(&sched_engine->lock); + return; + } + } +@@ -1428,7 +1428,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) + + if (last && !can_merge_rq(last, rq)) { + spin_unlock(&ve->base.sched_engine->lock); +- spin_unlock(&engine->sched_engine->lock); ++ spin_unlock_irq(&engine->sched_engine->lock); + return; /* leave this for another sibling */ + } + +@@ -1590,7 +1590,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) + */ + sched_engine->queue_priority_hint = queue_prio(sched_engine); + i915_sched_engine_reset_on_empty(sched_engine); +- spin_unlock(&sched_engine->lock); ++ spin_unlock_irq(&sched_engine->lock); + + /* + * We can skip poking the HW if we ended up with exactly the same set +@@ -1616,13 +1616,6 @@ static void execlists_dequeue(struct intel_engine_cs *engine) + } + } + +-static void execlists_dequeue_irq(struct intel_engine_cs *engine) +-{ +- local_irq_disable(); /* Suspend interrupts across request submission */ +- execlists_dequeue(engine); +- local_irq_enable(); /* flush irq_work (e.g. breadcrumb enabling) */ +-} +- + static void clear_ports(struct i915_request **ports, int count) + { + memset_p((void **)ports, NULL, count); +@@ -2468,7 +2461,7 @@ static void execlists_submission_tasklet(struct tasklet_struct *t) + } + + if (!engine->execlists.pending[0]) { +- execlists_dequeue_irq(engine); ++ execlists_dequeue(engine); + start_timeslice(engine); + } + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 73cebc6aa6507..98305fb393413 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -917,7 +917,8 @@ static bool i915_get_crtc_scanoutpos(struct drm_crtc *_crtc, + */ + spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); + +- /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ ++ if (IS_ENABLED(CONFIG_PREEMPT_RT)) ++ preempt_disable(); + + /* Get optional system timestamp before query. */ + if (stime) +@@ -981,7 +982,8 @@ static bool i915_get_crtc_scanoutpos(struct drm_crtc *_crtc, + if (etime) + *etime = ktime_get(); + +- /* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */ ++ if (IS_ENABLED(CONFIG_PREEMPT_RT)) ++ preempt_enable(); + + spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); + +diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c +index 62fad16a55e84..af07927650b24 100644 +--- a/drivers/gpu/drm/i915/i915_request.c ++++ b/drivers/gpu/drm/i915/i915_request.c +@@ -612,7 +612,6 @@ bool __i915_request_submit(struct i915_request *request) + + RQ_TRACE(request, "\n"); + +- GEM_BUG_ON(!irqs_disabled()); + lockdep_assert_held(&engine->sched_engine->lock); + + /* +@@ -721,7 +720,6 @@ void __i915_request_unsubmit(struct i915_request *request) + */ + RQ_TRACE(request, "\n"); + +- GEM_BUG_ON(!irqs_disabled()); + lockdep_assert_held(&engine->sched_engine->lock); + + /* +diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h +index 37b5c9e9d260e..73f29d8008f0c 100644 +--- a/drivers/gpu/drm/i915/i915_trace.h ++++ b/drivers/gpu/drm/i915/i915_trace.h +@@ -6,6 +6,10 @@ + #if !defined(_I915_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) + #define _I915_TRACE_H_ + ++#ifdef CONFIG_PREEMPT_RT ++#define NOTRACE ++#endif ++ + #include + #include + #include +@@ -323,7 +327,7 @@ DEFINE_EVENT(i915_request, i915_request_add, + TP_ARGS(rq) + ); + +-#if defined(CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS) ++#if defined(CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS) && !defined(NOTRACE) + DEFINE_EVENT(i915_request, i915_request_guc_submit, + TP_PROTO(struct i915_request *rq), + TP_ARGS(rq) +diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h +index c10d68cdc3ca5..593f3a7e0e4fc 100644 +--- a/drivers/gpu/drm/i915/i915_utils.h ++++ b/drivers/gpu/drm/i915/i915_utils.h +@@ -294,7 +294,7 @@ wait_remaining_ms_from_jiffies(unsigned long timestamp_jiffies, int to_wait_ms) + #define wait_for(COND, MS) _wait_for((COND), (MS) * 1000, 10, 1000) + + /* If CONFIG_PREEMPT_COUNT is disabled, in_atomic() always reports false. */ +-#if defined(CONFIG_DRM_I915_DEBUG) && defined(CONFIG_PREEMPT_COUNT) ++#if defined(CONFIG_DRM_I915_DEBUG) && defined(CONFIG_PREEMPT_COUNT) && !defined(CONFIG_PREEMPT_RT) + # define _WAIT_FOR_ATOMIC_CHECK(ATOMIC) WARN_ON_ONCE((ATOMIC) && !in_atomic()) + #else + # define _WAIT_FOR_ATOMIC_CHECK(ATOMIC) do { } while (0) +diff --git a/drivers/net/ethernet/alacritech/slic.h b/drivers/net/ethernet/alacritech/slic.h +index 4eecbdfff3ff1..82071d0e5f7fc 100644 +--- a/drivers/net/ethernet/alacritech/slic.h ++++ b/drivers/net/ethernet/alacritech/slic.h +@@ -288,13 +288,13 @@ do { \ + u64_stats_update_end(&(st)->syncp); \ + } while (0) + +-#define SLIC_GET_STATS_COUNTER(newst, st, counter) \ +-{ \ +- unsigned int start; \ ++#define SLIC_GET_STATS_COUNTER(newst, st, counter) \ ++{ \ ++ unsigned int start; \ + do { \ +- start = u64_stats_fetch_begin_irq(&(st)->syncp); \ +- newst = (st)->counter; \ +- } while (u64_stats_fetch_retry_irq(&(st)->syncp, start)); \ ++ start = u64_stats_fetch_begin(&(st)->syncp); \ ++ newst = (st)->counter; \ ++ } while (u64_stats_fetch_retry(&(st)->syncp, start)); \ + } + + struct slic_upr { +diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c b/drivers/net/ethernet/amazon/ena/ena_ethtool.c +index 39242c5a17290..8f81d288c4880 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c ++++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c +@@ -118,9 +118,9 @@ static void ena_safe_update_stat(u64 *src, u64 *dst, + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(syncp); ++ start = u64_stats_fetch_begin(syncp); + *(dst) = *src; +- } while (u64_stats_fetch_retry_irq(syncp, start)); ++ } while (u64_stats_fetch_retry(syncp, start)); + } + + static void ena_queue_stats(struct ena_adapter *adapter, u64 **data) +diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c +index 6a356a6cee15a..1c5d482990806 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -3270,10 +3270,10 @@ static void ena_get_stats64(struct net_device *netdev, + tx_ring = &adapter->tx_ring[i]; + + do { +- start = u64_stats_fetch_begin_irq(&tx_ring->syncp); ++ start = u64_stats_fetch_begin(&tx_ring->syncp); + packets = tx_ring->tx_stats.cnt; + bytes = tx_ring->tx_stats.bytes; +- } while (u64_stats_fetch_retry_irq(&tx_ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&tx_ring->syncp, start)); + + stats->tx_packets += packets; + stats->tx_bytes += bytes; +@@ -3281,20 +3281,20 @@ static void ena_get_stats64(struct net_device *netdev, + rx_ring = &adapter->rx_ring[i]; + + do { +- start = u64_stats_fetch_begin_irq(&rx_ring->syncp); ++ start = u64_stats_fetch_begin(&rx_ring->syncp); + packets = rx_ring->rx_stats.cnt; + bytes = rx_ring->rx_stats.bytes; +- } while (u64_stats_fetch_retry_irq(&rx_ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&rx_ring->syncp, start)); + + stats->rx_packets += packets; + stats->rx_bytes += bytes; + } + + do { +- start = u64_stats_fetch_begin_irq(&adapter->syncp); ++ start = u64_stats_fetch_begin(&adapter->syncp); + rx_drops = adapter->dev_stats.rx_drops; + tx_drops = adapter->dev_stats.tx_drops; +- } while (u64_stats_fetch_retry_irq(&adapter->syncp, start)); ++ } while (u64_stats_fetch_retry(&adapter->syncp, start)); + + stats->rx_dropped = rx_drops; + stats->tx_dropped = tx_drops; +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +index 25129e723b575..1e8d902e1c8ea 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +@@ -934,7 +934,7 @@ unsigned int aq_ring_fill_stats_data(struct aq_ring_s *self, u64 *data) + /* This data should mimic aq_ethtool_queue_rx_stat_names structure */ + do { + count = 0; +- start = u64_stats_fetch_begin_irq(&self->stats.rx.syncp); ++ start = u64_stats_fetch_begin(&self->stats.rx.syncp); + data[count] = self->stats.rx.packets; + data[++count] = self->stats.rx.jumbo_packets; + data[++count] = self->stats.rx.lro_packets; +@@ -951,15 +951,15 @@ unsigned int aq_ring_fill_stats_data(struct aq_ring_s *self, u64 *data) + data[++count] = self->stats.rx.xdp_tx; + data[++count] = self->stats.rx.xdp_invalid; + data[++count] = self->stats.rx.xdp_redirect; +- } while (u64_stats_fetch_retry_irq(&self->stats.rx.syncp, start)); ++ } while (u64_stats_fetch_retry(&self->stats.rx.syncp, start)); + } else { + /* This data should mimic aq_ethtool_queue_tx_stat_names structure */ + do { + count = 0; +- start = u64_stats_fetch_begin_irq(&self->stats.tx.syncp); ++ start = u64_stats_fetch_begin(&self->stats.tx.syncp); + data[count] = self->stats.tx.packets; + data[++count] = self->stats.tx.queue_restarts; +- } while (u64_stats_fetch_retry_irq(&self->stats.tx.syncp, start)); ++ } while (u64_stats_fetch_retry(&self->stats.tx.syncp, start)); + } + + return ++count; +diff --git a/drivers/net/ethernet/asix/ax88796c_main.c b/drivers/net/ethernet/asix/ax88796c_main.c +index 6ba5b024a7be7..25e7beb68e515 100644 +--- a/drivers/net/ethernet/asix/ax88796c_main.c ++++ b/drivers/net/ethernet/asix/ax88796c_main.c +@@ -662,12 +662,12 @@ static void ax88796c_get_stats64(struct net_device *ndev, + s = per_cpu_ptr(ax_local->stats, cpu); + + do { +- start = u64_stats_fetch_begin_irq(&s->syncp); ++ start = u64_stats_fetch_begin(&s->syncp); + rx_packets = u64_stats_read(&s->rx_packets); + rx_bytes = u64_stats_read(&s->rx_bytes); + tx_packets = u64_stats_read(&s->tx_packets); + tx_bytes = u64_stats_read(&s->tx_bytes); +- } while (u64_stats_fetch_retry_irq(&s->syncp, start)); ++ } while (u64_stats_fetch_retry(&s->syncp, start)); + + stats->rx_packets += rx_packets; + stats->rx_bytes += rx_bytes; +diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c +index e5857e88c2076..caf1714f36a18 100644 +--- a/drivers/net/ethernet/broadcom/b44.c ++++ b/drivers/net/ethernet/broadcom/b44.c +@@ -1680,7 +1680,7 @@ static void b44_get_stats64(struct net_device *dev, + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&hwstat->syncp); ++ start = u64_stats_fetch_begin(&hwstat->syncp); + + /* Convert HW stats into rtnl_link_stats64 stats. */ + nstat->rx_packets = hwstat->rx_pkts; +@@ -1714,7 +1714,7 @@ static void b44_get_stats64(struct net_device *dev, + /* Carrier lost counter seems to be broken for some devices */ + nstat->tx_carrier_errors = hwstat->tx_carrier_lost; + #endif +- } while (u64_stats_fetch_retry_irq(&hwstat->syncp, start)); ++ } while (u64_stats_fetch_retry(&hwstat->syncp, start)); + + } + +@@ -2082,12 +2082,12 @@ static void b44_get_ethtool_stats(struct net_device *dev, + do { + data_src = &hwstat->tx_good_octets; + data_dst = data; +- start = u64_stats_fetch_begin_irq(&hwstat->syncp); ++ start = u64_stats_fetch_begin(&hwstat->syncp); + + for (i = 0; i < ARRAY_SIZE(b44_gstrings); i++) + *data_dst++ = *data_src++; + +- } while (u64_stats_fetch_retry_irq(&hwstat->syncp, start)); ++ } while (u64_stats_fetch_retry(&hwstat->syncp, start)); + } + + static void b44_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c +index 47fc8e6963d59..98d5bd15ee433 100644 +--- a/drivers/net/ethernet/broadcom/bcmsysport.c ++++ b/drivers/net/ethernet/broadcom/bcmsysport.c +@@ -457,10 +457,10 @@ static void bcm_sysport_update_tx_stats(struct bcm_sysport_priv *priv, + for (q = 0; q < priv->netdev->num_tx_queues; q++) { + ring = &priv->tx_rings[q]; + do { +- start = u64_stats_fetch_begin_irq(&priv->syncp); ++ start = u64_stats_fetch_begin(&priv->syncp); + bytes = ring->bytes; + packets = ring->packets; +- } while (u64_stats_fetch_retry_irq(&priv->syncp, start)); ++ } while (u64_stats_fetch_retry(&priv->syncp, start)); + + *tx_bytes += bytes; + *tx_packets += packets; +@@ -504,9 +504,9 @@ static void bcm_sysport_get_stats(struct net_device *dev, + if (s->stat_sizeof == sizeof(u64) && + s->type == BCM_SYSPORT_STAT_NETDEV64) { + do { +- start = u64_stats_fetch_begin_irq(syncp); ++ start = u64_stats_fetch_begin(syncp); + data[i] = *(u64 *)p; +- } while (u64_stats_fetch_retry_irq(syncp, start)); ++ } while (u64_stats_fetch_retry(syncp, start)); + } else + data[i] = *(u32 *)p; + j++; +@@ -1878,10 +1878,10 @@ static void bcm_sysport_get_stats64(struct net_device *dev, + &stats->tx_packets); + + do { +- start = u64_stats_fetch_begin_irq(&priv->syncp); ++ start = u64_stats_fetch_begin(&priv->syncp); + stats->rx_packets = stats64->rx_packets; + stats->rx_bytes = stats64->rx_bytes; +- } while (u64_stats_fetch_retry_irq(&priv->syncp, start)); ++ } while (u64_stats_fetch_retry(&priv->syncp, start)); + } + + static void bcm_sysport_netif_start(struct net_device *dev) +diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c +index 6dae768671e3d..9e6de2f968fa3 100644 +--- a/drivers/net/ethernet/cortina/gemini.c ++++ b/drivers/net/ethernet/cortina/gemini.c +@@ -1919,7 +1919,7 @@ static void gmac_get_stats64(struct net_device *netdev, + + /* Racing with RX NAPI */ + do { +- start = u64_stats_fetch_begin_irq(&port->rx_stats_syncp); ++ start = u64_stats_fetch_begin(&port->rx_stats_syncp); + + stats->rx_packets = port->stats.rx_packets; + stats->rx_bytes = port->stats.rx_bytes; +@@ -1931,11 +1931,11 @@ static void gmac_get_stats64(struct net_device *netdev, + stats->rx_crc_errors = port->stats.rx_crc_errors; + stats->rx_frame_errors = port->stats.rx_frame_errors; + +- } while (u64_stats_fetch_retry_irq(&port->rx_stats_syncp, start)); ++ } while (u64_stats_fetch_retry(&port->rx_stats_syncp, start)); + + /* Racing with MIB and TX completion interrupts */ + do { +- start = u64_stats_fetch_begin_irq(&port->ir_stats_syncp); ++ start = u64_stats_fetch_begin(&port->ir_stats_syncp); + + stats->tx_errors = port->stats.tx_errors; + stats->tx_packets = port->stats.tx_packets; +@@ -1945,15 +1945,15 @@ static void gmac_get_stats64(struct net_device *netdev, + stats->rx_missed_errors = port->stats.rx_missed_errors; + stats->rx_fifo_errors = port->stats.rx_fifo_errors; + +- } while (u64_stats_fetch_retry_irq(&port->ir_stats_syncp, start)); ++ } while (u64_stats_fetch_retry(&port->ir_stats_syncp, start)); + + /* Racing with hard_start_xmit */ + do { +- start = u64_stats_fetch_begin_irq(&port->tx_stats_syncp); ++ start = u64_stats_fetch_begin(&port->tx_stats_syncp); + + stats->tx_dropped = port->stats.tx_dropped; + +- } while (u64_stats_fetch_retry_irq(&port->tx_stats_syncp, start)); ++ } while (u64_stats_fetch_retry(&port->tx_stats_syncp, start)); + + stats->rx_dropped += stats->rx_missed_errors; + } +@@ -2031,18 +2031,18 @@ static void gmac_get_ethtool_stats(struct net_device *netdev, + /* Racing with MIB interrupt */ + do { + p = values; +- start = u64_stats_fetch_begin_irq(&port->ir_stats_syncp); ++ start = u64_stats_fetch_begin(&port->ir_stats_syncp); + + for (i = 0; i < RX_STATS_NUM; i++) + *p++ = port->hw_stats[i]; + +- } while (u64_stats_fetch_retry_irq(&port->ir_stats_syncp, start)); ++ } while (u64_stats_fetch_retry(&port->ir_stats_syncp, start)); + values = p; + + /* Racing with RX NAPI */ + do { + p = values; +- start = u64_stats_fetch_begin_irq(&port->rx_stats_syncp); ++ start = u64_stats_fetch_begin(&port->rx_stats_syncp); + + for (i = 0; i < RX_STATUS_NUM; i++) + *p++ = port->rx_stats[i]; +@@ -2050,13 +2050,13 @@ static void gmac_get_ethtool_stats(struct net_device *netdev, + *p++ = port->rx_csum_stats[i]; + *p++ = port->rx_napi_exits; + +- } while (u64_stats_fetch_retry_irq(&port->rx_stats_syncp, start)); ++ } while (u64_stats_fetch_retry(&port->rx_stats_syncp, start)); + values = p; + + /* Racing with TX start_xmit */ + do { + p = values; +- start = u64_stats_fetch_begin_irq(&port->tx_stats_syncp); ++ start = u64_stats_fetch_begin(&port->tx_stats_syncp); + + for (i = 0; i < TX_MAX_FRAGS; i++) { + *values++ = port->tx_frag_stats[i]; +@@ -2065,7 +2065,7 @@ static void gmac_get_ethtool_stats(struct net_device *netdev, + *values++ = port->tx_frags_linearized; + *values++ = port->tx_hw_csummed; + +- } while (u64_stats_fetch_retry_irq(&port->tx_stats_syncp, start)); ++ } while (u64_stats_fetch_retry(&port->tx_stats_syncp, start)); + } + + static int gmac_get_ksettings(struct net_device *netdev, +diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c +index bd0df189d8719..39e7a4a3c15e6 100644 +--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c ++++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c +@@ -389,10 +389,10 @@ static void be_get_ethtool_stats(struct net_device *netdev, + struct be_rx_stats *stats = rx_stats(rxo); + + do { +- start = u64_stats_fetch_begin_irq(&stats->sync); ++ start = u64_stats_fetch_begin(&stats->sync); + data[base] = stats->rx_bytes; + data[base + 1] = stats->rx_pkts; +- } while (u64_stats_fetch_retry_irq(&stats->sync, start)); ++ } while (u64_stats_fetch_retry(&stats->sync, start)); + + for (i = 2; i < ETHTOOL_RXSTATS_NUM; i++) { + p = (u8 *)stats + et_rx_stats[i].offset; +@@ -405,19 +405,19 @@ static void be_get_ethtool_stats(struct net_device *netdev, + struct be_tx_stats *stats = tx_stats(txo); + + do { +- start = u64_stats_fetch_begin_irq(&stats->sync_compl); ++ start = u64_stats_fetch_begin(&stats->sync_compl); + data[base] = stats->tx_compl; +- } while (u64_stats_fetch_retry_irq(&stats->sync_compl, start)); ++ } while (u64_stats_fetch_retry(&stats->sync_compl, start)); + + do { +- start = u64_stats_fetch_begin_irq(&stats->sync); ++ start = u64_stats_fetch_begin(&stats->sync); + for (i = 1; i < ETHTOOL_TXSTATS_NUM; i++) { + p = (u8 *)stats + et_tx_stats[i].offset; + data[base + i] = + (et_tx_stats[i].size == sizeof(u64)) ? + *(u64 *)p : *(u32 *)p; + } +- } while (u64_stats_fetch_retry_irq(&stats->sync, start)); ++ } while (u64_stats_fetch_retry(&stats->sync, start)); + base += ETHTOOL_TXSTATS_NUM; + } + } +diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c +index 414362febbb9d..9350c901aa27b 100644 +--- a/drivers/net/ethernet/emulex/benet/be_main.c ++++ b/drivers/net/ethernet/emulex/benet/be_main.c +@@ -665,10 +665,10 @@ static void be_get_stats64(struct net_device *netdev, + const struct be_rx_stats *rx_stats = rx_stats(rxo); + + do { +- start = u64_stats_fetch_begin_irq(&rx_stats->sync); ++ start = u64_stats_fetch_begin(&rx_stats->sync); + pkts = rx_stats(rxo)->rx_pkts; + bytes = rx_stats(rxo)->rx_bytes; +- } while (u64_stats_fetch_retry_irq(&rx_stats->sync, start)); ++ } while (u64_stats_fetch_retry(&rx_stats->sync, start)); + stats->rx_packets += pkts; + stats->rx_bytes += bytes; + stats->multicast += rx_stats(rxo)->rx_mcast_pkts; +@@ -680,10 +680,10 @@ static void be_get_stats64(struct net_device *netdev, + const struct be_tx_stats *tx_stats = tx_stats(txo); + + do { +- start = u64_stats_fetch_begin_irq(&tx_stats->sync); ++ start = u64_stats_fetch_begin(&tx_stats->sync); + pkts = tx_stats(txo)->tx_pkts; + bytes = tx_stats(txo)->tx_bytes; +- } while (u64_stats_fetch_retry_irq(&tx_stats->sync, start)); ++ } while (u64_stats_fetch_retry(&tx_stats->sync, start)); + stats->tx_packets += pkts; + stats->tx_bytes += bytes; + } +@@ -2155,16 +2155,16 @@ static int be_get_new_eqd(struct be_eq_obj *eqo) + + for_all_rx_queues_on_eq(adapter, eqo, rxo, i) { + do { +- start = u64_stats_fetch_begin_irq(&rxo->stats.sync); ++ start = u64_stats_fetch_begin(&rxo->stats.sync); + rx_pkts += rxo->stats.rx_pkts; +- } while (u64_stats_fetch_retry_irq(&rxo->stats.sync, start)); ++ } while (u64_stats_fetch_retry(&rxo->stats.sync, start)); + } + + for_all_tx_queues_on_eq(adapter, eqo, txo, i) { + do { +- start = u64_stats_fetch_begin_irq(&txo->stats.sync); ++ start = u64_stats_fetch_begin(&txo->stats.sync); + tx_pkts += txo->stats.tx_reqs; +- } while (u64_stats_fetch_retry_irq(&txo->stats.sync, start)); ++ } while (u64_stats_fetch_retry(&txo->stats.sync, start)); + } + + /* Skip, if wrapped around or first calculation */ +diff --git a/drivers/net/ethernet/fungible/funeth/funeth_txrx.h b/drivers/net/ethernet/fungible/funeth/funeth_txrx.h +index 671f51135c269..53b7e95213a85 100644 +--- a/drivers/net/ethernet/fungible/funeth/funeth_txrx.h ++++ b/drivers/net/ethernet/fungible/funeth/funeth_txrx.h +@@ -206,9 +206,9 @@ struct funeth_rxq { + + #define FUN_QSTAT_READ(q, seq, stats_copy) \ + do { \ +- seq = u64_stats_fetch_begin_irq(&(q)->syncp); \ ++ seq = u64_stats_fetch_begin(&(q)->syncp); \ + stats_copy = (q)->stats; \ +- } while (u64_stats_fetch_retry_irq(&(q)->syncp, (seq))) ++ } while (u64_stats_fetch_retry(&(q)->syncp, (seq))) + + #define FUN_INT_NAME_LEN (IFNAMSIZ + 16) + +diff --git a/drivers/net/ethernet/google/gve/gve_ethtool.c b/drivers/net/ethernet/google/gve/gve_ethtool.c +index 7b9a2d9d96243..50b384910c839 100644 +--- a/drivers/net/ethernet/google/gve/gve_ethtool.c ++++ b/drivers/net/ethernet/google/gve/gve_ethtool.c +@@ -177,14 +177,14 @@ gve_get_ethtool_stats(struct net_device *netdev, + struct gve_rx_ring *rx = &priv->rx[ring]; + + start = +- u64_stats_fetch_begin_irq(&priv->rx[ring].statss); ++ u64_stats_fetch_begin(&priv->rx[ring].statss); + tmp_rx_pkts = rx->rpackets; + tmp_rx_bytes = rx->rbytes; + tmp_rx_skb_alloc_fail = rx->rx_skb_alloc_fail; + tmp_rx_buf_alloc_fail = rx->rx_buf_alloc_fail; + tmp_rx_desc_err_dropped_pkt = + rx->rx_desc_err_dropped_pkt; +- } while (u64_stats_fetch_retry_irq(&priv->rx[ring].statss, ++ } while (u64_stats_fetch_retry(&priv->rx[ring].statss, + start)); + rx_pkts += tmp_rx_pkts; + rx_bytes += tmp_rx_bytes; +@@ -198,10 +198,10 @@ gve_get_ethtool_stats(struct net_device *netdev, + if (priv->tx) { + do { + start = +- u64_stats_fetch_begin_irq(&priv->tx[ring].statss); ++ u64_stats_fetch_begin(&priv->tx[ring].statss); + tmp_tx_pkts = priv->tx[ring].pkt_done; + tmp_tx_bytes = priv->tx[ring].bytes_done; +- } while (u64_stats_fetch_retry_irq(&priv->tx[ring].statss, ++ } while (u64_stats_fetch_retry(&priv->tx[ring].statss, + start)); + tx_pkts += tmp_tx_pkts; + tx_bytes += tmp_tx_bytes; +@@ -259,13 +259,13 @@ gve_get_ethtool_stats(struct net_device *netdev, + data[i++] = rx->fill_cnt - rx->cnt; + do { + start = +- u64_stats_fetch_begin_irq(&priv->rx[ring].statss); ++ u64_stats_fetch_begin(&priv->rx[ring].statss); + tmp_rx_bytes = rx->rbytes; + tmp_rx_skb_alloc_fail = rx->rx_skb_alloc_fail; + tmp_rx_buf_alloc_fail = rx->rx_buf_alloc_fail; + tmp_rx_desc_err_dropped_pkt = + rx->rx_desc_err_dropped_pkt; +- } while (u64_stats_fetch_retry_irq(&priv->rx[ring].statss, ++ } while (u64_stats_fetch_retry(&priv->rx[ring].statss, + start)); + data[i++] = tmp_rx_bytes; + data[i++] = rx->rx_cont_packet_cnt; +@@ -331,9 +331,9 @@ gve_get_ethtool_stats(struct net_device *netdev, + } + do { + start = +- u64_stats_fetch_begin_irq(&priv->tx[ring].statss); ++ u64_stats_fetch_begin(&priv->tx[ring].statss); + tmp_tx_bytes = tx->bytes_done; +- } while (u64_stats_fetch_retry_irq(&priv->tx[ring].statss, ++ } while (u64_stats_fetch_retry(&priv->tx[ring].statss, + start)); + data[i++] = tmp_tx_bytes; + data[i++] = tx->wake_queue; +diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c +index 044db3ebb071c..6cafee55efc32 100644 +--- a/drivers/net/ethernet/google/gve/gve_main.c ++++ b/drivers/net/ethernet/google/gve/gve_main.c +@@ -51,10 +51,10 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s) + for (ring = 0; ring < priv->rx_cfg.num_queues; ring++) { + do { + start = +- u64_stats_fetch_begin_irq(&priv->rx[ring].statss); ++ u64_stats_fetch_begin(&priv->rx[ring].statss); + packets = priv->rx[ring].rpackets; + bytes = priv->rx[ring].rbytes; +- } while (u64_stats_fetch_retry_irq(&priv->rx[ring].statss, ++ } while (u64_stats_fetch_retry(&priv->rx[ring].statss, + start)); + s->rx_packets += packets; + s->rx_bytes += bytes; +@@ -64,10 +64,10 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s) + for (ring = 0; ring < priv->tx_cfg.num_queues; ring++) { + do { + start = +- u64_stats_fetch_begin_irq(&priv->tx[ring].statss); ++ u64_stats_fetch_begin(&priv->tx[ring].statss); + packets = priv->tx[ring].pkt_done; + bytes = priv->tx[ring].bytes_done; +- } while (u64_stats_fetch_retry_irq(&priv->tx[ring].statss, ++ } while (u64_stats_fetch_retry(&priv->tx[ring].statss, + start)); + s->tx_packets += packets; + s->tx_bytes += bytes; +@@ -1274,9 +1274,9 @@ void gve_handle_report_stats(struct gve_priv *priv) + } + + do { +- start = u64_stats_fetch_begin_irq(&priv->tx[idx].statss); ++ start = u64_stats_fetch_begin(&priv->tx[idx].statss); + tx_bytes = priv->tx[idx].bytes_done; +- } while (u64_stats_fetch_retry_irq(&priv->tx[idx].statss, start)); ++ } while (u64_stats_fetch_retry(&priv->tx[idx].statss, start)); + stats[stats_idx++] = (struct stats) { + .stat_name = cpu_to_be32(TX_WAKE_CNT), + .value = cpu_to_be64(priv->tx[idx].wake_queue), +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +index 35d70041b9e84..f82e98263307a 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +@@ -2486,7 +2486,7 @@ static void hns3_fetch_stats(struct rtnl_link_stats64 *stats, + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + if (is_tx) { + stats->tx_bytes += ring->stats.tx_bytes; + stats->tx_packets += ring->stats.tx_pkts; +@@ -2520,7 +2520,7 @@ static void hns3_fetch_stats(struct rtnl_link_stats64 *stats, + stats->multicast += ring->stats.rx_multicast; + stats->rx_length_errors += ring->stats.err_pkt_len; + } +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + } + + static void hns3_nic_get_stats64(struct net_device *netdev, +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_rx.c b/drivers/net/ethernet/huawei/hinic/hinic_rx.c +index e5828a658caf4..a866bea651103 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_rx.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_rx.c +@@ -74,14 +74,14 @@ void hinic_rxq_get_stats(struct hinic_rxq *rxq, struct hinic_rxq_stats *stats) + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&rxq_stats->syncp); ++ start = u64_stats_fetch_begin(&rxq_stats->syncp); + stats->pkts = rxq_stats->pkts; + stats->bytes = rxq_stats->bytes; + stats->errors = rxq_stats->csum_errors + + rxq_stats->other_errors; + stats->csum_errors = rxq_stats->csum_errors; + stats->other_errors = rxq_stats->other_errors; +- } while (u64_stats_fetch_retry_irq(&rxq_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&rxq_stats->syncp, start)); + } + + /** +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_tx.c b/drivers/net/ethernet/huawei/hinic/hinic_tx.c +index 3b6c7b5857376..5051cdff2384b 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_tx.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_tx.c +@@ -99,14 +99,14 @@ void hinic_txq_get_stats(struct hinic_txq *txq, struct hinic_txq_stats *stats) + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&txq_stats->syncp); ++ start = u64_stats_fetch_begin(&txq_stats->syncp); + stats->pkts = txq_stats->pkts; + stats->bytes = txq_stats->bytes; + stats->tx_busy = txq_stats->tx_busy; + stats->tx_wake = txq_stats->tx_wake; + stats->tx_dropped = txq_stats->tx_dropped; + stats->big_frags_pkts = txq_stats->big_frags_pkts; +- } while (u64_stats_fetch_retry_irq(&txq_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&txq_stats->syncp, start)); + } + + /** +diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c +index 2cca9e84e31e1..34ab5ff9823b7 100644 +--- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c +@@ -1229,10 +1229,10 @@ static void fm10k_get_stats64(struct net_device *netdev, + continue; + + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + packets = ring->stats.packets; + bytes = ring->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + + stats->rx_packets += packets; + stats->rx_bytes += bytes; +@@ -1245,10 +1245,10 @@ static void fm10k_get_stats64(struct net_device *netdev, + continue; + + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + packets = ring->stats.packets; + bytes = ring->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + + stats->tx_packets += packets; + stats->tx_bytes += bytes; +diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +index e9cd0fa6a0d2f..90f2eee78a3ee 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +@@ -154,7 +154,7 @@ __i40e_add_ethtool_stats(u64 **data, void *pointer, + * @ring: the ring to copy + * + * Queue statistics must be copied while protected by +- * u64_stats_fetch_begin_irq, so we can't directly use i40e_add_ethtool_stats. ++ * u64_stats_fetch_begin, so we can't directly use i40e_add_ethtool_stats. + * Assumes that queue stats are defined in i40e_gstrings_queue_stats. If the + * ring pointer is null, zero out the queue stat values and update the data + * pointer. Otherwise safely copy the stats from the ring into the supplied +@@ -172,16 +172,16 @@ i40e_add_queue_stats(u64 **data, struct i40e_ring *ring) + + /* To avoid invalid statistics values, ensure that we keep retrying + * the copy until we get a consistent value according to +- * u64_stats_fetch_retry_irq. But first, make sure our ring is ++ * u64_stats_fetch_retry. But first, make sure our ring is + * non-null before attempting to access its syncp. + */ + do { +- start = !ring ? 0 : u64_stats_fetch_begin_irq(&ring->syncp); ++ start = !ring ? 0 : u64_stats_fetch_begin(&ring->syncp); + for (i = 0; i < size; i++) { + i40e_add_one_ethtool_stat(&(*data)[i], ring, + &stats[i]); + } +- } while (ring && u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (ring && u64_stats_fetch_retry(&ring->syncp, start)); + + /* Once we successfully copy the stats in, update the data pointer */ + *data += size; +diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c +index e3d9804aeb25e..09a9f67d9ebc0 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -418,10 +418,10 @@ static void i40e_get_netdev_stats_struct_tx(struct i40e_ring *ring, + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + packets = ring->stats.packets; + bytes = ring->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + + stats->tx_packets += packets; + stats->tx_bytes += bytes; +@@ -471,10 +471,10 @@ static void i40e_get_netdev_stats_struct(struct net_device *netdev, + if (!ring) + continue; + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + packets = ring->stats.packets; + bytes = ring->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + + stats->rx_packets += packets; + stats->rx_bytes += bytes; +@@ -896,10 +896,10 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi) + continue; + + do { +- start = u64_stats_fetch_begin_irq(&p->syncp); ++ start = u64_stats_fetch_begin(&p->syncp); + packets = p->stats.packets; + bytes = p->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&p->syncp, start)); ++ } while (u64_stats_fetch_retry(&p->syncp, start)); + tx_b += bytes; + tx_p += packets; + tx_restart += p->tx_stats.restart_queue; +@@ -914,10 +914,10 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi) + continue; + + do { +- start = u64_stats_fetch_begin_irq(&p->syncp); ++ start = u64_stats_fetch_begin(&p->syncp); + packets = p->stats.packets; + bytes = p->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&p->syncp, start)); ++ } while (u64_stats_fetch_retry(&p->syncp, start)); + rx_b += bytes; + rx_p += packets; + rx_buf += p->rx_stats.alloc_buff_failed; +@@ -934,10 +934,10 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi) + continue; + + do { +- start = u64_stats_fetch_begin_irq(&p->syncp); ++ start = u64_stats_fetch_begin(&p->syncp); + packets = p->stats.packets; + bytes = p->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&p->syncp, start)); ++ } while (u64_stats_fetch_retry(&p->syncp, start)); + tx_b += bytes; + tx_p += packets; + tx_restart += p->tx_stats.restart_queue; +diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c +index e535d4c3da49d..fafa3406e0bcc 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c ++++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c +@@ -147,7 +147,7 @@ __iavf_add_ethtool_stats(u64 **data, void *pointer, + * @ring: the ring to copy + * + * Queue statistics must be copied while protected by +- * u64_stats_fetch_begin_irq, so we can't directly use iavf_add_ethtool_stats. ++ * u64_stats_fetch_begin, so we can't directly use iavf_add_ethtool_stats. + * Assumes that queue stats are defined in iavf_gstrings_queue_stats. If the + * ring pointer is null, zero out the queue stat values and update the data + * pointer. Otherwise safely copy the stats from the ring into the supplied +@@ -165,14 +165,14 @@ iavf_add_queue_stats(u64 **data, struct iavf_ring *ring) + + /* To avoid invalid statistics values, ensure that we keep retrying + * the copy until we get a consistent value according to +- * u64_stats_fetch_retry_irq. But first, make sure our ring is ++ * u64_stats_fetch_retry. But first, make sure our ring is + * non-null before attempting to access its syncp. + */ + do { +- start = !ring ? 0 : u64_stats_fetch_begin_irq(&ring->syncp); ++ start = !ring ? 0 : u64_stats_fetch_begin(&ring->syncp); + for (i = 0; i < size; i++) + iavf_add_one_ethtool_stat(&(*data)[i], ring, &stats[i]); +- } while (ring && u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (ring && u64_stats_fetch_retry(&ring->syncp, start)); + + /* Once we successfully copy the stats in, update the data pointer */ + *data += size; +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index e109cb93886be..b7394c7e5eed2 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -6295,10 +6295,10 @@ ice_fetch_u64_stats_per_ring(struct u64_stats_sync *syncp, + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(syncp); ++ start = u64_stats_fetch_begin(syncp); + *pkts = stats.pkts; + *bytes = stats.bytes; +- } while (u64_stats_fetch_retry_irq(syncp, start)); ++ } while (u64_stats_fetch_retry(syncp, start)); + } + + /** +diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c +index c14fc871dd417..23c6fcfcb905c 100644 +--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c ++++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c +@@ -2311,15 +2311,15 @@ static void igb_get_ethtool_stats(struct net_device *netdev, + + ring = adapter->tx_ring[j]; + do { +- start = u64_stats_fetch_begin_irq(&ring->tx_syncp); ++ start = u64_stats_fetch_begin(&ring->tx_syncp); + data[i] = ring->tx_stats.packets; + data[i+1] = ring->tx_stats.bytes; + data[i+2] = ring->tx_stats.restart_queue; +- } while (u64_stats_fetch_retry_irq(&ring->tx_syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->tx_syncp, start)); + do { +- start = u64_stats_fetch_begin_irq(&ring->tx_syncp2); ++ start = u64_stats_fetch_begin(&ring->tx_syncp2); + restart2 = ring->tx_stats.restart_queue2; +- } while (u64_stats_fetch_retry_irq(&ring->tx_syncp2, start)); ++ } while (u64_stats_fetch_retry(&ring->tx_syncp2, start)); + data[i+2] += restart2; + + i += IGB_TX_QUEUE_STATS_LEN; +@@ -2327,13 +2327,13 @@ static void igb_get_ethtool_stats(struct net_device *netdev, + for (j = 0; j < adapter->num_rx_queues; j++) { + ring = adapter->rx_ring[j]; + do { +- start = u64_stats_fetch_begin_irq(&ring->rx_syncp); ++ start = u64_stats_fetch_begin(&ring->rx_syncp); + data[i] = ring->rx_stats.packets; + data[i+1] = ring->rx_stats.bytes; + data[i+2] = ring->rx_stats.drops; + data[i+3] = ring->rx_stats.csum_err; + data[i+4] = ring->rx_stats.alloc_failed; +- } while (u64_stats_fetch_retry_irq(&ring->rx_syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->rx_syncp, start)); + i += IGB_RX_QUEUE_STATS_LEN; + } + spin_unlock(&adapter->stats64_lock); +diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c +index 2796e81d27260..98df55dc1e933 100644 +--- a/drivers/net/ethernet/intel/igb/igb_main.c ++++ b/drivers/net/ethernet/intel/igb/igb_main.c +@@ -6633,10 +6633,10 @@ void igb_update_stats(struct igb_adapter *adapter) + } + + do { +- start = u64_stats_fetch_begin_irq(&ring->rx_syncp); ++ start = u64_stats_fetch_begin(&ring->rx_syncp); + _bytes = ring->rx_stats.bytes; + _packets = ring->rx_stats.packets; +- } while (u64_stats_fetch_retry_irq(&ring->rx_syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->rx_syncp, start)); + bytes += _bytes; + packets += _packets; + } +@@ -6649,10 +6649,10 @@ void igb_update_stats(struct igb_adapter *adapter) + for (i = 0; i < adapter->num_tx_queues; i++) { + struct igb_ring *ring = adapter->tx_ring[i]; + do { +- start = u64_stats_fetch_begin_irq(&ring->tx_syncp); ++ start = u64_stats_fetch_begin(&ring->tx_syncp); + _bytes = ring->tx_stats.bytes; + _packets = ring->tx_stats.packets; +- } while (u64_stats_fetch_retry_irq(&ring->tx_syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->tx_syncp, start)); + bytes += _bytes; + packets += _packets; + } +diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c +index 8cc077b712add..5a26a7805ef80 100644 +--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c ++++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c +@@ -839,15 +839,15 @@ static void igc_ethtool_get_stats(struct net_device *netdev, + + ring = adapter->tx_ring[j]; + do { +- start = u64_stats_fetch_begin_irq(&ring->tx_syncp); ++ start = u64_stats_fetch_begin(&ring->tx_syncp); + data[i] = ring->tx_stats.packets; + data[i + 1] = ring->tx_stats.bytes; + data[i + 2] = ring->tx_stats.restart_queue; +- } while (u64_stats_fetch_retry_irq(&ring->tx_syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->tx_syncp, start)); + do { +- start = u64_stats_fetch_begin_irq(&ring->tx_syncp2); ++ start = u64_stats_fetch_begin(&ring->tx_syncp2); + restart2 = ring->tx_stats.restart_queue2; +- } while (u64_stats_fetch_retry_irq(&ring->tx_syncp2, start)); ++ } while (u64_stats_fetch_retry(&ring->tx_syncp2, start)); + data[i + 2] += restart2; + + i += IGC_TX_QUEUE_STATS_LEN; +@@ -855,13 +855,13 @@ static void igc_ethtool_get_stats(struct net_device *netdev, + for (j = 0; j < adapter->num_rx_queues; j++) { + ring = adapter->rx_ring[j]; + do { +- start = u64_stats_fetch_begin_irq(&ring->rx_syncp); ++ start = u64_stats_fetch_begin(&ring->rx_syncp); + data[i] = ring->rx_stats.packets; + data[i + 1] = ring->rx_stats.bytes; + data[i + 2] = ring->rx_stats.drops; + data[i + 3] = ring->rx_stats.csum_err; + data[i + 4] = ring->rx_stats.alloc_failed; +- } while (u64_stats_fetch_retry_irq(&ring->rx_syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->rx_syncp, start)); + i += IGC_RX_QUEUE_STATS_LEN; + } + spin_unlock(&adapter->stats64_lock); +diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c +index ebff0e04045d6..944299b06cc3d 100644 +--- a/drivers/net/ethernet/intel/igc/igc_main.c ++++ b/drivers/net/ethernet/intel/igc/igc_main.c +@@ -4645,10 +4645,10 @@ void igc_update_stats(struct igc_adapter *adapter) + } + + do { +- start = u64_stats_fetch_begin_irq(&ring->rx_syncp); ++ start = u64_stats_fetch_begin(&ring->rx_syncp); + _bytes = ring->rx_stats.bytes; + _packets = ring->rx_stats.packets; +- } while (u64_stats_fetch_retry_irq(&ring->rx_syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->rx_syncp, start)); + bytes += _bytes; + packets += _packets; + } +@@ -4662,10 +4662,10 @@ void igc_update_stats(struct igc_adapter *adapter) + struct igc_ring *ring = adapter->tx_ring[i]; + + do { +- start = u64_stats_fetch_begin_irq(&ring->tx_syncp); ++ start = u64_stats_fetch_begin(&ring->tx_syncp); + _bytes = ring->tx_stats.bytes; + _packets = ring->tx_stats.packets; +- } while (u64_stats_fetch_retry_irq(&ring->tx_syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->tx_syncp, start)); + bytes += _bytes; + packets += _packets; + } +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +index 04f453eabef64..51bcf0df3adcc 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +@@ -1335,10 +1335,10 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev, + } + + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + data[i] = ring->stats.packets; + data[i+1] = ring->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + i += 2; + } + for (j = 0; j < IXGBE_NUM_RX_QUEUES; j++) { +@@ -1351,10 +1351,10 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev, + } + + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + data[i] = ring->stats.packets; + data[i+1] = ring->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + i += 2; + } + +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +index d1e430b8c8aa1..01c5548f181d5 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +@@ -9041,10 +9041,10 @@ static void ixgbe_get_ring_stats64(struct rtnl_link_stats64 *stats, + + if (ring) { + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + packets = ring->stats.packets; + bytes = ring->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + stats->tx_packets += packets; + stats->tx_bytes += bytes; + } +@@ -9064,10 +9064,10 @@ static void ixgbe_get_stats64(struct net_device *netdev, + + if (ring) { + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + packets = ring->stats.packets; + bytes = ring->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + stats->rx_packets += packets; + stats->rx_bytes += bytes; + } +diff --git a/drivers/net/ethernet/intel/ixgbevf/ethtool.c b/drivers/net/ethernet/intel/ixgbevf/ethtool.c +index fed46872af2bf..b4632b67ab143 100644 +--- a/drivers/net/ethernet/intel/ixgbevf/ethtool.c ++++ b/drivers/net/ethernet/intel/ixgbevf/ethtool.c +@@ -458,10 +458,10 @@ static void ixgbevf_get_ethtool_stats(struct net_device *netdev, + } + + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + data[i] = ring->stats.packets; + data[i + 1] = ring->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + i += 2; + } + +@@ -475,10 +475,10 @@ static void ixgbevf_get_ethtool_stats(struct net_device *netdev, + } + + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + data[i] = ring->stats.packets; + data[i + 1] = ring->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + i += 2; + } + +@@ -492,10 +492,10 @@ static void ixgbevf_get_ethtool_stats(struct net_device *netdev, + } + + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + data[i] = ring->stats.packets; + data[i + 1] = ring->stats.bytes; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + i += 2; + } + } +diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +index 2f12fbe229c15..1d31b8cff4f10 100644 +--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c ++++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +@@ -4350,10 +4350,10 @@ static void ixgbevf_get_tx_ring_stats(struct rtnl_link_stats64 *stats, + + if (ring) { + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + bytes = ring->stats.bytes; + packets = ring->stats.packets; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + stats->tx_bytes += bytes; + stats->tx_packets += packets; + } +@@ -4376,10 +4376,10 @@ static void ixgbevf_get_stats(struct net_device *netdev, + for (i = 0; i < adapter->num_rx_queues; i++) { + ring = adapter->rx_ring[i]; + do { +- start = u64_stats_fetch_begin_irq(&ring->syncp); ++ start = u64_stats_fetch_begin(&ring->syncp); + bytes = ring->stats.bytes; + packets = ring->stats.packets; +- } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); ++ } while (u64_stats_fetch_retry(&ring->syncp, start)); + stats->rx_bytes += bytes; + stats->rx_packets += packets; + } +diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c +index 0caa2df87c044..89ea3ef0ee162 100644 +--- a/drivers/net/ethernet/marvell/mvneta.c ++++ b/drivers/net/ethernet/marvell/mvneta.c +@@ -813,14 +813,14 @@ mvneta_get_stats64(struct net_device *dev, + + cpu_stats = per_cpu_ptr(pp->stats, cpu); + do { +- start = u64_stats_fetch_begin_irq(&cpu_stats->syncp); ++ start = u64_stats_fetch_begin(&cpu_stats->syncp); + rx_packets = cpu_stats->es.ps.rx_packets; + rx_bytes = cpu_stats->es.ps.rx_bytes; + rx_dropped = cpu_stats->rx_dropped; + rx_errors = cpu_stats->rx_errors; + tx_packets = cpu_stats->es.ps.tx_packets; + tx_bytes = cpu_stats->es.ps.tx_bytes; +- } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&cpu_stats->syncp, start)); + + stats->rx_packets += rx_packets; + stats->rx_bytes += rx_bytes; +@@ -4762,7 +4762,7 @@ mvneta_ethtool_update_pcpu_stats(struct mvneta_port *pp, + + stats = per_cpu_ptr(pp->stats, cpu); + do { +- start = u64_stats_fetch_begin_irq(&stats->syncp); ++ start = u64_stats_fetch_begin(&stats->syncp); + skb_alloc_error = stats->es.skb_alloc_error; + refill_error = stats->es.refill_error; + xdp_redirect = stats->es.ps.xdp_redirect; +@@ -4772,7 +4772,7 @@ mvneta_ethtool_update_pcpu_stats(struct mvneta_port *pp, + xdp_xmit_err = stats->es.ps.xdp_xmit_err; + xdp_tx = stats->es.ps.xdp_tx; + xdp_tx_err = stats->es.ps.xdp_tx_err; +- } while (u64_stats_fetch_retry_irq(&stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&stats->syncp, start)); + + es->skb_alloc_error += skb_alloc_error; + es->refill_error += refill_error; +diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +index eaa51cd7456b6..9dd8e0315dd4f 100644 +--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c ++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +@@ -2008,7 +2008,7 @@ mvpp2_get_xdp_stats(struct mvpp2_port *port, struct mvpp2_pcpu_stats *xdp_stats) + + cpu_stats = per_cpu_ptr(port->stats, cpu); + do { +- start = u64_stats_fetch_begin_irq(&cpu_stats->syncp); ++ start = u64_stats_fetch_begin(&cpu_stats->syncp); + xdp_redirect = cpu_stats->xdp_redirect; + xdp_pass = cpu_stats->xdp_pass; + xdp_drop = cpu_stats->xdp_drop; +@@ -2016,7 +2016,7 @@ mvpp2_get_xdp_stats(struct mvpp2_port *port, struct mvpp2_pcpu_stats *xdp_stats) + xdp_xmit_err = cpu_stats->xdp_xmit_err; + xdp_tx = cpu_stats->xdp_tx; + xdp_tx_err = cpu_stats->xdp_tx_err; +- } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&cpu_stats->syncp, start)); + + xdp_stats->xdp_redirect += xdp_redirect; + xdp_stats->xdp_pass += xdp_pass; +@@ -5115,12 +5115,12 @@ mvpp2_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) + + cpu_stats = per_cpu_ptr(port->stats, cpu); + do { +- start = u64_stats_fetch_begin_irq(&cpu_stats->syncp); ++ start = u64_stats_fetch_begin(&cpu_stats->syncp); + rx_packets = cpu_stats->rx_packets; + rx_bytes = cpu_stats->rx_bytes; + tx_packets = cpu_stats->tx_packets; + tx_bytes = cpu_stats->tx_bytes; +- } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&cpu_stats->syncp, start)); + + stats->rx_packets += rx_packets; + stats->rx_bytes += rx_bytes; +diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c +index bbea5458000bf..c9bb92187719c 100644 +--- a/drivers/net/ethernet/marvell/sky2.c ++++ b/drivers/net/ethernet/marvell/sky2.c +@@ -3894,19 +3894,19 @@ static void sky2_get_stats(struct net_device *dev, + u64 _bytes, _packets; + + do { +- start = u64_stats_fetch_begin_irq(&sky2->rx_stats.syncp); ++ start = u64_stats_fetch_begin(&sky2->rx_stats.syncp); + _bytes = sky2->rx_stats.bytes; + _packets = sky2->rx_stats.packets; +- } while (u64_stats_fetch_retry_irq(&sky2->rx_stats.syncp, start)); ++ } while (u64_stats_fetch_retry(&sky2->rx_stats.syncp, start)); + + stats->rx_packets = _packets; + stats->rx_bytes = _bytes; + + do { +- start = u64_stats_fetch_begin_irq(&sky2->tx_stats.syncp); ++ start = u64_stats_fetch_begin(&sky2->tx_stats.syncp); + _bytes = sky2->tx_stats.bytes; + _packets = sky2->tx_stats.packets; +- } while (u64_stats_fetch_retry_irq(&sky2->tx_stats.syncp, start)); ++ } while (u64_stats_fetch_retry(&sky2->tx_stats.syncp, start)); + + stats->tx_packets = _packets; + stats->tx_bytes = _bytes; +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index b344632beaddf..988927f8c5d7d 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -853,7 +853,7 @@ static void mtk_get_stats64(struct net_device *dev, + } + + do { +- start = u64_stats_fetch_begin_irq(&hw_stats->syncp); ++ start = u64_stats_fetch_begin(&hw_stats->syncp); + storage->rx_packets = hw_stats->rx_packets; + storage->tx_packets = hw_stats->tx_packets; + storage->rx_bytes = hw_stats->rx_bytes; +@@ -865,7 +865,7 @@ static void mtk_get_stats64(struct net_device *dev, + storage->rx_crc_errors = hw_stats->rx_fcs_errors; + storage->rx_errors = hw_stats->rx_checksum_errors; + storage->tx_aborted_errors = hw_stats->tx_skip; +- } while (u64_stats_fetch_retry_irq(&hw_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&hw_stats->syncp, start)); + + storage->tx_errors = dev->stats.tx_errors; + storage->rx_dropped = dev->stats.rx_dropped; +@@ -3664,13 +3664,13 @@ static void mtk_get_ethtool_stats(struct net_device *dev, + + do { + data_dst = data; +- start = u64_stats_fetch_begin_irq(&hwstats->syncp); ++ start = u64_stats_fetch_begin(&hwstats->syncp); + + for (i = 0; i < ARRAY_SIZE(mtk_ethtool_stats); i++) + *data_dst++ = *(data_src + mtk_ethtool_stats[i].offset); + if (mtk_page_pool_enabled(mac->hw)) + mtk_ethtool_pp_stats(mac->hw, data_dst); +- } while (u64_stats_fetch_retry_irq(&hwstats->syncp, start)); ++ } while (u64_stats_fetch_retry(&hwstats->syncp, start)); + } + + static int mtk_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +index 30c7b0e157218..fa2753318cdf7 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +@@ -827,12 +827,12 @@ mlxsw_sp_port_get_sw_stats64(const struct net_device *dev, + for_each_possible_cpu(i) { + p = per_cpu_ptr(mlxsw_sp_port->pcpu_stats, i); + do { +- start = u64_stats_fetch_begin_irq(&p->syncp); ++ start = u64_stats_fetch_begin(&p->syncp); + rx_packets = p->rx_packets; + rx_bytes = p->rx_bytes; + tx_packets = p->tx_packets; + tx_bytes = p->tx_bytes; +- } while (u64_stats_fetch_retry_irq(&p->syncp, start)); ++ } while (u64_stats_fetch_retry(&p->syncp, start)); + + stats->rx_packets += rx_packets; + stats->rx_bytes += rx_bytes; +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index 9259a74eca40b..318dbbb482797 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -315,10 +315,10 @@ static void mana_get_stats64(struct net_device *ndev, + rx_stats = &apc->rxqs[q]->stats; + + do { +- start = u64_stats_fetch_begin_irq(&rx_stats->syncp); ++ start = u64_stats_fetch_begin(&rx_stats->syncp); + packets = rx_stats->packets; + bytes = rx_stats->bytes; +- } while (u64_stats_fetch_retry_irq(&rx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&rx_stats->syncp, start)); + + st->rx_packets += packets; + st->rx_bytes += bytes; +@@ -328,10 +328,10 @@ static void mana_get_stats64(struct net_device *ndev, + tx_stats = &apc->tx_qp[q].txq.stats; + + do { +- start = u64_stats_fetch_begin_irq(&tx_stats->syncp); ++ start = u64_stats_fetch_begin(&tx_stats->syncp); + packets = tx_stats->packets; + bytes = tx_stats->bytes; +- } while (u64_stats_fetch_retry_irq(&tx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&tx_stats->syncp, start)); + + st->tx_packets += packets; + st->tx_bytes += bytes; +diff --git a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c +index c530db76880f0..96d55c91c9698 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c +@@ -90,13 +90,13 @@ static void mana_get_ethtool_stats(struct net_device *ndev, + rx_stats = &apc->rxqs[q]->stats; + + do { +- start = u64_stats_fetch_begin_irq(&rx_stats->syncp); ++ start = u64_stats_fetch_begin(&rx_stats->syncp); + packets = rx_stats->packets; + bytes = rx_stats->bytes; + xdp_drop = rx_stats->xdp_drop; + xdp_tx = rx_stats->xdp_tx; + xdp_redirect = rx_stats->xdp_redirect; +- } while (u64_stats_fetch_retry_irq(&rx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&rx_stats->syncp, start)); + + data[i++] = packets; + data[i++] = bytes; +@@ -109,11 +109,11 @@ static void mana_get_ethtool_stats(struct net_device *ndev, + tx_stats = &apc->tx_qp[q].txq.stats; + + do { +- start = u64_stats_fetch_begin_irq(&tx_stats->syncp); ++ start = u64_stats_fetch_begin(&tx_stats->syncp); + packets = tx_stats->packets; + bytes = tx_stats->bytes; + xdp_xmit = tx_stats->xdp_xmit; +- } while (u64_stats_fetch_retry_irq(&tx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&tx_stats->syncp, start)); + + data[i++] = packets; + data[i++] = bytes; +diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +index 349a2b1a19a24..cf4d6f1129fa2 100644 +--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c ++++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +@@ -1630,21 +1630,21 @@ static void nfp_net_stat64(struct net_device *netdev, + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&r_vec->rx_sync); ++ start = u64_stats_fetch_begin(&r_vec->rx_sync); + data[0] = r_vec->rx_pkts; + data[1] = r_vec->rx_bytes; + data[2] = r_vec->rx_drops; +- } while (u64_stats_fetch_retry_irq(&r_vec->rx_sync, start)); ++ } while (u64_stats_fetch_retry(&r_vec->rx_sync, start)); + stats->rx_packets += data[0]; + stats->rx_bytes += data[1]; + stats->rx_dropped += data[2]; + + do { +- start = u64_stats_fetch_begin_irq(&r_vec->tx_sync); ++ start = u64_stats_fetch_begin(&r_vec->tx_sync); + data[0] = r_vec->tx_pkts; + data[1] = r_vec->tx_bytes; + data[2] = r_vec->tx_errors; +- } while (u64_stats_fetch_retry_irq(&r_vec->tx_sync, start)); ++ } while (u64_stats_fetch_retry(&r_vec->tx_sync, start)); + stats->tx_packets += data[0]; + stats->tx_bytes += data[1]; + stats->tx_errors += data[2]; +diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c +index b1b1b648e40cb..eeb1455a4e5db 100644 +--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c ++++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c +@@ -649,7 +649,7 @@ static u64 *nfp_vnic_get_sw_stats(struct net_device *netdev, u64 *data) + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&nn->r_vecs[i].rx_sync); ++ start = u64_stats_fetch_begin(&nn->r_vecs[i].rx_sync); + data[0] = nn->r_vecs[i].rx_pkts; + tmp[0] = nn->r_vecs[i].hw_csum_rx_ok; + tmp[1] = nn->r_vecs[i].hw_csum_rx_inner_ok; +@@ -657,10 +657,10 @@ static u64 *nfp_vnic_get_sw_stats(struct net_device *netdev, u64 *data) + tmp[3] = nn->r_vecs[i].hw_csum_rx_error; + tmp[4] = nn->r_vecs[i].rx_replace_buf_alloc_fail; + tmp[5] = nn->r_vecs[i].hw_tls_rx; +- } while (u64_stats_fetch_retry_irq(&nn->r_vecs[i].rx_sync, start)); ++ } while (u64_stats_fetch_retry(&nn->r_vecs[i].rx_sync, start)); + + do { +- start = u64_stats_fetch_begin_irq(&nn->r_vecs[i].tx_sync); ++ start = u64_stats_fetch_begin(&nn->r_vecs[i].tx_sync); + data[1] = nn->r_vecs[i].tx_pkts; + data[2] = nn->r_vecs[i].tx_busy; + tmp[6] = nn->r_vecs[i].hw_csum_tx; +@@ -670,7 +670,7 @@ static u64 *nfp_vnic_get_sw_stats(struct net_device *netdev, u64 *data) + tmp[10] = nn->r_vecs[i].hw_tls_tx; + tmp[11] = nn->r_vecs[i].tls_tx_fallback; + tmp[12] = nn->r_vecs[i].tls_tx_no_fallback; +- } while (u64_stats_fetch_retry_irq(&nn->r_vecs[i].tx_sync, start)); ++ } while (u64_stats_fetch_retry(&nn->r_vecs[i].tx_sync, start)); + + data += NN_RVEC_PER_Q_STATS; + +diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c +index 8b77582bdfa01..a6b6ca1fd55ee 100644 +--- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c ++++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c +@@ -134,13 +134,13 @@ nfp_repr_get_host_stats64(const struct net_device *netdev, + + repr_stats = per_cpu_ptr(repr->stats, i); + do { +- start = u64_stats_fetch_begin_irq(&repr_stats->syncp); ++ start = u64_stats_fetch_begin(&repr_stats->syncp); + tbytes = repr_stats->tx_bytes; + tpkts = repr_stats->tx_packets; + tdrops = repr_stats->tx_drops; + rbytes = repr_stats->rx_bytes; + rpkts = repr_stats->rx_packets; +- } while (u64_stats_fetch_retry_irq(&repr_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&repr_stats->syncp, start)); + + stats->tx_bytes += tbytes; + stats->tx_packets += tpkts; +diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c +index 5116badaf0919..50ebbd7e91c48 100644 +--- a/drivers/net/ethernet/nvidia/forcedeth.c ++++ b/drivers/net/ethernet/nvidia/forcedeth.c +@@ -1734,12 +1734,12 @@ static void nv_get_stats(int cpu, struct fe_priv *np, + u64 tx_packets, tx_bytes, tx_dropped; + + do { +- syncp_start = u64_stats_fetch_begin_irq(&np->swstats_rx_syncp); ++ syncp_start = u64_stats_fetch_begin(&np->swstats_rx_syncp); + rx_packets = src->stat_rx_packets; + rx_bytes = src->stat_rx_bytes; + rx_dropped = src->stat_rx_dropped; + rx_missed_errors = src->stat_rx_missed_errors; +- } while (u64_stats_fetch_retry_irq(&np->swstats_rx_syncp, syncp_start)); ++ } while (u64_stats_fetch_retry(&np->swstats_rx_syncp, syncp_start)); + + storage->rx_packets += rx_packets; + storage->rx_bytes += rx_bytes; +@@ -1747,11 +1747,11 @@ static void nv_get_stats(int cpu, struct fe_priv *np, + storage->rx_missed_errors += rx_missed_errors; + + do { +- syncp_start = u64_stats_fetch_begin_irq(&np->swstats_tx_syncp); ++ syncp_start = u64_stats_fetch_begin(&np->swstats_tx_syncp); + tx_packets = src->stat_tx_packets; + tx_bytes = src->stat_tx_bytes; + tx_dropped = src->stat_tx_dropped; +- } while (u64_stats_fetch_retry_irq(&np->swstats_tx_syncp, syncp_start)); ++ } while (u64_stats_fetch_retry(&np->swstats_tx_syncp, syncp_start)); + + storage->tx_packets += tx_packets; + storage->tx_bytes += tx_bytes; +diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c +index 1b2119b1d48aa..3f5e6572d20e7 100644 +--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c ++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c +@@ -135,9 +135,9 @@ static void rmnet_get_stats64(struct net_device *dev, + pcpu_ptr = per_cpu_ptr(priv->pcpu_stats, cpu); + + do { +- start = u64_stats_fetch_begin_irq(&pcpu_ptr->syncp); ++ start = u64_stats_fetch_begin(&pcpu_ptr->syncp); + snapshot = pcpu_ptr->stats; /* struct assignment */ +- } while (u64_stats_fetch_retry_irq(&pcpu_ptr->syncp, start)); ++ } while (u64_stats_fetch_retry(&pcpu_ptr->syncp, start)); + + total_stats.rx_pkts += snapshot.rx_pkts; + total_stats.rx_bytes += snapshot.rx_bytes; +diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c +index 15b40fd93cd2e..82bd0eb614634 100644 +--- a/drivers/net/ethernet/realtek/8139too.c ++++ b/drivers/net/ethernet/realtek/8139too.c +@@ -2532,16 +2532,16 @@ rtl8139_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) + netdev_stats_to_stats64(stats, &dev->stats); + + do { +- start = u64_stats_fetch_begin_irq(&tp->rx_stats.syncp); ++ start = u64_stats_fetch_begin(&tp->rx_stats.syncp); + stats->rx_packets = tp->rx_stats.packets; + stats->rx_bytes = tp->rx_stats.bytes; +- } while (u64_stats_fetch_retry_irq(&tp->rx_stats.syncp, start)); ++ } while (u64_stats_fetch_retry(&tp->rx_stats.syncp, start)); + + do { +- start = u64_stats_fetch_begin_irq(&tp->tx_stats.syncp); ++ start = u64_stats_fetch_begin(&tp->tx_stats.syncp); + stats->tx_packets = tp->tx_stats.packets; + stats->tx_bytes = tp->tx_stats.bytes; +- } while (u64_stats_fetch_retry_irq(&tp->tx_stats.syncp, start)); ++ } while (u64_stats_fetch_retry(&tp->tx_stats.syncp, start)); + } + + /* Set or clear the multicast filter for this adaptor. +diff --git a/drivers/net/ethernet/socionext/sni_ave.c b/drivers/net/ethernet/socionext/sni_ave.c +index f0c8de2c60755..d4f7238333bb7 100644 +--- a/drivers/net/ethernet/socionext/sni_ave.c ++++ b/drivers/net/ethernet/socionext/sni_ave.c +@@ -1506,16 +1506,16 @@ static void ave_get_stats64(struct net_device *ndev, + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&priv->stats_rx.syncp); ++ start = u64_stats_fetch_begin(&priv->stats_rx.syncp); + stats->rx_packets = priv->stats_rx.packets; + stats->rx_bytes = priv->stats_rx.bytes; +- } while (u64_stats_fetch_retry_irq(&priv->stats_rx.syncp, start)); ++ } while (u64_stats_fetch_retry(&priv->stats_rx.syncp, start)); + + do { +- start = u64_stats_fetch_begin_irq(&priv->stats_tx.syncp); ++ start = u64_stats_fetch_begin(&priv->stats_tx.syncp); + stats->tx_packets = priv->stats_tx.packets; + stats->tx_bytes = priv->stats_tx.bytes; +- } while (u64_stats_fetch_retry_irq(&priv->stats_tx.syncp, start)); ++ } while (u64_stats_fetch_retry(&priv->stats_tx.syncp, start)); + + stats->rx_errors = priv->stats_rx.errors; + stats->tx_errors = priv->stats_tx.errors; +diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c +index f4a6b590a1e39..1b62400c19049 100644 +--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c ++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c +@@ -1365,12 +1365,12 @@ static void am65_cpsw_nuss_ndo_get_stats(struct net_device *dev, + + cpu_stats = per_cpu_ptr(ndev_priv->stats, cpu); + do { +- start = u64_stats_fetch_begin_irq(&cpu_stats->syncp); ++ start = u64_stats_fetch_begin(&cpu_stats->syncp); + rx_packets = cpu_stats->rx_packets; + rx_bytes = cpu_stats->rx_bytes; + tx_packets = cpu_stats->tx_packets; + tx_bytes = cpu_stats->tx_bytes; +- } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&cpu_stats->syncp, start)); + + stats->rx_packets += rx_packets; + stats->rx_bytes += rx_bytes; +diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c +index b15d44261e766..68c7b2c05aab3 100644 +--- a/drivers/net/ethernet/ti/netcp_core.c ++++ b/drivers/net/ethernet/ti/netcp_core.c +@@ -1916,16 +1916,16 @@ netcp_get_stats(struct net_device *ndev, struct rtnl_link_stats64 *stats) + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&p->syncp_rx); ++ start = u64_stats_fetch_begin(&p->syncp_rx); + rxpackets = p->rx_packets; + rxbytes = p->rx_bytes; +- } while (u64_stats_fetch_retry_irq(&p->syncp_rx, start)); ++ } while (u64_stats_fetch_retry(&p->syncp_rx, start)); + + do { +- start = u64_stats_fetch_begin_irq(&p->syncp_tx); ++ start = u64_stats_fetch_begin(&p->syncp_tx); + txpackets = p->tx_packets; + txbytes = p->tx_bytes; +- } while (u64_stats_fetch_retry_irq(&p->syncp_tx, start)); ++ } while (u64_stats_fetch_retry(&p->syncp_tx, start)); + + stats->rx_packets = rxpackets; + stats->rx_bytes = rxbytes; +diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c +index 509c5e9b29dfa..5301c907b5ae3 100644 +--- a/drivers/net/ethernet/via/via-rhine.c ++++ b/drivers/net/ethernet/via/via-rhine.c +@@ -2217,16 +2217,16 @@ rhine_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) + netdev_stats_to_stats64(stats, &dev->stats); + + do { +- start = u64_stats_fetch_begin_irq(&rp->rx_stats.syncp); ++ start = u64_stats_fetch_begin(&rp->rx_stats.syncp); + stats->rx_packets = rp->rx_stats.packets; + stats->rx_bytes = rp->rx_stats.bytes; +- } while (u64_stats_fetch_retry_irq(&rp->rx_stats.syncp, start)); ++ } while (u64_stats_fetch_retry(&rp->rx_stats.syncp, start)); + + do { +- start = u64_stats_fetch_begin_irq(&rp->tx_stats.syncp); ++ start = u64_stats_fetch_begin(&rp->tx_stats.syncp); + stats->tx_packets = rp->tx_stats.packets; + stats->tx_bytes = rp->tx_stats.bytes; +- } while (u64_stats_fetch_retry_irq(&rp->tx_stats.syncp, start)); ++ } while (u64_stats_fetch_retry(&rp->tx_stats.syncp, start)); + } + + static void rhine_set_rx_mode(struct net_device *dev) +diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +index 9262988d26a32..2c233b59e7d93 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c ++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +@@ -1305,16 +1305,16 @@ axienet_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) + netdev_stats_to_stats64(stats, &dev->stats); + + do { +- start = u64_stats_fetch_begin_irq(&lp->rx_stat_sync); ++ start = u64_stats_fetch_begin(&lp->rx_stat_sync); + stats->rx_packets = u64_stats_read(&lp->rx_packets); + stats->rx_bytes = u64_stats_read(&lp->rx_bytes); +- } while (u64_stats_fetch_retry_irq(&lp->rx_stat_sync, start)); ++ } while (u64_stats_fetch_retry(&lp->rx_stat_sync, start)); + + do { +- start = u64_stats_fetch_begin_irq(&lp->tx_stat_sync); ++ start = u64_stats_fetch_begin(&lp->tx_stat_sync); + stats->tx_packets = u64_stats_read(&lp->tx_packets); + stats->tx_bytes = u64_stats_read(&lp->tx_bytes); +- } while (u64_stats_fetch_retry_irq(&lp->tx_stat_sync, start)); ++ } while (u64_stats_fetch_retry(&lp->tx_stat_sync, start)); + } + + static const struct net_device_ops axienet_netdev_ops = { +diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c +index 8113ac17ab70a..2fd8b9c51e839 100644 +--- a/drivers/net/hyperv/netvsc_drv.c ++++ b/drivers/net/hyperv/netvsc_drv.c +@@ -1264,12 +1264,12 @@ static void netvsc_get_vf_stats(struct net_device *net, + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&stats->syncp); ++ start = u64_stats_fetch_begin(&stats->syncp); + rx_packets = stats->rx_packets; + tx_packets = stats->tx_packets; + rx_bytes = stats->rx_bytes; + tx_bytes = stats->tx_bytes; +- } while (u64_stats_fetch_retry_irq(&stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&stats->syncp, start)); + + tot->rx_packets += rx_packets; + tot->tx_packets += tx_packets; +@@ -1294,12 +1294,12 @@ static void netvsc_get_pcpu_stats(struct net_device *net, + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&stats->syncp); ++ start = u64_stats_fetch_begin(&stats->syncp); + this_tot->vf_rx_packets = stats->rx_packets; + this_tot->vf_tx_packets = stats->tx_packets; + this_tot->vf_rx_bytes = stats->rx_bytes; + this_tot->vf_tx_bytes = stats->tx_bytes; +- } while (u64_stats_fetch_retry_irq(&stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&stats->syncp, start)); + this_tot->rx_packets = this_tot->vf_rx_packets; + this_tot->tx_packets = this_tot->vf_tx_packets; + this_tot->rx_bytes = this_tot->vf_rx_bytes; +@@ -1318,20 +1318,20 @@ static void netvsc_get_pcpu_stats(struct net_device *net, + + tx_stats = &nvchan->tx_stats; + do { +- start = u64_stats_fetch_begin_irq(&tx_stats->syncp); ++ start = u64_stats_fetch_begin(&tx_stats->syncp); + packets = tx_stats->packets; + bytes = tx_stats->bytes; +- } while (u64_stats_fetch_retry_irq(&tx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&tx_stats->syncp, start)); + + this_tot->tx_bytes += bytes; + this_tot->tx_packets += packets; + + rx_stats = &nvchan->rx_stats; + do { +- start = u64_stats_fetch_begin_irq(&rx_stats->syncp); ++ start = u64_stats_fetch_begin(&rx_stats->syncp); + packets = rx_stats->packets; + bytes = rx_stats->bytes; +- } while (u64_stats_fetch_retry_irq(&rx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&rx_stats->syncp, start)); + + this_tot->rx_bytes += bytes; + this_tot->rx_packets += packets; +@@ -1370,21 +1370,21 @@ static void netvsc_get_stats64(struct net_device *net, + + tx_stats = &nvchan->tx_stats; + do { +- start = u64_stats_fetch_begin_irq(&tx_stats->syncp); ++ start = u64_stats_fetch_begin(&tx_stats->syncp); + packets = tx_stats->packets; + bytes = tx_stats->bytes; +- } while (u64_stats_fetch_retry_irq(&tx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&tx_stats->syncp, start)); + + t->tx_bytes += bytes; + t->tx_packets += packets; + + rx_stats = &nvchan->rx_stats; + do { +- start = u64_stats_fetch_begin_irq(&rx_stats->syncp); ++ start = u64_stats_fetch_begin(&rx_stats->syncp); + packets = rx_stats->packets; + bytes = rx_stats->bytes; + multicast = rx_stats->multicast + rx_stats->broadcast; +- } while (u64_stats_fetch_retry_irq(&rx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&rx_stats->syncp, start)); + + t->rx_bytes += bytes; + t->rx_packets += packets; +@@ -1527,24 +1527,24 @@ static void netvsc_get_ethtool_stats(struct net_device *dev, + tx_stats = &nvdev->chan_table[j].tx_stats; + + do { +- start = u64_stats_fetch_begin_irq(&tx_stats->syncp); ++ start = u64_stats_fetch_begin(&tx_stats->syncp); + packets = tx_stats->packets; + bytes = tx_stats->bytes; + xdp_xmit = tx_stats->xdp_xmit; +- } while (u64_stats_fetch_retry_irq(&tx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&tx_stats->syncp, start)); + data[i++] = packets; + data[i++] = bytes; + data[i++] = xdp_xmit; + + rx_stats = &nvdev->chan_table[j].rx_stats; + do { +- start = u64_stats_fetch_begin_irq(&rx_stats->syncp); ++ start = u64_stats_fetch_begin(&rx_stats->syncp); + packets = rx_stats->packets; + bytes = rx_stats->bytes; + xdp_drop = rx_stats->xdp_drop; + xdp_redirect = rx_stats->xdp_redirect; + xdp_tx = rx_stats->xdp_tx; +- } while (u64_stats_fetch_retry_irq(&rx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&rx_stats->syncp, start)); + data[i++] = packets; + data[i++] = bytes; + data[i++] = xdp_drop; +diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c +index 1c64d5347b8e0..78253ad57b2ef 100644 +--- a/drivers/net/ifb.c ++++ b/drivers/net/ifb.c +@@ -162,18 +162,18 @@ static void ifb_stats64(struct net_device *dev, + + for (i = 0; i < dev->num_tx_queues; i++,txp++) { + do { +- start = u64_stats_fetch_begin_irq(&txp->rx_stats.sync); ++ start = u64_stats_fetch_begin(&txp->rx_stats.sync); + packets = txp->rx_stats.packets; + bytes = txp->rx_stats.bytes; +- } while (u64_stats_fetch_retry_irq(&txp->rx_stats.sync, start)); ++ } while (u64_stats_fetch_retry(&txp->rx_stats.sync, start)); + stats->rx_packets += packets; + stats->rx_bytes += bytes; + + do { +- start = u64_stats_fetch_begin_irq(&txp->tx_stats.sync); ++ start = u64_stats_fetch_begin(&txp->tx_stats.sync); + packets = txp->tx_stats.packets; + bytes = txp->tx_stats.bytes; +- } while (u64_stats_fetch_retry_irq(&txp->tx_stats.sync, start)); ++ } while (u64_stats_fetch_retry(&txp->tx_stats.sync, start)); + stats->tx_packets += packets; + stats->tx_bytes += bytes; + } +@@ -245,12 +245,12 @@ static void ifb_fill_stats_data(u64 **data, + int j; + + do { +- start = u64_stats_fetch_begin_irq(&q_stats->sync); ++ start = u64_stats_fetch_begin(&q_stats->sync); + for (j = 0; j < IFB_Q_STATS_LEN; j++) { + offset = ifb_q_stats_desc[j].offset; + (*data)[j] = *(u64 *)(stats_base + offset); + } +- } while (u64_stats_fetch_retry_irq(&q_stats->sync, start)); ++ } while (u64_stats_fetch_retry(&q_stats->sync, start)); + + *data += IFB_Q_STATS_LEN; + } +diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c +index 49ba8a50dfb1e..8a58d74638cd8 100644 +--- a/drivers/net/ipvlan/ipvlan_main.c ++++ b/drivers/net/ipvlan/ipvlan_main.c +@@ -299,13 +299,13 @@ static void ipvlan_get_stats64(struct net_device *dev, + for_each_possible_cpu(idx) { + pcptr = per_cpu_ptr(ipvlan->pcpu_stats, idx); + do { +- strt= u64_stats_fetch_begin_irq(&pcptr->syncp); ++ strt = u64_stats_fetch_begin(&pcptr->syncp); + rx_pkts = u64_stats_read(&pcptr->rx_pkts); + rx_bytes = u64_stats_read(&pcptr->rx_bytes); + rx_mcast = u64_stats_read(&pcptr->rx_mcast); + tx_pkts = u64_stats_read(&pcptr->tx_pkts); + tx_bytes = u64_stats_read(&pcptr->tx_bytes); +- } while (u64_stats_fetch_retry_irq(&pcptr->syncp, ++ } while (u64_stats_fetch_retry(&pcptr->syncp, + strt)); + + s->rx_packets += rx_pkts; +diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c +index 14e8d04cb4347..c4ad98d39ea60 100644 +--- a/drivers/net/loopback.c ++++ b/drivers/net/loopback.c +@@ -106,10 +106,10 @@ void dev_lstats_read(struct net_device *dev, u64 *packets, u64 *bytes) + + lb_stats = per_cpu_ptr(dev->lstats, i); + do { +- start = u64_stats_fetch_begin_irq(&lb_stats->syncp); ++ start = u64_stats_fetch_begin(&lb_stats->syncp); + tpackets = u64_stats_read(&lb_stats->packets); + tbytes = u64_stats_read(&lb_stats->bytes); +- } while (u64_stats_fetch_retry_irq(&lb_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&lb_stats->syncp, start)); + *bytes += tbytes; + *packets += tpackets; + } +diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c +index c6d271e5687e9..5056f3cd5699a 100644 +--- a/drivers/net/macsec.c ++++ b/drivers/net/macsec.c +@@ -2823,9 +2823,9 @@ static void get_rx_sc_stats(struct net_device *dev, + + stats = per_cpu_ptr(rx_sc->stats, cpu); + do { +- start = u64_stats_fetch_begin_irq(&stats->syncp); ++ start = u64_stats_fetch_begin(&stats->syncp); + memcpy(&tmp, &stats->stats, sizeof(tmp)); +- } while (u64_stats_fetch_retry_irq(&stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&stats->syncp, start)); + + sum->InOctetsValidated += tmp.InOctetsValidated; + sum->InOctetsDecrypted += tmp.InOctetsDecrypted; +@@ -2904,9 +2904,9 @@ static void get_tx_sc_stats(struct net_device *dev, + + stats = per_cpu_ptr(macsec_priv(dev)->secy.tx_sc.stats, cpu); + do { +- start = u64_stats_fetch_begin_irq(&stats->syncp); ++ start = u64_stats_fetch_begin(&stats->syncp); + memcpy(&tmp, &stats->stats, sizeof(tmp)); +- } while (u64_stats_fetch_retry_irq(&stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&stats->syncp, start)); + + sum->OutPktsProtected += tmp.OutPktsProtected; + sum->OutPktsEncrypted += tmp.OutPktsEncrypted; +@@ -2960,9 +2960,9 @@ static void get_secy_stats(struct net_device *dev, struct macsec_dev_stats *sum) + + stats = per_cpu_ptr(macsec_priv(dev)->stats, cpu); + do { +- start = u64_stats_fetch_begin_irq(&stats->syncp); ++ start = u64_stats_fetch_begin(&stats->syncp); + memcpy(&tmp, &stats->stats, sizeof(tmp)); +- } while (u64_stats_fetch_retry_irq(&stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&stats->syncp, start)); + + sum->OutPktsUntagged += tmp.OutPktsUntagged; + sum->InPktsUntagged += tmp.InPktsUntagged; +diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c +index 1080d6ebff63b..a1c7823f0ba66 100644 +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -948,13 +948,13 @@ static void macvlan_dev_get_stats64(struct net_device *dev, + for_each_possible_cpu(i) { + p = per_cpu_ptr(vlan->pcpu_stats, i); + do { +- start = u64_stats_fetch_begin_irq(&p->syncp); ++ start = u64_stats_fetch_begin(&p->syncp); + rx_packets = u64_stats_read(&p->rx_packets); + rx_bytes = u64_stats_read(&p->rx_bytes); + rx_multicast = u64_stats_read(&p->rx_multicast); + tx_packets = u64_stats_read(&p->tx_packets); + tx_bytes = u64_stats_read(&p->tx_bytes); +- } while (u64_stats_fetch_retry_irq(&p->syncp, start)); ++ } while (u64_stats_fetch_retry(&p->syncp, start)); + + stats->rx_packets += rx_packets; + stats->rx_bytes += rx_bytes; +diff --git a/drivers/net/mhi_net.c b/drivers/net/mhi_net.c +index 0b1b6f650104b..ff302144029de 100644 +--- a/drivers/net/mhi_net.c ++++ b/drivers/net/mhi_net.c +@@ -104,19 +104,19 @@ static void mhi_ndo_get_stats64(struct net_device *ndev, + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&mhi_netdev->stats.rx_syncp); ++ start = u64_stats_fetch_begin(&mhi_netdev->stats.rx_syncp); + stats->rx_packets = u64_stats_read(&mhi_netdev->stats.rx_packets); + stats->rx_bytes = u64_stats_read(&mhi_netdev->stats.rx_bytes); + stats->rx_errors = u64_stats_read(&mhi_netdev->stats.rx_errors); +- } while (u64_stats_fetch_retry_irq(&mhi_netdev->stats.rx_syncp, start)); ++ } while (u64_stats_fetch_retry(&mhi_netdev->stats.rx_syncp, start)); + + do { +- start = u64_stats_fetch_begin_irq(&mhi_netdev->stats.tx_syncp); ++ start = u64_stats_fetch_begin(&mhi_netdev->stats.tx_syncp); + stats->tx_packets = u64_stats_read(&mhi_netdev->stats.tx_packets); + stats->tx_bytes = u64_stats_read(&mhi_netdev->stats.tx_bytes); + stats->tx_errors = u64_stats_read(&mhi_netdev->stats.tx_errors); + stats->tx_dropped = u64_stats_read(&mhi_netdev->stats.tx_dropped); +- } while (u64_stats_fetch_retry_irq(&mhi_netdev->stats.tx_syncp, start)); ++ } while (u64_stats_fetch_retry(&mhi_netdev->stats.tx_syncp, start)); + } + + static const struct net_device_ops mhi_netdev_ops = { +diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c +index 9a1a5b2036240..e470e3398abc2 100644 +--- a/drivers/net/netdevsim/netdev.c ++++ b/drivers/net/netdevsim/netdev.c +@@ -67,10 +67,10 @@ nsim_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&ns->syncp); ++ start = u64_stats_fetch_begin(&ns->syncp); + stats->tx_bytes = ns->tx_bytes; + stats->tx_packets = ns->tx_packets; +- } while (u64_stats_fetch_retry_irq(&ns->syncp, start)); ++ } while (u64_stats_fetch_retry(&ns->syncp, start)); + } + + static int +diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c +index 154a3c0a6dfd8..3de937141c168 100644 +--- a/drivers/net/team/team.c ++++ b/drivers/net/team/team.c +@@ -1865,13 +1865,13 @@ team_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) + for_each_possible_cpu(i) { + p = per_cpu_ptr(team->pcpu_stats, i); + do { +- start = u64_stats_fetch_begin_irq(&p->syncp); ++ start = u64_stats_fetch_begin(&p->syncp); + rx_packets = u64_stats_read(&p->rx_packets); + rx_bytes = u64_stats_read(&p->rx_bytes); + rx_multicast = u64_stats_read(&p->rx_multicast); + tx_packets = u64_stats_read(&p->tx_packets); + tx_bytes = u64_stats_read(&p->tx_bytes); +- } while (u64_stats_fetch_retry_irq(&p->syncp, start)); ++ } while (u64_stats_fetch_retry(&p->syncp, start)); + + stats->rx_packets += rx_packets; + stats->rx_bytes += rx_bytes; +diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c +index b095a4b4957bb..18d99fda997cf 100644 +--- a/drivers/net/team/team_mode_loadbalance.c ++++ b/drivers/net/team/team_mode_loadbalance.c +@@ -466,9 +466,9 @@ static void __lb_one_cpu_stats_add(struct lb_stats *acc_stats, + struct lb_stats tmp; + + do { +- start = u64_stats_fetch_begin_irq(syncp); ++ start = u64_stats_fetch_begin(syncp); + tmp.tx_bytes = cpu_stats->tx_bytes; +- } while (u64_stats_fetch_retry_irq(syncp, start)); ++ } while (u64_stats_fetch_retry(syncp, start)); + acc_stats->tx_bytes += tmp.tx_bytes; + } + +diff --git a/drivers/net/veth.c b/drivers/net/veth.c +index 466da01ba2e3e..2da7cfcfe1c31 100644 +--- a/drivers/net/veth.c ++++ b/drivers/net/veth.c +@@ -182,12 +182,12 @@ static void veth_get_ethtool_stats(struct net_device *dev, + size_t offset; + + do { +- start = u64_stats_fetch_begin_irq(&rq_stats->syncp); ++ start = u64_stats_fetch_begin(&rq_stats->syncp); + for (j = 0; j < VETH_RQ_STATS_LEN; j++) { + offset = veth_rq_stats_desc[j].offset; + data[idx + j] = *(u64 *)(stats_base + offset); + } +- } while (u64_stats_fetch_retry_irq(&rq_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&rq_stats->syncp, start)); + idx += VETH_RQ_STATS_LEN; + } + +@@ -203,12 +203,12 @@ static void veth_get_ethtool_stats(struct net_device *dev, + + tx_idx += (i % dev->real_num_tx_queues) * VETH_TQ_STATS_LEN; + do { +- start = u64_stats_fetch_begin_irq(&rq_stats->syncp); ++ start = u64_stats_fetch_begin(&rq_stats->syncp); + for (j = 0; j < VETH_TQ_STATS_LEN; j++) { + offset = veth_tq_stats_desc[j].offset; + data[tx_idx + j] += *(u64 *)(base + offset); + } +- } while (u64_stats_fetch_retry_irq(&rq_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&rq_stats->syncp, start)); + } + } + +@@ -379,13 +379,13 @@ static void veth_stats_rx(struct veth_stats *result, struct net_device *dev) + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&stats->syncp); ++ start = u64_stats_fetch_begin(&stats->syncp); + peer_tq_xdp_xmit_err = stats->vs.peer_tq_xdp_xmit_err; + xdp_tx_err = stats->vs.xdp_tx_err; + packets = stats->vs.xdp_packets; + bytes = stats->vs.xdp_bytes; + drops = stats->vs.rx_drops; +- } while (u64_stats_fetch_retry_irq(&stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&stats->syncp, start)); + result->peer_tq_xdp_xmit_err += peer_tq_xdp_xmit_err; + result->xdp_tx_err += xdp_tx_err; + result->xdp_packets += packets; +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index 9cce7dec7366d..a94d9d8f67fd0 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -2066,18 +2066,18 @@ static void virtnet_stats(struct net_device *dev, + struct send_queue *sq = &vi->sq[i]; + + do { +- start = u64_stats_fetch_begin_irq(&sq->stats.syncp); ++ start = u64_stats_fetch_begin(&sq->stats.syncp); + tpackets = sq->stats.packets; + tbytes = sq->stats.bytes; + terrors = sq->stats.tx_timeouts; +- } while (u64_stats_fetch_retry_irq(&sq->stats.syncp, start)); ++ } while (u64_stats_fetch_retry(&sq->stats.syncp, start)); + + do { +- start = u64_stats_fetch_begin_irq(&rq->stats.syncp); ++ start = u64_stats_fetch_begin(&rq->stats.syncp); + rpackets = rq->stats.packets; + rbytes = rq->stats.bytes; + rdrops = rq->stats.drops; +- } while (u64_stats_fetch_retry_irq(&rq->stats.syncp, start)); ++ } while (u64_stats_fetch_retry(&rq->stats.syncp, start)); + + tot->rx_packets += rpackets; + tot->tx_packets += tpackets; +@@ -2688,12 +2688,12 @@ static void virtnet_get_ethtool_stats(struct net_device *dev, + + stats_base = (u8 *)&rq->stats; + do { +- start = u64_stats_fetch_begin_irq(&rq->stats.syncp); ++ start = u64_stats_fetch_begin(&rq->stats.syncp); + for (j = 0; j < VIRTNET_RQ_STATS_LEN; j++) { + offset = virtnet_rq_stats_desc[j].offset; + data[idx + j] = *(u64 *)(stats_base + offset); + } +- } while (u64_stats_fetch_retry_irq(&rq->stats.syncp, start)); ++ } while (u64_stats_fetch_retry(&rq->stats.syncp, start)); + idx += VIRTNET_RQ_STATS_LEN; + } + +@@ -2702,12 +2702,12 @@ static void virtnet_get_ethtool_stats(struct net_device *dev, + + stats_base = (u8 *)&sq->stats; + do { +- start = u64_stats_fetch_begin_irq(&sq->stats.syncp); ++ start = u64_stats_fetch_begin(&sq->stats.syncp); + for (j = 0; j < VIRTNET_SQ_STATS_LEN; j++) { + offset = virtnet_sq_stats_desc[j].offset; + data[idx + j] = *(u64 *)(stats_base + offset); + } +- } while (u64_stats_fetch_retry_irq(&sq->stats.syncp, start)); ++ } while (u64_stats_fetch_retry(&sq->stats.syncp, start)); + idx += VIRTNET_SQ_STATS_LEN; + } + } +diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c +index 5df7a0abc39d5..191ebc482f0c1 100644 +--- a/drivers/net/vrf.c ++++ b/drivers/net/vrf.c +@@ -159,13 +159,13 @@ static void vrf_get_stats64(struct net_device *dev, + + dstats = per_cpu_ptr(dev->dstats, i); + do { +- start = u64_stats_fetch_begin_irq(&dstats->syncp); ++ start = u64_stats_fetch_begin(&dstats->syncp); + tbytes = dstats->tx_bytes; + tpkts = dstats->tx_pkts; + tdrops = dstats->tx_drps; + rbytes = dstats->rx_bytes; + rpkts = dstats->rx_pkts; +- } while (u64_stats_fetch_retry_irq(&dstats->syncp, start)); ++ } while (u64_stats_fetch_retry(&dstats->syncp, start)); + stats->tx_bytes += tbytes; + stats->tx_packets += tpkts; + stats->tx_dropped += tdrops; +diff --git a/drivers/net/vxlan/vxlan_vnifilter.c b/drivers/net/vxlan/vxlan_vnifilter.c +index 3e04af4c5daa1..a3de081cda5ee 100644 +--- a/drivers/net/vxlan/vxlan_vnifilter.c ++++ b/drivers/net/vxlan/vxlan_vnifilter.c +@@ -129,9 +129,9 @@ static void vxlan_vnifilter_stats_get(const struct vxlan_vni_node *vninode, + + pstats = per_cpu_ptr(vninode->stats, i); + do { +- start = u64_stats_fetch_begin_irq(&pstats->syncp); ++ start = u64_stats_fetch_begin(&pstats->syncp); + memcpy(&temp, &pstats->stats, sizeof(temp)); +- } while (u64_stats_fetch_retry_irq(&pstats->syncp, start)); ++ } while (u64_stats_fetch_retry(&pstats->syncp, start)); + + dest->rx_packets += temp.rx_packets; + dest->rx_bytes += temp.rx_bytes; +diff --git a/drivers/net/wwan/mhi_wwan_mbim.c b/drivers/net/wwan/mhi_wwan_mbim.c +index 6872782e8dd89..22b5939a42bb3 100644 +--- a/drivers/net/wwan/mhi_wwan_mbim.c ++++ b/drivers/net/wwan/mhi_wwan_mbim.c +@@ -456,19 +456,19 @@ static void mhi_mbim_ndo_get_stats64(struct net_device *ndev, + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&link->rx_syncp); ++ start = u64_stats_fetch_begin(&link->rx_syncp); + stats->rx_packets = u64_stats_read(&link->rx_packets); + stats->rx_bytes = u64_stats_read(&link->rx_bytes); + stats->rx_errors = u64_stats_read(&link->rx_errors); +- } while (u64_stats_fetch_retry_irq(&link->rx_syncp, start)); ++ } while (u64_stats_fetch_retry(&link->rx_syncp, start)); + + do { +- start = u64_stats_fetch_begin_irq(&link->tx_syncp); ++ start = u64_stats_fetch_begin(&link->tx_syncp); + stats->tx_packets = u64_stats_read(&link->tx_packets); + stats->tx_bytes = u64_stats_read(&link->tx_bytes); + stats->tx_errors = u64_stats_read(&link->tx_errors); + stats->tx_dropped = u64_stats_read(&link->tx_dropped); +- } while (u64_stats_fetch_retry_irq(&link->tx_syncp, start)); ++ } while (u64_stats_fetch_retry(&link->tx_syncp, start)); + } + + static void mhi_mbim_ul_callback(struct mhi_device *mhi_dev, +diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c +index 27a11cc08c61e..df4dc02638a00 100644 +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -1392,16 +1392,16 @@ static void xennet_get_stats64(struct net_device *dev, + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&tx_stats->syncp); ++ start = u64_stats_fetch_begin(&tx_stats->syncp); + tx_packets = tx_stats->packets; + tx_bytes = tx_stats->bytes; +- } while (u64_stats_fetch_retry_irq(&tx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&tx_stats->syncp, start)); + + do { +- start = u64_stats_fetch_begin_irq(&rx_stats->syncp); ++ start = u64_stats_fetch_begin(&rx_stats->syncp); + rx_packets = rx_stats->packets; + rx_bytes = rx_stats->bytes; +- } while (u64_stats_fetch_retry_irq(&rx_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&rx_stats->syncp, start)); + + tot->rx_packets += rx_packets; + tot->tx_packets += tx_packets; +diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c +index 2a4b3efb7e12b..9f6ed09538cd0 100644 +--- a/drivers/pinctrl/pinctrl-amd.c ++++ b/drivers/pinctrl/pinctrl-amd.c +@@ -639,7 +639,7 @@ static bool do_amd_gpio_irq_handler(int irq, void *dev_id) + if (!(regval & PIN_IRQ_PENDING) || + !(regval & BIT(INTERRUPT_MASK_OFF))) + continue; +- generic_handle_domain_irq(gc->irq.domain, irqnr + i); ++ generic_handle_domain_irq_safe(gc->irq.domain, irqnr + i); + + /* Clear interrupt. + * We must read the pin register again, in case the +diff --git a/drivers/platform/x86/intel/int0002_vgpio.c b/drivers/platform/x86/intel/int0002_vgpio.c +index 617dbf98980ec..97cfbc520a02c 100644 +--- a/drivers/platform/x86/intel/int0002_vgpio.c ++++ b/drivers/platform/x86/intel/int0002_vgpio.c +@@ -125,8 +125,7 @@ static irqreturn_t int0002_irq(int irq, void *data) + if (!(gpe_sts_reg & GPE0A_PME_B0_STS_BIT)) + return IRQ_NONE; + +- generic_handle_irq(irq_find_mapping(chip->irq.domain, +- GPE0A_PME_B0_VIRT_GPIO_PIN)); ++ generic_handle_domain_irq_safe(chip->irq.domain, GPE0A_PME_B0_VIRT_GPIO_PIN); + + pm_wakeup_hard_event(chip->parent); + +diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c +index 4b42f2302a8a8..d4f77f6688cf7 100644 +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -127,10 +127,10 @@ do { \ + unsigned int start; \ + pcpu_stats = per_cpu_ptr(in, i); \ + do { \ +- start = u64_stats_fetch_begin_irq( \ ++ start = u64_stats_fetch_begin( \ + &pcpu_stats->syncp); \ + inc = u64_stats_read(&pcpu_stats->field); \ +- } while (u64_stats_fetch_retry_irq( \ ++ } while (u64_stats_fetch_retry( \ + &pcpu_stats->syncp, start)); \ + ret += inc; \ + } \ +diff --git a/drivers/ssb/driver_gpio.c b/drivers/ssb/driver_gpio.c +index 2de3896489c84..897cb8db5084f 100644 +--- a/drivers/ssb/driver_gpio.c ++++ b/drivers/ssb/driver_gpio.c +@@ -132,7 +132,8 @@ static irqreturn_t ssb_gpio_irq_chipco_handler(int irq, void *dev_id) + return IRQ_NONE; + + for_each_set_bit(gpio, &irqs, bus->gpio.ngpio) +- generic_handle_irq(ssb_gpio_to_irq(&bus->gpio, gpio)); ++ generic_handle_domain_irq_safe(bus->irq_domain, gpio); ++ + ssb_chipco_gpio_polarity(chipco, irqs, val & irqs); + + return IRQ_HANDLED; +@@ -330,7 +331,8 @@ static irqreturn_t ssb_gpio_irq_extif_handler(int irq, void *dev_id) + return IRQ_NONE; + + for_each_set_bit(gpio, &irqs, bus->gpio.ngpio) +- generic_handle_irq(ssb_gpio_to_irq(&bus->gpio, gpio)); ++ generic_handle_domain_irq_safe(bus->irq_domain, gpio); ++ + ssb_extif_gpio_polarity(extif, irqs, val & irqs); + + return IRQ_HANDLED; +diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h +index 287153d325365..81f5fce6e895f 100644 +--- a/drivers/tty/serial/8250/8250.h ++++ b/drivers/tty/serial/8250/8250.h +@@ -177,12 +177,74 @@ static inline void serial_dl_write(struct uart_8250_port *up, int value) + up->dl_write(up, value); + } + ++static inline int serial8250_in_IER(struct uart_8250_port *up) ++{ ++ struct uart_port *port = &up->port; ++ unsigned long flags; ++ bool is_console; ++ int ier; ++ ++ is_console = uart_console(port); ++ ++ if (is_console) ++ printk_cpu_sync_get_irqsave(flags); ++ ++ ier = serial_in(up, UART_IER); ++ ++ if (is_console) ++ printk_cpu_sync_put_irqrestore(flags); ++ ++ return ier; ++} ++ ++static inline void serial8250_set_IER(struct uart_8250_port *up, int ier) ++{ ++ struct uart_port *port = &up->port; ++ unsigned long flags; ++ bool is_console; ++ ++ is_console = uart_console(port); ++ ++ if (is_console) ++ printk_cpu_sync_get_irqsave(flags); ++ ++ serial_out(up, UART_IER, ier); ++ ++ if (is_console) ++ printk_cpu_sync_put_irqrestore(flags); ++} ++ ++static inline int serial8250_clear_IER(struct uart_8250_port *up) ++{ ++ struct uart_port *port = &up->port; ++ unsigned int clearval = 0; ++ unsigned long flags; ++ bool is_console; ++ int prior; ++ ++ is_console = uart_console(port); ++ ++ if (up->capabilities & UART_CAP_UUE) ++ clearval = UART_IER_UUE; ++ ++ if (is_console) ++ printk_cpu_sync_get_irqsave(flags); ++ ++ prior = serial_in(up, UART_IER); ++ serial_out(up, UART_IER, clearval); ++ ++ if (is_console) ++ printk_cpu_sync_put_irqrestore(flags); ++ ++ return prior; ++} ++ + static inline bool serial8250_set_THRI(struct uart_8250_port *up) + { + if (up->ier & UART_IER_THRI) + return false; + up->ier |= UART_IER_THRI; +- serial_out(up, UART_IER, up->ier); ++ serial8250_set_IER(up, up->ier); + return true; + } + +@@ -191,7 +253,7 @@ static inline bool serial8250_clear_THRI(struct uart_8250_port *up) + if (!(up->ier & UART_IER_THRI)) + return false; + up->ier &= ~UART_IER_THRI; +- serial_out(up, UART_IER, up->ier); ++ serial8250_set_IER(up, up->ier); + return true; + } + +diff --git a/drivers/tty/serial/8250/8250_aspeed_vuart.c b/drivers/tty/serial/8250/8250_aspeed_vuart.c +index 9d2a7856784f7..7cc6b527c088b 100644 +--- a/drivers/tty/serial/8250/8250_aspeed_vuart.c ++++ b/drivers/tty/serial/8250/8250_aspeed_vuart.c +@@ -278,7 +278,7 @@ static void __aspeed_vuart_set_throttle(struct uart_8250_port *up, + up->ier &= ~irqs; + if (!throttle) + up->ier |= irqs; +- serial_out(up, UART_IER, up->ier); ++ serial8250_set_IER(up, up->ier); + } + static void aspeed_vuart_set_throttle(struct uart_port *port, bool throttle) + { +diff --git a/drivers/tty/serial/8250/8250_bcm7271.c b/drivers/tty/serial/8250/8250_bcm7271.c +index 8efdc271eb75f..d30c74618411f 100644 +--- a/drivers/tty/serial/8250/8250_bcm7271.c ++++ b/drivers/tty/serial/8250/8250_bcm7271.c +@@ -609,7 +609,7 @@ static int brcmuart_startup(struct uart_port *port) + * will handle this. + */ + up->ier &= ~UART_IER_RDI; +- serial_port_out(port, UART_IER, up->ier); ++ serial8250_set_IER(up, up->ier); + + priv->tx_running = false; + priv->dma.rx_dma = NULL; +@@ -775,10 +775,12 @@ static int brcmuart_handle_irq(struct uart_port *p) + unsigned int iir = serial_port_in(p, UART_IIR); + struct brcmuart_priv *priv = p->private_data; + struct uart_8250_port *up = up_to_u8250p(p); ++ unsigned long cs_flags; + unsigned int status; + unsigned long flags; + unsigned int ier; + unsigned int mcr; ++ bool is_console; + int handled = 0; + + /* +@@ -789,6 +791,10 @@ static int brcmuart_handle_irq(struct uart_port *p) + spin_lock_irqsave(&p->lock, flags); + status = serial_port_in(p, UART_LSR); + if ((status & UART_LSR_DR) == 0) { ++ is_console = uart_console(p); ++ ++ if (is_console) ++ printk_cpu_sync_get_irqsave(cs_flags); + + ier = serial_port_in(p, UART_IER); + /* +@@ -809,6 +815,9 @@ static int brcmuart_handle_irq(struct uart_port *p) + serial_port_in(p, UART_RX); + } + ++ if (is_console) ++ printk_cpu_sync_put_irqrestore(cs_flags); ++ + handled = 1; + } + spin_unlock_irqrestore(&p->lock, flags); +@@ -823,8 +832,10 @@ static enum hrtimer_restart brcmuart_hrtimer_func(struct hrtimer *t) + struct brcmuart_priv *priv = container_of(t, struct brcmuart_priv, hrt); + struct uart_port *p = priv->up; + struct uart_8250_port *up = up_to_u8250p(p); ++ unsigned long cs_flags; + unsigned int status; + unsigned long flags; ++ bool is_console; + + if (priv->shutdown) + return HRTIMER_NORESTART; +@@ -846,12 +857,20 @@ static enum hrtimer_restart brcmuart_hrtimer_func(struct hrtimer *t) + /* re-enable receive unless upper layer has disabled it */ + if ((up->ier & (UART_IER_RLSI | UART_IER_RDI)) == + (UART_IER_RLSI | UART_IER_RDI)) { ++ is_console = uart_console(p); ++ ++ if (is_console) ++ printk_cpu_sync_get_irqsave(cs_flags); ++ + status = serial_port_in(p, UART_IER); + status |= (UART_IER_RLSI | UART_IER_RDI); + serial_port_out(p, UART_IER, status); + status = serial_port_in(p, UART_MCR); + status |= UART_MCR_RTS; + serial_port_out(p, UART_MCR, status); ++ ++ if (is_console) ++ printk_cpu_sync_put_irqrestore(cs_flags); + } + spin_unlock_irqrestore(&p->lock, flags); + return HRTIMER_NORESTART; +diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c +index 94fbf0add2ce2..196d0c55dfe99 100644 +--- a/drivers/tty/serial/8250/8250_core.c ++++ b/drivers/tty/serial/8250/8250_core.c +@@ -255,8 +255,11 @@ static void serial8250_timeout(struct timer_list *t) + static void serial8250_backup_timeout(struct timer_list *t) + { + struct uart_8250_port *up = from_timer(up, t, timer); ++ struct uart_port *port = &up->port; + unsigned int iir, ier = 0, lsr; ++ unsigned long cs_flags; + unsigned long flags; ++ bool is_console; + + spin_lock_irqsave(&up->port.lock, flags); + +@@ -265,8 +268,16 @@ static void serial8250_backup_timeout(struct timer_list *t) + * based handler. + */ + if (up->port.irq) { ++ is_console = uart_console(port); ++ ++ if (is_console) ++ printk_cpu_sync_get_irqsave(cs_flags); ++ + ier = serial_in(up, UART_IER); + serial_out(up, UART_IER, 0); ++ ++ if (is_console) ++ printk_cpu_sync_put_irqrestore(cs_flags); + } + + iir = serial_in(up, UART_IIR); +@@ -289,7 +300,7 @@ static void serial8250_backup_timeout(struct timer_list *t) + serial8250_tx_chars(up); + + if (up->port.irq) +- serial_out(up, UART_IER, ier); ++ serial8250_set_IER(up, ier); + + spin_unlock_irqrestore(&up->port.lock, flags); + +@@ -575,6 +586,14 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev) + + #ifdef CONFIG_SERIAL_8250_CONSOLE + ++static void univ8250_console_write_atomic(struct console *co, const char *s, ++ unsigned int count) ++{ ++ struct uart_8250_port *up = &serial8250_ports[co->index]; ++ ++ serial8250_console_write_atomic(up, s, count); ++} ++ + static void univ8250_console_write(struct console *co, const char *s, + unsigned int count) + { +@@ -668,6 +687,7 @@ static int univ8250_console_match(struct console *co, char *name, int idx, + + static struct console univ8250_console = { + .name = "ttyS", ++ .write_atomic = univ8250_console_write_atomic, + .write = univ8250_console_write, + .device = uart_console_device, + .setup = univ8250_console_setup, +@@ -961,7 +981,7 @@ static void serial_8250_overrun_backoff_work(struct work_struct *work) + spin_lock_irqsave(&port->lock, flags); + up->ier |= UART_IER_RLSI | UART_IER_RDI; + up->port.read_status_mask |= UART_LSR_DR; +- serial_out(up, UART_IER, up->ier); ++ serial8250_set_IER(up, up->ier); + spin_unlock_irqrestore(&port->lock, flags); + } + +diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c +index 314a05e009df9..9809517de8270 100644 +--- a/drivers/tty/serial/8250/8250_exar.c ++++ b/drivers/tty/serial/8250/8250_exar.c +@@ -179,6 +179,8 @@ static void xr17v35x_set_divisor(struct uart_port *p, unsigned int baud, + + static int xr17v35x_startup(struct uart_port *port) + { ++ struct uart_8250_port *up = up_to_u8250p(port); ++ + /* + * First enable access to IER [7:5], ISR [5:4], FCR [5:4], + * MCR [7:5] and MSR [7:0] +@@ -189,7 +191,7 @@ static int xr17v35x_startup(struct uart_port *port) + * Make sure all interrups are masked until initialization is + * complete and the FIFOs are cleared + */ +- serial_port_out(port, UART_IER, 0); ++ serial8250_set_IER(up, 0); + + return serial8250_do_startup(port); + } +diff --git a/drivers/tty/serial/8250/8250_fsl.c b/drivers/tty/serial/8250/8250_fsl.c +index 8aad15622a2e5..74bb85b705e7f 100644 +--- a/drivers/tty/serial/8250/8250_fsl.c ++++ b/drivers/tty/serial/8250/8250_fsl.c +@@ -58,7 +58,8 @@ int fsl8250_handle_irq(struct uart_port *port) + if ((orig_lsr & UART_LSR_OE) && (up->overrun_backoff_time_ms > 0)) { + unsigned long delay; + +- up->ier = port->serial_in(port, UART_IER); ++ up->ier = serial8250_in_IER(up); ++ + if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) { + port->ops->stop_rx(port); + } else { +diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c +index 2b2f5d8d24b91..2b78e6c394fb9 100644 +--- a/drivers/tty/serial/8250/8250_ingenic.c ++++ b/drivers/tty/serial/8250/8250_ingenic.c +@@ -146,6 +146,7 @@ OF_EARLYCON_DECLARE(x1000_uart, "ingenic,x1000-uart", + + static void ingenic_uart_serial_out(struct uart_port *p, int offset, int value) + { ++ struct uart_8250_port *up = up_to_u8250p(p); + int ier; + + switch (offset) { +@@ -167,7 +168,7 @@ static void ingenic_uart_serial_out(struct uart_port *p, int offset, int value) + * If we have enabled modem status IRQs we should enable + * modem mode. + */ +- ier = p->serial_in(p, UART_IER); ++ ier = serial8250_in_IER(up); + + if (ier & UART_IER_MSI) + value |= UART_MCR_MDCE | UART_MCR_FCM; +diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c +index 54051ec7b4992..6092c75808fb9 100644 +--- a/drivers/tty/serial/8250/8250_mtk.c ++++ b/drivers/tty/serial/8250/8250_mtk.c +@@ -222,12 +222,40 @@ static void mtk8250_shutdown(struct uart_port *port) + + static void mtk8250_disable_intrs(struct uart_8250_port *up, int mask) + { +- serial_out(up, UART_IER, serial_in(up, UART_IER) & (~mask)); ++ struct uart_port *port = &up->port; ++ unsigned long flags; ++ bool is_console; ++ int ier; ++ ++ is_console = uart_console(port); ++ ++ if (is_console) ++ printk_cpu_sync_get_irqsave(flags); ++ ++ ier = serial_in(up, UART_IER); ++ serial_out(up, UART_IER, ier & (~mask)); ++ ++ if (is_console) ++ printk_cpu_sync_put_irqrestore(flags); + } + + static void mtk8250_enable_intrs(struct uart_8250_port *up, int mask) + { +- serial_out(up, UART_IER, serial_in(up, UART_IER) | mask); ++ struct uart_port *port = &up->port; ++ unsigned long flags; ++ bool is_console; ++ int ier; ++ ++ is_console = uart_console(port); ++ ++ if (is_console) ++ printk_cpu_sync_get_irqsave(flags); ++ ++ ier = serial_in(up, UART_IER); ++ serial_out(up, UART_IER, ier | mask); ++ ++ if (is_console) ++ printk_cpu_sync_put_irqrestore(flags); + } + + static void mtk8250_set_flow_ctrl(struct uart_8250_port *up, int mode) +diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c +index 38ee3e42251af..8dc983a8cad15 100644 +--- a/drivers/tty/serial/8250/8250_omap.c ++++ b/drivers/tty/serial/8250/8250_omap.c +@@ -325,7 +325,7 @@ static void omap8250_restore_regs(struct uart_8250_port *up) + + /* drop TCR + TLR access, we setup XON/XOFF later */ + serial8250_out_MCR(up, up->mcr); +- serial_out(up, UART_IER, up->ier); ++ serial8250_set_IER(up, up->ier); + + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); + serial_dl_write(up, priv->quot); +@@ -515,7 +515,7 @@ static void omap_8250_pm(struct uart_port *port, unsigned int state, + serial_out(up, UART_EFR, efr | UART_EFR_ECB); + serial_out(up, UART_LCR, 0); + +- serial_out(up, UART_IER, (state != 0) ? UART_IERX_SLEEP : 0); ++ serial8250_set_IER(up, (state != 0) ? UART_IERX_SLEEP : 0); + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); + serial_out(up, UART_EFR, efr); + serial_out(up, UART_LCR, 0); +@@ -636,7 +636,7 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id) + if ((lsr & UART_LSR_OE) && up->overrun_backoff_time_ms > 0) { + unsigned long delay; + +- up->ier = port->serial_in(port, UART_IER); ++ up->ier = serial8250_in_IER(up); + if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) { + port->ops->stop_rx(port); + } else { +@@ -696,7 +696,7 @@ static int omap_8250_startup(struct uart_port *port) + goto err; + + up->ier = UART_IER_RLSI | UART_IER_RDI; +- serial_out(up, UART_IER, up->ier); ++ serial8250_set_IER(up, up->ier); + + #ifdef CONFIG_PM + up->capabilities |= UART_CAP_RPM; +@@ -737,7 +737,7 @@ static void omap_8250_shutdown(struct uart_port *port) + serial_out(up, UART_OMAP_EFR2, 0x0); + + up->ier = 0; +- serial_out(up, UART_IER, 0); ++ serial8250_set_IER(up, 0); + + if (up->dma) + serial8250_release_dma(up); +@@ -785,7 +785,7 @@ static void omap_8250_unthrottle(struct uart_port *port) + up->dma->rx_dma(up); + up->ier |= UART_IER_RLSI | UART_IER_RDI; + port->read_status_mask |= UART_LSR_DR; +- serial_out(up, UART_IER, up->ier); ++ serial8250_set_IER(up, up->ier); + spin_unlock_irqrestore(&port->lock, flags); + + pm_runtime_mark_last_busy(port->dev); +@@ -876,7 +876,7 @@ static void __dma_rx_complete(void *param) + __dma_rx_do_complete(p); + if (!priv->throttled) { + p->ier |= UART_IER_RLSI | UART_IER_RDI; +- serial_out(p, UART_IER, p->ier); ++ serial8250_set_IER(p, p->ier); + if (!(priv->habit & UART_HAS_EFR2)) + omap_8250_rx_dma(p); + } +@@ -933,7 +933,7 @@ static int omap_8250_rx_dma(struct uart_8250_port *p) + * callback to run. + */ + p->ier &= ~(UART_IER_RLSI | UART_IER_RDI); +- serial_out(p, UART_IER, p->ier); ++ serial8250_set_IER(p, p->ier); + } + goto out; + } +@@ -1148,12 +1148,12 @@ static void am654_8250_handle_rx_dma(struct uart_8250_port *up, u8 iir, + * periodic timeouts, re-enable interrupts. + */ + up->ier &= ~(UART_IER_RLSI | UART_IER_RDI); +- serial_out(up, UART_IER, up->ier); ++ serial8250_set_IER(up, up->ier); + omap_8250_rx_dma_flush(up); + serial_in(up, UART_IIR); + serial_out(up, UART_OMAP_EFR2, 0x0); + up->ier |= UART_IER_RLSI | UART_IER_RDI; +- serial_out(up, UART_IER, up->ier); ++ serial8250_set_IER(up, up->ier); + } + } + +diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c +index 2030a92ac66e7..326549603740d 100644 +--- a/drivers/tty/serial/8250/8250_port.c ++++ b/drivers/tty/serial/8250/8250_port.c +@@ -743,7 +743,7 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) + serial_out(p, UART_EFR, UART_EFR_ECB); + serial_out(p, UART_LCR, 0); + } +- serial_out(p, UART_IER, sleep ? UART_IERX_SLEEP : 0); ++ serial8250_set_IER(p, sleep ? UART_IERX_SLEEP : 0); + if (p->capabilities & UART_CAP_EFR) { + serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); + serial_out(p, UART_EFR, efr); +@@ -1017,8 +1017,11 @@ static int broken_efr(struct uart_8250_port *up) + */ + static void autoconfig_16550a(struct uart_8250_port *up) + { ++ struct uart_port *port = &up->port; + unsigned char status1, status2; + unsigned int iersave; ++ unsigned long flags; ++ bool is_console; + + up->port.type = PORT_16550A; + up->capabilities |= UART_CAP_FIFO; +@@ -1130,6 +1133,11 @@ static void autoconfig_16550a(struct uart_8250_port *up) + return; + } + ++ is_console = uart_console(port); ++ ++ if (is_console) ++ printk_cpu_sync_get_irqsave(flags); ++ + /* + * Try writing and reading the UART_IER_UUE bit (b6). + * If it works, this is probably one of the Xscale platform's +@@ -1165,6 +1173,9 @@ static void autoconfig_16550a(struct uart_8250_port *up) + } + serial_out(up, UART_IER, iersave); + ++ if (is_console) ++ printk_cpu_sync_put_irqrestore(flags); ++ + /* + * We distinguish between 16550A and U6 16550A by counting + * how many bytes are in the FIFO. +@@ -1187,8 +1198,10 @@ static void autoconfig(struct uart_8250_port *up) + unsigned char status1, scratch, scratch2, scratch3; + unsigned char save_lcr, save_mcr; + struct uart_port *port = &up->port; ++ unsigned long cs_flags; + unsigned long flags; + unsigned int old_capabilities; ++ bool is_console; + + if (!port->iobase && !port->mapbase && !port->membase) + return; +@@ -1206,6 +1219,11 @@ static void autoconfig(struct uart_8250_port *up) + up->bugs = 0; + + if (!(port->flags & UPF_BUGGY_UART)) { ++ is_console = uart_console(port); ++ ++ if (is_console) ++ printk_cpu_sync_get_irqsave(cs_flags); ++ + /* + * Do a simple existence test first; if we fail this, + * there's no point trying anything else. +@@ -1235,6 +1253,10 @@ static void autoconfig(struct uart_8250_port *up) + #endif + scratch3 = serial_in(up, UART_IER) & 0x0f; + serial_out(up, UART_IER, scratch); ++ ++ if (is_console) ++ printk_cpu_sync_put_irqrestore(cs_flags); ++ + if (scratch2 != 0 || scratch3 != 0x0F) { + /* + * We failed; there's nothing here +@@ -1332,10 +1354,7 @@ static void autoconfig(struct uart_8250_port *up) + serial8250_out_MCR(up, save_mcr); + serial8250_clear_fifos(up); + serial_in(up, UART_RX); +- if (up->capabilities & UART_CAP_UUE) +- serial_out(up, UART_IER, UART_IER_UUE); +- else +- serial_out(up, UART_IER, 0); ++ serial8250_clear_IER(up); + + out_unlock: + spin_unlock_irqrestore(&port->lock, flags); +@@ -1361,7 +1380,9 @@ static void autoconfig_irq(struct uart_8250_port *up) + unsigned char save_mcr, save_ier; + unsigned char save_ICP = 0; + unsigned int ICP = 0; ++ unsigned long flags; + unsigned long irqs; ++ bool is_console; + int irq; + + if (port->flags & UPF_FOURPORT) { +@@ -1371,8 +1392,12 @@ static void autoconfig_irq(struct uart_8250_port *up) + inb_p(ICP); + } + +- if (uart_console(port)) ++ is_console = uart_console(port); ++ ++ if (is_console) { + console_lock(); ++ printk_cpu_sync_get_irqsave(flags); ++ } + + /* forget possible initially masked and pending IRQ */ + probe_irq_off(probe_irq_on()); +@@ -1404,8 +1429,10 @@ static void autoconfig_irq(struct uart_8250_port *up) + if (port->flags & UPF_FOURPORT) + outb_p(save_ICP, ICP); + +- if (uart_console(port)) ++ if (is_console) { ++ printk_cpu_sync_put_irqrestore(flags); + console_unlock(); ++ } + + port->irq = (irq > 0) ? irq : 0; + } +@@ -1418,7 +1445,7 @@ static void serial8250_stop_rx(struct uart_port *port) + + up->ier &= ~(UART_IER_RLSI | UART_IER_RDI); + up->port.read_status_mask &= ~UART_LSR_DR; +- serial_port_out(port, UART_IER, up->ier); ++ serial8250_set_IER(up, up->ier); + + serial8250_rpm_put(up); + } +@@ -1448,7 +1475,7 @@ void serial8250_em485_stop_tx(struct uart_8250_port *p) + serial8250_clear_and_reinit_fifos(p); + + p->ier |= UART_IER_RLSI | UART_IER_RDI; +- serial_port_out(&p->port, UART_IER, p->ier); ++ serial8250_set_IER(p, p->ier); + } + } + EXPORT_SYMBOL_GPL(serial8250_em485_stop_tx); +@@ -1697,7 +1724,7 @@ static void serial8250_disable_ms(struct uart_port *port) + mctrl_gpio_disable_ms(up->gpios); + + up->ier &= ~UART_IER_MSI; +- serial_port_out(port, UART_IER, up->ier); ++ serial8250_set_IER(up, up->ier); + } + + static void serial8250_enable_ms(struct uart_port *port) +@@ -1713,7 +1740,7 @@ static void serial8250_enable_ms(struct uart_port *port) + up->ier |= UART_IER_MSI; + + serial8250_rpm_get(up); +- serial_port_out(port, UART_IER, up->ier); ++ serial8250_set_IER(up, up->ier); + serial8250_rpm_put(up); + } + +@@ -2144,14 +2171,7 @@ static void serial8250_put_poll_char(struct uart_port *port, + struct uart_8250_port *up = up_to_u8250p(port); + + serial8250_rpm_get(up); +- /* +- * First save the IER then disable the interrupts +- */ +- ier = serial_port_in(port, UART_IER); +- if (up->capabilities & UART_CAP_UUE) +- serial_port_out(port, UART_IER, UART_IER_UUE); +- else +- serial_port_out(port, UART_IER, 0); ++ ier = serial8250_clear_IER(up); + + wait_for_xmitr(up, UART_LSR_BOTH_EMPTY); + /* +@@ -2164,7 +2184,7 @@ static void serial8250_put_poll_char(struct uart_port *port, + * and restore the IER + */ + wait_for_xmitr(up, UART_LSR_BOTH_EMPTY); +- serial_port_out(port, UART_IER, ier); ++ serial8250_set_IER(up, ier); + serial8250_rpm_put(up); + } + +@@ -2173,8 +2193,10 @@ static void serial8250_put_poll_char(struct uart_port *port, + int serial8250_do_startup(struct uart_port *port) + { + struct uart_8250_port *up = up_to_u8250p(port); ++ unsigned long cs_flags; + unsigned long flags; + unsigned char iir; ++ bool is_console; + int retval; + u16 lsr; + +@@ -2195,7 +2217,7 @@ int serial8250_do_startup(struct uart_port *port) + up->acr = 0; + serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); + serial_port_out(port, UART_EFR, UART_EFR_ECB); +- serial_port_out(port, UART_IER, 0); ++ serial8250_set_IER(up, 0); + serial_port_out(port, UART_LCR, 0); + serial_icr_write(up, UART_CSR, 0); /* Reset the UART */ + serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); +@@ -2205,7 +2227,7 @@ int serial8250_do_startup(struct uart_port *port) + + if (port->type == PORT_DA830) { + /* Reset the port */ +- serial_port_out(port, UART_IER, 0); ++ serial8250_set_IER(up, 0); + serial_port_out(port, UART_DA830_PWREMU_MGMT, 0); + mdelay(10); + +@@ -2304,6 +2326,8 @@ int serial8250_do_startup(struct uart_port *port) + if (retval) + goto out; + ++ is_console = uart_console(port); ++ + if (port->irq && !(up->port.flags & UPF_NO_THRE_TEST)) { + unsigned char iir1; + +@@ -2320,6 +2344,9 @@ int serial8250_do_startup(struct uart_port *port) + */ + spin_lock_irqsave(&port->lock, flags); + ++ if (is_console) ++ printk_cpu_sync_get_irqsave(cs_flags); ++ + wait_for_xmitr(up, UART_LSR_THRE); + serial_port_out_sync(port, UART_IER, UART_IER_THRI); + udelay(1); /* allow THRE to set */ +@@ -2330,6 +2357,9 @@ int serial8250_do_startup(struct uart_port *port) + iir = serial_port_in(port, UART_IIR); + serial_port_out(port, UART_IER, 0); + ++ if (is_console) ++ printk_cpu_sync_put_irqrestore(cs_flags); ++ + spin_unlock_irqrestore(&port->lock, flags); + + if (port->irqflags & IRQF_SHARED) +@@ -2384,10 +2414,14 @@ int serial8250_do_startup(struct uart_port *port) + * Do a quick test to see if we receive an interrupt when we enable + * the TX irq. + */ ++ if (is_console) ++ printk_cpu_sync_get_irqsave(cs_flags); + serial_port_out(port, UART_IER, UART_IER_THRI); + lsr = serial_port_in(port, UART_LSR); + iir = serial_port_in(port, UART_IIR); + serial_port_out(port, UART_IER, 0); ++ if (is_console) ++ printk_cpu_sync_put_irqrestore(cs_flags); + + if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) { + if (!(up->bugs & UART_BUG_TXEN)) { +@@ -2419,7 +2453,7 @@ int serial8250_do_startup(struct uart_port *port) + if (up->dma) { + const char *msg = NULL; + +- if (uart_console(port)) ++ if (is_console) + msg = "forbid DMA for kernel console"; + else if (serial8250_request_dma(up)) + msg = "failed to request DMA"; +@@ -2470,7 +2504,7 @@ void serial8250_do_shutdown(struct uart_port *port) + */ + spin_lock_irqsave(&port->lock, flags); + up->ier = 0; +- serial_port_out(port, UART_IER, 0); ++ serial8250_set_IER(up, 0); + spin_unlock_irqrestore(&port->lock, flags); + + synchronize_irq(port->irq); +@@ -2836,7 +2870,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, + if (up->capabilities & UART_CAP_RTOIE) + up->ier |= UART_IER_RTOIE; + +- serial_port_out(port, UART_IER, up->ier); ++ serial8250_set_IER(up, up->ier); + + if (up->capabilities & UART_CAP_EFR) { + unsigned char efr = 0; +@@ -3301,7 +3335,7 @@ EXPORT_SYMBOL_GPL(serial8250_set_defaults); + + #ifdef CONFIG_SERIAL_8250_CONSOLE + +-static void serial8250_console_putchar(struct uart_port *port, unsigned char ch) ++static void serial8250_console_putchar_locked(struct uart_port *port, unsigned char ch) + { + struct uart_8250_port *up = up_to_u8250p(port); + +@@ -3309,6 +3343,18 @@ static void serial8250_console_putchar(struct uart_port *port, unsigned char ch) + serial_port_out(port, UART_TX, ch); + } + ++static void serial8250_console_putchar(struct uart_port *port, unsigned char ch) ++{ ++ struct uart_8250_port *up = up_to_u8250p(port); ++ unsigned long flags; ++ ++ wait_for_xmitr(up, UART_LSR_THRE); ++ ++ printk_cpu_sync_get_irqsave(flags); ++ serial8250_console_putchar_locked(port, ch); ++ printk_cpu_sync_put_irqrestore(flags); ++} ++ + /* + * Restore serial console when h/w power-off detected + */ +@@ -3335,6 +3381,32 @@ static void serial8250_console_restore(struct uart_8250_port *up) + serial8250_out_MCR(up, up->mcr | UART_MCR_DTR | UART_MCR_RTS); + } + ++void serial8250_console_write_atomic(struct uart_8250_port *up, ++ const char *s, unsigned int count) ++{ ++ struct uart_port *port = &up->port; ++ unsigned long flags; ++ unsigned int ier; ++ ++ printk_cpu_sync_get_irqsave(flags); ++ ++ touch_nmi_watchdog(); ++ ++ ier = serial8250_clear_IER(up); ++ ++ if (atomic_fetch_inc(&up->console_printing)) { ++ uart_console_write(port, "\n", 1, ++ serial8250_console_putchar_locked); ++ } ++ uart_console_write(port, s, count, serial8250_console_putchar_locked); ++ atomic_dec(&up->console_printing); ++ ++ wait_for_xmitr(up, UART_LSR_BOTH_EMPTY); ++ serial8250_set_IER(up, ier); ++ ++ printk_cpu_sync_put_irqrestore(flags); ++} ++ + /* + * Print a string to the serial port using the device FIFO + * +@@ -3380,24 +3452,12 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s, + struct uart_port *port = &up->port; + unsigned long flags; + unsigned int ier, use_fifo; +- int locked = 1; + + touch_nmi_watchdog(); + +- if (oops_in_progress) +- locked = spin_trylock_irqsave(&port->lock, flags); +- else +- spin_lock_irqsave(&port->lock, flags); ++ spin_lock_irqsave(&port->lock, flags); + +- /* +- * First save the IER then disable the interrupts +- */ +- ier = serial_port_in(port, UART_IER); +- +- if (up->capabilities & UART_CAP_UUE) +- serial_port_out(port, UART_IER, UART_IER_UUE); +- else +- serial_port_out(port, UART_IER, 0); ++ ier = serial8250_clear_IER(up); + + /* check scratch reg to see if port powered off during system sleep */ + if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) { +@@ -3431,10 +3491,12 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s, + */ + !(up->port.flags & UPF_CONS_FLOW); + ++ atomic_inc(&up->console_printing); + if (likely(use_fifo)) + serial8250_console_fifo_write(up, s, count); + else + uart_console_write(port, s, count, serial8250_console_putchar); ++ atomic_dec(&up->console_printing); + + /* + * Finally, wait for transmitter to become empty +@@ -3447,8 +3509,7 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s, + if (em485->tx_stopped) + up->rs485_stop_tx(up); + } +- +- serial_port_out(port, UART_IER, ier); ++ serial8250_set_IER(up, ier); + + /* + * The receive handling will happen properly because the +@@ -3460,8 +3521,7 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s, + if (up->msr_saved_flags) + serial8250_modem_status(up); + +- if (locked) +- spin_unlock_irqrestore(&port->lock, flags); ++ spin_unlock_irqrestore(&port->lock, flags); + } + + static unsigned int probe_baud(struct uart_port *port) +@@ -3481,6 +3541,7 @@ static unsigned int probe_baud(struct uart_port *port) + + int serial8250_console_setup(struct uart_port *port, char *options, bool probe) + { ++ struct uart_8250_port *up = up_to_u8250p(port); + int baud = 9600; + int bits = 8; + int parity = 'n'; +@@ -3490,6 +3551,8 @@ int serial8250_console_setup(struct uart_port *port, char *options, bool probe) + if (!port->iobase && !port->membase) + return -ENODEV; + ++ atomic_set(&up->console_printing, 0); ++ + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); + else if (probe) +diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig +index d0b49e15fbf5e..02c308467339c 100644 +--- a/drivers/tty/serial/8250/Kconfig ++++ b/drivers/tty/serial/8250/Kconfig +@@ -9,6 +9,7 @@ config SERIAL_8250 + depends on !S390 + select SERIAL_CORE + select SERIAL_MCTRL_GPIO if GPIOLIB ++ select HAVE_ATOMIC_CONSOLE + help + This selects whether you want to include the driver for the standard + serial ports. The standard answer is Y. People who might say N +diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c +index 15f0e4d88c5a0..ffdb001e3d109 100644 +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -2308,18 +2308,24 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) + { + struct uart_amba_port *uap = amba_ports[co->index]; + unsigned int old_cr = 0, new_cr; +- unsigned long flags; ++ unsigned long flags = 0; + int locked = 1; + + clk_enable(uap->clk); + +- local_irq_save(flags); ++ /* ++ * local_irq_save(flags); ++ * ++ * This local_irq_save() is nonsense. If we come in via sysrq ++ * handling then interrupts are already disabled. Aside of ++ * that the port.sysrq check is racy on SMP regardless. ++ */ + if (uap->port.sysrq) + locked = 0; + else if (oops_in_progress) +- locked = spin_trylock(&uap->port.lock); ++ locked = spin_trylock_irqsave(&uap->port.lock, flags); + else +- spin_lock(&uap->port.lock); ++ spin_lock_irqsave(&uap->port.lock, flags); + + /* + * First save the CR then disable the interrupts +@@ -2345,8 +2351,7 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) + pl011_write(old_cr, uap, REG_CR); + + if (locked) +- spin_unlock(&uap->port.lock); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(&uap->port.lock, flags); + + clk_disable(uap->clk); + } +diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c +index 0aa666e247d57..d7130d1ae64c0 100644 +--- a/drivers/tty/serial/omap-serial.c ++++ b/drivers/tty/serial/omap-serial.c +@@ -1240,13 +1240,10 @@ serial_omap_console_write(struct console *co, const char *s, + unsigned int ier; + int locked = 1; + +- local_irq_save(flags); +- if (up->port.sysrq) +- locked = 0; +- else if (oops_in_progress) +- locked = spin_trylock(&up->port.lock); ++ if (up->port.sysrq || oops_in_progress) ++ locked = spin_trylock_irqsave(&up->port.lock, flags); + else +- spin_lock(&up->port.lock); ++ spin_lock_irqsave(&up->port.lock, flags); + + /* + * First save the IER then disable the interrupts +@@ -1273,8 +1270,7 @@ serial_omap_console_write(struct console *co, const char *s, + check_modem_status(up); + + if (locked) +- spin_unlock(&up->port.lock); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(&up->port.lock, flags); + } + + static int __init +diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c +index d2b2720db6ca7..18e623325887f 100644 +--- a/drivers/tty/sysrq.c ++++ b/drivers/tty/sysrq.c +@@ -581,6 +581,7 @@ void __handle_sysrq(int key, bool check_mask) + + rcu_sysrq_start(); + rcu_read_lock(); ++ printk_prefer_direct_enter(); + /* + * Raise the apparent loglevel to maximum so that the sysrq header + * is shown to provide the user with positive feedback. We do not +@@ -622,6 +623,7 @@ void __handle_sysrq(int key, bool check_mask) + pr_cont("\n"); + console_loglevel = orig_log_level; + } ++ printk_prefer_direct_exit(); + rcu_read_unlock(); + rcu_sysrq_end(); + +diff --git a/drivers/vdpa/vdpa_user/iova_domain.h b/drivers/vdpa/vdpa_user/iova_domain.h +index 4e0e50e7ac153..173e979b84a93 100644 +--- a/drivers/vdpa/vdpa_user/iova_domain.h ++++ b/drivers/vdpa/vdpa_user/iova_domain.h +@@ -14,7 +14,6 @@ + #include + #include + #include +-#include + + #define IOVA_START_PFN 1 + +diff --git a/fs/dcache.c b/fs/dcache.c +index bb0c4d0038dbd..2ee8636016ee9 100644 +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -2597,15 +2597,7 @@ EXPORT_SYMBOL(d_rehash); + + static inline unsigned start_dir_add(struct inode *dir) + { +- /* +- * The caller holds a spinlock (dentry::d_lock). On !PREEMPT_RT +- * kernels spin_lock() implicitly disables preemption, but not on +- * PREEMPT_RT. So for RT it has to be done explicitly to protect +- * the sequence count write side critical section against a reader +- * or another writer preempting, which would result in a live lock. +- */ +- if (IS_ENABLED(CONFIG_PREEMPT_RT)) +- preempt_disable(); ++ preempt_disable_nested(); + for (;;) { + unsigned n = dir->i_dir_seq; + if (!(n & 1) && cmpxchg(&dir->i_dir_seq, n, n + 1) == n) +@@ -2618,8 +2610,7 @@ static inline void end_dir_add(struct inode *dir, unsigned int n, + wait_queue_head_t *d_wait) + { + smp_store_release(&dir->i_dir_seq, n + 2); +- if (IS_ENABLED(CONFIG_PREEMPT_RT)) +- preempt_enable(); ++ preempt_enable_nested(); + wake_up_all(d_wait); + } + +diff --git a/include/linux/console.h b/include/linux/console.h +index 8c1686e2c2337..8a813cbaf9285 100644 +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -16,6 +16,7 @@ + + #include + #include ++#include + + struct vc_data; + struct console_font_op; +@@ -137,9 +138,19 @@ static inline int con_debug_leave(void) + #define CON_BRL (32) /* Used for a braille device */ + #define CON_EXTENDED (64) /* Use the extended output format a la /dev/kmsg */ + ++#ifdef CONFIG_HAVE_ATOMIC_CONSOLE ++struct console_atomic_data { ++ u64 seq; ++ char *text; ++ char *ext_text; ++ char *dropped_text; ++}; ++#endif ++ + struct console { + char name[16]; + void (*write)(struct console *, const char *, unsigned); ++ void (*write_atomic)(struct console *, const char *, unsigned); + int (*read)(struct console *, char *, unsigned); + struct tty_driver *(*device)(struct console *, int *); + void (*unblank)(void); +@@ -152,7 +163,26 @@ struct console { + uint ispeed; + uint ospeed; + u64 seq; +- unsigned long dropped; ++ atomic_long_t dropped; ++#ifdef CONFIG_HAVE_ATOMIC_CONSOLE ++ struct console_atomic_data *atomic_data; ++#endif ++ struct task_struct *thread; ++ bool blocked; ++ ++ /* ++ * The per-console lock is used by printing kthreads to synchronize ++ * this console with callers of console_lock(). This is necessary in ++ * order to allow printing kthreads to run in parallel to each other, ++ * while each safely accessing the @blocked field and synchronizing ++ * against direct printing via console_lock/console_unlock. ++ * ++ * Note: For synchronizing against direct printing via ++ * console_trylock/console_unlock, see the static global ++ * variable @console_kthreads_active. ++ */ ++ struct mutex lock; ++ + void *data; + struct console *next; + }; +@@ -167,6 +197,7 @@ extern int console_set_on_cmdline; + extern struct console *early_console; + + enum con_flush_mode { ++ CONSOLE_ATOMIC_FLUSH_PENDING, + CONSOLE_FLUSH_PENDING, + CONSOLE_REPLAY_ALL, + }; +diff --git a/include/linux/entry-common.h b/include/linux/entry-common.h +index 84a466b176cf4..df6d17bc30aa3 100644 +--- a/include/linux/entry-common.h ++++ b/include/linux/entry-common.h +@@ -57,9 +57,15 @@ + # define ARCH_EXIT_TO_USER_MODE_WORK (0) + #endif + ++#ifdef CONFIG_PREEMPT_LAZY ++# define _TIF_NEED_RESCHED_MASK (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY) ++#else ++# define _TIF_NEED_RESCHED_MASK (_TIF_NEED_RESCHED) ++#endif ++ + #define EXIT_TO_USER_MODE_WORK \ + (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_UPROBE | \ +- _TIF_NEED_RESCHED | _TIF_PATCH_PENDING | _TIF_NOTIFY_SIGNAL | \ ++ _TIF_NEED_RESCHED_MASK | _TIF_PATCH_PENDING | _TIF_NOTIFY_SIGNAL | \ + ARCH_EXIT_TO_USER_MODE_WORK) + + /** +diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h +index a92bce40b04b3..bf82980f569df 100644 +--- a/include/linux/interrupt.h ++++ b/include/linux/interrupt.h +@@ -605,6 +605,35 @@ extern void __raise_softirq_irqoff(unsigned int nr); + extern void raise_softirq_irqoff(unsigned int nr); + extern void raise_softirq(unsigned int nr); + ++#ifdef CONFIG_PREEMPT_RT ++DECLARE_PER_CPU(struct task_struct *, timersd); ++DECLARE_PER_CPU(unsigned long, pending_timer_softirq); ++ ++extern void raise_timer_softirq(void); ++extern void raise_hrtimer_softirq(void); ++ ++static inline unsigned int local_pending_timers(void) ++{ ++ return __this_cpu_read(pending_timer_softirq); ++} ++ ++#else ++static inline void raise_timer_softirq(void) ++{ ++ raise_softirq(TIMER_SOFTIRQ); ++} ++ ++static inline void raise_hrtimer_softirq(void) ++{ ++ raise_softirq_irqoff(HRTIMER_SOFTIRQ); ++} ++ ++static inline unsigned int local_pending_timers(void) ++{ ++ return local_softirq_pending(); ++} ++#endif ++ + DECLARE_PER_CPU(struct task_struct *, ksoftirqd); + + static inline struct task_struct *this_cpu_ksoftirqd(void) +diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h +index 1cd4e36890fbf..844a8e30e6de5 100644 +--- a/include/linux/irqdesc.h ++++ b/include/linux/irqdesc.h +@@ -169,6 +169,7 @@ int generic_handle_irq_safe(unsigned int irq); + * conversion failed. + */ + int generic_handle_domain_irq(struct irq_domain *domain, unsigned int hwirq); ++int generic_handle_domain_irq_safe(struct irq_domain *domain, unsigned int hwirq); + int generic_handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq); + #endif + +diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h +index 1f1099dac3f05..1023f349af716 100644 +--- a/include/linux/lockdep.h ++++ b/include/linux/lockdep.h +@@ -435,7 +435,6 @@ enum xhlock_context_t { + XHLOCK_CTX_NR, + }; + +-#define lockdep_init_map_crosslock(m, n, k, s) do {} while (0) + /* + * To initialize a lockdep_map statically use this macro. + * Note that _name must not be NULL. +diff --git a/include/linux/mmdebug.h b/include/linux/mmdebug.h +index 15ae78cd28536..b8728d11c9490 100644 +--- a/include/linux/mmdebug.h ++++ b/include/linux/mmdebug.h +@@ -94,6 +94,12 @@ void dump_mm(const struct mm_struct *mm); + #define VM_WARN(cond, format...) BUILD_BUG_ON_INVALID(cond) + #endif + ++#ifdef CONFIG_DEBUG_VM_IRQSOFF ++#define VM_WARN_ON_IRQS_ENABLED() WARN_ON_ONCE(!irqs_disabled()) ++#else ++#define VM_WARN_ON_IRQS_ENABLED() do { } while (0) ++#endif ++ + #ifdef CONFIG_DEBUG_VIRTUAL + #define VIRTUAL_BUG_ON(cond) BUG_ON(cond) + #else +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index 05d6f3facd5a5..5e6b840f5a9ac 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -3156,7 +3156,11 @@ struct softnet_data { + int defer_count; + int defer_ipi_scheduled; + struct sk_buff *defer_list; ++#ifndef CONFIG_PREEMPT_RT + call_single_data_t defer_csd; ++#else ++ struct work_struct defer_work; ++#endif + }; + + static inline void input_queue_head_incr(struct softnet_data *sd) +diff --git a/include/linux/preempt.h b/include/linux/preempt.h +index b4381f255a5ca..12f59cdaaedda 100644 +--- a/include/linux/preempt.h ++++ b/include/linux/preempt.h +@@ -196,6 +196,20 @@ extern void preempt_count_sub(int val); + #define preempt_count_inc() preempt_count_add(1) + #define preempt_count_dec() preempt_count_sub(1) + ++#ifdef CONFIG_PREEMPT_LAZY ++#define add_preempt_lazy_count(val) do { preempt_lazy_count() += (val); } while (0) ++#define sub_preempt_lazy_count(val) do { preempt_lazy_count() -= (val); } while (0) ++#define inc_preempt_lazy_count() add_preempt_lazy_count(1) ++#define dec_preempt_lazy_count() sub_preempt_lazy_count(1) ++#define preempt_lazy_count() (current_thread_info()->preempt_lazy_count) ++#else ++#define add_preempt_lazy_count(val) do { } while (0) ++#define sub_preempt_lazy_count(val) do { } while (0) ++#define inc_preempt_lazy_count() do { } while (0) ++#define dec_preempt_lazy_count() do { } while (0) ++#define preempt_lazy_count() (0) ++#endif ++ + #ifdef CONFIG_PREEMPT_COUNT + + #define preempt_disable() \ +@@ -204,6 +218,12 @@ do { \ + barrier(); \ + } while (0) + ++#define preempt_lazy_disable() \ ++do { \ ++ inc_preempt_lazy_count(); \ ++ barrier(); \ ++} while (0) ++ + #define sched_preempt_enable_no_resched() \ + do { \ + barrier(); \ +@@ -235,6 +255,18 @@ do { \ + __preempt_schedule(); \ + } while (0) + ++/* ++ * open code preempt_check_resched() because it is not exported to modules and ++ * used by local_unlock() or bpf_enable_instrumentation(). ++ */ ++#define preempt_lazy_enable() \ ++do { \ ++ dec_preempt_lazy_count(); \ ++ barrier(); \ ++ if (should_resched(0)) \ ++ __preempt_schedule(); \ ++} while (0) ++ + #else /* !CONFIG_PREEMPTION */ + #define preempt_enable() \ + do { \ +@@ -242,6 +274,12 @@ do { \ + preempt_count_dec(); \ + } while (0) + ++#define preempt_lazy_enable() \ ++do { \ ++ dec_preempt_lazy_count(); \ ++ barrier(); \ ++} while (0) ++ + #define preempt_enable_notrace() \ + do { \ + barrier(); \ +@@ -282,6 +320,9 @@ do { \ + #define preempt_enable_notrace() barrier() + #define preemptible() 0 + ++#define preempt_lazy_disable() barrier() ++#define preempt_lazy_enable() barrier() ++ + #endif /* CONFIG_PREEMPT_COUNT */ + + #ifdef MODULE +@@ -300,7 +341,7 @@ do { \ + } while (0) + #define preempt_fold_need_resched() \ + do { \ +- if (tif_need_resched()) \ ++ if (tif_need_resched_now()) \ + set_preempt_need_resched(); \ + } while (0) + +@@ -416,9 +457,58 @@ extern void migrate_enable(void); + + #else + +-static inline void migrate_disable(void) { } +-static inline void migrate_enable(void) { } ++static inline void migrate_disable(void) ++{ ++ preempt_lazy_disable(); ++} ++ ++static inline void migrate_enable(void) ++{ ++ preempt_lazy_enable(); ++} + + #endif /* CONFIG_SMP */ + ++/** ++ * preempt_disable_nested - Disable preemption inside a normally preempt disabled section ++ * ++ * Use for code which requires preemption protection inside a critical ++ * section which has preemption disabled implicitly on non-PREEMPT_RT ++ * enabled kernels, by e.g.: ++ * - holding a spinlock/rwlock ++ * - soft interrupt context ++ * - regular interrupt handlers ++ * ++ * On PREEMPT_RT enabled kernels spinlock/rwlock held sections, soft ++ * interrupt context and regular interrupt handlers are preemptible and ++ * only prevent migration. preempt_disable_nested() ensures that preemption ++ * is disabled for cases which require CPU local serialization even on ++ * PREEMPT_RT. For non-PREEMPT_RT kernels this is a NOP. ++ * ++ * The use cases are code sequences which are not serialized by a ++ * particular lock instance, e.g.: ++ * - seqcount write side critical sections where the seqcount is not ++ * associated to a particular lock and therefore the automatic ++ * protection mechanism does not work. This prevents a live lock ++ * against a preempting high priority reader. ++ * - RMW per CPU variable updates like vmstat. ++ */ ++/* Macro to avoid header recursion hell vs. lockdep */ ++#define preempt_disable_nested() \ ++do { \ ++ if (IS_ENABLED(CONFIG_PREEMPT_RT)) \ ++ preempt_disable(); \ ++ else \ ++ lockdep_assert_preemption_disabled(); \ ++} while (0) ++ ++/** ++ * preempt_enable_nested - Undo the effect of preempt_disable_nested() ++ */ ++static __always_inline void preempt_enable_nested(void) ++{ ++ if (IS_ENABLED(CONFIG_PREEMPT_RT)) ++ preempt_enable(); ++} ++ + #endif /* __LINUX_PREEMPT_H */ +diff --git a/include/linux/printk.h b/include/linux/printk.h +index cf7d666ab1f8e..f88ec15f83dcc 100644 +--- a/include/linux/printk.h ++++ b/include/linux/printk.h +@@ -169,7 +169,11 @@ extern void __printk_safe_exit(void); + #define printk_deferred_enter __printk_safe_enter + #define printk_deferred_exit __printk_safe_exit + ++extern void printk_prefer_direct_enter(void); ++extern void printk_prefer_direct_exit(void); ++ + extern bool pr_flush(int timeout_ms, bool reset_on_progress); ++extern void try_block_console_kthreads(int timeout_ms); + + /* + * Please don't use printk_ratelimit(), because it shares ratelimiting state +@@ -221,11 +225,23 @@ static inline void printk_deferred_exit(void) + { + } + ++static inline void printk_prefer_direct_enter(void) ++{ ++} ++ ++static inline void printk_prefer_direct_exit(void) ++{ ++} ++ + static inline bool pr_flush(int timeout_ms, bool reset_on_progress) + { + return true; + } + ++static inline void try_block_console_kthreads(int timeout_ms) ++{ ++} ++ + static inline int printk_ratelimit(void) + { + return 0; +diff --git a/include/linux/rwlock.h b/include/linux/rwlock.h +index 8f416c5e929ea..c0ef596f340b5 100644 +--- a/include/linux/rwlock.h ++++ b/include/linux/rwlock.h +@@ -1,7 +1,7 @@ + #ifndef __LINUX_RWLOCK_H + #define __LINUX_RWLOCK_H + +-#ifndef __LINUX_SPINLOCK_H ++#ifndef __LINUX_INSIDE_SPINLOCK_H + # error "please don't include this file directly" + #endif + +diff --git a/include/linux/sched.h b/include/linux/sched.h +index 8d82d6d326701..e1623b3001c5b 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -2038,6 +2038,43 @@ static inline int test_tsk_need_resched(struct task_struct *tsk) + return unlikely(test_tsk_thread_flag(tsk,TIF_NEED_RESCHED)); + } + ++#ifdef CONFIG_PREEMPT_LAZY ++static inline void set_tsk_need_resched_lazy(struct task_struct *tsk) ++{ ++ set_tsk_thread_flag(tsk,TIF_NEED_RESCHED_LAZY); ++} ++ ++static inline void clear_tsk_need_resched_lazy(struct task_struct *tsk) ++{ ++ clear_tsk_thread_flag(tsk,TIF_NEED_RESCHED_LAZY); ++} ++ ++static inline int test_tsk_need_resched_lazy(struct task_struct *tsk) ++{ ++ return unlikely(test_tsk_thread_flag(tsk,TIF_NEED_RESCHED_LAZY)); ++} ++ ++static inline int need_resched_lazy(void) ++{ ++ return test_thread_flag(TIF_NEED_RESCHED_LAZY); ++} ++ ++static inline int need_resched_now(void) ++{ ++ return test_thread_flag(TIF_NEED_RESCHED); ++} ++ ++#else ++static inline void clear_tsk_need_resched_lazy(struct task_struct *tsk) { } ++static inline int need_resched_lazy(void) { return 0; } ++ ++static inline int need_resched_now(void) ++{ ++ return test_thread_flag(TIF_NEED_RESCHED); ++} ++ ++#endif ++ + /* + * cond_resched() and cond_resched_lock(): latency reduction via + * explicit rescheduling in places that are safe. The return +diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h +index 16e3d75a324c7..ee1f719a21678 100644 +--- a/include/linux/serial_8250.h ++++ b/include/linux/serial_8250.h +@@ -7,6 +7,7 @@ + #ifndef _LINUX_SERIAL_8250_H + #define _LINUX_SERIAL_8250_H + ++#include + #include + #include + #include +@@ -125,6 +126,8 @@ struct uart_8250_port { + #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA + unsigned char msr_saved_flags; + ++ atomic_t console_printing; ++ + struct uart_8250_dma *dma; + const struct uart_8250_ops *ops; + +@@ -180,6 +183,8 @@ void serial8250_init_port(struct uart_8250_port *up); + void serial8250_set_defaults(struct uart_8250_port *up); + void serial8250_console_write(struct uart_8250_port *up, const char *s, + unsigned int count); ++void serial8250_console_write_atomic(struct uart_8250_port *up, const char *s, ++ unsigned int count); + int serial8250_console_setup(struct uart_port *port, char *options, bool probe); + int serial8250_console_exit(struct uart_port *port); + +diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h +index 5c0c5174155d0..1341f7d62da44 100644 +--- a/include/linux/spinlock.h ++++ b/include/linux/spinlock.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: GPL-2.0 */ + #ifndef __LINUX_SPINLOCK_H + #define __LINUX_SPINLOCK_H ++#define __LINUX_INSIDE_SPINLOCK_H + + /* + * include/linux/spinlock.h - generic spinlock/rwlock declarations +@@ -492,4 +493,5 @@ int __alloc_bucket_spinlocks(spinlock_t **locks, unsigned int *lock_mask, + + void free_bucket_spinlocks(spinlock_t *locks); + ++#undef __LINUX_INSIDE_SPINLOCK_H + #endif /* __LINUX_SPINLOCK_H */ +diff --git a/include/linux/spinlock_api_smp.h b/include/linux/spinlock_api_smp.h +index 51fa0dab68c4d..89eb6f4c659c7 100644 +--- a/include/linux/spinlock_api_smp.h ++++ b/include/linux/spinlock_api_smp.h +@@ -1,7 +1,7 @@ + #ifndef __LINUX_SPINLOCK_API_SMP_H + #define __LINUX_SPINLOCK_API_SMP_H + +-#ifndef __LINUX_SPINLOCK_H ++#ifndef __LINUX_INSIDE_SPINLOCK_H + # error "please don't include this file directly" + #endif + +diff --git a/include/linux/spinlock_api_up.h b/include/linux/spinlock_api_up.h +index b8ba00ccccdeb..819aeba1c87e6 100644 +--- a/include/linux/spinlock_api_up.h ++++ b/include/linux/spinlock_api_up.h +@@ -1,7 +1,7 @@ + #ifndef __LINUX_SPINLOCK_API_UP_H + #define __LINUX_SPINLOCK_API_UP_H + +-#ifndef __LINUX_SPINLOCK_H ++#ifndef __LINUX_INSIDE_SPINLOCK_H + # error "please don't include this file directly" + #endif + +diff --git a/include/linux/spinlock_rt.h b/include/linux/spinlock_rt.h +index 835aedaf68acd..61c49b16f69ab 100644 +--- a/include/linux/spinlock_rt.h ++++ b/include/linux/spinlock_rt.h +@@ -2,7 +2,7 @@ + #ifndef __LINUX_SPINLOCK_RT_H + #define __LINUX_SPINLOCK_RT_H + +-#ifndef __LINUX_SPINLOCK_H ++#ifndef __LINUX_INSIDE_SPINLOCK_H + #error Do not include directly. Use spinlock.h + #endif + +diff --git a/include/linux/spinlock_up.h b/include/linux/spinlock_up.h +index 16521074b6f7c..c87204247592f 100644 +--- a/include/linux/spinlock_up.h ++++ b/include/linux/spinlock_up.h +@@ -1,7 +1,7 @@ + #ifndef __LINUX_SPINLOCK_UP_H + #define __LINUX_SPINLOCK_UP_H + +-#ifndef __LINUX_SPINLOCK_H ++#ifndef __LINUX_INSIDE_SPINLOCK_H + # error "please don't include this file directly" + #endif + +diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h +index 9f392ec76f2bb..779e0e96b9cb0 100644 +--- a/include/linux/thread_info.h ++++ b/include/linux/thread_info.h +@@ -177,7 +177,17 @@ static __always_inline unsigned long read_ti_thread_flags(struct thread_info *ti + clear_ti_thread_flag(task_thread_info(t), TIF_##fl) + #endif /* !CONFIG_GENERIC_ENTRY */ + +-#define tif_need_resched() test_thread_flag(TIF_NEED_RESCHED) ++#ifdef CONFIG_PREEMPT_LAZY ++#define tif_need_resched() (test_thread_flag(TIF_NEED_RESCHED) || \ ++ test_thread_flag(TIF_NEED_RESCHED_LAZY)) ++#define tif_need_resched_now() (test_thread_flag(TIF_NEED_RESCHED)) ++#define tif_need_resched_lazy() test_thread_flag(TIF_NEED_RESCHED_LAZY) ++ ++#else ++#define tif_need_resched() test_thread_flag(TIF_NEED_RESCHED) ++#define tif_need_resched_now() test_thread_flag(TIF_NEED_RESCHED) ++#define tif_need_resched_lazy() 0 ++#endif + + #ifndef CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES + static inline int arch_within_stack_frames(const void * const stack, +diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h +index 20749bd9db718..224bf60d6563c 100644 +--- a/include/linux/trace_events.h ++++ b/include/linux/trace_events.h +@@ -70,6 +70,7 @@ struct trace_entry { + unsigned char flags; + unsigned char preempt_count; + int pid; ++ unsigned char preempt_lazy_count; + }; + + #define TRACE_EVENT_TYPE_MAX \ +@@ -159,9 +160,10 @@ static inline void tracing_generic_entry_update(struct trace_entry *entry, + unsigned int trace_ctx) + { + entry->preempt_count = trace_ctx & 0xff; ++ entry->preempt_lazy_count = (trace_ctx >> 16) & 0xff; + entry->pid = current->pid; + entry->type = type; +- entry->flags = trace_ctx >> 16; ++ entry->flags = trace_ctx >> 24; + } + + unsigned int tracing_gen_ctx_irq_test(unsigned int irqs_status); +@@ -172,7 +174,13 @@ enum trace_flag_type { + TRACE_FLAG_NEED_RESCHED = 0x04, + TRACE_FLAG_HARDIRQ = 0x08, + TRACE_FLAG_SOFTIRQ = 0x10, ++#ifdef CONFIG_PREEMPT_LAZY ++ TRACE_FLAG_PREEMPT_RESCHED = 0x00, ++ TRACE_FLAG_NEED_RESCHED_LAZY = 0x20, ++#else ++ TRACE_FLAG_NEED_RESCHED_LAZY = 0x00, + TRACE_FLAG_PREEMPT_RESCHED = 0x20, ++#endif + TRACE_FLAG_NMI = 0x40, + TRACE_FLAG_BH_OFF = 0x80, + }; +diff --git a/include/linux/u64_stats_sync.h b/include/linux/u64_stats_sync.h +index 6ad4e9032d538..ffe48e69b3f3a 100644 +--- a/include/linux/u64_stats_sync.h ++++ b/include/linux/u64_stats_sync.h +@@ -8,7 +8,7 @@ + * + * Key points : + * +- * - Use a seqcount on 32-bit SMP, only disable preemption for 32-bit UP. ++ * - Use a seqcount on 32-bit + * - The whole thing is a no-op on 64-bit architectures. + * + * Usage constraints: +@@ -20,7 +20,8 @@ + * writer and also spin forever. + * + * 3) Write side must use the _irqsave() variant if other writers, or a reader, +- * can be invoked from an IRQ context. ++ * can be invoked from an IRQ context. On 64bit systems this variant does not ++ * disable interrupts. + * + * 4) If reader fetches several counters, there is no guarantee the whole values + * are consistent w.r.t. each other (remember point #2: seqcounts are not +@@ -29,11 +30,6 @@ + * 5) Readers are allowed to sleep or be preempted/interrupted: they perform + * pure reads. + * +- * 6) Readers must use both u64_stats_fetch_{begin,retry}_irq() if the stats +- * might be updated from a hardirq or softirq context (remember point #1: +- * seqcounts are not used for UP kernels). 32-bit UP stat readers could read +- * corrupted 64-bit values otherwise. +- * + * Usage : + * + * Stats producer (writer) should use following template granted it already got +@@ -66,7 +62,7 @@ + #include + + struct u64_stats_sync { +-#if BITS_PER_LONG == 32 && (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT)) ++#if BITS_PER_LONG == 32 + seqcount_t seq; + #endif + }; +@@ -98,7 +94,22 @@ static inline void u64_stats_inc(u64_stats_t *p) + local64_inc(&p->v); + } + +-#else ++static inline void u64_stats_init(struct u64_stats_sync *syncp) { } ++static inline void __u64_stats_update_begin(struct u64_stats_sync *syncp) { } ++static inline void __u64_stats_update_end(struct u64_stats_sync *syncp) { } ++static inline unsigned long __u64_stats_irqsave(void) { return 0; } ++static inline void __u64_stats_irqrestore(unsigned long flags) { } ++static inline unsigned int __u64_stats_fetch_begin(const struct u64_stats_sync *syncp) ++{ ++ return 0; ++} ++static inline bool __u64_stats_fetch_retry(const struct u64_stats_sync *syncp, ++ unsigned int start) ++{ ++ return false; ++} ++ ++#else /* 64 bit */ + + typedef struct { + u64 v; +@@ -123,122 +134,82 @@ static inline void u64_stats_inc(u64_stats_t *p) + { + p->v++; + } +-#endif + +-#if BITS_PER_LONG == 32 && (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT)) +-#define u64_stats_init(syncp) seqcount_init(&(syncp)->seq) +-#else + static inline void u64_stats_init(struct u64_stats_sync *syncp) + { ++ seqcount_init(&syncp->seq); + } +-#endif + +-static inline void u64_stats_update_begin(struct u64_stats_sync *syncp) ++static inline void __u64_stats_update_begin(struct u64_stats_sync *syncp) + { +-#if BITS_PER_LONG == 32 && (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT)) +- if (IS_ENABLED(CONFIG_PREEMPT_RT)) +- preempt_disable(); ++ preempt_disable_nested(); + write_seqcount_begin(&syncp->seq); +-#endif + } + +-static inline void u64_stats_update_end(struct u64_stats_sync *syncp) ++static inline void __u64_stats_update_end(struct u64_stats_sync *syncp) + { +-#if BITS_PER_LONG == 32 && (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT)) + write_seqcount_end(&syncp->seq); +- if (IS_ENABLED(CONFIG_PREEMPT_RT)) +- preempt_enable(); +-#endif ++ preempt_enable_nested(); + } + +-static inline unsigned long +-u64_stats_update_begin_irqsave(struct u64_stats_sync *syncp) ++static inline unsigned long __u64_stats_irqsave(void) + { +- unsigned long flags = 0; ++ unsigned long flags; + +-#if BITS_PER_LONG == 32 && (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT)) +- if (IS_ENABLED(CONFIG_PREEMPT_RT)) +- preempt_disable(); +- else +- local_irq_save(flags); +- write_seqcount_begin(&syncp->seq); +-#endif ++ local_irq_save(flags); + return flags; + } + +-static inline void +-u64_stats_update_end_irqrestore(struct u64_stats_sync *syncp, +- unsigned long flags) ++static inline void __u64_stats_irqrestore(unsigned long flags) + { +-#if BITS_PER_LONG == 32 && (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT)) +- write_seqcount_end(&syncp->seq); +- if (IS_ENABLED(CONFIG_PREEMPT_RT)) +- preempt_enable(); +- else +- local_irq_restore(flags); +-#endif ++ local_irq_restore(flags); + } + + static inline unsigned int __u64_stats_fetch_begin(const struct u64_stats_sync *syncp) + { +-#if BITS_PER_LONG == 32 && (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT)) + return read_seqcount_begin(&syncp->seq); +-#else +- return 0; +-#endif ++} ++ ++static inline bool __u64_stats_fetch_retry(const struct u64_stats_sync *syncp, ++ unsigned int start) ++{ ++ return read_seqcount_retry(&syncp->seq, start); ++} ++#endif /* !64 bit */ ++ ++static inline void u64_stats_update_begin(struct u64_stats_sync *syncp) ++{ ++ __u64_stats_update_begin(syncp); ++} ++ ++static inline void u64_stats_update_end(struct u64_stats_sync *syncp) ++{ ++ __u64_stats_update_end(syncp); ++} ++ ++static inline unsigned long u64_stats_update_begin_irqsave(struct u64_stats_sync *syncp) ++{ ++ unsigned long flags = __u64_stats_irqsave(); ++ ++ __u64_stats_update_begin(syncp); ++ return flags; ++} ++ ++static inline void u64_stats_update_end_irqrestore(struct u64_stats_sync *syncp, ++ unsigned long flags) ++{ ++ __u64_stats_update_end(syncp); ++ __u64_stats_irqrestore(flags); + } + + static inline unsigned int u64_stats_fetch_begin(const struct u64_stats_sync *syncp) + { +-#if BITS_PER_LONG == 32 && (!defined(CONFIG_SMP) && !defined(CONFIG_PREEMPT_RT)) +- preempt_disable(); +-#endif + return __u64_stats_fetch_begin(syncp); + } + +-static inline bool __u64_stats_fetch_retry(const struct u64_stats_sync *syncp, +- unsigned int start) +-{ +-#if BITS_PER_LONG == 32 && (defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT)) +- return read_seqcount_retry(&syncp->seq, start); +-#else +- return false; +-#endif +-} +- + static inline bool u64_stats_fetch_retry(const struct u64_stats_sync *syncp, + unsigned int start) + { +-#if BITS_PER_LONG == 32 && (!defined(CONFIG_SMP) && !defined(CONFIG_PREEMPT_RT)) +- preempt_enable(); +-#endif +- return __u64_stats_fetch_retry(syncp, start); +-} +- +-/* +- * In case irq handlers can update u64 counters, readers can use following helpers +- * - SMP 32bit arches use seqcount protection, irq safe. +- * - UP 32bit must disable irqs. +- * - 64bit have no problem atomically reading u64 values, irq safe. +- */ +-static inline unsigned int u64_stats_fetch_begin_irq(const struct u64_stats_sync *syncp) +-{ +-#if BITS_PER_LONG == 32 && defined(CONFIG_PREEMPT_RT) +- preempt_disable(); +-#elif BITS_PER_LONG == 32 && !defined(CONFIG_SMP) +- local_irq_disable(); +-#endif +- return __u64_stats_fetch_begin(syncp); +-} +- +-static inline bool u64_stats_fetch_retry_irq(const struct u64_stats_sync *syncp, +- unsigned int start) +-{ +-#if BITS_PER_LONG == 32 && defined(CONFIG_PREEMPT_RT) +- preempt_enable(); +-#elif BITS_PER_LONG == 32 && !defined(CONFIG_SMP) +- local_irq_enable(); +-#endif + return __u64_stats_fetch_retry(syncp, start); + } + +diff --git a/init/Kconfig b/init/Kconfig +index 532362fcfe31f..08ec5f25e6642 100644 +--- a/init/Kconfig ++++ b/init/Kconfig +@@ -1574,6 +1574,10 @@ config PRINTK + very difficult to diagnose system problems, saying N here is + strongly discouraged. + ++config HAVE_ATOMIC_CONSOLE ++ bool ++ default n ++ + config BUG + bool "BUG() support" if EXPERT + default y +diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt +index c2f1fd95a8214..260c08efeb486 100644 +--- a/kernel/Kconfig.preempt ++++ b/kernel/Kconfig.preempt +@@ -1,5 +1,11 @@ + # SPDX-License-Identifier: GPL-2.0-only + ++config HAVE_PREEMPT_LAZY ++ bool ++ ++config PREEMPT_LAZY ++ def_bool y if HAVE_PREEMPT_LAZY && PREEMPT_RT ++ + config PREEMPT_NONE_BUILD + bool + +diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c +index 22e7a805c6723..b492e482b63a9 100644 +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -2107,11 +2107,11 @@ static void bpf_prog_get_stats(const struct bpf_prog *prog, + + st = per_cpu_ptr(prog->stats, cpu); + do { +- start = u64_stats_fetch_begin_irq(&st->syncp); ++ start = u64_stats_fetch_begin(&st->syncp); + tnsecs = u64_stats_read(&st->nsecs); + tcnt = u64_stats_read(&st->cnt); + tmisses = u64_stats_read(&st->misses); +- } while (u64_stats_fetch_retry_irq(&st->syncp, start)); ++ } while (u64_stats_fetch_retry(&st->syncp, start)); + nsecs += tnsecs; + cnt += tcnt; + misses += tmisses; +diff --git a/kernel/entry/common.c b/kernel/entry/common.c +index 063068a9ea9b3..26b772720b227 100644 +--- a/kernel/entry/common.c ++++ b/kernel/entry/common.c +@@ -153,7 +153,7 @@ static unsigned long exit_to_user_mode_loop(struct pt_regs *regs, + + local_irq_enable_exit_to_user(ti_work); + +- if (ti_work & _TIF_NEED_RESCHED) ++ if (ti_work & _TIF_NEED_RESCHED_MASK) + schedule(); + + if (ti_work & _TIF_UPROBE) +@@ -381,7 +381,7 @@ void raw_irqentry_exit_cond_resched(void) + rcu_irq_exit_check_preempt(); + if (IS_ENABLED(CONFIG_DEBUG_ENTRY)) + WARN_ON_ONCE(!on_thread_stack()); +- if (need_resched()) ++ if (should_resched(0)) + preempt_schedule_irq(); + } + } +diff --git a/kernel/hung_task.c b/kernel/hung_task.c +index bb2354f73dedc..19c9de825d248 100644 +--- a/kernel/hung_task.c ++++ b/kernel/hung_task.c +@@ -127,6 +127,8 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout) + * complain: + */ + if (sysctl_hung_task_warnings) { ++ printk_prefer_direct_enter(); ++ + if (sysctl_hung_task_warnings > 0) + sysctl_hung_task_warnings--; + pr_err("INFO: task %s:%d blocked for more than %ld seconds.\n", +@@ -142,6 +144,8 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout) + + if (sysctl_hung_task_all_cpu_backtrace) + hung_task_show_all_bt = true; ++ ++ printk_prefer_direct_exit(); + } + + touch_nmi_watchdog(); +@@ -204,12 +208,17 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout) + } + unlock: + rcu_read_unlock(); +- if (hung_task_show_lock) ++ if (hung_task_show_lock) { ++ printk_prefer_direct_enter(); + debug_show_all_locks(); ++ printk_prefer_direct_exit(); ++ } + + if (hung_task_show_all_bt) { + hung_task_show_all_bt = false; ++ printk_prefer_direct_enter(); + trigger_all_cpu_backtrace(); ++ printk_prefer_direct_exit(); + } + + if (hung_task_call_panic) +diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c +index 5db0230aa6b52..476a3fecb8c53 100644 +--- a/kernel/irq/irqdesc.c ++++ b/kernel/irq/irqdesc.c +@@ -705,6 +705,30 @@ int generic_handle_domain_irq(struct irq_domain *domain, unsigned int hwirq) + } + EXPORT_SYMBOL_GPL(generic_handle_domain_irq); + ++ /** ++ * generic_handle_irq_safe - Invoke the handler for a HW irq belonging ++ * to a domain from any context. ++ * @domain: The domain where to perform the lookup ++ * @hwirq: The HW irq number to convert to a logical one ++ * ++ * Returns: 0 on success, a negative value on error. ++ * ++ * This function can be called from any context (IRQ or process context). It ++ * will report an error if not invoked from IRQ context and the irq has been ++ * marked to enforce IRQ-context only. ++ */ ++int generic_handle_domain_irq_safe(struct irq_domain *domain, unsigned int hwirq) ++{ ++ unsigned long flags; ++ int ret; ++ ++ local_irq_save(flags); ++ ret = handle_irq_desc(irq_resolve_mapping(domain, hwirq)); ++ local_irq_restore(flags); ++ return ret; ++} ++EXPORT_SYMBOL_GPL(generic_handle_domain_irq_safe); ++ + /** + * generic_handle_domain_nmi - Invoke the handler for a HW nmi belonging + * to a domain. +diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c +index b1292a57c2a53..a6514db7ef58e 100644 +--- a/kernel/ksysfs.c ++++ b/kernel/ksysfs.c +@@ -137,6 +137,15 @@ KERNEL_ATTR_RO(vmcoreinfo); + + #endif /* CONFIG_CRASH_CORE */ + ++#if defined(CONFIG_PREEMPT_RT) ++static ssize_t realtime_show(struct kobject *kobj, ++ struct kobj_attribute *attr, char *buf) ++{ ++ return sprintf(buf, "%d\n", 1); ++} ++KERNEL_ATTR_RO(realtime); ++#endif ++ + /* whether file capabilities are enabled */ + static ssize_t fscaps_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +@@ -227,6 +236,9 @@ static struct attribute * kernel_attrs[] = { + #ifndef CONFIG_TINY_RCU + &rcu_expedited_attr.attr, + &rcu_normal_attr.attr, ++#endif ++#ifdef CONFIG_PREEMPT_RT ++ &realtime_attr.attr, + #endif + NULL + }; +diff --git a/kernel/panic.c b/kernel/panic.c +index c6eb8f8db0c05..c4e8896e3caba 100644 +--- a/kernel/panic.c ++++ b/kernel/panic.c +@@ -257,7 +257,6 @@ void panic(const char *fmt, ...) + panic_smp_self_stop(); + + console_verbose(); +- bust_spinlocks(1); + va_start(args, fmt); + len = vscnprintf(buf, sizeof(buf), fmt, args); + va_end(args); +@@ -274,6 +273,11 @@ void panic(const char *fmt, ...) + dump_stack(); + #endif + ++ /* If atomic consoles are available, flush the kernel log. */ ++ console_flush_on_panic(CONSOLE_ATOMIC_FLUSH_PENDING); ++ ++ bust_spinlocks(1); ++ + /* + * If kgdb is enabled, give it a chance to run before we stop all + * the other CPUs or else we won't be able to debug processes left +@@ -297,6 +301,7 @@ void panic(const char *fmt, ...) + * unfortunately means it may not be hardened to work in a + * panic situation. + */ ++ try_block_console_kthreads(10000); + smp_send_stop(); + } else { + /* +@@ -304,6 +309,7 @@ void panic(const char *fmt, ...) + * kmsg_dump, we will need architecture dependent extra + * works in addition to stopping other CPUs. + */ ++ try_block_console_kthreads(10000); + crash_smp_send_stop(); + } + +@@ -604,6 +610,8 @@ void __warn(const char *file, int line, void *caller, unsigned taint, + { + disable_trace_on_warning(); + ++ printk_prefer_direct_enter(); ++ + if (file) + pr_warn("WARNING: CPU: %d PID: %d at %s:%d %pS\n", + raw_smp_processor_id(), current->pid, file, line, +@@ -633,6 +641,8 @@ void __warn(const char *file, int line, void *caller, unsigned taint, + + /* Just a warning, don't kill lockdep. */ + add_taint(taint, LOCKDEP_STILL_OK); ++ ++ printk_prefer_direct_exit(); + } + + #ifndef __WARN_FLAGS +diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h +index d947ca6c84f99..e7d8578860adf 100644 +--- a/kernel/printk/internal.h ++++ b/kernel/printk/internal.h +@@ -20,6 +20,8 @@ enum printk_info_flags { + LOG_CONT = 8, /* text is a fragment of a continuation line */ + }; + ++extern bool block_console_kthreads; ++ + __printf(4, 0) + int vprintk_store(int facility, int level, + const struct dev_printk_info *dev_info, +diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c +index a1a81fd9889bb..f1f9ce9b23f60 100644 +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -44,6 +44,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -223,6 +224,36 @@ int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write, + /* Number of registered extended console drivers. */ + static int nr_ext_console_drivers; + ++/* ++ * Used to synchronize printing kthreads against direct printing via ++ * console_trylock/console_unlock. ++ * ++ * Values: ++ * -1 = console kthreads atomically blocked (via global trylock) ++ * 0 = no kthread printing, console not locked (via trylock) ++ * >0 = kthread(s) actively printing ++ * ++ * Note: For synchronizing against direct printing via ++ * console_lock/console_unlock, see the @lock variable in ++ * struct console. ++ */ ++static atomic_t console_kthreads_active = ATOMIC_INIT(0); ++ ++#define console_kthreads_atomic_tryblock() \ ++ (atomic_cmpxchg(&console_kthreads_active, 0, -1) == 0) ++#define console_kthreads_atomic_unblock() \ ++ atomic_cmpxchg(&console_kthreads_active, -1, 0) ++#define console_kthreads_atomically_blocked() \ ++ (atomic_read(&console_kthreads_active) == -1) ++ ++#define console_kthread_printing_tryenter() \ ++ atomic_inc_unless_negative(&console_kthreads_active) ++#define console_kthread_printing_exit() \ ++ atomic_dec(&console_kthreads_active) ++ ++/* Block console kthreads to avoid processing new messages. */ ++bool block_console_kthreads; ++ + /* + * Helper macros to handle lockdep when locking/unlocking console_sem. We use + * macros instead of functions so that _RET_IP_ contains useful information. +@@ -271,14 +302,49 @@ static bool panic_in_progress(void) + } + + /* +- * This is used for debugging the mess that is the VT code by +- * keeping track if we have the console semaphore held. It's +- * definitely not the perfect debug tool (we don't know if _WE_ +- * hold it and are racing, but it helps tracking those weird code +- * paths in the console code where we end up in places I want +- * locked without the console semaphore held). ++ * Tracks whether kthread printers are all blocked. A value of true implies ++ * that the console is locked via console_lock() or the console is suspended. ++ * Writing to this variable requires holding @console_sem. + */ +-static int console_locked, console_suspended; ++static bool console_kthreads_blocked; ++ ++/* ++ * Block all kthread printers from a schedulable context. ++ * ++ * Requires holding @console_sem. ++ */ ++static void console_kthreads_block(void) ++{ ++ struct console *con; ++ ++ for_each_console(con) { ++ mutex_lock(&con->lock); ++ con->blocked = true; ++ mutex_unlock(&con->lock); ++ } ++ ++ console_kthreads_blocked = true; ++} ++ ++/* ++ * Unblock all kthread printers from a schedulable context. ++ * ++ * Requires holding @console_sem. ++ */ ++static void console_kthreads_unblock(void) ++{ ++ struct console *con; ++ ++ for_each_console(con) { ++ mutex_lock(&con->lock); ++ con->blocked = false; ++ mutex_unlock(&con->lock); ++ } ++ ++ console_kthreads_blocked = false; ++} ++ ++static int console_suspended; + + /* + * Array of consoles built from command line options (console=) +@@ -361,7 +427,75 @@ static int console_msg_format = MSG_FORMAT_DEFAULT; + /* syslog_lock protects syslog_* variables and write access to clear_seq. */ + static DEFINE_MUTEX(syslog_lock); + ++/* ++ * A flag to signify if printk_activate_kthreads() has already started the ++ * kthread printers. If true, any later registered consoles must start their ++ * own kthread directly. The flag is write protected by the console_lock. ++ */ ++static bool printk_kthreads_available; ++ + #ifdef CONFIG_PRINTK ++static atomic_t printk_prefer_direct = ATOMIC_INIT(0); ++ ++/** ++ * printk_prefer_direct_enter - cause printk() calls to attempt direct ++ * printing to all enabled consoles ++ * ++ * Since it is not possible to call into the console printing code from any ++ * context, there is no guarantee that direct printing will occur. ++ * ++ * This globally effects all printk() callers. ++ * ++ * Context: Any context. ++ */ ++void printk_prefer_direct_enter(void) ++{ ++ atomic_inc(&printk_prefer_direct); ++} ++ ++/** ++ * printk_prefer_direct_exit - restore printk() behavior ++ * ++ * Context: Any context. ++ */ ++void printk_prefer_direct_exit(void) ++{ ++ WARN_ON(atomic_dec_if_positive(&printk_prefer_direct) < 0); ++} ++ ++/* ++ * Calling printk() always wakes kthread printers so that they can ++ * flush the new message to their respective consoles. Also, if direct ++ * printing is allowed, printk() tries to flush the messages directly. ++ * ++ * Direct printing is allowed in situations when the kthreads ++ * are not available or the system is in a problematic state. ++ * ++ * See the implementation about possible races. ++ */ ++static inline bool allow_direct_printing(void) ++{ ++ /* ++ * Checking kthread availability is a possible race because the ++ * kthread printers can become permanently disabled during runtime. ++ * However, doing that requires holding the console_lock, so any ++ * pending messages will be direct printed by console_unlock(). ++ */ ++ if (!printk_kthreads_available) ++ return true; ++ ++ /* ++ * Prefer direct printing when the system is in a problematic state. ++ * The context that sets this state will always see the updated value. ++ * The other contexts do not care. Anyway, direct printing is just a ++ * best effort. The direct output is only possible when console_lock ++ * is not already taken and no kthread printers are actively printing. ++ */ ++ return (system_state > SYSTEM_RUNNING || ++ oops_in_progress || ++ atomic_read(&printk_prefer_direct)); ++} ++ + DECLARE_WAIT_QUEUE_HEAD(log_wait); + /* All 3 protected by @syslog_lock. */ + /* the next printk record to read by syslog(READ) or /proc/kmsg */ +@@ -1850,6 +1984,7 @@ static int console_lock_spinning_disable_and_check(void) + return 1; + } + ++#if !IS_ENABLED(CONFIG_PREEMPT_RT) + /** + * console_trylock_spinning - try to get console_lock by busy waiting + * +@@ -1923,6 +2058,7 @@ static int console_trylock_spinning(void) + + return 1; + } ++#endif /* CONFIG_PREEMPT_RT */ + + /* + * Call the specified console driver, asking it to write out the specified +@@ -1930,19 +2066,28 @@ static int console_trylock_spinning(void) + * dropped, a dropped message will be written out first. + */ + static void call_console_driver(struct console *con, const char *text, size_t len, +- char *dropped_text) ++ char *dropped_text, bool atomic_printing) + { ++ unsigned long dropped = 0; + size_t dropped_len; + +- if (con->dropped && dropped_text) { ++ if (dropped_text) ++ dropped = atomic_long_xchg_relaxed(&con->dropped, 0); ++ ++ if (dropped) { + dropped_len = snprintf(dropped_text, DROPPED_TEXT_MAX, + "** %lu printk messages dropped **\n", +- con->dropped); +- con->dropped = 0; +- con->write(con, dropped_text, dropped_len); ++ dropped); ++ if (atomic_printing) ++ con->write_atomic(con, dropped_text, dropped_len); ++ else ++ con->write(con, dropped_text, dropped_len); + } + +- con->write(con, text, len); ++ if (atomic_printing) ++ con->write_atomic(con, text, len); ++ else ++ con->write(con, text, len); + } + + /* +@@ -2252,10 +2397,22 @@ asmlinkage int vprintk_emit(int facility, int level, + printed_len = vprintk_store(facility, level, dev_info, fmt, args); + + /* If called from the scheduler, we can not call up(). */ +- if (!in_sched) { ++ if (!in_sched && allow_direct_printing()) { ++#if IS_ENABLED(CONFIG_PREEMPT_RT) ++ /* ++ * Use the non-spinning trylock since PREEMPT_RT does not ++ * support console lock handovers. ++ * ++ * Direct printing will most likely involve taking spinlocks. ++ * For PREEMPT_RT, this is only allowed if in a preemptible ++ * context. ++ */ ++ if (preemptible() && console_trylock()) ++ console_unlock(); ++#else + /* + * The caller may be holding system-critical or +- * timing-sensitive locks. Disable preemption during ++ * timing-sensitive locks. Disable preemption during direct + * printing of all remaining records to all consoles so that + * this context can return as soon as possible. Hopefully + * another printk() caller will take over the printing. +@@ -2270,6 +2427,7 @@ asmlinkage int vprintk_emit(int facility, int level, + if (console_trylock_spinning()) + console_unlock(); + preempt_enable(); ++#endif + } + + wake_up_klogd(); +@@ -2296,8 +2454,80 @@ asmlinkage __visible int _printk(const char *fmt, ...) + } + EXPORT_SYMBOL(_printk); + ++#ifdef CONFIG_HAVE_ATOMIC_CONSOLE ++static void __free_atomic_data(struct console_atomic_data *d) ++{ ++ kfree(d->text); ++ kfree(d->ext_text); ++ kfree(d->dropped_text); ++} ++ ++static void free_atomic_data(struct console_atomic_data *d) ++{ ++ int count = 1; ++ int i; ++ ++ if (!d) ++ return; ++ ++#ifdef CONFIG_HAVE_NMI ++ count = 2; ++#endif ++ ++ for (i = 0; i < count; i++) ++ __free_atomic_data(&d[i]); ++ kfree(d); ++} ++ ++static int __alloc_atomic_data(struct console_atomic_data *d, short flags) ++{ ++ d->text = kmalloc(CONSOLE_LOG_MAX, GFP_KERNEL); ++ if (!d->text) ++ return -1; ++ ++ if (flags & CON_EXTENDED) { ++ d->ext_text = kmalloc(CONSOLE_EXT_LOG_MAX, GFP_KERNEL); ++ if (!d->ext_text) ++ return -1; ++ } else { ++ d->dropped_text = kmalloc(DROPPED_TEXT_MAX, GFP_KERNEL); ++ if (!d->dropped_text) ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static struct console_atomic_data *alloc_atomic_data(short flags) ++{ ++ struct console_atomic_data *d; ++ int count = 1; ++ int i; ++ ++#ifdef CONFIG_HAVE_NMI ++ count = 2; ++#endif ++ ++ d = kzalloc(sizeof(*d) * count, GFP_KERNEL); ++ if (!d) ++ goto err_out; ++ ++ for (i = 0; i < count; i++) { ++ if (__alloc_atomic_data(&d[i], flags) != 0) ++ goto err_out; ++ } ++ ++ return d; ++err_out: ++ free_atomic_data(d); ++ return NULL; ++} ++#endif /* CONFIG_HAVE_ATOMIC_CONSOLE */ ++ + static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progress); + ++static void printk_start_kthread(struct console *con); ++ + #else /* CONFIG_PRINTK */ + + #define CONSOLE_LOG_MAX 0 +@@ -2308,6 +2538,8 @@ static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progre + #define prb_first_valid_seq(rb) 0 + #define prb_next_seq(rb) 0 + ++#define free_atomic_data(d) ++ + static u64 syslog_seq; + + static size_t record_print_text(const struct printk_record *r, +@@ -2326,11 +2558,13 @@ static ssize_t msg_print_ext_body(char *buf, size_t size, + static void console_lock_spinning_enable(void) { } + static int console_lock_spinning_disable_and_check(void) { return 0; } + static void call_console_driver(struct console *con, const char *text, size_t len, +- char *dropped_text) ++ char *dropped_text, bool atomic_printing) + { + } + static bool suppress_message_printing(int level) { return false; } + static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progress) { return true; } ++static void printk_start_kthread(struct console *con) { } ++static bool allow_direct_printing(void) { return true; } + + #endif /* CONFIG_PRINTK */ + +@@ -2549,6 +2783,14 @@ static int console_cpu_notify(unsigned int cpu) + /* If trylock fails, someone else is doing the printing */ + if (console_trylock()) + console_unlock(); ++ else { ++ /* ++ * If a new CPU comes online, the conditions for ++ * printer_should_wake() may have changed for some ++ * kthread printer with !CON_ANYTIME. ++ */ ++ wake_up_klogd(); ++ } + } + return 0; + } +@@ -2568,7 +2810,7 @@ void console_lock(void) + down_console_sem(); + if (console_suspended) + return; +- console_locked = 1; ++ console_kthreads_block(); + console_may_schedule = 1; + } + EXPORT_SYMBOL(console_lock); +@@ -2589,15 +2831,30 @@ int console_trylock(void) + up_console_sem(); + return 0; + } +- console_locked = 1; ++ if (!console_kthreads_atomic_tryblock()) { ++ up_console_sem(); ++ return 0; ++ } + console_may_schedule = 0; + return 1; + } + EXPORT_SYMBOL(console_trylock); + ++/* ++ * This is used to help to make sure that certain paths within the VT code are ++ * running with the console lock held. It is definitely not the perfect debug ++ * tool (it is not known if the VT code is the task holding the console lock), ++ * but it helps tracking those weird code paths in the console code such as ++ * when the console is suspended: where the console is not locked but no ++ * console printing may occur. ++ * ++ * Note: This returns true when the console is suspended but is not locked. ++ * This is intentional because the VT code must consider that situation ++ * the same as if the console was locked. ++ */ + int is_console_locked(void) + { +- return console_locked; ++ return (console_kthreads_blocked || atomic_read(&console_kthreads_active)); + } + EXPORT_SYMBOL(is_console_locked); + +@@ -2620,18 +2877,9 @@ static bool abandon_console_lock_in_panic(void) + return atomic_read(&panic_cpu) != raw_smp_processor_id(); + } + +-/* +- * Check if the given console is currently capable and allowed to print +- * records. +- * +- * Requires the console_lock. +- */ +-static inline bool console_is_usable(struct console *con) ++static inline bool __console_is_usable(short flags) + { +- if (!(con->flags & CON_ENABLED)) +- return false; +- +- if (!con->write) ++ if (!(flags & CON_ENABLED)) + return false; + + /* +@@ -2640,18 +2888,116 @@ static inline bool console_is_usable(struct console *con) + * cope (CON_ANYTIME) don't call them until this CPU is officially up. + */ + if (!cpu_online(raw_smp_processor_id()) && +- !(con->flags & CON_ANYTIME)) ++ !(flags & CON_ANYTIME)) + return false; + + return true; + } + ++/* ++ * Check if the given console is currently capable and allowed to print ++ * records. ++ * ++ * Requires holding the console_lock. ++ */ ++static inline bool console_is_usable(struct console *con, bool atomic_printing) ++{ ++ if (atomic_printing) { ++#ifdef CONFIG_HAVE_ATOMIC_CONSOLE ++ if (!con->write_atomic) ++ return false; ++ if (!con->atomic_data) ++ return false; ++#else ++ return false; ++#endif ++ } else if (!con->write) { ++ return false; ++ } ++ ++ return __console_is_usable(con->flags); ++} ++ + static void __console_unlock(void) + { +- console_locked = 0; ++ /* ++ * Depending on whether console_lock() or console_trylock() was used, ++ * appropriately allow the kthread printers to continue. ++ */ ++ if (console_kthreads_blocked) ++ console_kthreads_unblock(); ++ else ++ console_kthreads_atomic_unblock(); ++ ++ /* ++ * New records may have arrived while the console was locked. ++ * Wake the kthread printers to print them. ++ */ ++ wake_up_klogd(); ++ + up_console_sem(); + } + ++static u64 read_console_seq(struct console *con) ++{ ++#ifdef CONFIG_HAVE_ATOMIC_CONSOLE ++ unsigned long flags; ++ u64 seq2; ++ u64 seq; ++ ++ if (!con->atomic_data) ++ return con->seq; ++ ++ printk_cpu_sync_get_irqsave(flags); ++ ++ seq = con->seq; ++ seq2 = con->atomic_data[0].seq; ++ if (seq2 > seq) ++ seq = seq2; ++#ifdef CONFIG_HAVE_NMI ++ seq2 = con->atomic_data[1].seq; ++ if (seq2 > seq) ++ seq = seq2; ++#endif ++ ++ printk_cpu_sync_put_irqrestore(flags); ++ ++ return seq; ++#else /* CONFIG_HAVE_ATOMIC_CONSOLE */ ++ return con->seq; ++#endif ++} ++ ++static void write_console_seq(struct console *con, u64 val, bool atomic_printing) ++{ ++#ifdef CONFIG_HAVE_ATOMIC_CONSOLE ++ unsigned long flags; ++ u64 *seq; ++ ++ if (!con->atomic_data) { ++ con->seq = val; ++ return; ++ } ++ ++ printk_cpu_sync_get_irqsave(flags); ++ ++ if (atomic_printing) { ++ seq = &con->atomic_data[0].seq; ++#ifdef CONFIG_HAVE_NMI ++ if (in_nmi()) ++ seq = &con->atomic_data[1].seq; ++#endif ++ } else { ++ seq = &con->seq; ++ } ++ *seq = val; ++ ++ printk_cpu_sync_put_irqrestore(flags); ++#else /* CONFIG_HAVE_ATOMIC_CONSOLE */ ++ con->seq = val; ++#endif ++} ++ + /* + * Print one record for the given console. The record printed is whatever + * record is the next available record for the given console. +@@ -2664,36 +3010,47 @@ static void __console_unlock(void) + * If dropped messages should be printed, @dropped_text is a buffer of size + * DROPPED_TEXT_MAX. Otherwise @dropped_text must be NULL. + * ++ * @atomic_printing specifies if atomic printing should be used. ++ * + * @handover will be set to true if a printk waiter has taken over the + * console_lock, in which case the caller is no longer holding the +- * console_lock. Otherwise it is set to false. ++ * console_lock. Otherwise it is set to false. A NULL pointer may be provided ++ * to disable allowing the console_lock to be taken over by a printk waiter. + * + * Returns false if the given console has no next record to print, otherwise + * true. + * +- * Requires the console_lock. ++ * Requires the console_lock if @handover is non-NULL. ++ * Requires con->lock otherwise. + */ +-static bool console_emit_next_record(struct console *con, char *text, char *ext_text, +- char *dropped_text, bool *handover) ++static bool __console_emit_next_record(struct console *con, char *text, char *ext_text, ++ char *dropped_text, bool atomic_printing, ++ bool *handover) + { +- static int panic_console_dropped; ++ static atomic_t panic_console_dropped = ATOMIC_INIT(0); + struct printk_info info; + struct printk_record r; + unsigned long flags; + char *write_text; + size_t len; ++ u64 seq; + + prb_rec_init_rd(&r, &info, text, CONSOLE_LOG_MAX); + +- *handover = false; ++ if (handover) ++ *handover = false; + +- if (!prb_read_valid(prb, con->seq, &r)) ++ seq = read_console_seq(con); ++ ++ if (!prb_read_valid(prb, seq, &r)) + return false; + +- if (con->seq != r.info->seq) { +- con->dropped += r.info->seq - con->seq; +- con->seq = r.info->seq; +- if (panic_in_progress() && panic_console_dropped++ > 10) { ++ if (seq != r.info->seq) { ++ atomic_long_add((unsigned long)(r.info->seq - seq), &con->dropped); ++ write_console_seq(con, r.info->seq, atomic_printing); ++ seq = r.info->seq; ++ if (panic_in_progress() && ++ atomic_fetch_inc_relaxed(&panic_console_dropped) > 10) { + suppress_panic_printk = 1; + pr_warn_once("Too many dropped messages. Suppress messages on non-panic CPUs to prevent livelock.\n"); + } +@@ -2701,7 +3058,7 @@ static bool console_emit_next_record(struct console *con, char *text, char *ext_ + + /* Skip record that has level above the console loglevel. */ + if (suppress_message_printing(r.info->level)) { +- con->seq++; ++ write_console_seq(con, seq + 1, atomic_printing); + goto skip; + } + +@@ -2715,31 +3072,65 @@ static bool console_emit_next_record(struct console *con, char *text, char *ext_ + len = record_print_text(&r, console_msg_format & MSG_FORMAT_SYSLOG, printk_time); + } + +- /* +- * While actively printing out messages, if another printk() +- * were to occur on another CPU, it may wait for this one to +- * finish. This task can not be preempted if there is a +- * waiter waiting to take over. +- * +- * Interrupts are disabled because the hand over to a waiter +- * must not be interrupted until the hand over is completed +- * (@console_waiter is cleared). +- */ +- printk_safe_enter_irqsave(flags); +- console_lock_spinning_enable(); ++ if (handover) { ++ /* ++ * While actively printing out messages, if another printk() ++ * were to occur on another CPU, it may wait for this one to ++ * finish. This task can not be preempted if there is a ++ * waiter waiting to take over. ++ * ++ * Interrupts are disabled because the hand over to a waiter ++ * must not be interrupted until the hand over is completed ++ * (@console_waiter is cleared). ++ */ ++ printk_safe_enter_irqsave(flags); ++ console_lock_spinning_enable(); + +- stop_critical_timings(); /* don't trace print latency */ +- call_console_driver(con, write_text, len, dropped_text); +- start_critical_timings(); ++ /* don't trace irqsoff print latency */ ++ stop_critical_timings(); ++ } + +- con->seq++; ++ call_console_driver(con, write_text, len, dropped_text, atomic_printing); + +- *handover = console_lock_spinning_disable_and_check(); +- printk_safe_exit_irqrestore(flags); ++ write_console_seq(con, seq + 1, atomic_printing); ++ ++ if (handover) { ++ start_critical_timings(); ++ *handover = console_lock_spinning_disable_and_check(); ++ printk_safe_exit_irqrestore(flags); ++ } + skip: + return true; + } + ++/* ++ * Print a record for a given console, but allow another printk() caller to ++ * take over the console_lock and continue printing. ++ * ++ * Requires the console_lock, but depending on @handover after the call, the ++ * caller may no longer have the console_lock. ++ * ++ * See __console_emit_next_record() for argument and return details. ++ */ ++static bool console_emit_next_record_transferable(struct console *con, char *text, char *ext_text, ++ char *dropped_text, bool *handover) ++{ ++ /* ++ * Handovers are only supported if threaded printers are atomically ++ * blocked. The context taking over the console_lock may be atomic. ++ * ++ * PREEMPT_RT also does not support handovers because the spinning ++ * waiter can cause large latencies. ++ */ ++ if (!console_kthreads_atomically_blocked() || ++ IS_ENABLED(CONFIG_PREEMPT_RT)) { ++ *handover = false; ++ handover = NULL; ++ } ++ ++ return __console_emit_next_record(con, text, ext_text, dropped_text, false, handover); ++} ++ + /* + * Print out all remaining records to all consoles. + * +@@ -2758,8 +3149,8 @@ static bool console_emit_next_record(struct console *con, char *text, char *ext_ + * were flushed to all usable consoles. A returned false informs the caller + * that everything was not flushed (either there were no usable consoles or + * another context has taken over printing or it is a panic situation and this +- * is not the panic CPU). Regardless the reason, the caller should assume it +- * is not useful to immediately try again. ++ * is not the panic CPU or direct printing is not preferred). Regardless the ++ * reason, the caller should assume it is not useful to immediately try again. + * + * Requires the console_lock. + */ +@@ -2776,24 +3167,26 @@ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove + *handover = false; + + do { ++ /* Let the kthread printers do the work if they can. */ ++ if (!allow_direct_printing()) ++ return false; ++ + any_progress = false; + + for_each_console(con) { + bool progress; + +- if (!console_is_usable(con)) ++ if (!console_is_usable(con, false)) + continue; + any_usable = true; + + if (con->flags & CON_EXTENDED) { + /* Extended consoles do not print "dropped messages". */ +- progress = console_emit_next_record(con, &text[0], +- &ext_text[0], NULL, +- handover); ++ progress = console_emit_next_record_transferable(con, &text[0], ++ &ext_text[0], NULL, handover); + } else { +- progress = console_emit_next_record(con, &text[0], +- NULL, &dropped_text[0], +- handover); ++ progress = console_emit_next_record_transferable(con, &text[0], ++ NULL, &dropped_text[0], handover); + } + if (*handover) + return false; +@@ -2818,6 +3211,68 @@ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove + return any_usable; + } + ++#if defined(CONFIG_HAVE_ATOMIC_CONSOLE) && defined(CONFIG_PRINTK) ++static bool console_emit_next_record(struct console *con, char *text, char *ext_text, ++ char *dropped_text, bool atomic_printing); ++ ++static void atomic_console_flush_all(void) ++{ ++ unsigned long flags; ++ struct console *con; ++ bool any_progress; ++ int index = 0; ++ ++ if (console_suspended) ++ return; ++ ++#ifdef CONFIG_HAVE_NMI ++ if (in_nmi()) ++ index = 1; ++#endif ++ ++ printk_cpu_sync_get_irqsave(flags); ++ ++ do { ++ any_progress = false; ++ ++ for_each_console(con) { ++ bool progress; ++ ++ if (!console_is_usable(con, true)) ++ continue; ++ ++ if (con->flags & CON_EXTENDED) { ++ /* Extended consoles do not print "dropped messages". */ ++ progress = console_emit_next_record(con, ++ &con->atomic_data->text[index], ++ &con->atomic_data->ext_text[index], ++ NULL, ++ true); ++ } else { ++ progress = console_emit_next_record(con, ++ &con->atomic_data->text[index], ++ NULL, ++ &con->atomic_data->dropped_text[index], ++ true); ++ } ++ ++ if (!progress) ++ continue; ++ any_progress = true; ++ ++ touch_softlockup_watchdog_sync(); ++ clocksource_touch_watchdog(); ++ rcu_cpu_stall_reset(); ++ touch_nmi_watchdog(); ++ } ++ } while (any_progress); ++ ++ printk_cpu_sync_put_irqrestore(flags); ++} ++#else /* CONFIG_HAVE_ATOMIC_CONSOLE && CONFIG_PRINTK */ ++#define atomic_console_flush_all() ++#endif ++ + /** + * console_unlock - unlock the console system + * +@@ -2908,10 +3363,13 @@ void console_unblank(void) + if (oops_in_progress) { + if (down_trylock_console_sem() != 0) + return; ++ if (!console_kthreads_atomic_tryblock()) { ++ up_console_sem(); ++ return; ++ } + } else + console_lock(); + +- console_locked = 1; + console_may_schedule = 0; + for_each_console(c) + if ((c->flags & CON_ENABLED) && c->unblank) +@@ -2930,6 +3388,11 @@ void console_unblank(void) + */ + void console_flush_on_panic(enum con_flush_mode mode) + { ++ if (mode == CONSOLE_ATOMIC_FLUSH_PENDING) { ++ atomic_console_flush_all(); ++ return; ++ } ++ + /* + * If someone else is holding the console lock, trylock will fail + * and may_schedule may be set. Ignore and proceed to unlock so +@@ -2946,7 +3409,7 @@ void console_flush_on_panic(enum con_flush_mode mode) + + seq = prb_first_valid_seq(prb); + for_each_console(c) +- c->seq = seq; ++ write_console_seq(c, seq, false); + } + console_unlock(); + } +@@ -3189,16 +3652,27 @@ void register_console(struct console *newcon) + if (newcon->flags & CON_EXTENDED) + nr_ext_console_drivers++; + +- newcon->dropped = 0; ++ atomic_long_set(&newcon->dropped, 0); ++ newcon->thread = NULL; ++ newcon->blocked = true; ++ mutex_init(&newcon->lock); ++#ifdef CONFIG_HAVE_ATOMIC_CONSOLE ++ newcon->atomic_data = NULL; ++#endif ++ + if (newcon->flags & CON_PRINTBUFFER) { + /* Get a consistent copy of @syslog_seq. */ + mutex_lock(&syslog_lock); +- newcon->seq = syslog_seq; ++ write_console_seq(newcon, syslog_seq, false); + mutex_unlock(&syslog_lock); + } else { + /* Begin with next message. */ +- newcon->seq = prb_next_seq(prb); ++ write_console_seq(newcon, prb_next_seq(prb), false); + } ++ ++ if (printk_kthreads_available) ++ printk_start_kthread(newcon); ++ + console_unlock(); + console_sysfs_notify(); + +@@ -3225,6 +3699,7 @@ EXPORT_SYMBOL(register_console); + + int unregister_console(struct console *console) + { ++ struct task_struct *thd; + struct console *con; + int res; + +@@ -3265,9 +3740,26 @@ int unregister_console(struct console *console) + console_drivers->flags |= CON_CONSDEV; + + console->flags &= ~CON_ENABLED; ++ ++ /* ++ * console->thread can only be cleared under the console lock. But ++ * stopping the thread must be done without the console lock. The ++ * task that clears @thread is the task that stops the kthread. ++ */ ++ thd = console->thread; ++ console->thread = NULL; ++ + console_unlock(); ++ ++ if (thd) ++ kthread_stop(thd); ++ + console_sysfs_notify(); + ++#ifdef CONFIG_HAVE_ATOMIC_CONSOLE ++ free_atomic_data(console->atomic_data); ++#endif ++ + if (console->exit) + res = console->exit(console); + +@@ -3361,6 +3853,20 @@ static int __init printk_late_init(void) + } + late_initcall(printk_late_init); + ++static int __init printk_activate_kthreads(void) ++{ ++ struct console *con; ++ ++ console_lock(); ++ printk_kthreads_available = true; ++ for_each_console(con) ++ printk_start_kthread(con); ++ console_unlock(); ++ ++ return 0; ++} ++early_initcall(printk_activate_kthreads); ++ + #if defined CONFIG_PRINTK + /* If @con is specified, only wait for that console. Otherwise wait for all. */ + static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progress) +@@ -3384,7 +3890,7 @@ static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progre + for_each_console(c) { + if (con && con != c) + continue; +- if (!console_is_usable(c)) ++ if (!console_is_usable(c, false)) + continue; + printk_seq = c->seq; + if (printk_seq < seq) +@@ -3444,11 +3950,215 @@ bool pr_flush(int timeout_ms, bool reset_on_progress) + } + EXPORT_SYMBOL(pr_flush); + ++static void __printk_fallback_preferred_direct(void) ++{ ++ printk_prefer_direct_enter(); ++ pr_err("falling back to preferred direct printing\n"); ++ printk_kthreads_available = false; ++} ++ ++/* ++ * Enter preferred direct printing, but never exit. Mark console threads as ++ * unavailable. The system is then forever in preferred direct printing and ++ * any printing threads will exit. ++ * ++ * Must *not* be called under console_lock. Use ++ * __printk_fallback_preferred_direct() if already holding console_lock. ++ */ ++static void printk_fallback_preferred_direct(void) ++{ ++ console_lock(); ++ __printk_fallback_preferred_direct(); ++ console_unlock(); ++} ++ ++/* ++ * Print a record for a given console, not allowing another printk() caller ++ * to take over. This is appropriate for contexts that do not have the ++ * console_lock. ++ * ++ * See __console_emit_next_record() for argument and return details. ++ */ ++static bool console_emit_next_record(struct console *con, char *text, char *ext_text, ++ char *dropped_text, bool atomic_printing) ++{ ++ return __console_emit_next_record(con, text, ext_text, dropped_text, ++ atomic_printing, NULL); ++} ++ ++static bool printer_should_wake(struct console *con, u64 seq) ++{ ++ short flags; ++ ++ if (kthread_should_stop() || !printk_kthreads_available) ++ return true; ++ ++ if (con->blocked || ++ console_kthreads_atomically_blocked() || ++ block_console_kthreads || ++ system_state > SYSTEM_RUNNING || ++ oops_in_progress) { ++ return false; ++ } ++ ++ /* ++ * This is an unsafe read from con->flags, but a false positive is ++ * not a problem. Worst case it would allow the printer to wake up ++ * although it is disabled. But the printer will notice that when ++ * attempting to print and instead go back to sleep. ++ */ ++ flags = data_race(READ_ONCE(con->flags)); ++ ++ if (!__console_is_usable(flags)) ++ return false; ++ ++ return prb_read_valid(prb, seq, NULL); ++} ++ ++static int printk_kthread_func(void *data) ++{ ++ struct console *con = data; ++ char *dropped_text = NULL; ++ char *ext_text = NULL; ++ u64 seq = 0; ++ char *text; ++ int error; ++ ++#ifdef CONFIG_HAVE_ATOMIC_CONSOLE ++ if (con->write_atomic) ++ con->atomic_data = alloc_atomic_data(con->flags); ++#endif ++ ++ text = kmalloc(CONSOLE_LOG_MAX, GFP_KERNEL); ++ if (!text) { ++ con_printk(KERN_ERR, con, "failed to allocate text buffer\n"); ++ printk_fallback_preferred_direct(); ++ goto out; ++ } ++ ++ if (con->flags & CON_EXTENDED) { ++ ext_text = kmalloc(CONSOLE_EXT_LOG_MAX, GFP_KERNEL); ++ if (!ext_text) { ++ con_printk(KERN_ERR, con, "failed to allocate ext_text buffer\n"); ++ printk_fallback_preferred_direct(); ++ goto out; ++ } ++ } else { ++ dropped_text = kmalloc(DROPPED_TEXT_MAX, GFP_KERNEL); ++ if (!dropped_text) { ++ con_printk(KERN_ERR, con, "failed to allocate dropped_text buffer\n"); ++ printk_fallback_preferred_direct(); ++ goto out; ++ } ++ } ++ ++ con_printk(KERN_INFO, con, "printing thread started\n"); ++ ++ for (;;) { ++ /* ++ * Guarantee this task is visible on the waitqueue before ++ * checking the wake condition. ++ * ++ * The full memory barrier within set_current_state() of ++ * prepare_to_wait_event() pairs with the full memory barrier ++ * within wq_has_sleeper(). ++ * ++ * This pairs with __wake_up_klogd:A. ++ */ ++ error = wait_event_interruptible(log_wait, ++ printer_should_wake(con, seq)); /* LMM(printk_kthread_func:A) */ ++ ++ if (kthread_should_stop() || !printk_kthreads_available) ++ break; ++ ++ if (error) ++ continue; ++ ++ error = mutex_lock_interruptible(&con->lock); ++ if (error) ++ continue; ++ ++ if (con->blocked || ++ !console_kthread_printing_tryenter()) { ++ /* Another context has locked the console_lock. */ ++ mutex_unlock(&con->lock); ++ continue; ++ } ++ ++ /* ++ * Although this context has not locked the console_lock, it ++ * is known that the console_lock is not locked and it is not ++ * possible for any other context to lock the console_lock. ++ * Therefore it is safe to read con->flags. ++ */ ++ ++ if (!__console_is_usable(con->flags)) { ++ console_kthread_printing_exit(); ++ mutex_unlock(&con->lock); ++ continue; ++ } ++ ++ /* ++ * Even though the printk kthread is always preemptible, it is ++ * still not allowed to call cond_resched() from within ++ * console drivers. The task may become non-preemptible in the ++ * console driver call chain. For example, vt_console_print() ++ * takes a spinlock and then can call into fbcon_redraw(), ++ * which can conditionally invoke cond_resched(). ++ */ ++ console_may_schedule = 0; ++ console_emit_next_record(con, text, ext_text, dropped_text, false); ++ ++ seq = con->seq; ++ ++ console_kthread_printing_exit(); ++ ++ mutex_unlock(&con->lock); ++ } ++ ++ con_printk(KERN_INFO, con, "printing thread stopped\n"); ++out: ++ kfree(dropped_text); ++ kfree(ext_text); ++ kfree(text); ++ ++ console_lock(); ++ /* ++ * If this kthread is being stopped by another task, con->thread will ++ * already be NULL. That is fine. The important thing is that it is ++ * NULL after the kthread exits. ++ */ ++ con->thread = NULL; ++ console_unlock(); ++ ++ return 0; ++} ++ ++/* Must be called under console_lock. */ ++static void printk_start_kthread(struct console *con) ++{ ++ /* ++ * Do not start a kthread if there is no write() callback. The ++ * kthreads assume the write() callback exists. ++ */ ++ if (!con->write) ++ return; ++ ++ con->thread = kthread_run(printk_kthread_func, con, ++ "pr/%s%d", con->name, con->index); ++ if (IS_ERR(con->thread)) { ++ con->thread = NULL; ++ con_printk(KERN_ERR, con, "unable to start printing thread\n"); ++ __printk_fallback_preferred_direct(); ++ return; ++ } ++} ++ + /* + * Delayed printk version, for scheduler-internal messages: + */ +-#define PRINTK_PENDING_WAKEUP 0x01 +-#define PRINTK_PENDING_OUTPUT 0x02 ++#define PRINTK_PENDING_WAKEUP 0x01 ++#define PRINTK_PENDING_DIRECT_OUTPUT 0x02 + + static DEFINE_PER_CPU(int, printk_pending); + +@@ -3456,10 +4166,14 @@ static void wake_up_klogd_work_func(struct irq_work *irq_work) + { + int pending = this_cpu_xchg(printk_pending, 0); + +- if (pending & PRINTK_PENDING_OUTPUT) { ++ if (pending & PRINTK_PENDING_DIRECT_OUTPUT) { ++ printk_prefer_direct_enter(); ++ + /* If trylock fails, someone else is doing the printing */ + if (console_trylock()) + console_unlock(); ++ ++ printk_prefer_direct_exit(); + } + + if (pending & PRINTK_PENDING_WAKEUP) +@@ -3484,10 +4198,11 @@ static void __wake_up_klogd(int val) + * prepare_to_wait_event(), which is called after ___wait_event() adds + * the waiter but before it has checked the wait condition. + * +- * This pairs with devkmsg_read:A and syslog_print:A. ++ * This pairs with devkmsg_read:A, syslog_print:A, and ++ * printk_kthread_func:A. + */ + if (wq_has_sleeper(&log_wait) || /* LMM(__wake_up_klogd:A) */ +- (val & PRINTK_PENDING_OUTPUT)) { ++ (val & PRINTK_PENDING_DIRECT_OUTPUT)) { + this_cpu_or(printk_pending, val); + irq_work_queue(this_cpu_ptr(&wake_up_klogd_work)); + } +@@ -3505,7 +4220,17 @@ void defer_console_output(void) + * New messages may have been added directly to the ringbuffer + * using vprintk_store(), so wake any waiters as well. + */ +- __wake_up_klogd(PRINTK_PENDING_WAKEUP | PRINTK_PENDING_OUTPUT); ++ int val = PRINTK_PENDING_WAKEUP; ++ ++ /* ++ * Make sure that some context will print the messages when direct ++ * printing is allowed. This happens in situations when the kthreads ++ * may not be as reliable or perhaps unusable. ++ */ ++ if (allow_direct_printing()) ++ val |= PRINTK_PENDING_DIRECT_OUTPUT; ++ ++ __wake_up_klogd(val); + } + + void printk_trigger_flush(void) +diff --git a/kernel/printk/printk_safe.c b/kernel/printk/printk_safe.c +index ef0f9a2044da1..caac4de1ea59a 100644 +--- a/kernel/printk/printk_safe.c ++++ b/kernel/printk/printk_safe.c +@@ -8,7 +8,9 @@ + #include + #include + #include ++#include + #include ++#include + + #include "internal.h" + +@@ -50,3 +52,33 @@ asmlinkage int vprintk(const char *fmt, va_list args) + return vprintk_default(fmt, args); + } + EXPORT_SYMBOL(vprintk); ++ ++/** ++ * try_block_console_kthreads() - Try to block console kthreads and ++ * make the global console_lock() avaialble ++ * ++ * @timeout_ms: The maximum time (in ms) to wait. ++ * ++ * Prevent console kthreads from starting processing new messages. Wait ++ * until the global console_lock() become available. ++ * ++ * Context: Can be called in any context. ++ */ ++void try_block_console_kthreads(int timeout_ms) ++{ ++ block_console_kthreads = true; ++ ++ /* Do not wait when the console lock could not be safely taken. */ ++ if (this_cpu_read(printk_context) || in_nmi()) ++ return; ++ ++ while (timeout_ms > 0) { ++ if (console_trylock()) { ++ console_unlock(); ++ return; ++ } ++ ++ udelay(1000); ++ timeout_ms -= 1; ++ } ++} +diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c +index d8e1b270a065f..257cb6f5ea622 100644 +--- a/kernel/rcu/rcutorture.c ++++ b/kernel/rcu/rcutorture.c +@@ -2157,6 +2157,12 @@ static int rcutorture_booster_init(unsigned int cpu) + WARN_ON_ONCE(!t); + sp.sched_priority = 2; + sched_setscheduler_nocheck(t, SCHED_FIFO, &sp); ++#ifdef CONFIG_PREEMPT_RT ++ t = per_cpu(timersd, cpu); ++ WARN_ON_ONCE(!t); ++ sp.sched_priority = 2; ++ sched_setscheduler_nocheck(t, SCHED_FIFO, &sp); ++#endif + } + + /* Don't allow time recalculation while creating a new task. */ +diff --git a/kernel/rcu/tree_stall.h b/kernel/rcu/tree_stall.h +index c3fbbcc09327f..195cad14742dd 100644 +--- a/kernel/rcu/tree_stall.h ++++ b/kernel/rcu/tree_stall.h +@@ -643,6 +643,7 @@ static void print_cpu_stall(unsigned long gps) + * See Documentation/RCU/stallwarn.rst for info on how to debug + * RCU CPU stall warnings. + */ ++ printk_prefer_direct_enter(); + trace_rcu_stall_warning(rcu_state.name, TPS("SelfDetected")); + pr_err("INFO: %s self-detected stall on CPU\n", rcu_state.name); + raw_spin_lock_irqsave_rcu_node(rdp->mynode, flags); +@@ -677,6 +678,7 @@ static void print_cpu_stall(unsigned long gps) + */ + set_tsk_need_resched(current); + set_preempt_need_resched(); ++ printk_prefer_direct_exit(); + } + + static void check_cpu_stall(struct rcu_data *rdp) +diff --git a/kernel/reboot.c b/kernel/reboot.c +index 3c35445bf5ad3..80564ffafabff 100644 +--- a/kernel/reboot.c ++++ b/kernel/reboot.c +@@ -82,6 +82,7 @@ void kernel_restart_prepare(char *cmd) + { + blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); + system_state = SYSTEM_RESTART; ++ try_block_console_kthreads(10000); + usermodehelper_disable(); + device_shutdown(); + } +@@ -270,6 +271,7 @@ static void kernel_shutdown_prepare(enum system_states state) + blocking_notifier_call_chain(&reboot_notifier_list, + (state == SYSTEM_HALT) ? SYS_HALT : SYS_POWER_OFF, NULL); + system_state = state; ++ try_block_console_kthreads(10000); + usermodehelper_disable(); + device_shutdown(); + } +@@ -819,9 +821,11 @@ static int __orderly_reboot(void) + ret = run_cmd(reboot_cmd); + + if (ret) { ++ printk_prefer_direct_enter(); + pr_warn("Failed to start orderly reboot: forcing the issue\n"); + emergency_sync(); + kernel_restart(NULL); ++ printk_prefer_direct_exit(); + } + + return ret; +@@ -834,6 +838,7 @@ static int __orderly_poweroff(bool force) + ret = run_cmd(poweroff_cmd); + + if (ret && force) { ++ printk_prefer_direct_enter(); + pr_warn("Failed to start orderly shutdown: forcing the issue\n"); + + /* +@@ -843,6 +848,7 @@ static int __orderly_poweroff(bool force) + */ + emergency_sync(); + kernel_power_off(); ++ printk_prefer_direct_exit(); + } + + return ret; +@@ -900,6 +906,8 @@ EXPORT_SYMBOL_GPL(orderly_reboot); + */ + static void hw_failure_emergency_poweroff_func(struct work_struct *work) + { ++ printk_prefer_direct_enter(); ++ + /* + * We have reached here after the emergency shutdown waiting period has + * expired. This means orderly_poweroff has not been able to shut off +@@ -916,6 +924,8 @@ static void hw_failure_emergency_poweroff_func(struct work_struct *work) + */ + pr_emerg("Hardware protection shutdown failed. Trying emergency restart\n"); + emergency_restart(); ++ ++ printk_prefer_direct_exit(); + } + + static DECLARE_DELAYED_WORK(hw_failure_emergency_poweroff_work, +@@ -954,11 +964,13 @@ void hw_protection_shutdown(const char *reason, int ms_until_forced) + { + static atomic_t allow_proceed = ATOMIC_INIT(1); + ++ printk_prefer_direct_enter(); ++ + pr_emerg("HARDWARE PROTECTION shutdown (%s)\n", reason); + + /* Shutdown should be initiated only once. */ + if (!atomic_dec_and_test(&allow_proceed)) +- return; ++ goto out; + + /* + * Queue a backup emergency shutdown in the event of +@@ -966,6 +978,8 @@ void hw_protection_shutdown(const char *reason, int ms_until_forced) + */ + hw_failure_emergency_poweroff(ms_until_forced); + orderly_poweroff(true); ++out: ++ printk_prefer_direct_exit(); + } + EXPORT_SYMBOL_GPL(hw_protection_shutdown); + +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index ee28253c9ac0c..2ce515d3e6f8d 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -1046,6 +1046,46 @@ void resched_curr(struct rq *rq) + trace_sched_wake_idle_without_ipi(cpu); + } + ++#ifdef CONFIG_PREEMPT_LAZY ++ ++static int tsk_is_polling(struct task_struct *p) ++{ ++#ifdef TIF_POLLING_NRFLAG ++ return test_tsk_thread_flag(p, TIF_POLLING_NRFLAG); ++#else ++ return 0; ++#endif ++} ++ ++void resched_curr_lazy(struct rq *rq) ++{ ++ struct task_struct *curr = rq->curr; ++ int cpu; ++ ++ if (!sched_feat(PREEMPT_LAZY)) { ++ resched_curr(rq); ++ return; ++ } ++ ++ if (test_tsk_need_resched(curr)) ++ return; ++ ++ if (test_tsk_need_resched_lazy(curr)) ++ return; ++ ++ set_tsk_need_resched_lazy(curr); ++ ++ cpu = cpu_of(rq); ++ if (cpu == smp_processor_id()) ++ return; ++ ++ /* NEED_RESCHED_LAZY must be visible before we test polling */ ++ smp_mb(); ++ if (!tsk_is_polling(curr)) ++ smp_send_reschedule(cpu); ++} ++#endif ++ + void resched_cpu(int cpu) + { + struct rq *rq = cpu_rq(cpu); +@@ -2227,6 +2267,7 @@ void migrate_disable(void) + preempt_disable(); + this_rq()->nr_pinned++; + p->migration_disabled = 1; ++ preempt_lazy_disable(); + preempt_enable(); + } + EXPORT_SYMBOL_GPL(migrate_disable); +@@ -2258,6 +2299,7 @@ void migrate_enable(void) + barrier(); + p->migration_disabled = 0; + this_rq()->nr_pinned--; ++ preempt_lazy_enable(); + preempt_enable(); + } + EXPORT_SYMBOL_GPL(migrate_enable); +@@ -3251,6 +3293,70 @@ int migrate_swap(struct task_struct *cur, struct task_struct *p, + } + #endif /* CONFIG_NUMA_BALANCING */ + ++#ifdef CONFIG_PREEMPT_RT ++ ++/* ++ * Consider: ++ * ++ * set_special_state(X); ++ * ++ * do_things() ++ * // Somewhere in there is an rtlock that can be contended: ++ * current_save_and_set_rtlock_wait_state(); ++ * [...] ++ * schedule_rtlock(); (A) ++ * [...] ++ * current_restore_rtlock_saved_state(); ++ * ++ * schedule(); (B) ++ * ++ * If p->saved_state is anything else than TASK_RUNNING, then p blocked on an ++ * rtlock (A) *before* voluntarily calling into schedule() (B) after setting its ++ * state to X. For things like ptrace (X=TASK_TRACED), the task could have more ++ * work to do upon acquiring the lock in do_things() before whoever called ++ * wait_task_inactive() should return. IOW, we have to wait for: ++ * ++ * p.saved_state = TASK_RUNNING ++ * p.__state = X ++ * ++ * which implies the task isn't blocked on an RT lock and got to schedule() (B). ++ * ++ * Also see comments in ttwu_state_match(). ++ */ ++ ++static __always_inline bool state_mismatch(struct task_struct *p, unsigned int match_state) ++{ ++ unsigned long flags; ++ bool mismatch; ++ ++ raw_spin_lock_irqsave(&p->pi_lock, flags); ++ mismatch = READ_ONCE(p->__state) != match_state && ++ READ_ONCE(p->saved_state) != match_state; ++ raw_spin_unlock_irqrestore(&p->pi_lock, flags); ++ return mismatch; ++} ++static __always_inline bool state_match(struct task_struct *p, unsigned int match_state, ++ bool *wait) ++{ ++ if (READ_ONCE(p->__state) == match_state) ++ return true; ++ if (READ_ONCE(p->saved_state) != match_state) ++ return false; ++ *wait = true; ++ return true; ++} ++#else ++static __always_inline bool state_mismatch(struct task_struct *p, unsigned int match_state) ++{ ++ return READ_ONCE(p->__state) != match_state; ++} ++static __always_inline bool state_match(struct task_struct *p, unsigned int match_state, ++ bool *wait) ++{ ++ return READ_ONCE(p->__state) == match_state; ++} ++#endif ++ + /* + * wait_task_inactive - wait for a thread to unschedule. + * +@@ -3269,7 +3375,7 @@ int migrate_swap(struct task_struct *cur, struct task_struct *p, + */ + unsigned long wait_task_inactive(struct task_struct *p, unsigned int match_state) + { +- int running, queued; ++ bool running, wait; + struct rq_flags rf; + unsigned long ncsw; + struct rq *rq; +@@ -3295,7 +3401,7 @@ unsigned long wait_task_inactive(struct task_struct *p, unsigned int match_state + * is actually now running somewhere else! + */ + while (task_running(rq, p)) { +- if (match_state && unlikely(READ_ONCE(p->__state) != match_state)) ++ if (match_state && state_mismatch(p, match_state)) + return 0; + cpu_relax(); + } +@@ -3308,10 +3414,12 @@ unsigned long wait_task_inactive(struct task_struct *p, unsigned int match_state + rq = task_rq_lock(p, &rf); + trace_sched_wait_task(p); + running = task_running(rq, p); +- queued = task_on_rq_queued(p); ++ wait = task_on_rq_queued(p); + ncsw = 0; +- if (!match_state || READ_ONCE(p->__state) == match_state) ++ ++ if (!match_state || state_match(p, match_state, &wait)) + ncsw = p->nvcsw | LONG_MIN; /* sets MSB */ ++ + task_rq_unlock(rq, p, &rf); + + /* +@@ -3340,7 +3448,7 @@ unsigned long wait_task_inactive(struct task_struct *p, unsigned int match_state + * running right now), it's preempted, and we should + * yield - it could be a while. + */ +- if (unlikely(queued)) { ++ if (unlikely(wait)) { + ktime_t to = NSEC_PER_SEC / HZ; + + set_current_state(TASK_UNINTERRUPTIBLE); +@@ -4589,6 +4697,9 @@ int sched_fork(unsigned long clone_flags, struct task_struct *p) + p->on_cpu = 0; + #endif + init_task_preempt_count(p); ++#ifdef CONFIG_HAVE_PREEMPT_LAZY ++ task_thread_info(p)->preempt_lazy_count = 0; ++#endif + #ifdef CONFIG_SMP + plist_node_init(&p->pushable_tasks, MAX_PRIO); + RB_CLEAR_NODE(&p->pushable_dl_tasks); +@@ -6457,6 +6568,7 @@ static void __sched notrace __schedule(unsigned int sched_mode) + + next = pick_next_task(rq, prev, &rf); + clear_tsk_need_resched(prev); ++ clear_tsk_need_resched_lazy(prev); + clear_preempt_need_resched(); + #ifdef CONFIG_SCHED_DEBUG + rq->last_seen_need_resched_ns = 0; +@@ -6671,6 +6783,30 @@ static void __sched notrace preempt_schedule_common(void) + } while (need_resched()); + } + ++#ifdef CONFIG_PREEMPT_LAZY ++/* ++ * If TIF_NEED_RESCHED is then we allow to be scheduled away since this is ++ * set by a RT task. Oterwise we try to avoid beeing scheduled out as long as ++ * preempt_lazy_count counter >0. ++ */ ++static __always_inline int preemptible_lazy(void) ++{ ++ if (test_thread_flag(TIF_NEED_RESCHED)) ++ return 1; ++ if (current_thread_info()->preempt_lazy_count) ++ return 0; ++ return 1; ++} ++ ++#else ++ ++static inline int preemptible_lazy(void) ++{ ++ return 1; ++} ++ ++#endif ++ + #ifdef CONFIG_PREEMPTION + /* + * This is the entry point to schedule() from in-kernel preemption +@@ -6684,6 +6820,8 @@ asmlinkage __visible void __sched notrace preempt_schedule(void) + */ + if (likely(!preemptible())) + return; ++ if (!preemptible_lazy()) ++ return; + preempt_schedule_common(); + } + NOKPROBE_SYMBOL(preempt_schedule); +@@ -6731,6 +6869,9 @@ asmlinkage __visible void __sched notrace preempt_schedule_notrace(void) + if (likely(!preemptible())) + return; + ++ if (!preemptible_lazy()) ++ return; ++ + do { + /* + * Because the function tracer can trace preempt_count_sub() +@@ -8988,7 +9129,9 @@ void __init init_idle(struct task_struct *idle, int cpu) + + /* Set the preempt count _outside_ the spinlocks! */ + init_idle_preempt_count(idle, cpu); +- ++#ifdef CONFIG_HAVE_PREEMPT_LAZY ++ task_thread_info(idle)->preempt_lazy_count = 0; ++#endif + /* + * The idle tasks have their own, simple scheduling class: + */ +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 914096c5b1ae1..3cb55e6ede337 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -4576,7 +4576,7 @@ check_preempt_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr) + ideal_runtime = sched_slice(cfs_rq, curr); + delta_exec = curr->sum_exec_runtime - curr->prev_sum_exec_runtime; + if (delta_exec > ideal_runtime) { +- resched_curr(rq_of(cfs_rq)); ++ resched_curr_lazy(rq_of(cfs_rq)); + /* + * The current task ran long enough, ensure it doesn't get + * re-elected due to buddy favours. +@@ -4600,7 +4600,7 @@ check_preempt_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr) + return; + + if (delta > ideal_runtime) +- resched_curr(rq_of(cfs_rq)); ++ resched_curr_lazy(rq_of(cfs_rq)); + } + + static void +@@ -4746,7 +4746,7 @@ entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr, int queued) + * validating it and just reschedule. + */ + if (queued) { +- resched_curr(rq_of(cfs_rq)); ++ resched_curr_lazy(rq_of(cfs_rq)); + return; + } + /* +@@ -4895,7 +4895,7 @@ static void __account_cfs_rq_runtime(struct cfs_rq *cfs_rq, u64 delta_exec) + * hierarchy can be throttled + */ + if (!assign_cfs_rq_runtime(cfs_rq) && likely(cfs_rq->curr)) +- resched_curr(rq_of(cfs_rq)); ++ resched_curr_lazy(rq_of(cfs_rq)); + } + + static __always_inline +@@ -5646,7 +5646,7 @@ static void hrtick_start_fair(struct rq *rq, struct task_struct *p) + + if (delta < 0) { + if (task_current(rq, p)) +- resched_curr(rq); ++ resched_curr_lazy(rq); + return; + } + hrtick_start(rq, delta); +@@ -7307,7 +7307,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_ + return; + + preempt: +- resched_curr(rq); ++ resched_curr_lazy(rq); + /* + * Only set the backward buddy when the current task is still + * on the rq. This can happen when a wakeup gets interleaved +@@ -11454,7 +11454,7 @@ static void task_fork_fair(struct task_struct *p) + * 'current' within the tree based on its new key value. + */ + swap(curr->vruntime, se->vruntime); +- resched_curr(rq); ++ resched_curr_lazy(rq); + } + + se->vruntime -= cfs_rq->min_vruntime; +@@ -11481,7 +11481,7 @@ prio_changed_fair(struct rq *rq, struct task_struct *p, int oldprio) + */ + if (task_current(rq, p)) { + if (p->prio > oldprio) +- resched_curr(rq); ++ resched_curr_lazy(rq); + } else + check_preempt_curr(rq, p, 0); + } +diff --git a/kernel/sched/features.h b/kernel/sched/features.h +index ee7f23c76bd33..e13090e33f3c4 100644 +--- a/kernel/sched/features.h ++++ b/kernel/sched/features.h +@@ -48,6 +48,9 @@ SCHED_FEAT(NONTASK_CAPACITY, true) + + #ifdef CONFIG_PREEMPT_RT + SCHED_FEAT(TTWU_QUEUE, false) ++# ifdef CONFIG_PREEMPT_LAZY ++SCHED_FEAT(PREEMPT_LAZY, true) ++# endif + #else + + /* +diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h +index e26688d387aeb..5b889de29e3c9 100644 +--- a/kernel/sched/sched.h ++++ b/kernel/sched/sched.h +@@ -2356,6 +2356,15 @@ extern void reweight_task(struct task_struct *p, int prio); + extern void resched_curr(struct rq *rq); + extern void resched_cpu(int cpu); + ++#ifdef CONFIG_PREEMPT_LAZY ++extern void resched_curr_lazy(struct rq *rq); ++#else ++static inline void resched_curr_lazy(struct rq *rq) ++{ ++ resched_curr(rq); ++} ++#endif ++ + extern struct rt_bandwidth def_rt_bandwidth; + extern void init_rt_bandwidth(struct rt_bandwidth *rt_b, u64 period, u64 runtime); + extern bool sched_rt_bandwidth_account(struct rt_rq *rt_rq); +diff --git a/kernel/signal.c b/kernel/signal.c +index 6f86fda5e432a..139b965e4fafc 100644 +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -2297,13 +2297,13 @@ static int ptrace_stop(int exit_code, int why, unsigned long message, + /* + * Don't want to allow preemption here, because + * sys_ptrace() needs this task to be inactive. +- * +- * XXX: implement read_unlock_no_resched(). + */ +- preempt_disable(); ++ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) ++ preempt_disable(); + read_unlock(&tasklist_lock); + cgroup_enter_frozen(); +- preempt_enable_no_resched(); ++ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) ++ preempt_enable_no_resched(); + freezable_schedule(); + cgroup_leave_frozen(true); + +diff --git a/kernel/softirq.c b/kernel/softirq.c +index c8a6913c067d9..ab1fe34326bab 100644 +--- a/kernel/softirq.c ++++ b/kernel/softirq.c +@@ -637,6 +637,24 @@ static inline void tick_irq_exit(void) + #endif + } + ++#ifdef CONFIG_PREEMPT_RT ++DEFINE_PER_CPU(struct task_struct *, timersd); ++DEFINE_PER_CPU(unsigned long, pending_timer_softirq); ++ ++static void wake_timersd(void) ++{ ++ struct task_struct *tsk = __this_cpu_read(timersd); ++ ++ if (tsk) ++ wake_up_process(tsk); ++} ++ ++#else ++ ++static inline void wake_timersd(void) { } ++ ++#endif ++ + static inline void __irq_exit_rcu(void) + { + #ifndef __ARCH_IRQ_EXIT_IRQS_DISABLED +@@ -646,8 +664,13 @@ static inline void __irq_exit_rcu(void) + #endif + account_hardirq_exit(current); + preempt_count_sub(HARDIRQ_OFFSET); +- if (!in_interrupt() && local_softirq_pending()) +- invoke_softirq(); ++ if (!in_interrupt()) { ++ if (local_softirq_pending()) ++ invoke_softirq(); ++ ++ if (IS_ENABLED(CONFIG_PREEMPT_RT) && local_pending_timers()) ++ wake_timersd(); ++ } + + tick_irq_exit(); + } +@@ -976,12 +999,70 @@ static struct smp_hotplug_thread softirq_threads = { + .thread_comm = "ksoftirqd/%u", + }; + ++#ifdef CONFIG_PREEMPT_RT ++static void timersd_setup(unsigned int cpu) ++{ ++ sched_set_fifo_low(current); ++} ++ ++static int timersd_should_run(unsigned int cpu) ++{ ++ return local_pending_timers(); ++} ++ ++static void run_timersd(unsigned int cpu) ++{ ++ unsigned int timer_si; ++ ++ ksoftirqd_run_begin(); ++ ++ timer_si = local_pending_timers(); ++ __this_cpu_write(pending_timer_softirq, 0); ++ or_softirq_pending(timer_si); ++ ++ __do_softirq(); ++ ++ ksoftirqd_run_end(); ++} ++ ++static void raise_ktimers_thread(unsigned int nr) ++{ ++ trace_softirq_raise(nr); ++ __this_cpu_or(pending_timer_softirq, 1 << nr); ++} ++ ++void raise_hrtimer_softirq(void) ++{ ++ raise_ktimers_thread(HRTIMER_SOFTIRQ); ++} ++ ++void raise_timer_softirq(void) ++{ ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ raise_ktimers_thread(TIMER_SOFTIRQ); ++ wake_timersd(); ++ local_irq_restore(flags); ++} ++ ++static struct smp_hotplug_thread timer_threads = { ++ .store = &timersd, ++ .setup = timersd_setup, ++ .thread_should_run = timersd_should_run, ++ .thread_fn = run_timersd, ++ .thread_comm = "ktimers/%u", ++}; ++#endif ++ + static __init int spawn_ksoftirqd(void) + { + cpuhp_setup_state_nocalls(CPUHP_SOFTIRQ_DEAD, "softirq:dead", NULL, + takeover_tasklets); + BUG_ON(smpboot_register_percpu_thread(&softirq_threads)); +- ++#ifdef CONFIG_PREEMPT_RT ++ BUG_ON(smpboot_register_percpu_thread(&timer_threads)); ++#endif + return 0; + } + early_initcall(spawn_ksoftirqd); +diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c +index 23af5eca11b14..b0b4e44dd0968 100644 +--- a/kernel/time/hrtimer.c ++++ b/kernel/time/hrtimer.c +@@ -1805,7 +1805,7 @@ void hrtimer_interrupt(struct clock_event_device *dev) + if (!ktime_before(now, cpu_base->softirq_expires_next)) { + cpu_base->softirq_expires_next = KTIME_MAX; + cpu_base->softirq_activated = 1; +- raise_softirq_irqoff(HRTIMER_SOFTIRQ); ++ raise_hrtimer_softirq(); + } + + __hrtimer_run_queues(cpu_base, now, flags, HRTIMER_ACTIVE_HARD); +@@ -1918,7 +1918,7 @@ void hrtimer_run_queues(void) + if (!ktime_before(now, cpu_base->softirq_expires_next)) { + cpu_base->softirq_expires_next = KTIME_MAX; + cpu_base->softirq_activated = 1; +- raise_softirq_irqoff(HRTIMER_SOFTIRQ); ++ raise_hrtimer_softirq(); + } + + __hrtimer_run_queues(cpu_base, now, flags, HRTIMER_ACTIVE_HARD); +diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c +index b0e3c9205946f..133e4160ed54b 100644 +--- a/kernel/time/tick-sched.c ++++ b/kernel/time/tick-sched.c +@@ -779,7 +779,7 @@ static void tick_nohz_restart(struct tick_sched *ts, ktime_t now) + + static inline bool local_timer_softirq_pending(void) + { +- return local_softirq_pending() & BIT(TIMER_SOFTIRQ); ++ return local_pending_timers() & BIT(TIMER_SOFTIRQ); + } + + static ktime_t tick_nohz_next_event(struct tick_sched *ts, int cpu) +diff --git a/kernel/time/timer.c b/kernel/time/timer.c +index 717fcb9fb14aa..e6219da89933d 100644 +--- a/kernel/time/timer.c ++++ b/kernel/time/timer.c +@@ -1822,7 +1822,7 @@ static void run_local_timers(void) + if (time_before(jiffies, base->next_expiry)) + return; + } +- raise_softirq(TIMER_SOFTIRQ); ++ raise_timer_softirq(); + } + + /* +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index cc65887b31bd9..1d01756752676 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -2640,11 +2640,19 @@ unsigned int tracing_gen_ctx_irq_test(unsigned int irqs_status) + if (softirq_count() >> (SOFTIRQ_SHIFT + 1)) + trace_flags |= TRACE_FLAG_BH_OFF; + +- if (tif_need_resched()) ++ if (tif_need_resched_now()) + trace_flags |= TRACE_FLAG_NEED_RESCHED; ++#ifdef CONFIG_PREEMPT_LAZY ++ /* Run out of bits. Share the LAZY and PREEMPT_RESCHED */ ++ if (need_resched_lazy()) ++ trace_flags |= TRACE_FLAG_NEED_RESCHED_LAZY; ++#else + if (test_preempt_need_resched()) + trace_flags |= TRACE_FLAG_PREEMPT_RESCHED; +- return (trace_flags << 16) | (min_t(unsigned int, pc & 0xff, 0xf)) | ++#endif ++ ++ return (trace_flags << 24) | (min_t(unsigned int, pc & 0xff, 0xf)) | ++ (preempt_lazy_count() & 0xff) << 16 | + (min_t(unsigned int, migration_disable_value(), 0xf)) << 4; + } + +@@ -4230,15 +4238,17 @@ unsigned long trace_total_entries(struct trace_array *tr) + + static void print_lat_help_header(struct seq_file *m) + { +- seq_puts(m, "# _------=> CPU# \n" +- "# / _-----=> irqs-off/BH-disabled\n" +- "# | / _----=> need-resched \n" +- "# || / _---=> hardirq/softirq \n" +- "# ||| / _--=> preempt-depth \n" +- "# |||| / _-=> migrate-disable \n" +- "# ||||| / delay \n" +- "# cmd pid |||||| time | caller \n" +- "# \\ / |||||| \\ | / \n"); ++ seq_puts(m, "# _--------=> CPU# \n" ++ "# / _-------=> irqs-off/BH-disabled\n" ++ "# | / _------=> need-resched \n" ++ "# || / _-----=> need-resched-lazy\n" ++ "# ||| / _----=> hardirq/softirq \n" ++ "# |||| / _---=> preempt-depth \n" ++ "# ||||| / _--=> preempt-lazy-depth\n" ++ "# |||||| / _-=> migrate-disable \n" ++ "# ||||||| / delay \n" ++ "# cmd pid |||||||| time | caller \n" ++ "# \\ / |||||||| \\ | / \n"); + } + + static void print_event_info(struct array_buffer *buf, struct seq_file *m) +@@ -4272,14 +4282,16 @@ static void print_func_help_header_irq(struct array_buffer *buf, struct seq_file + + print_event_info(buf, m); + +- seq_printf(m, "# %.*s _-----=> irqs-off/BH-disabled\n", prec, space); +- seq_printf(m, "# %.*s / _----=> need-resched\n", prec, space); +- seq_printf(m, "# %.*s| / _---=> hardirq/softirq\n", prec, space); +- seq_printf(m, "# %.*s|| / _--=> preempt-depth\n", prec, space); +- seq_printf(m, "# %.*s||| / _-=> migrate-disable\n", prec, space); +- seq_printf(m, "# %.*s|||| / delay\n", prec, space); +- seq_printf(m, "# TASK-PID %.*s CPU# ||||| TIMESTAMP FUNCTION\n", prec, " TGID "); +- seq_printf(m, "# | | %.*s | ||||| | |\n", prec, " | "); ++ seq_printf(m, "# %.*s _-------=> irqs-off/BH-disabled\n", prec, space); ++ seq_printf(m, "# %.*s / _------=> need-resched\n", prec, space); ++ seq_printf(m, "# %.*s| / _-----=> need-resched-lazy\n", prec, space); ++ seq_printf(m, "# %.*s|| / _----=> hardirq/softirq\n", prec, space); ++ seq_printf(m, "# %.*s||| / _---=> preempt-depth\n", prec, space); ++ seq_printf(m, "# %.*s|||| / _--=> preempt-lazy-depth\n", prec, space); ++ seq_printf(m, "# %.*s||||| / _-=> migrate-disable\n", prec, space); ++ seq_printf(m, "# %.*s|||||| / delay\n", prec, space); ++ seq_printf(m, "# TASK-PID %.*s CPU# ||||||| TIMESTAMP FUNCTION\n", prec, " TGID "); ++ seq_printf(m, "# | | %.*s | ||||||| | |\n", prec, " | "); + } + + void +diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c +index 0356cae0cf74e..585380a3db753 100644 +--- a/kernel/trace/trace_events.c ++++ b/kernel/trace/trace_events.c +@@ -193,6 +193,7 @@ static int trace_define_common_fields(void) + /* Holds both preempt_count and migrate_disable */ + __common_field(unsigned char, preempt_count); + __common_field(int, pid); ++ __common_field(unsigned char, preempt_lazy_count); + + return ret; + } +diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c +index 67f47ea27921d..de58eaaf1ac7a 100644 +--- a/kernel/trace/trace_output.c ++++ b/kernel/trace/trace_output.c +@@ -442,6 +442,7 @@ int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry) + { + char hardsoft_irq; + char need_resched; ++ char need_resched_lazy; + char irqs_off; + int hardirq; + int softirq; +@@ -462,20 +463,27 @@ int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry) + + switch (entry->flags & (TRACE_FLAG_NEED_RESCHED | + TRACE_FLAG_PREEMPT_RESCHED)) { ++#ifndef CONFIG_PREEMPT_LAZY + case TRACE_FLAG_NEED_RESCHED | TRACE_FLAG_PREEMPT_RESCHED: + need_resched = 'N'; + break; ++#endif + case TRACE_FLAG_NEED_RESCHED: + need_resched = 'n'; + break; ++#ifndef CONFIG_PREEMPT_LAZY + case TRACE_FLAG_PREEMPT_RESCHED: + need_resched = 'p'; + break; ++#endif + default: + need_resched = '.'; + break; + } + ++ need_resched_lazy = ++ (entry->flags & TRACE_FLAG_NEED_RESCHED_LAZY) ? 'L' : '.'; ++ + hardsoft_irq = + (nmi && hardirq) ? 'Z' : + nmi ? 'z' : +@@ -484,14 +492,20 @@ int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry) + softirq ? 's' : + '.' ; + +- trace_seq_printf(s, "%c%c%c", +- irqs_off, need_resched, hardsoft_irq); ++ trace_seq_printf(s, "%c%c%c%c", ++ irqs_off, need_resched, need_resched_lazy, ++ hardsoft_irq); + + if (entry->preempt_count & 0xf) + trace_seq_printf(s, "%x", entry->preempt_count & 0xf); + else + trace_seq_putc(s, '.'); + ++ if (entry->preempt_lazy_count) ++ trace_seq_printf(s, "%x", entry->preempt_lazy_count); ++ else ++ trace_seq_putc(s, '.'); ++ + if (entry->preempt_count & 0xf0) + trace_seq_printf(s, "%x", entry->preempt_count >> 4); + else +diff --git a/kernel/watchdog.c b/kernel/watchdog.c +index 8e61f21e7e33e..41596c415111b 100644 +--- a/kernel/watchdog.c ++++ b/kernel/watchdog.c +@@ -424,6 +424,8 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer) + /* Start period for the next softlockup warning. */ + update_report_ts(); + ++ printk_prefer_direct_enter(); ++ + pr_emerg("BUG: soft lockup - CPU#%d stuck for %us! [%s:%d]\n", + smp_processor_id(), duration, + current->comm, task_pid_nr(current)); +@@ -442,6 +444,8 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer) + add_taint(TAINT_SOFTLOCKUP, LOCKDEP_STILL_OK); + if (softlockup_panic) + panic("softlockup: hung tasks"); ++ ++ printk_prefer_direct_exit(); + } + + return HRTIMER_RESTART; +diff --git a/kernel/watchdog_hld.c b/kernel/watchdog_hld.c +index 247bf0b1582ca..701f35f0e2d44 100644 +--- a/kernel/watchdog_hld.c ++++ b/kernel/watchdog_hld.c +@@ -135,6 +135,8 @@ static void watchdog_overflow_callback(struct perf_event *event, + if (__this_cpu_read(hard_watchdog_warn) == true) + return; + ++ printk_prefer_direct_enter(); ++ + pr_emerg("Watchdog detected hard LOCKUP on cpu %d\n", + this_cpu); + print_modules(); +@@ -155,6 +157,8 @@ static void watchdog_overflow_callback(struct perf_event *event, + if (hardlockup_panic) + nmi_panic(regs, "Hard LOCKUP"); + ++ printk_prefer_direct_exit(); ++ + __this_cpu_write(hard_watchdog_warn, true); + return; + } +diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug +index cb131fad117cc..c65e69bf4eebb 100644 +--- a/lib/Kconfig.debug ++++ b/lib/Kconfig.debug +@@ -811,6 +811,9 @@ config ARCH_HAS_DEBUG_VM_PGTABLE + An architecture should select this when it can successfully + build and run DEBUG_VM_PGTABLE. + ++config DEBUG_VM_IRQSOFF ++ def_bool DEBUG_VM && !PREEMPT_RT ++ + config DEBUG_VM + bool "Debug VM" + depends on DEBUG_KERNEL +diff --git a/lib/flex_proportions.c b/lib/flex_proportions.c +index 05cccbcf1661a..83332fefa6f42 100644 +--- a/lib/flex_proportions.c ++++ b/lib/flex_proportions.c +@@ -70,6 +70,7 @@ bool fprop_new_period(struct fprop_global *p, int periods) + */ + if (events <= 1) + return false; ++ preempt_disable_nested(); + write_seqcount_begin(&p->sequence); + if (periods < 64) + events -= events >> periods; +@@ -77,6 +78,7 @@ bool fprop_new_period(struct fprop_global *p, int periods) + percpu_counter_add(&p->events, -events); + p->period += periods; + write_seqcount_end(&p->sequence); ++ preempt_enable_nested(); + + return true; + } +diff --git a/lib/vsprintf.c b/lib/vsprintf.c +index 3c1853a9d1c09..ffaba68e6a290 100644 +--- a/lib/vsprintf.c ++++ b/lib/vsprintf.c +@@ -750,37 +750,42 @@ static int __init debug_boot_weak_hash_enable(char *str) + } + early_param("debug_boot_weak_hash", debug_boot_weak_hash_enable); + +-static DEFINE_STATIC_KEY_FALSE(filled_random_ptr_key); ++static bool filled_random_ptr_key; ++static siphash_key_t ptr_key __read_mostly; ++static void fill_ptr_key_workfn(struct work_struct *work); ++static DECLARE_DELAYED_WORK(fill_ptr_key_work, fill_ptr_key_workfn); + +-static void enable_ptr_key_workfn(struct work_struct *work) ++static void fill_ptr_key_workfn(struct work_struct *work) + { +- static_branch_enable(&filled_random_ptr_key); ++ if (!rng_is_initialized()) { ++ queue_delayed_work(system_unbound_wq, &fill_ptr_key_work, HZ * 2); ++ return; ++ } ++ ++ get_random_bytes(&ptr_key, sizeof(ptr_key)); ++ ++ /* Pairs with smp_rmb() before reading ptr_key. */ ++ smp_wmb(); ++ WRITE_ONCE(filled_random_ptr_key, true); + } + ++static int __init vsprintf_init_hashval(void) ++{ ++ fill_ptr_key_workfn(NULL); ++ return 0; ++} ++subsys_initcall(vsprintf_init_hashval) ++ + /* Maps a pointer to a 32 bit unique identifier. */ + static inline int __ptr_to_hashval(const void *ptr, unsigned long *hashval_out) + { +- static siphash_key_t ptr_key __read_mostly; + unsigned long hashval; + +- if (!static_branch_likely(&filled_random_ptr_key)) { +- static bool filled = false; +- static DEFINE_SPINLOCK(filling); +- static DECLARE_WORK(enable_ptr_key_work, enable_ptr_key_workfn); +- unsigned long flags; +- +- if (!system_unbound_wq || !rng_is_initialized() || +- !spin_trylock_irqsave(&filling, flags)) +- return -EAGAIN; +- +- if (!filled) { +- get_random_bytes(&ptr_key, sizeof(ptr_key)); +- queue_work(system_unbound_wq, &enable_ptr_key_work); +- filled = true; +- } +- spin_unlock_irqrestore(&filling, flags); +- } ++ if (!READ_ONCE(filled_random_ptr_key)) ++ return -EBUSY; + ++ /* Pairs with smp_wmb() after writing ptr_key. */ ++ smp_rmb(); + + #ifdef CONFIG_64BIT + hashval = (unsigned long)siphash_1u64((u64)ptr, &ptr_key); +diff --git a/localversion-rt b/localversion-rt +new file mode 100644 +index 0000000000000..08b3e75841adc +--- /dev/null ++++ b/localversion-rt +@@ -0,0 +1 @@ ++-rt14 +diff --git a/mm/Kconfig b/mm/Kconfig +index 0331f1461f81c..3897e924e40f2 100644 +--- a/mm/Kconfig ++++ b/mm/Kconfig +@@ -579,6 +579,12 @@ config COMPACTION + it and then we would be really interested to hear about that at + linux-mm@kvack.org. + ++config COMPACT_UNEVICTABLE_DEFAULT ++ int ++ depends on COMPACTION ++ default 0 if PREEMPT_RT ++ default 1 ++ + # + # support for free page reporting + config PAGE_REPORTING +diff --git a/mm/compaction.c b/mm/compaction.c +index 640fa76228dd9..10561cb1aaad9 100644 +--- a/mm/compaction.c ++++ b/mm/compaction.c +@@ -1727,11 +1727,7 @@ typedef enum { + * Allow userspace to control policy on scanning the unevictable LRU for + * compactable pages. + */ +-#ifdef CONFIG_PREEMPT_RT +-int sysctl_compact_unevictable_allowed __read_mostly = 0; +-#else +-int sysctl_compact_unevictable_allowed __read_mostly = 1; +-#endif ++int sysctl_compact_unevictable_allowed __read_mostly = CONFIG_COMPACT_UNEVICTABLE_DEFAULT; + + static inline void + update_fast_start_pfn(struct compact_control *cc, unsigned long pfn) +diff --git a/mm/memcontrol.c b/mm/memcontrol.c +index b69979c9ced5c..d35b6fa560f0a 100644 +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -597,25 +597,18 @@ static u64 flush_next_time; + */ + static void memcg_stats_lock(void) + { +-#ifdef CONFIG_PREEMPT_RT +- preempt_disable(); +-#else +- VM_BUG_ON(!irqs_disabled()); +-#endif ++ preempt_disable_nested(); ++ VM_WARN_ON_IRQS_ENABLED(); + } + + static void __memcg_stats_lock(void) + { +-#ifdef CONFIG_PREEMPT_RT +- preempt_disable(); +-#endif ++ preempt_disable_nested(); + } + + static void memcg_stats_unlock(void) + { +-#ifdef CONFIG_PREEMPT_RT +- preempt_enable(); +-#endif ++ preempt_enable_nested(); + } + + static inline void memcg_rstat_updated(struct mem_cgroup *memcg, int val) +@@ -715,7 +708,7 @@ void __mod_memcg_lruvec_state(struct lruvec *lruvec, enum node_stat_item idx, + * interrupt context while other caller need to have disabled interrupt. + */ + __memcg_stats_lock(); +- if (IS_ENABLED(CONFIG_DEBUG_VM) && !IS_ENABLED(CONFIG_PREEMPT_RT)) { ++ if (IS_ENABLED(CONFIG_DEBUG_VM)) { + switch (idx) { + case NR_ANON_MAPPED: + case NR_FILE_MAPPED: +@@ -725,7 +718,7 @@ void __mod_memcg_lruvec_state(struct lruvec *lruvec, enum node_stat_item idx, + WARN_ON_ONCE(!in_task()); + break; + default: +- WARN_ON_ONCE(!irqs_disabled()); ++ VM_WARN_ON_IRQS_ENABLED(); + } + } + +diff --git a/mm/slub.c b/mm/slub.c +index 4b98dff9be8e3..59173fa5901a0 100644 +--- a/mm/slub.c ++++ b/mm/slub.c +@@ -50,7 +50,7 @@ + * 1. slab_mutex (Global Mutex) + * 2. node->list_lock (Spinlock) + * 3. kmem_cache->cpu_slab->lock (Local lock) +- * 4. slab_lock(slab) (Only on some arches or for debugging) ++ * 4. slab_lock(slab) (Only on some arches) + * 5. object_map_lock (Only for debugging) + * + * slab_mutex +@@ -64,8 +64,9 @@ + * The slab_lock is a wrapper around the page lock, thus it is a bit + * spinlock. + * +- * The slab_lock is only used for debugging and on arches that do not +- * have the ability to do a cmpxchg_double. It only protects: ++ * The slab_lock is only used on arches that do not have the ability ++ * to do a cmpxchg_double. It only protects: ++ * + * A. slab->freelist -> List of free objects in a slab + * B. slab->inuse -> Number of objects in use + * C. slab->objects -> Number of objects in slab +@@ -94,15 +95,20 @@ + * allocating a long series of objects that fill up slabs does not require + * the list lock. + * ++ * For debug caches, all allocations are forced to go through a list_lock ++ * protected region to serialize against concurrent validation. ++ * + * cpu_slab->lock local lock + * + * This locks protect slowpath manipulation of all kmem_cache_cpu fields + * except the stat counters. This is a percpu structure manipulated only by + * the local cpu, so the lock protects against being preempted or interrupted + * by an irq. Fast path operations rely on lockless operations instead. +- * On PREEMPT_RT, the local lock does not actually disable irqs (and thus +- * prevent the lockless operations), so fastpath operations also need to take +- * the lock and are no longer lockless. ++ * ++ * On PREEMPT_RT, the local lock neither disables interrupts nor preemption ++ * which means the lockless fastpath cannot be used as it might interfere with ++ * an in-progress slow path operations. In this case the local lock is always ++ * taken but it still utilizes the freelist for the common operations. + * + * lockless fastpaths + * +@@ -163,8 +169,9 @@ + * function call even on !PREEMPT_RT, use inline preempt_disable() there. + */ + #ifndef CONFIG_PREEMPT_RT +-#define slub_get_cpu_ptr(var) get_cpu_ptr(var) +-#define slub_put_cpu_ptr(var) put_cpu_ptr(var) ++#define slub_get_cpu_ptr(var) get_cpu_ptr(var) ++#define slub_put_cpu_ptr(var) put_cpu_ptr(var) ++#define USE_LOCKLESS_FAST_PATH() (true) + #else + #define slub_get_cpu_ptr(var) \ + ({ \ +@@ -176,6 +183,7 @@ do { \ + (void)(var); \ + migrate_enable(); \ + } while (0) ++#define USE_LOCKLESS_FAST_PATH() (false) + #endif + + #ifdef CONFIG_SLUB_DEBUG +@@ -447,7 +455,7 @@ slub_set_cpu_partial(struct kmem_cache *s, unsigned int nr_objects) + /* + * Per slab locking using the pagelock + */ +-static __always_inline void __slab_lock(struct slab *slab) ++static __always_inline void slab_lock(struct slab *slab) + { + struct page *page = slab_page(slab); + +@@ -455,7 +463,7 @@ static __always_inline void __slab_lock(struct slab *slab) + bit_spin_lock(PG_locked, &page->flags); + } + +-static __always_inline void __slab_unlock(struct slab *slab) ++static __always_inline void slab_unlock(struct slab *slab) + { + struct page *page = slab_page(slab); + +@@ -463,31 +471,19 @@ static __always_inline void __slab_unlock(struct slab *slab) + __bit_spin_unlock(PG_locked, &page->flags); + } + +-static __always_inline void slab_lock(struct slab *slab, unsigned long *flags) +-{ +- if (IS_ENABLED(CONFIG_PREEMPT_RT)) +- local_irq_save(*flags); +- __slab_lock(slab); +-} +- +-static __always_inline void slab_unlock(struct slab *slab, unsigned long *flags) +-{ +- __slab_unlock(slab); +- if (IS_ENABLED(CONFIG_PREEMPT_RT)) +- local_irq_restore(*flags); +-} +- + /* + * Interrupts must be disabled (for the fallback code to work right), typically +- * by an _irqsave() lock variant. Except on PREEMPT_RT where locks are different +- * so we disable interrupts as part of slab_[un]lock(). ++ * by an _irqsave() lock variant. Except on PREEMPT_RT where these variants do ++ * not actually disable interrupts. On the other hand the migrate_disable() ++ * done by bit_spin_lock() is sufficient on PREEMPT_RT thanks to its threaded ++ * interrupts. + */ + static inline bool __cmpxchg_double_slab(struct kmem_cache *s, struct slab *slab, + void *freelist_old, unsigned long counters_old, + void *freelist_new, unsigned long counters_new, + const char *n) + { +- if (!IS_ENABLED(CONFIG_PREEMPT_RT)) ++ if (USE_LOCKLESS_FAST_PATH()) + lockdep_assert_irqs_disabled(); + #if defined(CONFIG_HAVE_CMPXCHG_DOUBLE) && \ + defined(CONFIG_HAVE_ALIGNED_STRUCT_PAGE) +@@ -499,18 +495,15 @@ static inline bool __cmpxchg_double_slab(struct kmem_cache *s, struct slab *slab + } else + #endif + { +- /* init to 0 to prevent spurious warnings */ +- unsigned long flags = 0; +- +- slab_lock(slab, &flags); ++ slab_lock(slab); + if (slab->freelist == freelist_old && + slab->counters == counters_old) { + slab->freelist = freelist_new; + slab->counters = counters_new; +- slab_unlock(slab, &flags); ++ slab_unlock(slab); + return true; + } +- slab_unlock(slab, &flags); ++ slab_unlock(slab); + } + + cpu_relax(); +@@ -541,16 +534,16 @@ static inline bool cmpxchg_double_slab(struct kmem_cache *s, struct slab *slab, + unsigned long flags; + + local_irq_save(flags); +- __slab_lock(slab); ++ slab_lock(slab); + if (slab->freelist == freelist_old && + slab->counters == counters_old) { + slab->freelist = freelist_new; + slab->counters = counters_new; +- __slab_unlock(slab); ++ slab_unlock(slab); + local_irq_restore(flags); + return true; + } +- __slab_unlock(slab); ++ slab_unlock(slab); + local_irq_restore(flags); + } + +@@ -566,7 +559,7 @@ static inline bool cmpxchg_double_slab(struct kmem_cache *s, struct slab *slab, + + #ifdef CONFIG_SLUB_DEBUG + static unsigned long object_map[BITS_TO_LONGS(MAX_OBJS_PER_PAGE)]; +-static DEFINE_RAW_SPINLOCK(object_map_lock); ++static DEFINE_SPINLOCK(object_map_lock); + + static void __fill_map(unsigned long *obj_map, struct kmem_cache *s, + struct slab *slab) +@@ -600,30 +593,6 @@ static bool slab_add_kunit_errors(void) + static inline bool slab_add_kunit_errors(void) { return false; } + #endif + +-/* +- * Determine a map of objects in use in a slab. +- * +- * Node listlock must be held to guarantee that the slab does +- * not vanish from under us. +- */ +-static unsigned long *get_map(struct kmem_cache *s, struct slab *slab) +- __acquires(&object_map_lock) +-{ +- VM_BUG_ON(!irqs_disabled()); +- +- raw_spin_lock(&object_map_lock); +- +- __fill_map(object_map, s, slab); +- +- return object_map; +-} +- +-static void put_map(unsigned long *map) __releases(&object_map_lock) +-{ +- VM_BUG_ON(map != object_map); +- raw_spin_unlock(&object_map_lock); +-} +- + static inline unsigned int size_from_object(struct kmem_cache *s) + { + if (s->flags & SLAB_RED_ZONE) +@@ -1329,17 +1298,14 @@ static inline int alloc_consistency_checks(struct kmem_cache *s, + } + + static noinline int alloc_debug_processing(struct kmem_cache *s, +- struct slab *slab, +- void *object, unsigned long addr) ++ struct slab *slab, void *object) + { + if (s->flags & SLAB_CONSISTENCY_CHECKS) { + if (!alloc_consistency_checks(s, slab, object)) + goto bad; + } + +- /* Success perform special debug activities for allocs */ +- if (s->flags & SLAB_STORE_USER) +- set_track(s, object, TRACK_ALLOC, addr); ++ /* Success. Perform special debug activities for allocs */ + trace(s, slab, object, 1); + init_object(s, object, SLUB_RED_ACTIVE); + return 1; +@@ -1390,63 +1356,6 @@ static inline int free_consistency_checks(struct kmem_cache *s, + return 1; + } + +-/* Supports checking bulk free of a constructed freelist */ +-static noinline int free_debug_processing( +- struct kmem_cache *s, struct slab *slab, +- void *head, void *tail, int bulk_cnt, +- unsigned long addr) +-{ +- struct kmem_cache_node *n = get_node(s, slab_nid(slab)); +- void *object = head; +- int cnt = 0; +- unsigned long flags, flags2; +- int ret = 0; +- depot_stack_handle_t handle = 0; +- +- if (s->flags & SLAB_STORE_USER) +- handle = set_track_prepare(); +- +- spin_lock_irqsave(&n->list_lock, flags); +- slab_lock(slab, &flags2); +- +- if (s->flags & SLAB_CONSISTENCY_CHECKS) { +- if (!check_slab(s, slab)) +- goto out; +- } +- +-next_object: +- cnt++; +- +- if (s->flags & SLAB_CONSISTENCY_CHECKS) { +- if (!free_consistency_checks(s, slab, object, addr)) +- goto out; +- } +- +- if (s->flags & SLAB_STORE_USER) +- set_track_update(s, object, TRACK_FREE, addr, handle); +- trace(s, slab, object, 0); +- /* Freepointer not overwritten by init_object(), SLAB_POISON moved it */ +- init_object(s, object, SLUB_RED_INACTIVE); +- +- /* Reached end of constructed freelist yet? */ +- if (object != tail) { +- object = get_freepointer(s, object); +- goto next_object; +- } +- ret = 1; +- +-out: +- if (cnt != bulk_cnt) +- slab_err(s, slab, "Bulk freelist count(%d) invalid(%d)\n", +- bulk_cnt, cnt); +- +- slab_unlock(slab, &flags2); +- spin_unlock_irqrestore(&n->list_lock, flags); +- if (!ret) +- slab_fix(s, "Object at 0x%p not freed", object); +- return ret; +-} +- + /* + * Parse a block of slub_debug options. Blocks are delimited by ';' + * +@@ -1666,16 +1575,18 @@ static inline + void setup_slab_debug(struct kmem_cache *s, struct slab *slab, void *addr) {} + + static inline int alloc_debug_processing(struct kmem_cache *s, +- struct slab *slab, void *object, unsigned long addr) { return 0; } ++ struct slab *slab, void *object) { return 0; } + +-static inline int free_debug_processing( ++static inline void free_debug_processing( + struct kmem_cache *s, struct slab *slab, + void *head, void *tail, int bulk_cnt, +- unsigned long addr) { return 0; } ++ unsigned long addr) {} + + static inline void slab_pad_check(struct kmem_cache *s, struct slab *slab) {} + static inline int check_object(struct kmem_cache *s, struct slab *slab, + void *object, u8 val) { return 1; } ++static inline void set_track(struct kmem_cache *s, void *object, ++ enum track_item alloc, unsigned long addr) {} + static inline void add_full(struct kmem_cache *s, struct kmem_cache_node *n, + struct slab *slab) {} + static inline void remove_full(struct kmem_cache *s, struct kmem_cache_node *n, +@@ -1981,11 +1892,13 @@ static struct slab *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) + */ + slab = alloc_slab_page(alloc_gfp, node, oo); + if (unlikely(!slab)) +- goto out; ++ return NULL; + stat(s, ORDER_FALLBACK); + } + + slab->objects = oo_objects(oo); ++ slab->inuse = 0; ++ slab->frozen = 0; + + account_slab(slab, oo_order(oo), s, flags); + +@@ -2012,15 +1925,6 @@ static struct slab *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) + set_freepointer(s, p, NULL); + } + +- slab->inuse = slab->objects; +- slab->frozen = 1; +- +-out: +- if (!slab) +- return NULL; +- +- inc_slabs_node(s, slab_nid(slab), slab->objects); +- + return slab; + } + +@@ -2107,6 +2011,75 @@ static inline void remove_partial(struct kmem_cache_node *n, + n->nr_partial--; + } + ++/* ++ * Called only for kmem_cache_debug() caches instead of acquire_slab(), with a ++ * slab from the n->partial list. Remove only a single object from the slab, do ++ * the alloc_debug_processing() checks and leave the slab on the list, or move ++ * it to full list if it was the last free object. ++ */ ++static void *alloc_single_from_partial(struct kmem_cache *s, ++ struct kmem_cache_node *n, struct slab *slab) ++{ ++ void *object; ++ ++ lockdep_assert_held(&n->list_lock); ++ ++ object = slab->freelist; ++ slab->freelist = get_freepointer(s, object); ++ slab->inuse++; ++ ++ if (!alloc_debug_processing(s, slab, object)) { ++ remove_partial(n, slab); ++ return NULL; ++ } ++ ++ if (slab->inuse == slab->objects) { ++ remove_partial(n, slab); ++ add_full(s, n, slab); ++ } ++ ++ return object; ++} ++ ++/* ++ * Called only for kmem_cache_debug() caches to allocate from a freshly ++ * allocated slab. Allocate a single object instead of whole freelist ++ * and put the slab to the partial (or full) list. ++ */ ++static void *alloc_single_from_new_slab(struct kmem_cache *s, ++ struct slab *slab) ++{ ++ int nid = slab_nid(slab); ++ struct kmem_cache_node *n = get_node(s, nid); ++ unsigned long flags; ++ void *object; ++ ++ ++ object = slab->freelist; ++ slab->freelist = get_freepointer(s, object); ++ slab->inuse = 1; ++ ++ if (!alloc_debug_processing(s, slab, object)) ++ /* ++ * It's not really expected that this would fail on a ++ * freshly allocated slab, but a concurrent memory ++ * corruption in theory could cause that. ++ */ ++ return NULL; ++ ++ spin_lock_irqsave(&n->list_lock, flags); ++ ++ if (slab->inuse == slab->objects) ++ add_full(s, n, slab); ++ else ++ add_partial(n, slab, DEACTIVATE_TO_HEAD); ++ ++ inc_slabs_node(s, nid, slab->objects); ++ spin_unlock_irqrestore(&n->list_lock, flags); ++ ++ return object; ++} ++ + /* + * Remove slab from the partial list, freeze it and + * return the pointer to the freelist. +@@ -2187,6 +2160,13 @@ static void *get_partial_node(struct kmem_cache *s, struct kmem_cache_node *n, + if (!pfmemalloc_match(slab, gfpflags)) + continue; + ++ if (kmem_cache_debug(s)) { ++ object = alloc_single_from_partial(s, n, slab); ++ if (object) ++ break; ++ continue; ++ } ++ + t = acquire_slab(s, n, slab, object == NULL); + if (!t) + break; +@@ -2793,6 +2773,109 @@ static inline unsigned long node_nr_objs(struct kmem_cache_node *n) + { + return atomic_long_read(&n->total_objects); + } ++ ++/* Supports checking bulk free of a constructed freelist */ ++static noinline void free_debug_processing( ++ struct kmem_cache *s, struct slab *slab, ++ void *head, void *tail, int bulk_cnt, ++ unsigned long addr) ++{ ++ struct kmem_cache_node *n = get_node(s, slab_nid(slab)); ++ struct slab *slab_free = NULL; ++ void *object = head; ++ int cnt = 0; ++ unsigned long flags; ++ bool checks_ok = false; ++ depot_stack_handle_t handle = 0; ++ ++ if (s->flags & SLAB_STORE_USER) ++ handle = set_track_prepare(); ++ ++ spin_lock_irqsave(&n->list_lock, flags); ++ ++ if (s->flags & SLAB_CONSISTENCY_CHECKS) { ++ if (!check_slab(s, slab)) ++ goto out; ++ } ++ ++ if (slab->inuse < bulk_cnt) { ++ slab_err(s, slab, "Slab has %d allocated objects but %d are to be freed\n", ++ slab->inuse, bulk_cnt); ++ goto out; ++ } ++ ++next_object: ++ ++ if (++cnt > bulk_cnt) ++ goto out_cnt; ++ ++ if (s->flags & SLAB_CONSISTENCY_CHECKS) { ++ if (!free_consistency_checks(s, slab, object, addr)) ++ goto out; ++ } ++ ++ if (s->flags & SLAB_STORE_USER) ++ set_track_update(s, object, TRACK_FREE, addr, handle); ++ trace(s, slab, object, 0); ++ /* Freepointer not overwritten by init_object(), SLAB_POISON moved it */ ++ init_object(s, object, SLUB_RED_INACTIVE); ++ ++ /* Reached end of constructed freelist yet? */ ++ if (object != tail) { ++ object = get_freepointer(s, object); ++ goto next_object; ++ } ++ checks_ok = true; ++ ++out_cnt: ++ if (cnt != bulk_cnt) ++ slab_err(s, slab, "Bulk free expected %d objects but found %d\n", ++ bulk_cnt, cnt); ++ ++out: ++ if (checks_ok) { ++ void *prior = slab->freelist; ++ ++ /* Perform the actual freeing while we still hold the locks */ ++ slab->inuse -= cnt; ++ set_freepointer(s, tail, prior); ++ slab->freelist = head; ++ ++ /* Do we need to remove the slab from full or partial list? */ ++ if (!prior) { ++ remove_full(s, n, slab); ++ } else if (slab->inuse == 0) { ++ remove_partial(n, slab); ++ stat(s, FREE_REMOVE_PARTIAL); ++ } ++ ++ /* Do we need to discard the slab or add to partial list? */ ++ if (slab->inuse == 0) { ++ slab_free = slab; ++ } else if (!prior) { ++ add_partial(n, slab, DEACTIVATE_TO_TAIL); ++ stat(s, FREE_ADD_PARTIAL); ++ } ++ } ++ ++ if (slab_free) { ++ /* ++ * Update the counters while still holding n->list_lock to ++ * prevent spurious validation warnings ++ */ ++ dec_slabs_node(s, slab_nid(slab_free), slab_free->objects); ++ } ++ ++ spin_unlock_irqrestore(&n->list_lock, flags); ++ ++ if (!checks_ok) ++ slab_fix(s, "Object at 0x%p not freed", object); ++ ++ if (slab_free) { ++ stat(s, FREE_SLAB); ++ free_slab(s, slab_free); ++ } ++} + #endif /* CONFIG_SLUB_DEBUG */ + + #if defined(CONFIG_SLUB_DEBUG) || defined(CONFIG_SYSFS) +@@ -3041,36 +3124,52 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, + return NULL; + } + ++ stat(s, ALLOC_SLAB); ++ ++ if (kmem_cache_debug(s)) { ++ freelist = alloc_single_from_new_slab(s, slab); ++ ++ if (unlikely(!freelist)) ++ goto new_objects; ++ ++ if (s->flags & SLAB_STORE_USER) ++ set_track(s, freelist, TRACK_ALLOC, addr); ++ ++ return freelist; ++ } ++ + /* + * No other reference to the slab yet so we can + * muck around with it freely without cmpxchg + */ + freelist = slab->freelist; + slab->freelist = NULL; ++ slab->inuse = slab->objects; ++ slab->frozen = 1; + +- stat(s, ALLOC_SLAB); ++ inc_slabs_node(s, slab_nid(slab), slab->objects); + + check_new_slab: + + if (kmem_cache_debug(s)) { +- if (!alloc_debug_processing(s, slab, freelist, addr)) { +- /* Slab failed checks. Next slab needed */ +- goto new_slab; +- } else { +- /* +- * For debug case, we don't load freelist so that all +- * allocations go through alloc_debug_processing() +- */ +- goto return_single; +- } ++ /* ++ * For debug caches here we had to go through ++ * alloc_single_from_partial() so just store the tracking info ++ * and return the object ++ */ ++ if (s->flags & SLAB_STORE_USER) ++ set_track(s, freelist, TRACK_ALLOC, addr); ++ return freelist; + } + +- if (unlikely(!pfmemalloc_match(slab, gfpflags))) ++ if (unlikely(!pfmemalloc_match(slab, gfpflags))) { + /* + * For !pfmemalloc_match() case we don't load freelist so that + * we don't make further mismatched allocations easier. + */ +- goto return_single; ++ deactivate_slab(s, slab, get_freepointer(s, freelist)); ++ return freelist; ++ } + + retry_load_slab: + +@@ -3094,11 +3193,6 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, + c->slab = slab; + + goto load_freelist; +- +-return_single: +- +- deactivate_slab(s, slab, get_freepointer(s, freelist)); +- return freelist; + } + + /* +@@ -3202,14 +3296,8 @@ static __always_inline void *slab_alloc_node(struct kmem_cache *s, struct list_l + + object = c->freelist; + slab = c->slab; +- /* +- * We cannot use the lockless fastpath on PREEMPT_RT because if a +- * slowpath has taken the local_lock_irqsave(), it is not protected +- * against a fast path operation in an irq handler. So we need to take +- * the slow path which uses local_lock. It is still relatively fast if +- * there is a suitable cpu freelist. +- */ +- if (IS_ENABLED(CONFIG_PREEMPT_RT) || ++ ++ if (!USE_LOCKLESS_FAST_PATH() || + unlikely(!object || !slab || !node_match(slab, node))) { + object = __slab_alloc(s, gfpflags, node, addr, c); + } else { +@@ -3346,9 +3434,10 @@ static void __slab_free(struct kmem_cache *s, struct slab *slab, + if (kfence_free(head)) + return; + +- if (kmem_cache_debug(s) && +- !free_debug_processing(s, slab, head, tail, cnt, addr)) ++ if (kmem_cache_debug(s)) { ++ free_debug_processing(s, slab, head, tail, cnt, addr); + return; ++ } + + do { + if (unlikely(n)) { +@@ -3468,6 +3557,7 @@ static __always_inline void do_slab_free(struct kmem_cache *s, + void *tail_obj = tail ? : head; + struct kmem_cache_cpu *c; + unsigned long tid; ++ void **freelist; + + redo: + /* +@@ -3482,9 +3572,13 @@ static __always_inline void do_slab_free(struct kmem_cache *s, + /* Same with comment on barrier() in slab_alloc_node() */ + barrier(); + +- if (likely(slab == c->slab)) { +-#ifndef CONFIG_PREEMPT_RT +- void **freelist = READ_ONCE(c->freelist); ++ if (unlikely(slab != c->slab)) { ++ __slab_free(s, slab, head, tail_obj, cnt, addr); ++ return; ++ } ++ ++ if (USE_LOCKLESS_FAST_PATH()) { ++ freelist = READ_ONCE(c->freelist); + + set_freepointer(s, tail_obj, freelist); + +@@ -3496,16 +3590,8 @@ static __always_inline void do_slab_free(struct kmem_cache *s, + note_cmpxchg_failure("slab_free", s, tid); + goto redo; + } +-#else /* CONFIG_PREEMPT_RT */ +- /* +- * We cannot use the lockless fastpath on PREEMPT_RT because if +- * a slowpath has taken the local_lock_irqsave(), it is not +- * protected against a fast path operation in an irq handler. So +- * we need to take the local_lock. We shouldn't simply defer to +- * __slab_free() as that wouldn't use the cpu freelist at all. +- */ +- void **freelist; +- ++ } else { ++ /* Update the free list under the local lock */ + local_lock(&s->cpu_slab->lock); + c = this_cpu_ptr(s->cpu_slab); + if (unlikely(slab != c->slab)) { +@@ -3520,11 +3606,8 @@ static __always_inline void do_slab_free(struct kmem_cache *s, + c->tid = next_tid(tid); + + local_unlock(&s->cpu_slab->lock); +-#endif +- stat(s, FREE_FASTPATH); +- } else +- __slab_free(s, slab, head, tail_obj, cnt, addr); +- ++ } ++ stat(s, FREE_FASTPATH); + } + + static __always_inline void slab_free(struct kmem_cache *s, struct slab *slab, +@@ -3941,6 +4024,7 @@ static void early_kmem_cache_node_alloc(int node) + slab = new_slab(kmem_cache_node, GFP_NOWAIT, node); + + BUG_ON(!slab); ++ inc_slabs_node(kmem_cache_node, slab_nid(slab), slab->objects); + if (slab_nid(slab) != node) { + pr_err("SLUB: Unable to allocate memory from node %d\n", node); + pr_err("SLUB: Allocating a useless per node structure in order to be able to continue\n"); +@@ -3955,7 +4039,6 @@ static void early_kmem_cache_node_alloc(int node) + n = kasan_slab_alloc(kmem_cache_node, n, GFP_KERNEL, false); + slab->freelist = get_freepointer(kmem_cache_node, n); + slab->inuse = 1; +- slab->frozen = 0; + kmem_cache_node->node[node] = n; + init_kmem_cache_node(n); + inc_slabs_node(kmem_cache_node, node, slab->objects); +@@ -4242,23 +4325,21 @@ static void list_slab_objects(struct kmem_cache *s, struct slab *slab, + { + #ifdef CONFIG_SLUB_DEBUG + void *addr = slab_address(slab); +- unsigned long flags; +- unsigned long *map; + void *p; + + slab_err(s, slab, text, s->name); +- slab_lock(slab, &flags); + +- map = get_map(s, slab); ++ spin_lock(&object_map_lock); ++ __fill_map(object_map, s, slab); ++ + for_each_object(p, s, addr, slab->objects) { + +- if (!test_bit(__obj_to_index(s, addr, p), map)) { ++ if (!test_bit(__obj_to_index(s, addr, p), object_map)) { + pr_err("Object 0x%p @offset=%tu\n", p, p - addr); + print_tracking(s, p); + } + } +- put_map(map); +- slab_unlock(slab, &flags); ++ spin_unlock(&object_map_lock); + #endif + } + +@@ -4616,6 +4697,7 @@ static int __kmem_cache_do_shrink(struct kmem_cache *s) + if (free == slab->objects) { + list_move(&slab->slab_list, &discard); + n->nr_partial--; ++ dec_slabs_node(s, node, slab->objects); + } else if (free <= SHRINK_PROMOTE_MAX) + list_move(&slab->slab_list, promote + free - 1); + } +@@ -4631,7 +4713,7 @@ static int __kmem_cache_do_shrink(struct kmem_cache *s) + + /* Release empty slabs */ + list_for_each_entry_safe(slab, t, &discard, slab_list) +- discard_slab(s, slab); ++ free_slab(s, slab); + + if (slabs_node(s, node)) + ret = 1; +@@ -4991,12 +5073,9 @@ static void validate_slab(struct kmem_cache *s, struct slab *slab, + { + void *p; + void *addr = slab_address(slab); +- unsigned long flags; +- +- slab_lock(slab, &flags); + + if (!check_slab(s, slab) || !on_freelist(s, slab, NULL)) +- goto unlock; ++ return; + + /* Now we know that a valid freelist exists */ + __fill_map(obj_map, s, slab); +@@ -5007,8 +5086,6 @@ static void validate_slab(struct kmem_cache *s, struct slab *slab, + if (!check_object(s, slab, p, val)) + break; + } +-unlock: +- slab_unlock(slab, &flags); + } + + static int validate_slab_node(struct kmem_cache *s, +@@ -5612,7 +5689,7 @@ static ssize_t validate_store(struct kmem_cache *s, + { + int ret = -EINVAL; + +- if (buf[0] == '1') { ++ if (buf[0] == '1' && kmem_cache_debug(s)) { + ret = validate_slab_cache(s); + if (ret >= 0) + ret = length; +diff --git a/mm/vmstat.c b/mm/vmstat.c +index 90af9a8572f5a..7a2d73f152304 100644 +--- a/mm/vmstat.c ++++ b/mm/vmstat.c +@@ -355,8 +355,7 @@ void __mod_zone_page_state(struct zone *zone, enum zone_stat_item item, + * CPU migrations and preemption potentially corrupts a counter so + * disable preemption. + */ +- if (IS_ENABLED(CONFIG_PREEMPT_RT)) +- preempt_disable(); ++ preempt_disable_nested(); + + x = delta + __this_cpu_read(*p); + +@@ -368,8 +367,7 @@ void __mod_zone_page_state(struct zone *zone, enum zone_stat_item item, + } + __this_cpu_write(*p, x); + +- if (IS_ENABLED(CONFIG_PREEMPT_RT)) +- preempt_enable(); ++ preempt_enable_nested(); + } + EXPORT_SYMBOL(__mod_zone_page_state); + +@@ -393,8 +391,7 @@ void __mod_node_page_state(struct pglist_data *pgdat, enum node_stat_item item, + } + + /* See __mod_node_page_state */ +- if (IS_ENABLED(CONFIG_PREEMPT_RT)) +- preempt_disable(); ++ preempt_disable_nested(); + + x = delta + __this_cpu_read(*p); + +@@ -406,8 +403,7 @@ void __mod_node_page_state(struct pglist_data *pgdat, enum node_stat_item item, + } + __this_cpu_write(*p, x); + +- if (IS_ENABLED(CONFIG_PREEMPT_RT)) +- preempt_enable(); ++ preempt_enable_nested(); + } + EXPORT_SYMBOL(__mod_node_page_state); + +@@ -441,8 +437,7 @@ void __inc_zone_state(struct zone *zone, enum zone_stat_item item) + s8 v, t; + + /* See __mod_node_page_state */ +- if (IS_ENABLED(CONFIG_PREEMPT_RT)) +- preempt_disable(); ++ preempt_disable_nested(); + + v = __this_cpu_inc_return(*p); + t = __this_cpu_read(pcp->stat_threshold); +@@ -453,8 +448,7 @@ void __inc_zone_state(struct zone *zone, enum zone_stat_item item) + __this_cpu_write(*p, -overstep); + } + +- if (IS_ENABLED(CONFIG_PREEMPT_RT)) +- preempt_enable(); ++ preempt_enable_nested(); + } + + void __inc_node_state(struct pglist_data *pgdat, enum node_stat_item item) +@@ -466,8 +460,7 @@ void __inc_node_state(struct pglist_data *pgdat, enum node_stat_item item) + VM_WARN_ON_ONCE(vmstat_item_in_bytes(item)); + + /* See __mod_node_page_state */ +- if (IS_ENABLED(CONFIG_PREEMPT_RT)) +- preempt_disable(); ++ preempt_disable_nested(); + + v = __this_cpu_inc_return(*p); + t = __this_cpu_read(pcp->stat_threshold); +@@ -478,8 +471,7 @@ void __inc_node_state(struct pglist_data *pgdat, enum node_stat_item item) + __this_cpu_write(*p, -overstep); + } + +- if (IS_ENABLED(CONFIG_PREEMPT_RT)) +- preempt_enable(); ++ preempt_enable_nested(); + } + + void __inc_zone_page_state(struct page *page, enum zone_stat_item item) +@@ -501,8 +493,7 @@ void __dec_zone_state(struct zone *zone, enum zone_stat_item item) + s8 v, t; + + /* See __mod_node_page_state */ +- if (IS_ENABLED(CONFIG_PREEMPT_RT)) +- preempt_disable(); ++ preempt_disable_nested(); + + v = __this_cpu_dec_return(*p); + t = __this_cpu_read(pcp->stat_threshold); +@@ -513,8 +504,7 @@ void __dec_zone_state(struct zone *zone, enum zone_stat_item item) + __this_cpu_write(*p, overstep); + } + +- if (IS_ENABLED(CONFIG_PREEMPT_RT)) +- preempt_enable(); ++ preempt_enable_nested(); + } + + void __dec_node_state(struct pglist_data *pgdat, enum node_stat_item item) +@@ -526,8 +516,7 @@ void __dec_node_state(struct pglist_data *pgdat, enum node_stat_item item) + VM_WARN_ON_ONCE(vmstat_item_in_bytes(item)); + + /* See __mod_node_page_state */ +- if (IS_ENABLED(CONFIG_PREEMPT_RT)) +- preempt_disable(); ++ preempt_disable_nested(); + + v = __this_cpu_dec_return(*p); + t = __this_cpu_read(pcp->stat_threshold); +@@ -538,8 +527,7 @@ void __dec_node_state(struct pglist_data *pgdat, enum node_stat_item item) + __this_cpu_write(*p, overstep); + } + +- if (IS_ENABLED(CONFIG_PREEMPT_RT)) +- preempt_enable(); ++ preempt_enable_nested(); + } + + void __dec_zone_page_state(struct page *page, enum zone_stat_item item) +diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c +index 035812b0461cc..ecdb47712d956 100644 +--- a/net/8021q/vlan_dev.c ++++ b/net/8021q/vlan_dev.c +@@ -712,13 +712,13 @@ static void vlan_dev_get_stats64(struct net_device *dev, + + p = per_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats, i); + do { +- start = u64_stats_fetch_begin_irq(&p->syncp); ++ start = u64_stats_fetch_begin(&p->syncp); + rxpackets = u64_stats_read(&p->rx_packets); + rxbytes = u64_stats_read(&p->rx_bytes); + rxmulticast = u64_stats_read(&p->rx_multicast); + txpackets = u64_stats_read(&p->tx_packets); + txbytes = u64_stats_read(&p->tx_bytes); +- } while (u64_stats_fetch_retry_irq(&p->syncp, start)); ++ } while (u64_stats_fetch_retry(&p->syncp, start)); + + stats->rx_packets += rxpackets; + stats->rx_bytes += rxbytes; +diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c +index db4f2641d1cd1..7e2a9fb5786c9 100644 +--- a/net/bridge/br_multicast.c ++++ b/net/bridge/br_multicast.c +@@ -4899,9 +4899,9 @@ void br_multicast_get_stats(const struct net_bridge *br, + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&cpu_stats->syncp); ++ start = u64_stats_fetch_begin(&cpu_stats->syncp); + memcpy(&temp, &cpu_stats->mstats, sizeof(temp)); +- } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&cpu_stats->syncp, start)); + + mcast_stats_add_dir(tdst.igmp_v1queries, temp.igmp_v1queries); + mcast_stats_add_dir(tdst.igmp_v2queries, temp.igmp_v2queries); +diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c +index 6e53dc9914094..f2fc284abab38 100644 +--- a/net/bridge/br_vlan.c ++++ b/net/bridge/br_vlan.c +@@ -1378,12 +1378,12 @@ void br_vlan_get_stats(const struct net_bridge_vlan *v, + + cpu_stats = per_cpu_ptr(v->stats, i); + do { +- start = u64_stats_fetch_begin_irq(&cpu_stats->syncp); ++ start = u64_stats_fetch_begin(&cpu_stats->syncp); + rxpackets = u64_stats_read(&cpu_stats->rx_packets); + rxbytes = u64_stats_read(&cpu_stats->rx_bytes); + txbytes = u64_stats_read(&cpu_stats->tx_bytes); + txpackets = u64_stats_read(&cpu_stats->tx_packets); +- } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&cpu_stats->syncp, start)); + + u64_stats_add(&stats->rx_packets, rxpackets); + u64_stats_add(&stats->rx_bytes, rxbytes); +diff --git a/net/core/dev.c b/net/core/dev.c +index 56c8b0921c9fd..d96506980d2f2 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -4582,15 +4582,6 @@ static void rps_trigger_softirq(void *data) + + #endif /* CONFIG_RPS */ + +-/* Called from hardirq (IPI) context */ +-static void trigger_rx_softirq(void *data) +-{ +- struct softnet_data *sd = data; +- +- __raise_softirq_irqoff(NET_RX_SOFTIRQ); +- smp_store_release(&sd->defer_ipi_scheduled, 0); +-} +- + /* + * Check if this softnet_data structure is another cpu one + * If yes, queue it to our IPI list and return 1 +@@ -6661,6 +6652,30 @@ static void skb_defer_free_flush(struct softnet_data *sd) + } + } + ++#ifndef CONFIG_PREEMPT_RT ++/* Called from hardirq (IPI) context */ ++static void trigger_rx_softirq(void *data) ++{ ++ struct softnet_data *sd = data; ++ ++ __raise_softirq_irqoff(NET_RX_SOFTIRQ); ++ smp_store_release(&sd->defer_ipi_scheduled, 0); ++} ++ ++#else ++ ++static void trigger_rx_softirq(struct work_struct *defer_work) ++{ ++ struct softnet_data *sd; ++ ++ sd = container_of(defer_work, struct softnet_data, defer_work); ++ smp_store_release(&sd->defer_ipi_scheduled, 0); ++ local_bh_disable(); ++ skb_defer_free_flush(sd); ++ local_bh_enable(); ++} ++#endif ++ + static __latent_entropy void net_rx_action(struct softirq_action *h) + { + struct softnet_data *sd = this_cpu_ptr(&softnet_data); +@@ -10492,12 +10507,12 @@ void dev_fetch_sw_netstats(struct rtnl_link_stats64 *s, + + stats = per_cpu_ptr(netstats, cpu); + do { +- start = u64_stats_fetch_begin_irq(&stats->syncp); ++ start = u64_stats_fetch_begin(&stats->syncp); + rx_packets = u64_stats_read(&stats->rx_packets); + rx_bytes = u64_stats_read(&stats->rx_bytes); + tx_packets = u64_stats_read(&stats->tx_packets); + tx_bytes = u64_stats_read(&stats->tx_bytes); +- } while (u64_stats_fetch_retry_irq(&stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&stats->syncp, start)); + + s->rx_packets += rx_packets; + s->rx_bytes += rx_bytes; +@@ -11412,7 +11427,11 @@ static int __init net_dev_init(void) + INIT_CSD(&sd->csd, rps_trigger_softirq, sd); + sd->cpu = i; + #endif ++#ifndef CONFIG_PREEMPT_RT + INIT_CSD(&sd->defer_csd, trigger_rx_softirq, sd); ++#else ++ INIT_WORK(&sd->defer_work, trigger_rx_softirq); ++#endif + spin_lock_init(&sd->defer_lock); + + init_gro_hash(&sd->backlog); +diff --git a/net/core/devlink.c b/net/core/devlink.c +index b50bcc18b8d9e..cfa6a099457ae 100644 +--- a/net/core/devlink.c ++++ b/net/core/devlink.c +@@ -8268,10 +8268,10 @@ static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats, + + cpu_stats = per_cpu_ptr(trap_stats, i); + do { +- start = u64_stats_fetch_begin_irq(&cpu_stats->syncp); ++ start = u64_stats_fetch_begin(&cpu_stats->syncp); + rx_packets = u64_stats_read(&cpu_stats->rx_packets); + rx_bytes = u64_stats_read(&cpu_stats->rx_bytes); +- } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&cpu_stats->syncp, start)); + + u64_stats_add(&stats->rx_packets, rx_packets); + u64_stats_add(&stats->rx_bytes, rx_bytes); +diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c +index 75501e1bdd25b..dfcaf61d972c7 100644 +--- a/net/core/drop_monitor.c ++++ b/net/core/drop_monitor.c +@@ -1432,9 +1432,9 @@ static void net_dm_stats_read(struct net_dm_stats *stats) + u64 dropped; + + do { +- start = u64_stats_fetch_begin_irq(&cpu_stats->syncp); ++ start = u64_stats_fetch_begin(&cpu_stats->syncp); + dropped = u64_stats_read(&cpu_stats->dropped); +- } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&cpu_stats->syncp, start)); + + u64_stats_add(&stats->dropped, dropped); + } +@@ -1476,9 +1476,9 @@ static void net_dm_hw_stats_read(struct net_dm_stats *stats) + u64 dropped; + + do { +- start = u64_stats_fetch_begin_irq(&cpu_stats->syncp); ++ start = u64_stats_fetch_begin(&cpu_stats->syncp); + dropped = u64_stats_read(&cpu_stats->dropped); +- } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&cpu_stats->syncp, start)); + + u64_stats_add(&stats->dropped, dropped); + } +diff --git a/net/core/gen_stats.c b/net/core/gen_stats.c +index c8d137ef5980e..b71ccaec09914 100644 +--- a/net/core/gen_stats.c ++++ b/net/core/gen_stats.c +@@ -135,10 +135,10 @@ static void gnet_stats_add_basic_cpu(struct gnet_stats_basic_sync *bstats, + u64 bytes, packets; + + do { +- start = u64_stats_fetch_begin_irq(&bcpu->syncp); ++ start = u64_stats_fetch_begin(&bcpu->syncp); + bytes = u64_stats_read(&bcpu->bytes); + packets = u64_stats_read(&bcpu->packets); +- } while (u64_stats_fetch_retry_irq(&bcpu->syncp, start)); ++ } while (u64_stats_fetch_retry(&bcpu->syncp, start)); + + t_bytes += bytes; + t_packets += packets; +@@ -162,10 +162,10 @@ void gnet_stats_add_basic(struct gnet_stats_basic_sync *bstats, + } + do { + if (running) +- start = u64_stats_fetch_begin_irq(&b->syncp); ++ start = u64_stats_fetch_begin(&b->syncp); + bytes = u64_stats_read(&b->bytes); + packets = u64_stats_read(&b->packets); +- } while (running && u64_stats_fetch_retry_irq(&b->syncp, start)); ++ } while (running && u64_stats_fetch_retry(&b->syncp, start)); + + _bstats_update(bstats, bytes, packets); + } +@@ -187,10 +187,10 @@ static void gnet_stats_read_basic(u64 *ret_bytes, u64 *ret_packets, + u64 bytes, packets; + + do { +- start = u64_stats_fetch_begin_irq(&bcpu->syncp); ++ start = u64_stats_fetch_begin(&bcpu->syncp); + bytes = u64_stats_read(&bcpu->bytes); + packets = u64_stats_read(&bcpu->packets); +- } while (u64_stats_fetch_retry_irq(&bcpu->syncp, start)); ++ } while (u64_stats_fetch_retry(&bcpu->syncp, start)); + + t_bytes += bytes; + t_packets += packets; +@@ -201,10 +201,10 @@ static void gnet_stats_read_basic(u64 *ret_bytes, u64 *ret_packets, + } + do { + if (running) +- start = u64_stats_fetch_begin_irq(&b->syncp); ++ start = u64_stats_fetch_begin(&b->syncp); + *ret_bytes = u64_stats_read(&b->bytes); + *ret_packets = u64_stats_read(&b->packets); +- } while (running && u64_stats_fetch_retry_irq(&b->syncp, start)); ++ } while (running && u64_stats_fetch_retry(&b->syncp, start)); + } + + static int +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index 417463da4fac7..505c72a9b1534 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -6555,6 +6555,11 @@ nodefer: __kfree_skb(skb); + /* Make sure to trigger NET_RX_SOFTIRQ on the remote CPU + * if we are unlucky enough (this seems very unlikely). + */ +- if (unlikely(kick) && !cmpxchg(&sd->defer_ipi_scheduled, 0, 1)) ++ if (unlikely(kick) && !cmpxchg(&sd->defer_ipi_scheduled, 0, 1)) { ++#ifndef CONFIG_PREEMPT_RT + smp_call_function_single_async(cpu, &sd->defer_csd); ++#else ++ schedule_work_on(cpu, &sd->defer_work); ++#endif ++ } + } +diff --git a/net/dsa/slave.c b/net/dsa/slave.c +index 1291c2431d440..dcc550b871623 100644 +--- a/net/dsa/slave.c ++++ b/net/dsa/slave.c +@@ -934,12 +934,12 @@ static void dsa_slave_get_ethtool_stats(struct net_device *dev, + + s = per_cpu_ptr(dev->tstats, i); + do { +- start = u64_stats_fetch_begin_irq(&s->syncp); ++ start = u64_stats_fetch_begin(&s->syncp); + tx_packets = u64_stats_read(&s->tx_packets); + tx_bytes = u64_stats_read(&s->tx_bytes); + rx_packets = u64_stats_read(&s->rx_packets); + rx_bytes = u64_stats_read(&s->rx_bytes); +- } while (u64_stats_fetch_retry_irq(&s->syncp, start)); ++ } while (u64_stats_fetch_retry(&s->syncp, start)); + data[0] += tx_packets; + data[1] += tx_bytes; + data[2] += rx_packets; +diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c +index 3ca0cc4678862..dbae0c79d5cfb 100644 +--- a/net/ipv4/af_inet.c ++++ b/net/ipv4/af_inet.c +@@ -1684,9 +1684,9 @@ u64 snmp_get_cpu_field64(void __percpu *mib, int cpu, int offt, + bhptr = per_cpu_ptr(mib, cpu); + syncp = (struct u64_stats_sync *)(bhptr + syncp_offset); + do { +- start = u64_stats_fetch_begin_irq(syncp); ++ start = u64_stats_fetch_begin(syncp); + v = *(((u64 *)bhptr) + offt); +- } while (u64_stats_fetch_retry_irq(syncp, start)); ++ } while (u64_stats_fetch_retry(syncp, start)); + + return v; + } +diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c +index b7de5e46fdd8f..f84da849819cc 100644 +--- a/net/ipv6/seg6_local.c ++++ b/net/ipv6/seg6_local.c +@@ -1508,13 +1508,13 @@ static int put_nla_counters(struct sk_buff *skb, struct seg6_local_lwt *slwt) + + pcounters = per_cpu_ptr(slwt->pcpu_counters, i); + do { +- start = u64_stats_fetch_begin_irq(&pcounters->syncp); ++ start = u64_stats_fetch_begin(&pcounters->syncp); + + packets = u64_stats_read(&pcounters->packets); + bytes = u64_stats_read(&pcounters->bytes); + errors = u64_stats_read(&pcounters->errors); + +- } while (u64_stats_fetch_retry_irq(&pcounters->syncp, start)); ++ } while (u64_stats_fetch_retry(&pcounters->syncp, start)); + + counters.packets += packets; + counters.bytes += bytes; +diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c +index 9d7b238a67372..965b9cb2ef3f2 100644 +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -2316,9 +2316,9 @@ static inline u64 sta_get_tidstats_msdu(struct ieee80211_sta_rx_stats *rxstats, + u64 value; + + do { +- start = u64_stats_fetch_begin_irq(&rxstats->syncp); ++ start = u64_stats_fetch_begin(&rxstats->syncp); + value = rxstats->msdu[tid]; +- } while (u64_stats_fetch_retry_irq(&rxstats->syncp, start)); ++ } while (u64_stats_fetch_retry(&rxstats->syncp, start)); + + return value; + } +@@ -2384,9 +2384,9 @@ static inline u64 sta_get_stats_bytes(struct ieee80211_sta_rx_stats *rxstats) + u64 value; + + do { +- start = u64_stats_fetch_begin_irq(&rxstats->syncp); ++ start = u64_stats_fetch_begin(&rxstats->syncp); + value = rxstats->bytes; +- } while (u64_stats_fetch_retry_irq(&rxstats->syncp, start)); ++ } while (u64_stats_fetch_retry(&rxstats->syncp, start)); + + return value; + } +diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c +index b52afe316dc41..35b5f806fdda1 100644 +--- a/net/mpls/af_mpls.c ++++ b/net/mpls/af_mpls.c +@@ -1079,9 +1079,9 @@ static void mpls_get_stats(struct mpls_dev *mdev, + + p = per_cpu_ptr(mdev->stats, i); + do { +- start = u64_stats_fetch_begin_irq(&p->syncp); ++ start = u64_stats_fetch_begin(&p->syncp); + local = p->stats; +- } while (u64_stats_fetch_retry_irq(&p->syncp, start)); ++ } while (u64_stats_fetch_retry(&p->syncp, start)); + + stats->rx_packets += local.rx_packets; + stats->rx_bytes += local.rx_bytes; +diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c +index efab2b06d3732..5a7349002508e 100644 +--- a/net/netfilter/ipvs/ip_vs_ctl.c ++++ b/net/netfilter/ipvs/ip_vs_ctl.c +@@ -2296,13 +2296,13 @@ static int ip_vs_stats_percpu_show(struct seq_file *seq, void *v) + u64 conns, inpkts, outpkts, inbytes, outbytes; + + do { +- start = u64_stats_fetch_begin_irq(&u->syncp); ++ start = u64_stats_fetch_begin(&u->syncp); + conns = u->cnt.conns; + inpkts = u->cnt.inpkts; + outpkts = u->cnt.outpkts; + inbytes = u->cnt.inbytes; + outbytes = u->cnt.outbytes; +- } while (u64_stats_fetch_retry_irq(&u->syncp, start)); ++ } while (u64_stats_fetch_retry(&u->syncp, start)); + + seq_printf(seq, "%3X %8LX %8LX %8LX %16LX %16LX\n", + i, (u64)conns, (u64)inpkts, +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 63c70141b3e5d..cde0d9f0d838e 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -1534,10 +1534,10 @@ static int nft_dump_stats(struct sk_buff *skb, struct nft_stats __percpu *stats) + for_each_possible_cpu(cpu) { + cpu_stats = per_cpu_ptr(stats, cpu); + do { +- seq = u64_stats_fetch_begin_irq(&cpu_stats->syncp); ++ seq = u64_stats_fetch_begin(&cpu_stats->syncp); + pkts = cpu_stats->pkts; + bytes = cpu_stats->bytes; +- } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, seq)); ++ } while (u64_stats_fetch_retry(&cpu_stats->syncp, seq)); + total.pkts += pkts; + total.bytes += bytes; + } +diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c +index 93c596e3b22b9..b05458c170484 100644 +--- a/net/openvswitch/datapath.c ++++ b/net/openvswitch/datapath.c +@@ -715,9 +715,9 @@ static void get_dp_stats(const struct datapath *dp, struct ovs_dp_stats *stats, + percpu_stats = per_cpu_ptr(dp->stats_percpu, i); + + do { +- start = u64_stats_fetch_begin_irq(&percpu_stats->syncp); ++ start = u64_stats_fetch_begin(&percpu_stats->syncp); + local_stats = *percpu_stats; +- } while (u64_stats_fetch_retry_irq(&percpu_stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&percpu_stats->syncp, start)); + + stats->n_hit += local_stats.n_hit; + stats->n_missed += local_stats.n_missed; +diff --git a/net/openvswitch/flow_table.c b/net/openvswitch/flow_table.c +index d4a2db0b22998..0a0e4c283f02e 100644 +--- a/net/openvswitch/flow_table.c ++++ b/net/openvswitch/flow_table.c +@@ -205,9 +205,9 @@ static void tbl_mask_array_reset_counters(struct mask_array *ma) + + stats = per_cpu_ptr(ma->masks_usage_stats, cpu); + do { +- start = u64_stats_fetch_begin_irq(&stats->syncp); ++ start = u64_stats_fetch_begin(&stats->syncp); + counter = stats->usage_cntrs[i]; +- } while (u64_stats_fetch_retry_irq(&stats->syncp, start)); ++ } while (u64_stats_fetch_retry(&stats->syncp, start)); + + ma->masks_usage_zero_cntr[i] += counter; + } +@@ -1136,10 +1136,9 @@ void ovs_flow_masks_rebalance(struct flow_table *table) + + stats = per_cpu_ptr(ma->masks_usage_stats, cpu); + do { +- start = u64_stats_fetch_begin_irq(&stats->syncp); ++ start = u64_stats_fetch_begin(&stats->syncp); + counter = stats->usage_cntrs[i]; +- } while (u64_stats_fetch_retry_irq(&stats->syncp, +- start)); ++ } while (u64_stats_fetch_retry(&stats->syncp, start)); + + masks_and_count[i].counter += counter; + } diff --git a/packages/lang/Python3/package.mk b/packages/lang/Python3/package.mk index 4b47634a7..bd8b8f3aa 100644 --- a/packages/lang/Python3/package.mk +++ b/packages/lang/Python3/package.mk @@ -3,12 +3,12 @@ PKG_NAME="Python3" # When changing PKG_VERSION remember to sync PKG_PYTHON_VERSION! -PKG_VERSION="3.9.12" -PKG_SHA256="2cd94b20670e4159c6d9ab57f91dbf255b97d8c1a1451d1c35f4ec1968adf971" +PKG_VERSION="3.9.15" +PKG_SHA256="12daff6809528d9f6154216950423c9e30f0e47336cb57c6aa0b4387dd5eb4b2" PKG_LICENSE="OSS" PKG_SITE="https://www.python.org/" PKG_URL="https://www.python.org/ftp/python/${PKG_VERSION}/${PKG_NAME::-1}-${PKG_VERSION}.tar.xz" -PKG_DEPENDS_HOST="zlib:host bzip2:host libffi:host util-linux:host xz:host" +PKG_DEPENDS_HOST="zlib:host bzip2:host libffi:host util-linux:host xz:host autoconf-archive:host" PKG_DEPENDS_TARGET="toolchain Python3:host sqlite expat zlib bzip2 xz openssl libffi readline ncurses util-linux" PKG_LONGDESC="Python3 is an interpreted object-oriented programming language." PKG_TOOLCHAIN="autotools" @@ -75,8 +75,8 @@ PKG_CONFIGURE_OPTS_TARGET="ac_cv_prog_HAS_HG=/bin/false --enable-lib2to3 --disable-idle3 --without-cxx-main - --disable-static - --enable-shared + --disable-static + --enable-shared --with-expat=system --with-libmpdec=none --with-doc-strings diff --git a/packages/lang/Python3/patches/Python3-0401-fix-bpo-46070-2.patch b/packages/lang/Python3/patches/Python3-0401-fix-bpo-46070-2.patch deleted file mode 100644 index 4dae908a0..000000000 --- a/packages/lang/Python3/patches/Python3-0401-fix-bpo-46070-2.patch +++ /dev/null @@ -1,57 +0,0 @@ -From e5d8e72824a34c78552bec74511cb8e5412746c2 Mon Sep 17 00:00:00 2001 -From: Alban Browaeys -Date: Thu, 24 Mar 2022 22:20:41 +0100 -Subject: [PATCH] Revert "bpo-46070: _PyGC_Fini() untracks objects (GH-30577) - (GH-30580)" - -This reverts commit 52937c26adc35350ca0402070160cf6dc838f359. -The above commit segfaults python 3.9.11 if importing sqlite3 in -threads. ---- - Modules/gcmodule.c | 24 ------------------------ - 1 file changed, 24 deletions(-) - -diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c -index 3cf1a00b00..2c6ef9252e 100644 ---- a/Modules/gcmodule.c -+++ b/Modules/gcmodule.c -@@ -2149,36 +2149,12 @@ _PyGC_DumpShutdownStats(PyThreadState *tstate) - } - } - -- --static void --gc_fini_untrack(PyGC_Head *list) --{ -- PyGC_Head *gc; -- for (gc = GC_NEXT(list); gc != list; gc = GC_NEXT(list)) { -- PyObject *op = FROM_GC(gc); -- _PyObject_GC_UNTRACK(op); -- } --} -- -- - void - _PyGC_Fini(PyThreadState *tstate) - { - GCState *gcstate = &tstate->interp->gc; - Py_CLEAR(gcstate->garbage); - Py_CLEAR(gcstate->callbacks); -- -- if (!_Py_IsMainInterpreter(tstate)) { -- // bpo-46070: Explicitly untrack all objects currently tracked by the -- // GC. Otherwise, if an object is used later by another interpreter, -- // calling PyObject_GC_UnTrack() on the object crashs if the previous -- // or the next object of the PyGC_Head structure became a dangling -- // pointer. -- for (int i = 0; i < NUM_GENERATIONS; i++) { -- PyGC_Head *gen = GEN_HEAD(gcstate, i); -- gc_fini_untrack(gen); -- } -- } - } - - /* for debugging */ --- -2.30.2 - diff --git a/packages/lang/dotnet-runtime/changelog.txt b/packages/lang/dotnet-runtime/changelog.txt deleted file mode 100644 index e13b8d5c6..000000000 --- a/packages/lang/dotnet-runtime/changelog.txt +++ /dev/null @@ -1,32 +0,0 @@ -110 -- Update to 3.1.5 - -109 -- Fix x86_64 url - -108 -- Update to 3.1.3 - -107 -- Update to 2.2.6 - -106 -- Update to 2.2.4 - -105 -- Update to 2.2.3 - -104 -- Update to 2.2.0 - -103 -- Update to 2.1.6 - -102 -- Update to 2.1.4 - -101 -- Update to 2.1.3 - -100 -- Initial release diff --git a/packages/lang/dotnet-runtime/icon/icon.png b/packages/lang/dotnet-runtime/icon/icon.png deleted file mode 100644 index 7b53b77cd..000000000 Binary files a/packages/lang/dotnet-runtime/icon/icon.png and /dev/null differ diff --git a/packages/lang/dotnet-runtime/package.mk b/packages/lang/dotnet-runtime/package.mk deleted file mode 100644 index 7a569768b..000000000 --- a/packages/lang/dotnet-runtime/package.mk +++ /dev/null @@ -1,54 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) - -case "$ARCH" in - "aarch64") - PKG_NC_ARCH="arm64" - PKG_SHA256="05875790fbfc487cefb04fc6ff6d9a3ade147f1ae554e859dca60ea6a3c232aa" - PKG_URL="https://download.visualstudio.microsoft.com/download/pr/65291ed8-e931-4605-9d5a-265928a835d0/1a15d18655c8b260170117e9bd1a1cb7/dotnet-runtime-3.1.5-linux-arm64.tar.gz" - ;; - "arm") - PKG_NC_ARCH="arm" - PKG_SHA256="5728786f517410f25c59799f443d0336129d6b1680fd40cb5b40202407949008" - PKG_URL="https://download.visualstudio.microsoft.com/download/pr/15132a5c-f0f4-4373-8b8b-b7e70834d899/cad479dda52359ad43956471274ec932/dotnet-runtime-3.1.5-linux-arm.tar.gz" - ;; - "x86_64") - PKG_NC_ARCH="x64" - PKG_SHA256="ae0a4e9a1e875b46d3201cdad2779572de1c12c0aae36688ae3c3978db319ff5" - PKG_URL="https://download.visualstudio.microsoft.com/download/pr/d00eaeea-6d7b-4e73-9d96-c0234ed3b665/0d25d9d1aeaebdeef01d15370d5cd22b/dotnet-runtime-3.1.5-linux-x64.tar.gz" - ;; -esac - -PKG_NAME="dotnet-runtime" -PKG_VERSION="3.1.5" -PKG_REV="110" -PKG_ARCH="any" -PKG_LICENSE="MIT" -PKG_SITE="https://dotnet.github.io/" -PKG_DEPENDS_TARGET="toolchain curl curl3 krb5 lttng-ust" -PKG_SECTION="tools" -PKG_SHORTDESC=".NET Core Runtime" -PKG_LONGDESC=".NET Core Runtime ($PKG_VERSION) runs applications built with .NET Core, a cross-platform .NET implementation." -PKG_TOOLCHAIN="manual" - -PKG_IS_ADDON="yes" -PKG_ADDON_NAME=".Net Core Runtime" -PKG_ADDON_TYPE="xbmc.python.script" -PKG_MAINTAINER="Anton Voyl (awiouy)" - -addon() { - mkdir -p $ADDON_BUILD/$PKG_ADDON_ID/bin - cp -r $PKG_BUILD/* \ - $ADDON_BUILD/$PKG_ADDON_ID/bin - - mkdir -p $ADDON_BUILD/$PKG_ADDON_ID/libs - cp -L $(get_build_dir curl3)/.install_pkg/usr/lib/libcurl.so.? \ - $(get_build_dir krb5)/.install_pkg/usr/lib/libcom_err.so.? \ - $(get_build_dir krb5)/.install_pkg/usr/lib/libgssapi_krb5.so.? \ - $(get_build_dir krb5)/.install_pkg/usr/lib/libk5crypto.so.? \ - $(get_build_dir krb5)/.install_pkg/usr/lib/libkrb5.so.? \ - $(get_build_dir krb5)/.install_pkg/usr/lib/libkrb5support.so.? \ - $(get_build_dir lttng-ust)/.install_pkg/usr/lib/liblttng-ust.so.? \ - $(get_build_dir lttng-ust)/.install_pkg/usr/lib/liblttng-ust-tracepoint.so.? \ - $ADDON_BUILD/$PKG_ADDON_ID/libs -} diff --git a/packages/lang/dotnet-runtime/source/bin/le_dotnet b/packages/lang/dotnet-runtime/source/bin/le_dotnet deleted file mode 100644 index c5ed97d3c..000000000 --- a/packages/lang/dotnet-runtime/source/bin/le_dotnet +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: GPL-2.0 -# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) - -. /etc/profile -oe_setup_addon tools.dotnet-runtime - -DOTNET_SYSTEM_GLOBALIZATION_INVARIANT="1" \ -LD_LIBRARY_PATH="$ADDON_DIR/libs:$LD_LIBRARY_PATH" \ -dotnet "$@" diff --git a/packages/lang/gcc-aarch64/package.mk b/packages/lang/gcc-aarch64/package.mk new file mode 100644 index 000000000..c5e27e878 --- /dev/null +++ b/packages/lang/gcc-aarch64/package.mk @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="gcc-aarch64" +PKG_VERSION="$(get_pkg_version gcc)" +PKG_LICENSE="GPL-2.0-or-later" +PKG_URL="" +PKG_DEPENDS_HOST="toolchain:host ccache:host autoconf:host binutils-aarch64:host gmp:host mpfr:host mpc:host zstd:host" +PKG_LONGDESC="This package contains the GNU Compiler Collection for 64-bit ARM." +PKG_DEPENDS_UNPACK+=" gcc" +PKG_PATCH_DIRS+=" $(get_pkg_directory gcc)/patches" + +if [ "${MOLD_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_HOST+=" mold:host" +fi + +PKG_CONFIGURE_OPTS_HOST="--target=aarch64-none-elf \ + --with-sysroot=${SYSROOT_PREFIX} \ + --with-gmp=${TOOLCHAIN} \ + --with-mpfr=${TOOLCHAIN} \ + --with-mpc=${TOOLCHAIN} \ + --with-zstd=${TOOLCHAIN} \ + --with-gnu-as \ + --with-gnu-ld \ + --with-newlib \ + --without-ppl \ + --without-headers \ + --without-cloog \ + --enable-__cxa_atexit \ + --enable-checking=release \ + --enable-gold \ + --enable-languages=c \ + --enable-ld=default \ + --enable-lto \ + --enable-plugin \ + --enable-static \ + --disable-decimal-float \ + --disable-gcov \ + --disable-libada \ + --disable-libatomic \ + --disable-libgomp \ + --disable-libitm \ + --disable-libmpx \ + --disable-libmudflap \ + --disable-libquadmath \ + --disable-libquadmath-support \ + --disable-libsanitizer \ + --disable-libssp \ + --disable-multilib \ + --disable-nls \ + --disable-shared \ + --disable-threads" + +unpack() { + mkdir -p ${PKG_BUILD} + tar --strip-components=1 -xf ${SOURCES}/gcc/gcc-${PKG_VERSION}.tar.xz -C ${PKG_BUILD} +} + +post_makeinstall_host() { + PKG_GCC_PREFIX="${TOOLCHAIN}/bin/aarch64-none-elf-" + GCC_VERSION=$(${PKG_GCC_PREFIX}gcc -dumpversion) + DATE="0501$(echo ${GCC_VERSION} | sed 's/\./0/g')" + CROSS_CC=${PKG_GCC_PREFIX}gcc-${GCC_VERSION} + + rm -f ${PKG_GCC_PREFIX}gcc + +cat > ${PKG_GCC_PREFIX}gcc < "${PKG_GCC_PREFIX}gcc" << EOF -#!/bin/sh -${TOOLCHAIN}/bin/ccache ${PKG_GCC_PREFIX}gcc.real "\$@" -EOF - - chmod +x "${PKG_GCC_PREFIX}gcc" - - cp "${PKG_GCC_PREFIX}g++" "${PKG_GCC_PREFIX}g++.real" -cat > "${PKG_GCC_PREFIX}g++" << EOF -#!/bin/sh -${TOOLCHAIN}/bin/ccache ${PKG_GCC_PREFIX}g++.real "\$@" -EOF - - chmod +x "${PKG_GCC_PREFIX}g++" -} diff --git a/packages/lang/gcc-arm-aarch64-none-linux-gnu/package.mk b/packages/lang/gcc-arm-aarch64-none-linux-gnu/package.mk deleted file mode 100644 index 499b6ece9..000000000 --- a/packages/lang/gcc-arm-aarch64-none-linux-gnu/package.mk +++ /dev/null @@ -1,35 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv) - -PKG_NAME="gcc-arm-aarch64-none-linux-gnu" -PKG_VERSION="10.3-2021.07" -PKG_LICENSE="GPL" -PKG_SITE="https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a" -PKG_URL="https://developer.arm.com/-/media/Files/downloads/gnu-a/${PKG_VERSION}/binrel/gcc-arm-${PKG_VERSION}-x86_64-aarch64-none-linux-gnu.tar.xz" -PKG_DEPENDS_HOST="ccache:host" -PKG_LONGDESC="ARM Aarch64 GNU Linux Binary Toolchain" -PKG_TOOLCHAIN="manual" - -makeinstall_host() { - mkdir -p ${TOOLCHAIN}/lib/gcc-arm-aarch64-none-linux-gnu/ - cp -a * ${TOOLCHAIN}/lib/gcc-arm-aarch64-none-linux-gnu - - # wrap gcc and g++ with ccache like in gcc package.mk - PKG_GCC_PREFIX="${TOOLCHAIN}/lib/gcc-arm-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-" - - cp "${PKG_GCC_PREFIX}gcc" "${PKG_GCC_PREFIX}gcc.real" -cat > "${PKG_GCC_PREFIX}gcc" << EOF -#!/bin/sh -${TOOLCHAIN}/bin/ccache ${PKG_GCC_PREFIX}gcc.real "\$@" -EOF - - chmod +x "${PKG_GCC_PREFIX}gcc" - - cp "${PKG_GCC_PREFIX}g++" "${PKG_GCC_PREFIX}g++.real" -cat > "${PKG_GCC_PREFIX}g++" << EOF -#!/bin/sh -${TOOLCHAIN}/bin/ccache ${PKG_GCC_PREFIX}g++.real "\$@" -EOF - - chmod +x "${PKG_GCC_PREFIX}g++" -} diff --git a/packages/lang/gcc-arm-none-eabi/package.mk b/packages/lang/gcc-arm-none-eabi/package.mk new file mode 100644 index 000000000..6344e6201 --- /dev/null +++ b/packages/lang/gcc-arm-none-eabi/package.mk @@ -0,0 +1,76 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="gcc-arm-none-eabi" +PKG_VERSION="$(get_pkg_version gcc)" +PKG_LICENSE="GPL-2.0-or-later" +PKG_URL="" +PKG_DEPENDS_HOST="toolchain:host ccache:host autoconf:host binutils-arm-none-eabi:host gmp:host mpfr:host mpc:host zstd:host" +PKG_LONGDESC="This package contains the GNU Compiler Collection for ARM Cortex-R/M processors." +PKG_DEPENDS_UNPACK+=" gcc" +PKG_PATCH_DIRS+=" $(get_pkg_directory gcc)/patches" + +if [ "${MOLD_SUPPORT}" = "yes" ]; then + PKG_DEPENDS_HOST+=" mold:host" +fi + +PKG_CONFIGURE_OPTS_HOST="--target=arm-none-eabi \ + --with-sysroot=${SYSROOT_PREFIX} \ + --with-gmp=${TOOLCHAIN} \ + --with-mpfr=${TOOLCHAIN} \ + --with-mpc=${TOOLCHAIN} \ + --with-zstd=${TOOLCHAIN} \ + --with-gnu-as \ + --with-gnu-ld \ + --with-newlib \ + --without-ppl \ + --without-headers \ + --without-cloog \ + --enable-__cxa_atexit \ + --enable-checking=release \ + --enable-languages=c \ + --enable-ld=default \ + --enable-lto \ + --enable-plugin \ + --enable-static \ + --disable-decimal-float \ + --disable-gcov \ + --disable-libada \ + --disable-libatomic \ + --disable-libgomp \ + --disable-libitm \ + --disable-libmpx \ + --disable-libmudflap \ + --disable-libquadmath \ + --disable-libquadmath-support \ + --disable-libsanitizer \ + --disable-libssp \ + --disable-multilib \ + --disable-nls \ + --disable-shared \ + --disable-threads" + +unpack() { + mkdir -p ${PKG_BUILD} + tar --strip-components=1 -xf ${SOURCES}/gcc/gcc-${PKG_VERSION}.tar.xz -C ${PKG_BUILD} +} + +post_makeinstall_host() { + PKG_GCC_PREFIX="${TOOLCHAIN}/bin/arm-none-eabi-" + GCC_VERSION=$(${PKG_GCC_PREFIX}gcc -dumpversion) + DATE="0501$(echo ${GCC_VERSION} | sed 's/\./0/g')" + CROSS_CC=${PKG_GCC_PREFIX}gcc-${GCC_VERSION} + + rm -f ${PKG_GCC_PREFIX}gcc + +cat > ${PKG_GCC_PREFIX}gcc < ${PKG_GCC_PREFIX}gcc < ${TARGET_PREFIX}gcc <construct = 0; p->user_supplied_p = user_supplied_p; diff --git a/packages/lang/jre.zulu/changelog.txt b/packages/lang/jre.zulu/changelog.txt deleted file mode 100644 index fe01f1b4f..000000000 --- a/packages/lang/jre.zulu/changelog.txt +++ /dev/null @@ -1,2 +0,0 @@ -100 -- Initial release diff --git a/packages/lang/jre.zulu/icon/icon.png b/packages/lang/jre.zulu/icon/icon.png deleted file mode 100644 index 9ee3a2d9f..000000000 Binary files a/packages/lang/jre.zulu/icon/icon.png and /dev/null differ diff --git a/packages/lang/jre.zulu/package.mk b/packages/lang/jre.zulu/package.mk deleted file mode 100644 index 427a3ae15..000000000 --- a/packages/lang/jre.zulu/package.mk +++ /dev/null @@ -1,42 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later -# Copyright (C) 2019-present Peter Vicman (peter.vicman@gmail.com) - -PKG_NAME="jre.zulu" -PKG_VERSION="1.0" -PKG_REV="100" -PKG_LICENSE="GPL2" -PKG_DEPENDS_TARGET="jdk-${TARGET_ARCH}-zulu jre-libbluray libXext chrome-libXtst chrome-libXi chrome-libXrender jre-libXinerama" -PKG_SECTION="tools" -PKG_SHORTDESC="Java Runtime Environment 8 for Blu-ray Disc Java menus from Azul Systems." -PKG_LONGDESC="$PKG_SHORTDESC" -PKG_TOOLCHAIN="manual" - -PKG_IS_ADDON="yes" -PKG_ADDON_NAME="JRE for BD-J menus" -PKG_ADDON_TYPE="xbmc.python.script" - -# find $1.so.[0-9]* in $2 and copy it to dest -_pkg_copy_lib() { - find "$2" -regextype sed -regex ".*/$1\.so\.[0-9]*" \ - -exec cp {} "$ADDON_BUILD/$PKG_ADDON_ID/lib" \; -} - -addon() { - mkdir -p $ADDON_BUILD/$PKG_ADDON_ID/lib - - cp -a $(get_build_dir jdk-${TARGET_ARCH}-zulu)/jre \ - $(get_build_dir jre-libbluray)/.$TARGET_NAME/.libs/*.jar \ - ${PKG_DIR}/profile.d \ - $ADDON_BUILD/$PKG_ADDON_ID - - # copy required libraries for JRE - _pkg_copy_lib libXtst $(get_build_dir chrome-libXtst)/.$TARGET_NAME/src/.libs - _pkg_copy_lib libXi $(get_build_dir chrome-libXi)/.$TARGET_NAME/src/.libs - _pkg_copy_lib libXrender $(get_build_dir chrome-libXrender)/.$TARGET_NAME/src/.libs - _pkg_copy_lib libXinerama $(get_build_dir jre-libXinerama)/.$TARGET_NAME/src/.libs - - if [ "$TARGET_ARCH" = "arm" ]; then - _pkg_copy_lib libX11 $(get_build_dir libX11)/.$TARGET_NAME/src/.libs - _pkg_copy_lib libXext $(get_build_dir libXext)/.$TARGET_NAME/src/.libs - fi -} diff --git a/packages/lang/jre.zulu/profile.d/jre.profile b/packages/lang/jre.zulu/profile.d/jre.profile deleted file mode 100644 index 21b43a658..000000000 --- a/packages/lang/jre.zulu/profile.d/jre.profile +++ /dev/null @@ -1,8 +0,0 @@ -# point to folder with jre -export JAVA_HOME="/storage/.kodi/addons/tools.jre.zulu" - -# libbluray-*.jar in this folder (need / at the end) -export LIBBLURAY_CP="/storage/.kodi/addons/tools.jre.zulu/" - -# or set file directly -# export LIBBLURAY_CP="/storage/.kodi/addons/tools.jre.zulu/libbluray-j2se-1.0.2.jar" diff --git a/packages/lang/jre.zulu/source/default.py b/packages/lang/jre.zulu/source/default.py deleted file mode 100644 index 60d94ff72..000000000 --- a/packages/lang/jre.zulu/source/default.py +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# Copyright (C) 2019-present Team LibreELEC (https://libreelec.tv) diff --git a/packages/lang/llvm/package.mk b/packages/lang/llvm/package.mk index 5557de475..c1101717b 100644 --- a/packages/lang/llvm/package.mk +++ b/packages/lang/llvm/package.mk @@ -3,8 +3,7 @@ # Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) PKG_NAME="llvm" -PKG_VERSION="14.0.5" -PKG_SHA256="c9d27903ba3883c476a83cd515e36e1e07b0585db55692835de11385d9e3c8fa" +PKG_VERSION="15.0.3" PKG_LICENSE="Apache-2.0" PKG_SITE="http://llvm.org/" PKG_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${PKG_VERSION}/llvm-project-${PKG_VERSION}.src.tar.xz" @@ -14,6 +13,7 @@ PKG_LONGDESC="Low-Level Virtual Machine (LLVM) is a compiler infrastructure." PKG_TOOLCHAIN="cmake" PKG_CMAKE_OPTS_COMMON="-DLLVM_INCLUDE_TOOLS=ON \ + -DCMAKE_BUILD_TYPE=Release \ -DLLVM_BUILD_TOOLS=OFF \ -DLLVM_BUILD_UTILS=OFF \ -DLLVM_BUILD_EXAMPLES=OFF \ diff --git a/packages/lang/lua/config/lua.pc b/packages/lang/lua52/config/lua52.pc similarity index 100% rename from packages/lang/lua/config/lua.pc rename to packages/lang/lua52/config/lua52.pc diff --git a/packages/lang/lua/package.mk b/packages/lang/lua52/package.mk similarity index 65% rename from packages/lang/lua/package.mk rename to packages/lang/lua52/package.mk index 7683eda30..6d3c6ac66 100644 --- a/packages/lang/lua/package.mk +++ b/packages/lang/lua52/package.mk @@ -1,14 +1,14 @@ # SPDX-License-Identifier: GPL-2.0 # Copyright (C) 2022-present Team LibreELEC (https://libreelec.tv) -# Copyright (C) 2022-present Fewtarius -PKG_NAME="lua" -PKG_VERSION="5.4.4" +PKG_NAME="lua52" +PKG_VERSION="5.2.4" +PKG_SHA256="b9e2e4aad6789b3b63a056d442f7b39f0ecfca3ae0f1fc0ae4e9614401b69f4b" PKG_LICENSE="MIT" PKG_SITE="https://www.lua.org" -PKG_URL="http://www.lua.org/ftp/${PKG_NAME}-${PKG_VERSION}.tar.gz" +PKG_URL="http://www.lua.org/ftp/lua-${PKG_VERSION}.tar.gz" PKG_DEPENDS_TARGET="toolchain" -PKG_LONGDESC="A powerful, efficient, lightweight, embeddable scripting language." +PKG_LONGDESC="Lua is a powerful, efficient, lightweight, embeddable scripting language." make_target() { make CC=${CC} AR="${AR} rcu" posix @@ -22,8 +22,8 @@ makeinstall_target() { cp src/liblua.a ${SYSROOT_PREFIX}/usr/lib/liblua$(get_pkg_version_maj_min).a mkdir -p ${SYSROOT_PREFIX}/usr/lib/pkgconfig - cp ${PKG_DIR}/config/lua.pc ${SYSROOT_PREFIX}/usr/lib/pkgconfig + cp ${PKG_DIR}/config/lua52.pc ${SYSROOT_PREFIX}/usr/lib/pkgconfig sed -e "s/@@VERSION@@/${PKG_VERSION}/g" \ -e "s/@@VERSION_MM@@/$(get_pkg_version_maj_min)/g" \ - -i ${SYSROOT_PREFIX}/usr/lib/pkgconfig/lua.pc + -i ${SYSROOT_PREFIX}/usr/lib/pkgconfig/lua52.pc } diff --git a/packages/lang/lua54/config/lua54.pc b/packages/lang/lua54/config/lua54.pc new file mode 100644 index 000000000..6645003e6 --- /dev/null +++ b/packages/lang/lua54/config/lua54.pc @@ -0,0 +1,10 @@ +prefix=/usr +libdir=${prefix}/lib +includedir=${prefix}/include/lua@@VERSION_MM@@ + +Name: Lua +Description: An Extensible Extension Language +Version: @@VERSION@@ +Requires: +Libs: -L${libdir} -llua@@VERSION_MM@@ -lm +Cflags: -I${includedir} diff --git a/packages/lang/lua54/package.mk b/packages/lang/lua54/package.mk new file mode 100644 index 000000000..8c9472706 --- /dev/null +++ b/packages/lang/lua54/package.mk @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2022-present Team LibreELEC (https://libreelec.tv) + +PKG_NAME="lua54" +PKG_VERSION="5.4.4" +PKG_SHA256="164c7849653b80ae67bec4b7473b884bf5cc8d2dca05653475ec2ed27b9ebf61" +PKG_LICENSE="MIT" +PKG_SITE="https://www.lua.org" +PKG_URL="http://www.lua.org/ftp/lua-${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain" +PKG_LONGDESC="Lua is a powerful, efficient, lightweight, embeddable scripting language." + +make_target() { + make CC=${CC} AR="${AR} rcu" MYCFLAGS="-fPIC" posix +} + +makeinstall_target() { + mkdir -p ${SYSROOT_PREFIX}/usr/include/lua$(get_pkg_version_maj_min) + cp src/lua.h src/luaconf.h src/lualib.h src/lauxlib.h ${SYSROOT_PREFIX}/usr/include/lua$(get_pkg_version_maj_min) + + mkdir -p ${SYSROOT_PREFIX}/usr/lib + cp src/liblua.a ${SYSROOT_PREFIX}/usr/lib/liblua$(get_pkg_version_maj_min).a + + mkdir -p ${SYSROOT_PREFIX}/usr/lib/pkgconfig + cp ${PKG_DIR}/config/lua54.pc ${SYSROOT_PREFIX}/usr/lib/pkgconfig + sed -e "s/@@VERSION@@/${PKG_VERSION}/g" \ + -e "s/@@VERSION_MM@@/$(get_pkg_version_maj_min)/g" \ + -i ${SYSROOT_PREFIX}/usr/lib/pkgconfig/lua54.pc +} diff --git a/packages/lang/mono/package.mk b/packages/lang/mono/package.mk deleted file mode 100644 index 9bba439ac..000000000 --- a/packages/lang/mono/package.mk +++ /dev/null @@ -1,25 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# Copyright (C) 2019-present Team LibreELEC (https://libreelec.tv) - -PKG_NAME="mono" -PKG_VERSION="1.0" -PKG_REV="100" -PKG_ARCH="any" -PKG_LICENSE="GPL" -PKG_SITE="" -PKG_URL="" -PKG_DEPENDS_TARGET="toolchain" -PKG_SECTION="tools" -PKG_SHORTDESC="Add-on removed" -PKG_LONGDESC="Add-on removed" -PKG_TOOLCHAIN="manual" - -PKG_ADDON_BROKEN="Mono is no longer maintained and has been removed." - -PKG_IS_ADDON="yes" -PKG_ADDON_NAME="Mono" -PKG_ADDON_TYPE="xbmc.broken" - -addon() { - : -} diff --git a/packages/multimedia/ffmpeg/package.mk b/packages/multimedia/ffmpeg/package.mk index eb57d2b9d..3f3fca430 100644 --- a/packages/multimedia/ffmpeg/package.mk +++ b/packages/multimedia/ffmpeg/package.mk @@ -5,31 +5,13 @@ PKG_NAME="ffmpeg" PKG_LICENSE="LGPLv2.1+" PKG_SITE="https://ffmpeg.org" -PKG_DEPENDS_TARGET="toolchain zlib bzip2 gnutls speex" +PKG_DEPENDS_TARGET="toolchain zlib bzip2 openssl speex gnutls" PKG_LONGDESC="FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video." -PKG_BUILD_FLAGS="-gold" -case "${PROJECT}" in - Amlogic) - PKG_VERSION="0e5290bcac015e52f6a65dafaf41ea125816257f" # dev/4.4/rpi_import_1 - PKG_SHA256="4bd6e56920b90429bc09e43cda554f5bb9125c4ac090b4331fc459bb709eea68" - PKG_URL="https://github.com/jc-kynesim/rpi-ffmpeg/archive/${PKG_VERSION}.tar.gz" - PKG_PATCH_DIRS="libreelec" - ;; - RPi) - PKG_VERSION="4.4-N-Alpha1" - PKG_SHA256="eb396f46ef7c5ac01b67818d0f2c0516fd4ab32aa9065a9ffa71eebede67ff20" - PKG_URL="https://github.com/xbmc/FFmpeg/archive/${PKG_VERSION}.tar.gz" - PKG_FFMPEG_RPI="--disable-mmal --disable-rpi --enable-sand" - PKG_PATCH_DIRS="libreelec rpi" - ;; - *) - PKG_VERSION="4.4-N-Alpha1" - PKG_SHA256="eb396f46ef7c5ac01b67818d0f2c0516fd4ab32aa9065a9ffa71eebede67ff20" - PKG_URL="https://github.com/xbmc/FFmpeg/archive/${PKG_VERSION}.tar.gz" - PKG_PATCH_DIRS="libreelec v4l2-request v4l2-drmprime" - ;; -esac +PKG_VERSION="4.4.1-Nexus-Alpha1" +PKG_SHA256="abbce62231baffe237e412689c71ffe01bfc83135afd375f1e538caae87729ed" +PKG_URL="https://github.com/xbmc/FFmpeg/archive/${PKG_VERSION}.tar.gz" +PKG_PATCH_DIRS="libreelec v4l2-request v4l2-drmprime" # Dependencies get_graphicdrivers @@ -120,6 +102,8 @@ if [ "${FFMPEG_TESTING}" = "yes" ]; then if [ "${PROJECT}" = "RPi" ]; then PKG_FFMPEG_TESTING+=" --enable-vout-drm --enable-outdev=vout_drm" fi +else + PKG_FFMPEG_TESTING="--disable-programs" fi configure_target() { @@ -145,7 +129,7 @@ configure_target() { --disable-static \ --enable-shared \ --enable-gpl \ - --disable-version3 \ + --enable-version3 \ --enable-logging \ --disable-doc \ ${PKG_FFMPEG_DEBUG} \ diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-support-dav1d-1-0-0.patch b/packages/multimedia/ffmpeg/patches/dav1d/ffmpeg-support-dav1d-1-0-0.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-support-dav1d-1-0-0.patch rename to packages/multimedia/ffmpeg/patches/dav1d/ffmpeg-support-dav1d-1-0-0.patch diff --git a/packages/multimedia/ffmpeg/patches/rpi/ffmpeg-001-rpi.patch b/packages/multimedia/ffmpeg/patches/rpi/ffmpeg-001-rpi.patch index 6809d2178..5e46eb726 100644 --- a/packages/multimedia/ffmpeg/patches/rpi/ffmpeg-001-rpi.patch +++ b/packages/multimedia/ffmpeg/patches/rpi/ffmpeg-001-rpi.patch @@ -1,5 +1,5 @@ diff --git a/configure b/configure -index d7a3f507e8..9b7435ec79 100755 +index d7a3f507e8..7c2dd7161c 100755 --- a/configure +++ b/configure @@ -207,6 +207,7 @@ External library support: @@ -57,7 +57,7 @@ index d7a3f507e8..9b7435ec79 100755 " DOCUMENT_LIST=" -@@ -1884,12 +1896,16 @@ FEATURE_LIST=" +@@ -1884,12 +1896,17 @@ FEATURE_LIST=" gray hardcoded_tables omx_rpi @@ -71,10 +71,11 @@ index d7a3f507e8..9b7435ec79 100755 swscale_alpha + vout_drm + vout_egl ++ v4l2_req_hevc_vx " # this list should be kept in linking order -@@ -1930,6 +1946,7 @@ SUBSYSTEM_LIST=" +@@ -1930,6 +1947,7 @@ SUBSYSTEM_LIST=" pixelutils network rdft @@ -82,7 +83,7 @@ index d7a3f507e8..9b7435ec79 100755 " # COMPONENT_LIST needs to come last to ensure correct dependency checking -@@ -2416,9 +2433,11 @@ CONFIG_EXTRA=" +@@ -2416,9 +2434,11 @@ CONFIG_EXTRA=" rangecoder riffdec riffenc @@ -94,7 +95,7 @@ index d7a3f507e8..9b7435ec79 100755 scene_sad sinewin snappy -@@ -2750,6 +2769,8 @@ hap_decoder_select="snappy texturedsp" +@@ -2750,6 +2770,8 @@ hap_decoder_select="snappy texturedsp" hap_encoder_deps="libsnappy" hap_encoder_select="texturedspenc" hevc_decoder_select="atsc_a53 bswapdsp cabac golomb hevcparse videodsp" @@ -103,7 +104,7 @@ index d7a3f507e8..9b7435ec79 100755 huffyuv_decoder_select="bswapdsp huffyuvdsp llviddsp" huffyuv_encoder_select="bswapdsp huffman huffyuvencdsp llvidencdsp" hymt_decoder_select="huffyuv_decoder" -@@ -2919,6 +2940,7 @@ d3d11va_deps="dxva_h ID3D11VideoDecoder ID3D11VideoContext" +@@ -2919,6 +2941,7 @@ d3d11va_deps="dxva_h ID3D11VideoDecoder ID3D11VideoContext" dxva2_deps="dxva2api_h DXVA2_ConfigPictureDecode ole32 user32" ffnvcodec_deps_any="libdl LoadLibrary" nvdec_deps="ffnvcodec" @@ -111,7 +112,7 @@ index d7a3f507e8..9b7435ec79 100755 vaapi_x11_deps="xlib" videotoolbox_hwaccel_deps="videotoolbox pthreads" videotoolbox_hwaccel_extralibs="-framework QuartzCore" -@@ -2960,6 +2982,12 @@ hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC" +@@ -2960,6 +2983,12 @@ hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC" hevc_dxva2_hwaccel_select="hevc_decoder" hevc_nvdec_hwaccel_deps="nvdec" hevc_nvdec_hwaccel_select="hevc_decoder" @@ -124,7 +125,7 @@ index d7a3f507e8..9b7435ec79 100755 hevc_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferHEVC" hevc_vaapi_hwaccel_select="hevc_decoder" hevc_vdpau_hwaccel_deps="vdpau VdpPictureInfoHEVC" -@@ -3437,8 +3465,13 @@ sndio_indev_deps="sndio" +@@ -3437,8 +3466,13 @@ sndio_indev_deps="sndio" sndio_outdev_deps="sndio" v4l2_indev_deps_any="linux_videodev2_h sys_videoio_h" v4l2_indev_suggest="libv4l2" @@ -138,7 +139,7 @@ index d7a3f507e8..9b7435ec79 100755 vfwcap_indev_deps="vfw32 vfwcap_defines" xcbgrab_indev_deps="libxcb" xcbgrab_indev_suggest="libxcb_shm libxcb_shape libxcb_xfixes" -@@ -3657,6 +3690,7 @@ tonemap_vaapi_filter_deps="vaapi VAProcFilterParameterBufferHDRToneMapping" +@@ -3657,6 +3691,7 @@ tonemap_vaapi_filter_deps="vaapi VAProcFilterParameterBufferHDRToneMapping" tonemap_opencl_filter_deps="opencl const_nan" transpose_opencl_filter_deps="opencl" transpose_vaapi_filter_deps="vaapi VAProcPipelineCaps_rotation_flags" @@ -146,7 +147,7 @@ index d7a3f507e8..9b7435ec79 100755 unsharp_opencl_filter_deps="opencl" uspp_filter_deps="gpl avcodec" vaguedenoiser_filter_deps="gpl" -@@ -6154,6 +6188,12 @@ check_func_headers glob.h glob +@@ -6154,6 +6189,12 @@ check_func_headers glob.h glob enabled xlib && check_lib xlib "X11/Xlib.h X11/extensions/Xvlib.h" XvGetPortAttribute -lXv -lX11 -lXext @@ -159,7 +160,7 @@ index d7a3f507e8..9b7435ec79 100755 check_headers direct.h check_headers dirent.h check_headers dxgidebug.h -@@ -6491,11 +6531,12 @@ enabled mbedtls && { check_pkg_config mbedtls mbedtls mbedtls/x509_crt +@@ -6491,11 +6532,12 @@ enabled mbedtls && { check_pkg_config mbedtls mbedtls mbedtls/x509_crt check_lib mbedtls mbedtls/ssl.h mbedtls_ssl_init -lmbedtls -lmbedx509 -lmbedcrypto || die "ERROR: mbedTLS not found"; } enabled mediacodec && { enabled jni || die "ERROR: mediacodec requires --enable-jni"; } @@ -174,7 +175,7 @@ index d7a3f507e8..9b7435ec79 100755 die "ERROR: mmal not found" && check_func_headers interface/mmal/mmal.h "MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS"; } enabled openal && { { for al_extralibs in "${OPENAL_LIBS}" "-lopenal" "-lOpenAL32"; do -@@ -6536,8 +6577,16 @@ enabled rkmpp && { require_pkg_config rkmpp rockchip_mpp rockchip/r +@@ -6536,8 +6578,16 @@ enabled rkmpp && { require_pkg_config rkmpp rockchip_mpp rockchip/r { enabled libdrm || die "ERROR: rkmpp requires --enable-libdrm"; } } @@ -191,12 +192,20 @@ index d7a3f507e8..9b7435ec79 100755 if enabled gcrypt; then GCRYPT_CONFIG="${cross_prefix}libgcrypt-config" -@@ -6617,6 +6666,8 @@ if enabled v4l2_m2m; then +@@ -6617,6 +6667,16 @@ if enabled v4l2_m2m; then check_cc vp9_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VP9;" fi +check_func_headers "linux/media.h linux/videodev2.h" v4l2_timeval_to_ns +check_cc hevc_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_HEVC_SLICE;" ++disable v4l2_req_hevc_vx ++if enabled hevc_v4l2request_hwaccel; then ++ enable v4l2_req_hevc_vx ++fi ++if enabled hevc_v4l2_request; then ++ disable v4l2_req_hevc_vx ++fi ++ check_headers sys/videoio.h test_code cc sys/videoio.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_sanitized struct_v4l2_frmivalenum_discrete @@ -375,7 +384,7 @@ index 807e783422..456d4f349b 100644 "write program-readable progress information", "url" }, { "stdin", OPT_BOOL | OPT_EXPERT, { &stdin_interaction }, diff --git a/libavcodec/Makefile b/libavcodec/Makefile -index 33a280cf69..ef22d26dc1 100644 +index 33a280cf69..1372d3981d 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -19,6 +19,7 @@ HEADERS = ac3_parser.h \ @@ -427,8 +436,8 @@ index 33a280cf69..ef22d26dc1 100644 OBJS-$(CONFIG_HEVC_QSV_HWACCEL) += qsvdec.o +OBJS-$(CONFIG_HEVC_RPI4_8_HWACCEL) += rpivid_hevc.o +OBJS-$(CONFIG_HEVC_RPI4_10_HWACCEL) += rpivid_hevc.o -+OBJS-$(CONFIG_HEVC_V4L2REQUEST_HWACCEL) += v4l2_request_hevc.o v4l2_req_decode_q.o\ -+ v4l2_req_hevc_v1.o v4l2_req_hevc_v2.o v4l2_req_hevc_v3.o ++OBJS-$(CONFIG_HEVC_V4L2REQUEST_HWACCEL) += v4l2_request_hevc.o v4l2_req_decode_q.o v4l2_req_hevc_v4.o ++OBJS-$(CONFIG_V4L2_REQ_HEVC_VX) += v4l2_req_hevc_v1.o v4l2_req_hevc_v2.o v4l2_req_hevc_v3.o OBJS-$(CONFIG_HEVC_VAAPI_HWACCEL) += vaapi_hevc.o h265_profile_level.o OBJS-$(CONFIG_HEVC_VDPAU_HWACCEL) += vdpau_hevc.o h265_profile_level.o OBJS-$(CONFIG_MJPEG_NVDEC_HWACCEL) += nvdec_mjpeg.o @@ -465,19 +474,10 @@ index 33a280cf69..ef22d26dc1 100644 +$(SUBDIR)rpi_hevcdec.o $(SUBDIR)rpi_shader_template.o $(SUBDIR)rpi_qpu.o: $(SUBDIR)rpi_hevc_shader.h +endif diff --git a/libavcodec/aarch64/Makefile b/libavcodec/aarch64/Makefile -index 954461f81d..7078dc6089 100644 +index 954461f81d..c8935f205e 100644 --- a/libavcodec/aarch64/Makefile +++ b/libavcodec/aarch64/Makefile -@@ -35,6 +35,8 @@ ARMV8-OBJS-$(CONFIG_VIDEODSP) += aarch64/videodsp.o - - # subsystems - NEON-OBJS-$(CONFIG_AAC_DECODER) += aarch64/sbrdsp_neon.o -+NEON-OBJS-$(CONFIG_BLOCKDSP) += aarch64/blockdsp_init_aarch64.o \ -+ aarch64/blockdsp_neon.o - NEON-OBJS-$(CONFIG_FFT) += aarch64/fft_neon.o - NEON-OBJS-$(CONFIG_FMTCONVERT) += aarch64/fmtconvert_neon.o - NEON-OBJS-$(CONFIG_H264CHROMA) += aarch64/h264cmc_neon.o -@@ -44,10 +46,12 @@ NEON-OBJS-$(CONFIG_H264PRED) += aarch64/h264pred_neon.o +@@ -44,10 +44,12 @@ NEON-OBJS-$(CONFIG_H264PRED) += aarch64/h264pred_neon.o NEON-OBJS-$(CONFIG_H264QPEL) += aarch64/h264qpel_neon.o \ aarch64/hpeldsp_neon.o NEON-OBJS-$(CONFIG_HPELDSP) += aarch64/hpeldsp_neon.o @@ -491,103 +491,6 @@ index 954461f81d..7078dc6089 100644 NEON-OBJS-$(CONFIG_VP8DSP) += aarch64/vp8dsp_neon.o # decoders/encoders -diff --git a/libavcodec/aarch64/blockdsp_init_aarch64.c b/libavcodec/aarch64/blockdsp_init_aarch64.c -new file mode 100644 -index 0000000000..9f3280f007 ---- /dev/null -+++ b/libavcodec/aarch64/blockdsp_init_aarch64.c -@@ -0,0 +1,42 @@ -+/* -+ * AArch64 NEON optimised block operations -+ * -+ * Copyright (c) 2022 Ben Avison -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#include -+ -+#include "libavutil/attributes.h" -+#include "libavutil/cpu.h" -+#include "libavutil/arm/cpu.h" -+#include "libavcodec/avcodec.h" -+#include "libavcodec/blockdsp.h" -+ -+void ff_clear_block_neon(int16_t *block); -+void ff_clear_blocks_neon(int16_t *blocks); -+ -+av_cold void ff_blockdsp_init_aarch64(BlockDSPContext *c) -+{ -+ int cpu_flags = av_get_cpu_flags(); -+ -+ if (have_neon(cpu_flags)) { -+ c->clear_block = ff_clear_block_neon; -+ c->clear_blocks = ff_clear_blocks_neon; -+ } -+} -diff --git a/libavcodec/aarch64/blockdsp_neon.S b/libavcodec/aarch64/blockdsp_neon.S -new file mode 100644 -index 0000000000..e4a4959ccc ---- /dev/null -+++ b/libavcodec/aarch64/blockdsp_neon.S -@@ -0,0 +1,43 @@ -+/* -+ * AArch64 NEON optimised block operations -+ * -+ * Copyright (c) 2022 Ben Avison -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#include "libavutil/aarch64/asm.S" -+ -+function ff_clear_block_neon, export=1 -+ movi v0.16b, #0 -+ movi v1.16b, #0 -+ st1 {v0.16b, v1.16b}, [x0], #32 -+ st1 {v0.16b, v1.16b}, [x0], #32 -+ st1 {v0.16b, v1.16b}, [x0], #32 -+ st1 {v0.16b, v1.16b}, [x0] -+ ret -+endfunc -+ -+function ff_clear_blocks_neon, export=1 -+ movi v0.16b, #0 -+ movi v1.16b, #0 -+ .rept 23 -+ st1 {v0.16b, v1.16b}, [x0], #32 -+ .endr -+ st1 {v0.16b, v1.16b}, [x0] -+ ret -+endfunc diff --git a/libavcodec/aarch64/idctdsp_init_aarch64.c b/libavcodec/aarch64/idctdsp_init_aarch64.c index 742a3372e3..eec21aa5a2 100644 --- a/libavcodec/aarch64/idctdsp_init_aarch64.c @@ -767,7 +670,7 @@ index 0000000000..7f47611206 + ret +endfunc diff --git a/libavcodec/aarch64/vc1dsp_init_aarch64.c b/libavcodec/aarch64/vc1dsp_init_aarch64.c -index 13dfd74940..161d5a972b 100644 +index 13dfd74940..a7976fd596 100644 --- a/libavcodec/aarch64/vc1dsp_init_aarch64.c +++ b/libavcodec/aarch64/vc1dsp_init_aarch64.c @@ -21,10 +21,28 @@ @@ -789,12 +692,12 @@ index 13dfd74940..161d5a972b 100644 +void ff_vc1_inv_trans_4x8_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t *block); +void ff_vc1_inv_trans_4x4_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t *block); + -+void ff_vc1_v_loop_filter4_neon(uint8_t *src, int stride, int pq); -+void ff_vc1_h_loop_filter4_neon(uint8_t *src, int stride, int pq); -+void ff_vc1_v_loop_filter8_neon(uint8_t *src, int stride, int pq); -+void ff_vc1_h_loop_filter8_neon(uint8_t *src, int stride, int pq); -+void ff_vc1_v_loop_filter16_neon(uint8_t *src, int stride, int pq); -+void ff_vc1_h_loop_filter16_neon(uint8_t *src, int stride, int pq); ++void ff_vc1_v_loop_filter4_neon(uint8_t *src, ptrdiff_t stride, int pq); ++void ff_vc1_h_loop_filter4_neon(uint8_t *src, ptrdiff_t stride, int pq); ++void ff_vc1_v_loop_filter8_neon(uint8_t *src, ptrdiff_t stride, int pq); ++void ff_vc1_h_loop_filter8_neon(uint8_t *src, ptrdiff_t stride, int pq); ++void ff_vc1_v_loop_filter16_neon(uint8_t *src, ptrdiff_t stride, int pq); ++void ff_vc1_h_loop_filter16_neon(uint8_t *src, ptrdiff_t stride, int pq); + void ff_put_vc1_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y); @@ -892,10 +795,10 @@ index 13dfd74940..161d5a972b 100644 } diff --git a/libavcodec/aarch64/vc1dsp_neon.S b/libavcodec/aarch64/vc1dsp_neon.S new file mode 100644 -index 0000000000..529c21d285 +index 0000000000..9a96c2523c --- /dev/null +++ b/libavcodec/aarch64/vc1dsp_neon.S -@@ -0,0 +1,1552 @@ +@@ -0,0 +1,1546 @@ +/* + * VC1 AArch64 NEON optimisations + * @@ -1605,11 +1508,10 @@ index 0000000000..529c21d285 +// VC-1 in-loop deblocking filter for 4 pixel pairs at boundary of vertically-neighbouring blocks +// On entry: +// x0 -> top-left pel of lower block -+// w1 = row stride, bytes ++// x1 = row stride, bytes +// w2 = PQUANT bitstream parameter +function ff_vc1_v_loop_filter4_neon, export=1 + sub x3, x0, w1, sxtw #2 -+ sxtw x1, w1 // technically, stride is signed int + ldr d0, .Lcoeffs + ld1 {v1.s}[0], [x0], x1 // P5 + ld1 {v2.s}[0], [x3], x1 // P1 @@ -1678,11 +1580,10 @@ index 0000000000..529c21d285 +// VC-1 in-loop deblocking filter for 4 pixel pairs at boundary of horizontally-neighbouring blocks +// On entry: +// x0 -> top-left pel of right block -+// w1 = row stride, bytes ++// x1 = row stride, bytes +// w2 = PQUANT bitstream parameter +function ff_vc1_h_loop_filter4_neon, export=1 + sub x3, x0, #4 // where to start reading -+ sxtw x1, w1 // technically, stride is signed int + ldr d0, .Lcoeffs + ld1 {v1.8b}, [x3], x1 + sub x0, x0, #1 // where to start writing @@ -1752,11 +1653,10 @@ index 0000000000..529c21d285 +// VC-1 in-loop deblocking filter for 8 pixel pairs at boundary of vertically-neighbouring blocks +// On entry: +// x0 -> top-left pel of lower block -+// w1 = row stride, bytes ++// x1 = row stride, bytes +// w2 = PQUANT bitstream parameter +function ff_vc1_v_loop_filter8_neon, export=1 + sub x3, x0, w1, sxtw #2 -+ sxtw x1, w1 // technically, stride is signed int + ldr d0, .Lcoeffs + ld1 {v1.8b}, [x0], x1 // P5 + movi v2.2d, #0x0000ffff00000000 @@ -1830,11 +1730,10 @@ index 0000000000..529c21d285 +// VC-1 in-loop deblocking filter for 8 pixel pairs at boundary of horizontally-neighbouring blocks +// On entry: +// x0 -> top-left pel of right block -+// w1 = row stride, bytes ++// x1 = row stride, bytes +// w2 = PQUANT bitstream parameter +function ff_vc1_h_loop_filter8_neon, export=1 + sub x3, x0, #4 // where to start reading -+ sxtw x1, w1 // technically, stride is signed int + ldr d0, .Lcoeffs + ld1 {v1.8b}, [x3], x1 // P1[0], P2[0]... + sub x0, x0, #1 // where to start writing @@ -1939,11 +1838,10 @@ index 0000000000..529c21d285 +// VC-1 in-loop deblocking filter for 16 pixel pairs at boundary of vertically-neighbouring blocks +// On entry: +// x0 -> top-left pel of lower block -+// w1 = row stride, bytes ++// x1 = row stride, bytes +// w2 = PQUANT bitstream parameter +function ff_vc1_v_loop_filter16_neon, export=1 + sub x3, x0, w1, sxtw #2 -+ sxtw x1, w1 // technically, stride is signed int + ldr d0, .Lcoeffs + ld1 {v1.16b}, [x0], x1 // P5 + movi v2.2d, #0x0000ffff00000000 @@ -2071,11 +1969,10 @@ index 0000000000..529c21d285 +// VC-1 in-loop deblocking filter for 16 pixel pairs at boundary of horizontally-neighbouring blocks +// On entry: +// x0 -> top-left pel of right block -+// w1 = row stride, bytes ++// x1 = row stride, bytes +// w2 = PQUANT bitstream parameter +function ff_vc1_h_loop_filter16_neon, export=1 + sub x3, x0, #4 // where to start reading -+ sxtw x1, w1 // technically, stride is signed int + ldr d0, .Lcoeffs + ld1 {v1.8b}, [x3], x1 // P1[0], P2[0]... + sub x0, x0, #1 // where to start writing @@ -17404,7 +17301,7 @@ index 2cca784f5a..48cb816b70 100644 + dsp->vc1_unescape_buffer = vc1_unescape_buffer_neon; } diff --git a/libavcodec/arm/vc1dsp_neon.S b/libavcodec/arm/vc1dsp_neon.S -index 93f043bf08..8e97bc5e58 100644 +index 93f043bf08..96014fbebc 100644 --- a/libavcodec/arm/vc1dsp_neon.S +++ b/libavcodec/arm/vc1dsp_neon.S @@ -1161,3 +1161,764 @@ function ff_vc1_inv_trans_4x4_dc_neon, export=1 @@ -17560,17 +17457,17 @@ index 93f043bf08..8e97bc5e58 100644 +function ff_vc1_v_loop_filter8_neon, export=1 + sub r3, r0, r1, lsl #2 + vldr d0, .Lcoeffs -+ vld1.32 {d1}, [r0], r1 @ P5 -+ vld1.32 {d2}, [r3], r1 @ P1 -+ vld1.32 {d3}, [r3], r1 @ P2 -+ vld1.32 {d4}, [r0], r1 @ P6 -+ vld1.32 {d5}, [r3], r1 @ P3 -+ vld1.32 {d6}, [r0], r1 @ P7 ++ vld1.32 {d1}, [r0 :64], r1 @ P5 ++ vld1.32 {d2}, [r3 :64], r1 @ P1 ++ vld1.32 {d3}, [r3 :64], r1 @ P2 ++ vld1.32 {d4}, [r0 :64], r1 @ P6 ++ vld1.32 {d5}, [r3 :64], r1 @ P3 ++ vld1.32 {d6}, [r0 :64], r1 @ P7 + vshll.u8 q8, d1, #1 @ 2*P5 + vshll.u8 q9, d2, #1 @ 2*P1 -+ vld1.32 {d7}, [r3] @ P4 ++ vld1.32 {d7}, [r3 :64] @ P4 + vmovl.u8 q1, d3 @ P2 -+ vld1.32 {d20}, [r0] @ P8 ++ vld1.32 {d20}, [r0 :64] @ P8 + vmovl.u8 q11, d4 @ P6 + vdup.16 q12, r2 @ pq + vmovl.u8 q13, d5 @ P3 @@ -17625,8 +17522,8 @@ index 93f043bf08..8e97bc5e58 100644 + vmla.i16 q1, q0, q2 @ invert d depending on clip_sign & a0_sign, or zero it if they match, and accumulate into P5 + vqmovun.s16 d0, q3 + vqmovun.s16 d1, q1 -+ vst1.32 {d0}, [r3], r1 -+ vst1.32 {d1}, [r3] ++ vst1.32 {d0}, [r3 :64], r1 ++ vst1.32 {d1}, [r3 :64] +1: bx lr +endfunc + @@ -17741,17 +17638,17 @@ index 93f043bf08..8e97bc5e58 100644 + vpush {d8-d15} + sub r3, r0, r1, lsl #2 + vldr d0, .Lcoeffs -+ vld1.64 {q1}, [r0], r1 @ P5 -+ vld1.64 {q2}, [r3], r1 @ P1 -+ vld1.64 {q3}, [r3], r1 @ P2 -+ vld1.64 {q4}, [r0], r1 @ P6 -+ vld1.64 {q5}, [r3], r1 @ P3 -+ vld1.64 {q6}, [r0], r1 @ P7 ++ vld1.64 {q1}, [r0 :128], r1 @ P5 ++ vld1.64 {q2}, [r3 :128], r1 @ P1 ++ vld1.64 {q3}, [r3 :128], r1 @ P2 ++ vld1.64 {q4}, [r0 :128], r1 @ P6 ++ vld1.64 {q5}, [r3 :128], r1 @ P3 ++ vld1.64 {q6}, [r0 :128], r1 @ P7 + vshll.u8 q7, d2, #1 @ 2*P5[0..7] + vshll.u8 q8, d4, #1 @ 2*P1[0..7] -+ vld1.64 {q9}, [r3] @ P4 ++ vld1.64 {q9}, [r3 :128] @ P4 + vmovl.u8 q10, d6 @ P2[0..7] -+ vld1.64 {q11}, [r0] @ P8 ++ vld1.64 {q11}, [r0 :128] @ P8 + vmovl.u8 q12, d8 @ P6[0..7] + vdup.16 q13, r2 @ pq + vshll.u8 q2, d5, #1 @ 2*P1[8..15] @@ -17861,8 +17758,8 @@ index 93f043bf08..8e97bc5e58 100644 + vqmovun.s16 d0, q6 + vqmovun.s16 d5, q9 + vqmovun.s16 d1, q1 -+ vst1.64 {q2}, [r3], r1 -+ vst1.64 {q0}, [r3] ++ vst1.64 {q2}, [r3 :128], r1 ++ vst1.64 {q0}, [r3 :128] +1: vpop {d8-d15} + bx lr +endfunc @@ -18194,31 +18091,6 @@ index 8a71c04230..53644506e5 100644 } AVHWAccel; /** -diff --git a/libavcodec/blockdsp.c b/libavcodec/blockdsp.c -index c7efe7e77b..46766244b8 100644 ---- a/libavcodec/blockdsp.c -+++ b/libavcodec/blockdsp.c -@@ -65,6 +65,8 @@ av_cold void ff_blockdsp_init(BlockDSPContext *c, AVCodecContext *avctx) - c->fill_block_tab[0] = fill_block16_c; - c->fill_block_tab[1] = fill_block8_c; - -+ if (ARCH_AARCH64) -+ ff_blockdsp_init_aarch64(c); - if (ARCH_ALPHA) - ff_blockdsp_init_alpha(c); - if (ARCH_ARM) -diff --git a/libavcodec/blockdsp.h b/libavcodec/blockdsp.h -index 26fc2ea13b..fe539491da 100644 ---- a/libavcodec/blockdsp.h -+++ b/libavcodec/blockdsp.h -@@ -41,6 +41,7 @@ typedef struct BlockDSPContext { - - void ff_blockdsp_init(BlockDSPContext *c, AVCodecContext *avctx); - -+void ff_blockdsp_init_aarch64(BlockDSPContext *c); - void ff_blockdsp_init_alpha(BlockDSPContext *c); - void ff_blockdsp_init_arm(BlockDSPContext *c); - void ff_blockdsp_init_ppc(BlockDSPContext *c); diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h index 38d06b2842..bbf5d70560 100644 --- a/libavcodec/cabac.h @@ -19015,6 +18887,536 @@ index 0000000000..4e35bd583d +#define V4L2_CID_HANTRO_HEVC_SLICE_HEADER_SKIP (V4L2_CID_CODEC_HANTRO_BASE + 0) + +#endif +diff --git a/libavcodec/hevc-ctrls-v4.h b/libavcodec/hevc-ctrls-v4.h +new file mode 100644 +index 0000000000..c02fdbe5a8 +--- /dev/null ++++ b/libavcodec/hevc-ctrls-v4.h +@@ -0,0 +1,524 @@ ++/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) */ ++/* ++ * Video for Linux Two controls header file ++ * ++ * Copyright (C) 1999-2012 the contributors ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Alternatively you can redistribute this file under the terms of the ++ * BSD license as stated below: ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * 3. The names of its contributors may not be used to endorse or promote ++ * products derived from this software without specific prior written ++ * permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED ++ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * The contents of this header was split off from videodev2.h. All control ++ * definitions should be added to this header, which is included by ++ * videodev2.h. ++ */ ++ ++#ifndef AVCODEC_HEVC_CTRLS_V4_H ++#define AVCODEC_HEVC_CTRLS_V4_H ++ ++#include ++#include ++ ++#ifndef V4L2_CTRL_CLASS_CODEC_STATELESS ++#define V4L2_CTRL_CLASS_CODEC_STATELESS 0x00a40000 /* Stateless codecs controls */ ++#endif ++#ifndef V4L2_CID_CODEC_STATELESS_BASE ++#define V4L2_CID_CODEC_STATELESS_BASE (V4L2_CTRL_CLASS_CODEC_STATELESS | 0x900) ++#endif ++ ++#define V4L2_PIX_FMT_HEVC_SLICE v4l2_fourcc('S', '2', '6', '5') /* HEVC parsed slices */ ++ ++#define V4L2_CID_STATELESS_HEVC_SPS (V4L2_CID_CODEC_STATELESS_BASE + 400) ++#define V4L2_CID_STATELESS_HEVC_PPS (V4L2_CID_CODEC_STATELESS_BASE + 401) ++#define V4L2_CID_STATELESS_HEVC_SLICE_PARAMS (V4L2_CID_CODEC_STATELESS_BASE + 402) ++#define V4L2_CID_STATELESS_HEVC_SCALING_MATRIX (V4L2_CID_CODEC_STATELESS_BASE + 403) ++#define V4L2_CID_STATELESS_HEVC_DECODE_PARAMS (V4L2_CID_CODEC_STATELESS_BASE + 404) ++#define V4L2_CID_STATELESS_HEVC_DECODE_MODE (V4L2_CID_CODEC_STATELESS_BASE + 405) ++#define V4L2_CID_STATELESS_HEVC_START_CODE (V4L2_CID_CODEC_STATELESS_BASE + 406) ++#define V4L2_CID_STATELESS_HEVC_ENTRY_POINT_OFFSETS (V4L2_CID_CODEC_STATELESS_BASE + 407) ++ ++enum v4l2_stateless_hevc_decode_mode { ++ V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED, ++ V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED, ++}; ++ ++enum v4l2_stateless_hevc_start_code { ++ V4L2_STATELESS_HEVC_START_CODE_NONE, ++ V4L2_STATELESS_HEVC_START_CODE_ANNEX_B, ++}; ++ ++#define V4L2_HEVC_SLICE_TYPE_B 0 ++#define V4L2_HEVC_SLICE_TYPE_P 1 ++#define V4L2_HEVC_SLICE_TYPE_I 2 ++ ++#define V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE (1ULL << 0) ++#define V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED (1ULL << 1) ++#define V4L2_HEVC_SPS_FLAG_AMP_ENABLED (1ULL << 2) ++#define V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET (1ULL << 3) ++#define V4L2_HEVC_SPS_FLAG_PCM_ENABLED (1ULL << 4) ++#define V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED (1ULL << 5) ++#define V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT (1ULL << 6) ++#define V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED (1ULL << 7) ++#define V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED (1ULL << 8) ++ ++/** ++ * struct v4l2_ctrl_hevc_sps - ITU-T Rec. H.265: Sequence parameter set ++ * ++ * @video_parameter_set_id: specifies the value of the ++ * vps_video_parameter_set_id of the active VPS ++ * @seq_parameter_set_id: provides an identifier for the SPS for ++ * reference by other syntax elements ++ * @pic_width_in_luma_samples: specifies the width of each decoded picture ++ * in units of luma samples ++ * @pic_height_in_luma_samples: specifies the height of each decoded picture ++ * in units of luma samples ++ * @bit_depth_luma_minus8: this value plus 8specifies the bit depth of the ++ * samples of the luma array ++ * @bit_depth_chroma_minus8: this value plus 8 specifies the bit depth of the ++ * samples of the chroma arrays ++ * @log2_max_pic_order_cnt_lsb_minus4: this value plus 4 specifies the value of ++ * the variable MaxPicOrderCntLsb ++ * @sps_max_dec_pic_buffering_minus1: this value plus 1 specifies the maximum ++ * required size of the decoded picture ++ * buffer for the codec video sequence ++ * @sps_max_num_reorder_pics: indicates the maximum allowed number of pictures ++ * @sps_max_latency_increase_plus1: not equal to 0 is used to compute the ++ * value of SpsMaxLatencyPictures array ++ * @log2_min_luma_coding_block_size_minus3: plus 3 specifies the minimum ++ * luma coding block size ++ * @log2_diff_max_min_luma_coding_block_size: specifies the difference between ++ * the maximum and minimum luma ++ * coding block size ++ * @log2_min_luma_transform_block_size_minus2: plus 2 specifies the minimum luma ++ * transform block size ++ * @log2_diff_max_min_luma_transform_block_size: specifies the difference between ++ * the maximum and minimum luma ++ * transform block size ++ * @max_transform_hierarchy_depth_inter: specifies the maximum hierarchy ++ * depth for transform units of ++ * coding units coded in inter ++ * prediction mode ++ * @max_transform_hierarchy_depth_intra: specifies the maximum hierarchy ++ * depth for transform units of ++ * coding units coded in intra ++ * prediction mode ++ * @pcm_sample_bit_depth_luma_minus1: this value plus 1 specifies the number of ++ * bits used to represent each of PCM sample ++ * values of the luma component ++ * @pcm_sample_bit_depth_chroma_minus1: this value plus 1 specifies the number ++ * of bits used to represent each of PCM ++ * sample values of the chroma components ++ * @log2_min_pcm_luma_coding_block_size_minus3: this value plus 3 specifies the ++ * minimum size of coding blocks ++ * @log2_diff_max_min_pcm_luma_coding_block_size: specifies the difference between ++ * the maximum and minimum size of ++ * coding blocks ++ * @num_short_term_ref_pic_sets: specifies the number of st_ref_pic_set() ++ * syntax structures included in the SPS ++ * @num_long_term_ref_pics_sps: specifies the number of candidate long-term ++ * reference pictures that are specified in the SPS ++ * @chroma_format_idc: specifies the chroma sampling ++ * @sps_max_sub_layers_minus1: this value plus 1 specifies the maximum number ++ * of temporal sub-layers ++ * @reserved: padding field. Should be zeroed by applications. ++ * @flags: see V4L2_HEVC_SPS_FLAG_{} ++ */ ++struct v4l2_ctrl_hevc_sps { ++ __u8 video_parameter_set_id; ++ __u8 seq_parameter_set_id; ++ __u16 pic_width_in_luma_samples; ++ __u16 pic_height_in_luma_samples; ++ __u8 bit_depth_luma_minus8; ++ __u8 bit_depth_chroma_minus8; ++ __u8 log2_max_pic_order_cnt_lsb_minus4; ++ __u8 sps_max_dec_pic_buffering_minus1; ++ __u8 sps_max_num_reorder_pics; ++ __u8 sps_max_latency_increase_plus1; ++ __u8 log2_min_luma_coding_block_size_minus3; ++ __u8 log2_diff_max_min_luma_coding_block_size; ++ __u8 log2_min_luma_transform_block_size_minus2; ++ __u8 log2_diff_max_min_luma_transform_block_size; ++ __u8 max_transform_hierarchy_depth_inter; ++ __u8 max_transform_hierarchy_depth_intra; ++ __u8 pcm_sample_bit_depth_luma_minus1; ++ __u8 pcm_sample_bit_depth_chroma_minus1; ++ __u8 log2_min_pcm_luma_coding_block_size_minus3; ++ __u8 log2_diff_max_min_pcm_luma_coding_block_size; ++ __u8 num_short_term_ref_pic_sets; ++ __u8 num_long_term_ref_pics_sps; ++ __u8 chroma_format_idc; ++ __u8 sps_max_sub_layers_minus1; ++ ++ __u8 reserved[6]; ++ __u64 flags; ++}; ++ ++#define V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT_ENABLED (1ULL << 0) ++#define V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT (1ULL << 1) ++#define V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED (1ULL << 2) ++#define V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT (1ULL << 3) ++#define V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED (1ULL << 4) ++#define V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED (1ULL << 5) ++#define V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED (1ULL << 6) ++#define V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT (1ULL << 7) ++#define V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED (1ULL << 8) ++#define V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED (1ULL << 9) ++#define V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED (1ULL << 10) ++#define V4L2_HEVC_PPS_FLAG_TILES_ENABLED (1ULL << 11) ++#define V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED (1ULL << 12) ++#define V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED (1ULL << 13) ++#define V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED (1ULL << 14) ++#define V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_OVERRIDE_ENABLED (1ULL << 15) ++#define V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER (1ULL << 16) ++#define V4L2_HEVC_PPS_FLAG_LISTS_MODIFICATION_PRESENT (1ULL << 17) ++#define V4L2_HEVC_PPS_FLAG_SLICE_SEGMENT_HEADER_EXTENSION_PRESENT (1ULL << 18) ++#define V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT (1ULL << 19) ++#define V4L2_HEVC_PPS_FLAG_UNIFORM_SPACING (1ULL << 20) ++ ++/** ++ * struct v4l2_ctrl_hevc_pps - ITU-T Rec. H.265: Picture parameter set ++ * ++ * @pic_parameter_set_id: identifies the PPS for reference by other ++ * syntax elements ++ * @num_extra_slice_header_bits: specifies the number of extra slice header ++ * bits that are present in the slice header RBSP ++ * for coded pictures referring to the PPS. ++ * @num_ref_idx_l0_default_active_minus1: this value plus 1 specifies the ++ * inferred value of num_ref_idx_l0_active_minus1 ++ * @num_ref_idx_l1_default_active_minus1: this value plus 1 specifies the ++ * inferred value of num_ref_idx_l1_active_minus1 ++ * @init_qp_minus26: this value plus 26 specifies the initial value of SliceQp Y for ++ * each slice referring to the PPS ++ * @diff_cu_qp_delta_depth: specifies the difference between the luma coding ++ * tree block size and the minimum luma coding block ++ * size of coding units that convey cu_qp_delta_abs ++ * and cu_qp_delta_sign_flag ++ * @pps_cb_qp_offset: specify the offsets to the luma quantization parameter Cb ++ * @pps_cr_qp_offset: specify the offsets to the luma quantization parameter Cr ++ * @num_tile_columns_minus1: this value plus 1 specifies the number of tile columns ++ * partitioning the picture ++ * @num_tile_rows_minus1: this value plus 1 specifies the number of tile rows partitioning ++ * the picture ++ * @column_width_minus1: this value plus 1 specifies the width of the each tile column in ++ * units of coding tree blocks ++ * @row_height_minus1: this value plus 1 specifies the height of the each tile row in ++ * units of coding tree blocks ++ * @pps_beta_offset_div2: specify the default deblocking parameter offsets for ++ * beta divided by 2 ++ * @pps_tc_offset_div2: specify the default deblocking parameter offsets for tC ++ * divided by 2 ++ * @log2_parallel_merge_level_minus2: this value plus 2 specifies the value of ++ * the variable Log2ParMrgLevel ++ * @reserved: padding field. Should be zeroed by applications. ++ * @flags: see V4L2_HEVC_PPS_FLAG_{} ++ */ ++struct v4l2_ctrl_hevc_pps { ++ __u8 pic_parameter_set_id; ++ __u8 num_extra_slice_header_bits; ++ __u8 num_ref_idx_l0_default_active_minus1; ++ __u8 num_ref_idx_l1_default_active_minus1; ++ __s8 init_qp_minus26; ++ __u8 diff_cu_qp_delta_depth; ++ __s8 pps_cb_qp_offset; ++ __s8 pps_cr_qp_offset; ++ __u8 num_tile_columns_minus1; ++ __u8 num_tile_rows_minus1; ++ __u8 column_width_minus1[20]; ++ __u8 row_height_minus1[22]; ++ __s8 pps_beta_offset_div2; ++ __s8 pps_tc_offset_div2; ++ __u8 log2_parallel_merge_level_minus2; ++ __u8 reserved; ++ __u64 flags; ++}; ++ ++#define V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE 0x01 ++ ++#define V4L2_HEVC_SEI_PIC_STRUCT_FRAME 0 ++#define V4L2_HEVC_SEI_PIC_STRUCT_TOP_FIELD 1 ++#define V4L2_HEVC_SEI_PIC_STRUCT_BOTTOM_FIELD 2 ++#define V4L2_HEVC_SEI_PIC_STRUCT_TOP_BOTTOM 3 ++#define V4L2_HEVC_SEI_PIC_STRUCT_BOTTOM_TOP 4 ++#define V4L2_HEVC_SEI_PIC_STRUCT_TOP_BOTTOM_TOP 5 ++#define V4L2_HEVC_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM 6 ++#define V4L2_HEVC_SEI_PIC_STRUCT_FRAME_DOUBLING 7 ++#define V4L2_HEVC_SEI_PIC_STRUCT_FRAME_TRIPLING 8 ++#define V4L2_HEVC_SEI_PIC_STRUCT_TOP_PAIRED_PREVIOUS_BOTTOM 9 ++#define V4L2_HEVC_SEI_PIC_STRUCT_BOTTOM_PAIRED_PREVIOUS_TOP 10 ++#define V4L2_HEVC_SEI_PIC_STRUCT_TOP_PAIRED_NEXT_BOTTOM 11 ++#define V4L2_HEVC_SEI_PIC_STRUCT_BOTTOM_PAIRED_NEXT_TOP 12 ++ ++#define V4L2_HEVC_DPB_ENTRIES_NUM_MAX 16 ++ ++/** ++ * struct v4l2_hevc_dpb_entry - HEVC decoded picture buffer entry ++ * ++ * @timestamp: timestamp of the V4L2 capture buffer to use as reference. ++ * @flags: long term flag for the reference frame ++ * @field_pic: whether the reference is a field picture or a frame. ++ * @reserved: padding field. Should be zeroed by applications. ++ * @pic_order_cnt_val: the picture order count of the current picture. ++ */ ++struct v4l2_hevc_dpb_entry { ++ __u64 timestamp; ++ __u8 flags; ++ __u8 field_pic; ++ __u16 reserved; ++ __s32 pic_order_cnt_val; ++}; ++ ++/** ++ * struct v4l2_hevc_pred_weight_table - HEVC weighted prediction parameters ++ * ++ * @delta_luma_weight_l0: the difference of the weighting factor applied ++ * to the luma prediction value for list 0 ++ * @luma_offset_l0: the additive offset applied to the luma prediction value ++ * for list 0 ++ * @delta_chroma_weight_l0: the difference of the weighting factor applied ++ * to the chroma prediction values for list 0 ++ * @chroma_offset_l0: the difference of the additive offset applied to ++ * the chroma prediction values for list 0 ++ * @delta_luma_weight_l1: the difference of the weighting factor applied ++ * to the luma prediction value for list 1 ++ * @luma_offset_l1: the additive offset applied to the luma prediction value ++ * for list 1 ++ * @delta_chroma_weight_l1: the difference of the weighting factor applied ++ * to the chroma prediction values for list 1 ++ * @chroma_offset_l1: the difference of the additive offset applied to ++ * the chroma prediction values for list 1 ++ * @luma_log2_weight_denom: the base 2 logarithm of the denominator for ++ * all luma weighting factors ++ * @delta_chroma_log2_weight_denom: the difference of the base 2 logarithm ++ * of the denominator for all chroma ++ * weighting factors ++ */ ++struct v4l2_hevc_pred_weight_table { ++ __s8 delta_luma_weight_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; ++ __s8 luma_offset_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; ++ __s8 delta_chroma_weight_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]; ++ __s8 chroma_offset_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]; ++ ++ __s8 delta_luma_weight_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; ++ __s8 luma_offset_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; ++ __s8 delta_chroma_weight_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]; ++ __s8 chroma_offset_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]; ++ ++ __u8 luma_log2_weight_denom; ++ __s8 delta_chroma_log2_weight_denom; ++}; ++ ++#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_LUMA (1ULL << 0) ++#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_CHROMA (1ULL << 1) ++#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_TEMPORAL_MVP_ENABLED (1ULL << 2) ++#define V4L2_HEVC_SLICE_PARAMS_FLAG_MVD_L1_ZERO (1ULL << 3) ++#define V4L2_HEVC_SLICE_PARAMS_FLAG_CABAC_INIT (1ULL << 4) ++#define V4L2_HEVC_SLICE_PARAMS_FLAG_COLLOCATED_FROM_L0 (1ULL << 5) ++#define V4L2_HEVC_SLICE_PARAMS_FLAG_USE_INTEGER_MV (1ULL << 6) ++#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED (1ULL << 7) ++#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED (1ULL << 8) ++#define V4L2_HEVC_SLICE_PARAMS_FLAG_DEPENDENT_SLICE_SEGMENT (1ULL << 9) ++ ++/** ++ * struct v4l2_ctrl_hevc_slice_params - HEVC slice parameters ++ * ++ * This control is a dynamically sized 1-dimensional array, ++ * V4L2_CTRL_FLAG_DYNAMIC_ARRAY flag must be set when using it. ++ * ++ * @bit_size: size (in bits) of the current slice data ++ * @data_byte_offset: offset (in bytes) to the video data in the current slice data ++ * @num_entry_point_offsets: specifies the number of entry point offset syntax ++ * elements in the slice header. ++ * @nal_unit_type: specifies the coding type of the slice (B, P or I) ++ * @nuh_temporal_id_plus1: minus 1 specifies a temporal identifier for the NAL unit ++ * @slice_type: see V4L2_HEVC_SLICE_TYPE_{} ++ * @colour_plane_id: specifies the colour plane associated with the current slice ++ * @slice_pic_order_cnt: specifies the picture order count ++ * @num_ref_idx_l0_active_minus1: this value plus 1 specifies the maximum ++ * reference index for reference picture list 0 ++ * that may be used to decode the slice ++ * @num_ref_idx_l1_active_minus1: this value plus 1 specifies the maximum ++ * reference index for reference picture list 1 ++ * that may be used to decode the slice ++ * @collocated_ref_idx: specifies the reference index of the collocated picture used ++ * for temporal motion vector prediction ++ * @five_minus_max_num_merge_cand: specifies the maximum number of merging ++ * motion vector prediction candidates supported in ++ * the slice subtracted from 5 ++ * @slice_qp_delta: specifies the initial value of QpY to be used for the coding ++ * blocks in the slice ++ * @slice_cb_qp_offset: specifies a difference to be added to the value of pps_cb_qp_offset ++ * @slice_cr_qp_offset: specifies a difference to be added to the value of pps_cr_qp_offset ++ * @slice_act_y_qp_offset: screen content extension parameters ++ * @slice_act_cb_qp_offset: screen content extension parameters ++ * @slice_act_cr_qp_offset: screen content extension parameters ++ * @slice_beta_offset_div2: specify the deblocking parameter offsets for beta divided by 2 ++ * @slice_tc_offset_div2: specify the deblocking parameter offsets for tC divided by 2 ++ * @pic_struct: indicates whether a picture should be displayed as a frame or as one or ++ * more fields ++ * @reserved0: padding field. Should be zeroed by applications. ++ * @slice_segment_addr: specifies the address of the first coding tree block in ++ * the slice segment ++ * @ref_idx_l0: the list of L0 reference elements as indices in the DPB ++ * @ref_idx_l1: the list of L1 reference elements as indices in the DPB ++ * @short_term_ref_pic_set_size: specifies the size of short-term reference ++ * pictures set included in the SPS ++ * @long_term_ref_pic_set_size: specifies the size of long-term reference ++ * pictures set include in the SPS ++ * @pred_weight_table: the prediction weight coefficients for inter-picture ++ * prediction ++ * @reserved1: padding field. Should be zeroed by applications. ++ * @flags: see V4L2_HEVC_SLICE_PARAMS_FLAG_{} ++ */ ++struct v4l2_ctrl_hevc_slice_params { ++ __u32 bit_size; ++ __u32 data_byte_offset; ++ __u32 num_entry_point_offsets; ++ ++ /* ISO/IEC 23008-2, ITU-T Rec. H.265: NAL unit header */ ++ __u8 nal_unit_type; ++ __u8 nuh_temporal_id_plus1; ++ ++ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ ++ __u8 slice_type; ++ __u8 colour_plane_id; ++ __s32 slice_pic_order_cnt; ++ __u8 num_ref_idx_l0_active_minus1; ++ __u8 num_ref_idx_l1_active_minus1; ++ __u8 collocated_ref_idx; ++ __u8 five_minus_max_num_merge_cand; ++ __s8 slice_qp_delta; ++ __s8 slice_cb_qp_offset; ++ __s8 slice_cr_qp_offset; ++ __s8 slice_act_y_qp_offset; ++ __s8 slice_act_cb_qp_offset; ++ __s8 slice_act_cr_qp_offset; ++ __s8 slice_beta_offset_div2; ++ __s8 slice_tc_offset_div2; ++ ++ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture timing SEI message */ ++ __u8 pic_struct; ++ ++ __u8 reserved0[3]; ++ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ ++ __u32 slice_segment_addr; ++ __u8 ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; ++ __u8 ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; ++ __u16 short_term_ref_pic_set_size; ++ __u16 long_term_ref_pic_set_size; ++ ++ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Weighted prediction parameter */ ++ struct v4l2_hevc_pred_weight_table pred_weight_table; ++ ++ __u8 reserved1[2]; ++ __u64 flags; ++}; ++ ++#define V4L2_HEVC_DECODE_PARAM_FLAG_IRAP_PIC 0x1 ++#define V4L2_HEVC_DECODE_PARAM_FLAG_IDR_PIC 0x2 ++#define V4L2_HEVC_DECODE_PARAM_FLAG_NO_OUTPUT_OF_PRIOR 0x4 ++ ++/** ++ * struct v4l2_ctrl_hevc_decode_params - HEVC decode parameters ++ * ++ * @pic_order_cnt_val: picture order count ++ * @short_term_ref_pic_set_size: specifies the size of short-term reference ++ * pictures set included in the SPS of the first slice ++ * @long_term_ref_pic_set_size: specifies the size of long-term reference ++ * pictures set include in the SPS of the first slice ++ * @num_active_dpb_entries: the number of entries in dpb ++ * @num_poc_st_curr_before: the number of reference pictures in the short-term ++ * set that come before the current frame ++ * @num_poc_st_curr_after: the number of reference pictures in the short-term ++ * set that come after the current frame ++ * @num_poc_lt_curr: the number of reference pictures in the long-term set ++ * @poc_st_curr_before: provides the index of the short term before references ++ * in DPB array ++ * @poc_st_curr_after: provides the index of the short term after references ++ * in DPB array ++ * @poc_lt_curr: provides the index of the long term references in DPB array ++ * @reserved: padding field. Should be zeroed by applications. ++ * @dpb: the decoded picture buffer, for meta-data about reference frames ++ * @flags: see V4L2_HEVC_DECODE_PARAM_FLAG_{} ++ */ ++struct v4l2_ctrl_hevc_decode_params { ++ __s32 pic_order_cnt_val; ++ __u16 short_term_ref_pic_set_size; ++ __u16 long_term_ref_pic_set_size; ++ __u8 num_active_dpb_entries; ++ __u8 num_poc_st_curr_before; ++ __u8 num_poc_st_curr_after; ++ __u8 num_poc_lt_curr; ++ __u8 poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; ++ __u8 poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; ++ __u8 poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; ++ __u8 reserved[4]; ++ struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; ++ __u64 flags; ++}; ++ ++/** ++ * struct v4l2_ctrl_hevc_scaling_matrix - HEVC scaling lists parameters ++ * ++ * @scaling_list_4x4: scaling list is used for the scaling process for ++ * transform coefficients. The values on each scaling ++ * list are expected in raster scan order ++ * @scaling_list_8x8: scaling list is used for the scaling process for ++ * transform coefficients. The values on each scaling ++ * list are expected in raster scan order ++ * @scaling_list_16x16: scaling list is used for the scaling process for ++ * transform coefficients. The values on each scaling ++ * list are expected in raster scan order ++ * @scaling_list_32x32: scaling list is used for the scaling process for ++ * transform coefficients. The values on each scaling ++ * list are expected in raster scan order ++ * @scaling_list_dc_coef_16x16: scaling list is used for the scaling process ++ * for transform coefficients. The values on each ++ * scaling list are expected in raster scan order. ++ * @scaling_list_dc_coef_32x32: scaling list is used for the scaling process ++ * for transform coefficients. The values on each ++ * scaling list are expected in raster scan order. ++ */ ++struct v4l2_ctrl_hevc_scaling_matrix { ++ __u8 scaling_list_4x4[6][16]; ++ __u8 scaling_list_8x8[6][64]; ++ __u8 scaling_list_16x16[6][64]; ++ __u8 scaling_list_32x32[2][64]; ++ __u8 scaling_list_dc_coef_16x16[6]; ++ __u8 scaling_list_dc_coef_32x32[2]; ++}; ++ ++#endif diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c index 463d352055..7feff43c28 100644 --- a/libavcodec/hevc_parser.c @@ -19039,8 +19441,67 @@ index 463d352055..7feff43c28 100644 if (ps->vps->vps_timing_info_present_flag) { num = ps->vps->vps_num_units_in_tick; den = ps->vps->vps_time_scale; +diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c +index 4f6d985ae6..eefae71275 100644 +--- a/libavcodec/hevc_refs.c ++++ b/libavcodec/hevc_refs.c +@@ -96,18 +96,22 @@ static HEVCFrame *alloc_frame(HEVCContext *s) + if (!frame->rpl_buf) + goto fail; + +- frame->tab_mvf_buf = av_buffer_pool_get(s->tab_mvf_pool); +- if (!frame->tab_mvf_buf) +- goto fail; +- frame->tab_mvf = (MvField *)frame->tab_mvf_buf->data; ++ if (s->tab_mvf_pool) { ++ frame->tab_mvf_buf = av_buffer_pool_get(s->tab_mvf_pool); ++ if (!frame->tab_mvf_buf) ++ goto fail; ++ frame->tab_mvf = (MvField *)frame->tab_mvf_buf->data; ++ } + +- frame->rpl_tab_buf = av_buffer_pool_get(s->rpl_tab_pool); +- if (!frame->rpl_tab_buf) +- goto fail; +- frame->rpl_tab = (RefPicListTab **)frame->rpl_tab_buf->data; +- frame->ctb_count = s->ps.sps->ctb_width * s->ps.sps->ctb_height; +- for (j = 0; j < frame->ctb_count; j++) +- frame->rpl_tab[j] = (RefPicListTab *)frame->rpl_buf->data; ++ if (s->rpl_tab_pool) { ++ frame->rpl_tab_buf = av_buffer_pool_get(s->rpl_tab_pool); ++ if (!frame->rpl_tab_buf) ++ goto fail; ++ frame->rpl_tab = (RefPicListTab **)frame->rpl_tab_buf->data; ++ frame->ctb_count = s->ps.sps->ctb_width * s->ps.sps->ctb_height; ++ for (j = 0; j < frame->ctb_count; j++) ++ frame->rpl_tab[j] = (RefPicListTab *)frame->rpl_buf->data; ++ } + + frame->frame->top_field_first = s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD; + frame->frame->interlaced_frame = (s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD) || (s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_BOTTOM_FIELD); +@@ -276,14 +280,17 @@ static int init_slice_rpl(HEVCContext *s) + int ctb_count = frame->ctb_count; + int ctb_addr_ts = s->ps.pps->ctb_addr_rs_to_ts[s->sh.slice_segment_addr]; + int i; ++ RefPicListTab * const tab = (RefPicListTab *)frame->rpl_buf->data + s->slice_idx; + + if (s->slice_idx >= frame->rpl_buf->size / sizeof(RefPicListTab)) + return AVERROR_INVALIDDATA; + +- for (i = ctb_addr_ts; i < ctb_count; i++) +- frame->rpl_tab[i] = (RefPicListTab *)frame->rpl_buf->data + s->slice_idx; ++ if (frame->rpl_tab) { ++ for (i = ctb_addr_ts; i < ctb_count; i++) ++ frame->rpl_tab[i] = tab; ++ } + +- frame->refPicList = (RefPicList *)frame->rpl_tab[ctb_addr_ts]; ++ frame->refPicList = tab->refPicList; + + return 0; + } diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c -index 2231aed259..6d2d66dfdf 100644 +index 2231aed259..7b05b41441 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -333,6 +333,19 @@ static void export_stream_params(HEVCContext *s, const HEVCSPS *sps) @@ -19110,7 +19571,43 @@ index 2231aed259..6d2d66dfdf 100644 #endif break; case AV_PIX_FMT_YUV444P: -@@ -3327,7 +3355,14 @@ static int hevc_decode_frame(AVCodecContext *avctx, void *data, int *got_output, +@@ -485,6 +513,16 @@ static int set_sps(HEVCContext *s, const HEVCSPS *sps, + if (!sps) + return 0; + ++ // If hwaccel then we don't need all the s/w decode helper arrays ++ if (s->avctx->hwaccel) { ++ export_stream_params(s, sps); ++ ++ s->avctx->pix_fmt = pix_fmt; ++ s->ps.sps = sps; ++ s->ps.vps = (HEVCVPS*) s->ps.vps_list[s->ps.sps->vps_id]->data; ++ return 0; ++ } ++ + ret = pic_arrays_init(s, sps); + if (ret < 0) + goto fail; +@@ -2901,11 +2939,13 @@ static int hevc_frame_start(HEVCContext *s) + ((s->ps.sps->height >> s->ps.sps->log2_min_cb_size) + 1); + int ret; + +- memset(s->horizontal_bs, 0, s->bs_width * s->bs_height); +- memset(s->vertical_bs, 0, s->bs_width * s->bs_height); +- memset(s->cbf_luma, 0, s->ps.sps->min_tb_width * s->ps.sps->min_tb_height); +- memset(s->is_pcm, 0, (s->ps.sps->min_pu_width + 1) * (s->ps.sps->min_pu_height + 1)); +- memset(s->tab_slice_address, -1, pic_size_in_ctb * sizeof(*s->tab_slice_address)); ++ if (s->horizontal_bs) { ++ memset(s->horizontal_bs, 0, s->bs_width * s->bs_height); ++ memset(s->vertical_bs, 0, s->bs_width * s->bs_height); ++ memset(s->cbf_luma, 0, s->ps.sps->min_tb_width * s->ps.sps->min_tb_height); ++ memset(s->is_pcm, 0, (s->ps.sps->min_pu_width + 1) * (s->ps.sps->min_pu_height + 1)); ++ memset(s->tab_slice_address, -1, pic_size_in_ctb * sizeof(*s->tab_slice_address)); ++ } + + s->is_decoded = 0; + s->first_nal_type = s->nal_unit_type; +@@ -3327,7 +3367,14 @@ static int hevc_decode_frame(AVCodecContext *avctx, void *data, int *got_output, s->ref = NULL; ret = decode_nal_units(s, avpkt->data, avpkt->size); if (ret < 0) @@ -19125,7 +19622,35 @@ index 2231aed259..6d2d66dfdf 100644 if (avctx->hwaccel) { if (s->ref && (ret = avctx->hwaccel->end_frame(avctx)) < 0) { -@@ -3697,6 +3732,15 @@ AVCodec ff_hevc_decoder = { +@@ -3370,15 +3417,19 @@ static int hevc_ref_frame(HEVCContext *s, HEVCFrame *dst, HEVCFrame *src) + if (ret < 0) + return ret; + +- dst->tab_mvf_buf = av_buffer_ref(src->tab_mvf_buf); +- if (!dst->tab_mvf_buf) +- goto fail; +- dst->tab_mvf = src->tab_mvf; ++ if (src->tab_mvf_buf) { ++ dst->tab_mvf_buf = av_buffer_ref(src->tab_mvf_buf); ++ if (!dst->tab_mvf_buf) ++ goto fail; ++ dst->tab_mvf = src->tab_mvf; ++ } + +- dst->rpl_tab_buf = av_buffer_ref(src->rpl_tab_buf); +- if (!dst->rpl_tab_buf) +- goto fail; +- dst->rpl_tab = src->rpl_tab; ++ if (src->rpl_tab_buf) { ++ dst->rpl_tab_buf = av_buffer_ref(src->rpl_tab_buf); ++ if (!dst->rpl_tab_buf) ++ goto fail; ++ dst->rpl_tab = src->rpl_tab; ++ } + + dst->rpl_buf = av_buffer_ref(src->rpl_buf); + if (!dst->rpl_buf) +@@ -3697,6 +3748,15 @@ AVCodec ff_hevc_decoder = { #if CONFIG_HEVC_NVDEC_HWACCEL HWACCEL_NVDEC(hevc), #endif @@ -49497,7 +50022,7 @@ index 0000000000..85c5b46d75 +}; + diff --git a/libavcodec/v4l2_buffers.c b/libavcodec/v4l2_buffers.c -index 4b2679eb38..6ca83cc21b 100644 +index 4b2679eb38..9ef2f40e39 100644 --- a/libavcodec/v4l2_buffers.c +++ b/libavcodec/v4l2_buffers.c @@ -21,6 +21,7 @@ @@ -49508,9 +50033,11 @@ index 4b2679eb38..6ca83cc21b 100644 #include #include #include -@@ -30,56 +31,68 @@ +@@ -29,57 +30,82 @@ + #include #include "libavcodec/avcodec.h" #include "libavcodec/internal.h" ++#include "libavutil/avassert.h" #include "libavutil/pixdesc.h" +#include "libavutil/hwcontext.h" #include "v4l2_context.h" @@ -49552,21 +50079,32 @@ index 4b2679eb38..6ca83cc21b 100644 } -static inline void v4l2_set_pts(V4L2Buffer *out, int64_t pts) -+static inline void v4l2_set_pts(V4L2Buffer * const out, const int64_t pts) ++static inline struct timeval tv_from_int(const int64_t t) { - int64_t v4l2_pts; -- ++ return (struct timeval){ ++ .tv_usec = t % USEC_PER_SEC, ++ .tv_sec = t / USEC_PER_SEC ++ }; ++} + - if (pts == AV_NOPTS_VALUE) - pts = 0; -- ++static inline int64_t int_from_tv(const struct timeval t) ++{ ++ return (int64_t)t.tv_sec * USEC_PER_SEC + t.tv_usec; ++} + ++static inline void v4l2_set_pts(V4L2Buffer * const out, const int64_t pts) ++{ /* convert pts to v4l2 timebase */ - v4l2_pts = av_rescale_q(pts, v4l2_get_timebase(out), v4l2_timebase); +- out->buf.timestamp.tv_usec = v4l2_pts % USEC_PER_SEC; +- out->buf.timestamp.tv_sec = v4l2_pts / USEC_PER_SEC; + const int64_t v4l2_pts = -+ out->context->no_pts_rescale ? pts : + pts == AV_NOPTS_VALUE ? 0 : + av_rescale_q(pts, v4l2_get_timebase(out), v4l2_timebase); - out->buf.timestamp.tv_usec = v4l2_pts % USEC_PER_SEC; - out->buf.timestamp.tv_sec = v4l2_pts / USEC_PER_SEC; ++ out->buf.timestamp = tv_from_int(v4l2_pts); } -static inline int64_t v4l2_get_pts(V4L2Buffer *avbuf) @@ -49574,18 +50112,20 @@ index 4b2679eb38..6ca83cc21b 100644 { - int64_t v4l2_pts; - ++ const int64_t v4l2_pts = int_from_tv(avbuf->buf.timestamp); ++ return v4l2_pts != 0 ? v4l2_pts : AV_NOPTS_VALUE; ++#if 0 /* convert pts back to encoder timebase */ - v4l2_pts = (int64_t)avbuf->buf.timestamp.tv_sec * USEC_PER_SEC + -+ const int64_t v4l2_pts = (int64_t)avbuf->buf.timestamp.tv_sec * USEC_PER_SEC + - avbuf->buf.timestamp.tv_usec; - -- return av_rescale_q(v4l2_pts, v4l2_timebase, v4l2_get_timebase(avbuf)); +- avbuf->buf.timestamp.tv_usec; + return + avbuf->context->no_pts_rescale ? v4l2_pts : + v4l2_pts == 0 ? AV_NOPTS_VALUE : + av_rescale_q(v4l2_pts, v4l2_timebase, v4l2_get_timebase(avbuf)); ++#endif +} -+ + +- return av_rescale_q(v4l2_pts, v4l2_timebase, v4l2_get_timebase(avbuf)); +static void set_buf_length(V4L2Buffer *out, unsigned int plane, uint32_t bytesused, uint32_t length) +{ + if (V4L2_TYPE_IS_MULTIPLANAR(out->buf.type)) { @@ -49598,7 +50138,7 @@ index 4b2679eb38..6ca83cc21b 100644 } static enum AVColorPrimaries v4l2_get_color_primaries(V4L2Buffer *buf) -@@ -116,6 +129,105 @@ static enum AVColorPrimaries v4l2_get_color_primaries(V4L2Buffer *buf) +@@ -116,6 +142,105 @@ static enum AVColorPrimaries v4l2_get_color_primaries(V4L2Buffer *buf) return AVCOL_PRI_UNSPECIFIED; } @@ -49704,7 +50244,7 @@ index 4b2679eb38..6ca83cc21b 100644 static enum AVColorRange v4l2_get_color_range(V4L2Buffer *buf) { enum v4l2_quantization qt; -@@ -134,6 +246,20 @@ static enum AVColorRange v4l2_get_color_range(V4L2Buffer *buf) +@@ -134,6 +259,20 @@ static enum AVColorRange v4l2_get_color_range(V4L2Buffer *buf) return AVCOL_RANGE_UNSPECIFIED; } @@ -49725,29 +50265,23 @@ index 4b2679eb38..6ca83cc21b 100644 static enum AVColorSpace v4l2_get_color_space(V4L2Buffer *buf) { enum v4l2_ycbcr_encoding ycbcr; -@@ -210,73 +336,165 @@ static enum AVColorTransferCharacteristic v4l2_get_color_trc(V4L2Buffer *buf) +@@ -210,73 +349,165 @@ static enum AVColorTransferCharacteristic v4l2_get_color_trc(V4L2Buffer *buf) return AVCOL_TRC_UNSPECIFIED; } -static void v4l2_free_buffer(void *opaque, uint8_t *unused) +static int v4l2_buf_is_interlaced(const V4L2Buffer * const buf) -+{ -+ return V4L2_FIELD_IS_INTERLACED(buf->buf.field); -+} -+ -+static int v4l2_buf_is_top_first(const V4L2Buffer * const buf) { - V4L2Buffer* avbuf = opaque; - V4L2m2mContext *s = buf_to_m2mctx(avbuf); -+ return buf->buf.field == V4L2_FIELD_INTERLACED_TB; ++ return V4L2_FIELD_IS_INTERLACED(buf->buf.field); +} - if (atomic_fetch_sub(&avbuf->context_refcount, 1) == 1) { - atomic_fetch_sub_explicit(&s->refcount, 1, memory_order_acq_rel); -+static void v4l2_set_interlace(V4L2Buffer * const buf, const int is_interlaced, const int is_tff) ++static int v4l2_buf_is_top_first(const V4L2Buffer * const buf) +{ -+ buf->buf.field = !is_interlaced ? V4L2_FIELD_NONE : -+ is_tff ? V4L2_FIELD_INTERLACED_TB : V4L2_FIELD_INTERLACED_BT; ++ return buf->buf.field == V4L2_FIELD_INTERLACED_TB; +} - if (s->reinit) { @@ -49761,11 +50295,18 @@ index 4b2679eb38..6ca83cc21b 100644 - else if (avbuf->context->streamon) - ff_v4l2_buffer_enqueue(avbuf); - } ++static void v4l2_set_interlace(V4L2Buffer * const buf, const int is_interlaced, const int is_tff) ++{ ++ buf->buf.field = !is_interlaced ? V4L2_FIELD_NONE : ++ is_tff ? V4L2_FIELD_INTERLACED_TB : V4L2_FIELD_INTERLACED_BT; ++} ++ +static uint8_t * v4l2_get_drm_frame(V4L2Buffer *avbuf) +{ + AVDRMFrameDescriptor *drm_desc = &avbuf->drm_frame; + AVDRMLayerDescriptor *layer; -+ + +- av_buffer_unref(&avbuf->context_ref); + /* fill the DRM frame descriptor */ + drm_desc->nb_objects = avbuf->num_planes; + drm_desc->nb_layers = 1; @@ -49777,7 +50318,7 @@ index 4b2679eb38..6ca83cc21b 100644 + layer->planes[i].object_index = i; + layer->planes[i].offset = 0; + layer->planes[i].pitch = avbuf->plane_info[i].bytesperline; -+ } + } + + switch (avbuf->context->av_pix_fmt) { + case AV_PIX_FMT_YUYV422: @@ -49805,8 +50346,7 @@ index 4b2679eb38..6ca83cc21b 100644 + break; + + case AV_PIX_FMT_YUV420P: - -- av_buffer_unref(&avbuf->context_ref); ++ + layer->format = DRM_FORMAT_YUV420; + + if (avbuf->num_planes > 1) @@ -49829,7 +50369,7 @@ index 4b2679eb38..6ca83cc21b 100644 + default: + drm_desc->nb_layers = 0; + break; - } ++ } + + return (uint8_t *) drm_desc; } @@ -49858,7 +50398,7 @@ index 4b2679eb38..6ca83cc21b 100644 - in->status = V4L2BUF_RET_USER; - atomic_fetch_add_explicit(&s->refcount, 1, memory_order_relaxed); -+ avbuf->status = V4L2BUF_AVAILABLE; ++ ff_v4l2_buffer_set_avail(avbuf); - return 0; + if (s->draining && V4L2_TYPE_IS_OUTPUT(ctx->type)) { @@ -49934,7 +50474,7 @@ index 4b2679eb38..6ca83cc21b 100644 if (plane >= out->num_planes) return AVERROR(EINVAL); -@@ -284,32 +502,57 @@ static int v4l2_bufref_to_buf(V4L2Buffer *out, int plane, const uint8_t* data, i +@@ -284,32 +515,57 @@ static int v4l2_bufref_to_buf(V4L2Buffer *out, int plane, const uint8_t* data, i length = out->plane_info[plane].length; bytesused = FFMIN(size+offset, length); @@ -49989,7 +50529,7 @@ index 4b2679eb38..6ca83cc21b 100644 + frame->buf[0] = wrap_avbuf(avbuf); + if (frame->buf[0] == NULL) + return AVERROR(ENOMEM); - ++ + if (buf_to_m2mctx(avbuf)->output_drm) { + /* 1. get references to the actual data */ + frame->data[0] = (uint8_t *) v4l2_get_drm_frame(avbuf); @@ -49997,7 +50537,7 @@ index 4b2679eb38..6ca83cc21b 100644 + frame->hw_frames_ctx = av_buffer_ref(avbuf->context->frames_ref); + return 0; + } -+ + + + /* 1. get references to the actual data */ + for (i = 0; i < avbuf->num_planes; i++) { @@ -50007,7 +50547,7 @@ index 4b2679eb38..6ca83cc21b 100644 } /* fixup special cases */ -@@ -318,17 +561,17 @@ static int v4l2_buffer_buf_to_swframe(AVFrame *frame, V4L2Buffer *avbuf) +@@ -318,17 +574,17 @@ static int v4l2_buffer_buf_to_swframe(AVFrame *frame, V4L2Buffer *avbuf) case AV_PIX_FMT_NV21: if (avbuf->num_planes > 1) break; @@ -50031,7 +50571,7 @@ index 4b2679eb38..6ca83cc21b 100644 break; default: -@@ -338,68 +581,95 @@ static int v4l2_buffer_buf_to_swframe(AVFrame *frame, V4L2Buffer *avbuf) +@@ -338,68 +594,127 @@ static int v4l2_buffer_buf_to_swframe(AVFrame *frame, V4L2Buffer *avbuf) return 0; } @@ -50053,6 +50593,38 @@ index 4b2679eb38..6ca83cc21b 100644 +{ + return i != 0 && !(i == num_planes - 1 && (desc->flags & AV_PIX_FMT_FLAG_ALPHA)); +} ++ ++static int v4l2_buffer_primeframe_to_buf(const AVFrame *frame, V4L2Buffer *out) ++{ ++ const AVDRMFrameDescriptor *const src = (const AVDRMFrameDescriptor *)frame->data[0]; ++ ++ if (frame->format != AV_PIX_FMT_DRM_PRIME || !src) ++ return AVERROR(EINVAL); ++ ++ av_assert0(out->buf.memory == V4L2_MEMORY_DMABUF); ++ ++ if (V4L2_TYPE_IS_MULTIPLANAR(out->buf.type)) { ++ // Only currently cope with single buffer types ++ if (out->buf.length != 1) ++ return AVERROR_PATCHWELCOME; ++ if (src->nb_objects != 1) ++ return AVERROR(EINVAL); ++ ++ out->planes[0].m.fd = src->objects[0].fd; ++ } ++ else { ++ if (src->nb_objects != 1) ++ return AVERROR(EINVAL); ++ ++ out->buf.m.fd = src->objects[0].fd; ++ } ++ ++ // No need to copy src AVDescriptor and if we did then we may confuse ++ // fd close on free ++ out->ref_buf = av_buffer_ref(frame->buf[0]); ++ ++ return 0; ++} + static int v4l2_buffer_swframe_to_buf(const AVFrame *frame, V4L2Buffer *out) { @@ -50181,10 +50753,16 @@ index 4b2679eb38..6ca83cc21b 100644 return 0; } -@@ -411,7 +681,16 @@ static int v4l2_buffer_swframe_to_buf(const AVFrame *frame, V4L2Buffer *out) +@@ -409,16 +724,31 @@ static int v4l2_buffer_swframe_to_buf(const AVFrame *frame, V4L2Buffer *out) + * + ******************************************************************************/ - int ff_v4l2_buffer_avframe_to_buf(const AVFrame *frame, V4L2Buffer *out) +-int ff_v4l2_buffer_avframe_to_buf(const AVFrame *frame, V4L2Buffer *out) ++int ff_v4l2_buffer_avframe_to_buf(const AVFrame *frame, V4L2Buffer *out, const int64_t track_ts) { +- v4l2_set_pts(out, frame->pts); +- +- return v4l2_buffer_swframe_to_buf(frame, out); + out->buf.flags = frame->key_frame ? + (out->buf.flags | V4L2_BUF_FLAG_KEYFRAME) : + (out->buf.flags & ~V4L2_BUF_FLAG_KEYFRAME); @@ -50193,12 +50771,17 @@ index 4b2679eb38..6ca83cc21b 100644 + v4l2_set_color(out, frame->color_primaries, frame->colorspace, frame->color_trc); + v4l2_set_color_range(out, frame->color_range); + // PTS & interlace are buffer vars - v4l2_set_pts(out, frame->pts); ++ if (track_ts) ++ out->buf.timestamp = tv_from_int(track_ts); ++ else ++ v4l2_set_pts(out, frame->pts); + v4l2_set_interlace(out, frame->interlaced_frame, frame->top_field_first); - - return v4l2_buffer_swframe_to_buf(frame, out); ++ ++ return frame->format == AV_PIX_FMT_DRM_PRIME ? ++ v4l2_buffer_primeframe_to_buf(frame, out) : ++ v4l2_buffer_swframe_to_buf(frame, out); } -@@ -419,6 +698,7 @@ int ff_v4l2_buffer_avframe_to_buf(const AVFrame *frame, V4L2Buffer *out) + int ff_v4l2_buffer_buf_to_avframe(AVFrame *frame, V4L2Buffer *avbuf) { int ret; @@ -50206,7 +50789,7 @@ index 4b2679eb38..6ca83cc21b 100644 av_frame_unref(frame); -@@ -429,17 +709,32 @@ int ff_v4l2_buffer_buf_to_avframe(AVFrame *frame, V4L2Buffer *avbuf) +@@ -429,17 +759,32 @@ int ff_v4l2_buffer_buf_to_avframe(AVFrame *frame, V4L2Buffer *avbuf) /* 2. get frame information */ frame->key_frame = !!(avbuf->buf.flags & V4L2_BUF_FLAG_KEYFRAME); @@ -50242,7 +50825,7 @@ index 4b2679eb38..6ca83cc21b 100644 /* 3. report errors upstream */ if (avbuf->buf.flags & V4L2_BUF_FLAG_ERROR) { -@@ -452,15 +747,14 @@ int ff_v4l2_buffer_buf_to_avframe(AVFrame *frame, V4L2Buffer *avbuf) +@@ -452,15 +797,15 @@ int ff_v4l2_buffer_buf_to_avframe(AVFrame *frame, V4L2Buffer *avbuf) int ff_v4l2_buffer_buf_to_avpkt(AVPacket *pkt, V4L2Buffer *avbuf) { @@ -50260,16 +50843,18 @@ index 4b2679eb38..6ca83cc21b 100644 pkt->size = V4L2_TYPE_IS_MULTIPLANAR(avbuf->buf.type) ? avbuf->buf.m.planes[0].bytesused : avbuf->buf.bytesused; - pkt->data = pkt->buf->data; + pkt->data = (uint8_t*)avbuf->plane_info[0].mm_addr + avbuf->planes[0].data_offset; ++ pkt->flags = 0; if (avbuf->buf.flags & V4L2_BUF_FLAG_KEYFRAME) pkt->flags |= AV_PKT_FLAG_KEY; -@@ -475,31 +769,85 @@ int ff_v4l2_buffer_buf_to_avpkt(AVPacket *pkt, V4L2Buffer *avbuf) +@@ -475,31 +820,91 @@ int ff_v4l2_buffer_buf_to_avpkt(AVPacket *pkt, V4L2Buffer *avbuf) return 0; } -int ff_v4l2_buffer_avpkt_to_buf(const AVPacket *pkt, V4L2Buffer *out) -+int ff_v4l2_buffer_avpkt_to_buf_ext(const AVPacket *pkt, V4L2Buffer *out, -+ const void *extdata, size_t extlen) ++int ff_v4l2_buffer_avpkt_to_buf_ext(const AVPacket * const pkt, V4L2Buffer * const out, ++ const void *extdata, size_t extlen, ++ const int64_t timestamp) { int ret; @@ -50285,7 +50870,11 @@ index 4b2679eb38..6ca83cc21b 100644 + if (ret && ret != AVERROR(ENOMEM)) return ret; - v4l2_set_pts(out, pkt->pts); +- v4l2_set_pts(out, pkt->pts); ++ if (timestamp) ++ out->buf.timestamp = tv_from_int(timestamp); ++ else ++ v4l2_set_pts(out, pkt->pts); - if (pkt->flags & AV_PKT_FLAG_KEY) - out->flags = V4L2_BUF_FLAG_KEYFRAME; @@ -50295,14 +50884,14 @@ index 4b2679eb38..6ca83cc21b 100644 - return 0; + return ret; ++} ++ ++int ff_v4l2_buffer_avpkt_to_buf(const AVPacket *pkt, V4L2Buffer *out) ++{ ++ return ff_v4l2_buffer_avpkt_to_buf_ext(pkt, out, NULL, 0, 0); } -int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index) -+int ff_v4l2_buffer_avpkt_to_buf(const AVPacket *pkt, V4L2Buffer *out) -+{ -+ return ff_v4l2_buffer_avpkt_to_buf_ext(pkt, out, NULL, 0); -+} -+ + +static void v4l2_buffer_buffer_free(void *opaque, uint8_t *data) +{ @@ -50320,13 +50909,15 @@ index 4b2679eb38..6ca83cc21b 100644 + close(avbuf->drm_frame.objects[i].fd); + } + ++ av_buffer_unref(&avbuf->ref_buf); ++ + ff_weak_link_unref(&avbuf->context_wl); + + av_free(avbuf); +} + + -+int ff_v4l2_buffer_initialize(AVBufferRef ** pbufref, int index, V4L2Context *ctx) ++int ff_v4l2_buffer_initialize(AVBufferRef ** pbufref, int index, V4L2Context *ctx, enum v4l2_memory mem) { - V4L2Context *ctx = avbuf->context; int ret, i; @@ -50343,8 +50934,9 @@ index 4b2679eb38..6ca83cc21b 100644 + return AVERROR(ENOMEM); + } +- avbuf->buf.memory = V4L2_MEMORY_MMAP; + avbuf->context = ctx; - avbuf->buf.memory = V4L2_MEMORY_MMAP; ++ avbuf->buf.memory = mem; avbuf->buf.type = ctx->type; avbuf->buf.index = index; @@ -50357,7 +50949,7 @@ index 4b2679eb38..6ca83cc21b 100644 if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) { avbuf->buf.length = VIDEO_MAX_PLANES; avbuf->buf.m.planes = avbuf->planes; -@@ -507,7 +855,7 @@ int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index) +@@ -507,7 +912,7 @@ int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index) ret = ioctl(buf_to_m2mctx(avbuf)->fd, VIDIOC_QUERYBUF, &avbuf->buf); if (ret < 0) @@ -50366,7 +50958,16 @@ index 4b2679eb38..6ca83cc21b 100644 if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) { avbuf->num_planes = 0; -@@ -527,25 +875,33 @@ int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index) +@@ -520,6 +925,8 @@ int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index) + avbuf->num_planes = 1; + + for (i = 0; i < avbuf->num_planes; i++) { ++ const int want_mmap = avbuf->buf.memory == V4L2_MEMORY_MMAP && ++ (V4L2_TYPE_IS_OUTPUT(ctx->type) || !buf_to_m2mctx(avbuf)->output_drm); + + avbuf->plane_info[i].bytesperline = V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ? + ctx->format.fmt.pix_mp.plane_fmt[i].bytesperline : +@@ -527,25 +934,29 @@ int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index) if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) { avbuf->plane_info[i].length = avbuf->buf.m.planes[i].length; @@ -50374,24 +50975,20 @@ index 4b2679eb38..6ca83cc21b 100644 - PROT_READ | PROT_WRITE, MAP_SHARED, - buf_to_m2mctx(avbuf)->fd, avbuf->buf.m.planes[i].m.mem_offset); + -+ if ((V4L2_TYPE_IS_OUTPUT(ctx->type) && buf_to_m2mctx(avbuf)->output_drm) || -+ !buf_to_m2mctx(avbuf)->output_drm) { ++ if (want_mmap) + avbuf->plane_info[i].mm_addr = mmap(NULL, avbuf->buf.m.planes[i].length, + PROT_READ | PROT_WRITE, MAP_SHARED, + buf_to_m2mctx(avbuf)->fd, avbuf->buf.m.planes[i].m.mem_offset); -+ } } else { avbuf->plane_info[i].length = avbuf->buf.length; - avbuf->plane_info[i].mm_addr = mmap(NULL, avbuf->buf.length, - PROT_READ | PROT_WRITE, MAP_SHARED, - buf_to_m2mctx(avbuf)->fd, avbuf->buf.m.offset); + -+ if ((V4L2_TYPE_IS_OUTPUT(ctx->type) && buf_to_m2mctx(avbuf)->output_drm) || -+ !buf_to_m2mctx(avbuf)->output_drm) { ++ if (want_mmap) + avbuf->plane_info[i].mm_addr = mmap(NULL, avbuf->buf.length, + PROT_READ | PROT_WRITE, MAP_SHARED, + buf_to_m2mctx(avbuf)->fd, avbuf->buf.m.offset); -+ } } - if (avbuf->plane_info[i].mm_addr == MAP_FAILED) @@ -50411,7 +51008,7 @@ index 4b2679eb38..6ca83cc21b 100644 if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) { avbuf->buf.m.planes = avbuf->planes; avbuf->buf.length = avbuf->num_planes; -@@ -555,20 +911,51 @@ int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index) +@@ -555,20 +966,51 @@ int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index) avbuf->buf.length = avbuf->planes[0].length; } @@ -50468,10 +51065,10 @@ index 4b2679eb38..6ca83cc21b 100644 return 0; } diff --git a/libavcodec/v4l2_buffers.h b/libavcodec/v4l2_buffers.h -index 8dbc7fc104..7d5fadcd3d 100644 +index 8dbc7fc104..e64441ec9b 100644 --- a/libavcodec/v4l2_buffers.h +++ b/libavcodec/v4l2_buffers.h -@@ -27,25 +27,34 @@ +@@ -27,25 +27,38 @@ #include #include @@ -50508,10 +51105,14 @@ index 8dbc7fc104..7d5fadcd3d 100644 - atomic_uint context_refcount; + /* DRM descriptor */ + AVDRMFrameDescriptor drm_frame; ++ /* For DRM_PRIME encode - need to keep a ref to the source buffer till we ++ * are done ++ */ ++ AVBufferRef * ref_buf; /* keep track of the mmap address and mmap length */ struct V4L2Plane_info { -@@ -60,7 +69,6 @@ typedef struct V4L2Buffer { +@@ -60,7 +73,6 @@ typedef struct V4L2Buffer { struct v4l2_buffer buf; struct v4l2_plane planes[VIDEO_MAX_PLANES]; @@ -50519,27 +51120,50 @@ index 8dbc7fc104..7d5fadcd3d 100644 enum V4L2Buffer_status status; } V4L2Buffer; -@@ -98,6 +106,9 @@ int ff_v4l2_buffer_buf_to_avpkt(AVPacket *pkt, V4L2Buffer *buf); +@@ -98,6 +110,10 @@ int ff_v4l2_buffer_buf_to_avpkt(AVPacket *pkt, V4L2Buffer *buf); */ int ff_v4l2_buffer_avpkt_to_buf(const AVPacket *pkt, V4L2Buffer *out); -+int ff_v4l2_buffer_avpkt_to_buf_ext(const AVPacket *pkt, V4L2Buffer *out, -+ const void *extdata, size_t extlen); ++int ff_v4l2_buffer_avpkt_to_buf_ext(const AVPacket * const pkt, V4L2Buffer * const out, ++ const void *extdata, size_t extlen, ++ const int64_t timestamp); + /** * Extracts the data from an AVFrame to a V4L2Buffer * -@@ -116,7 +127,7 @@ int ff_v4l2_buffer_avframe_to_buf(const AVFrame *frame, V4L2Buffer *out); +@@ -106,7 +122,7 @@ int ff_v4l2_buffer_avpkt_to_buf(const AVPacket *pkt, V4L2Buffer *out); + * + * @returns 0 in case of success, a negative AVERROR code otherwise + */ +-int ff_v4l2_buffer_avframe_to_buf(const AVFrame *frame, V4L2Buffer *out); ++int ff_v4l2_buffer_avframe_to_buf(const AVFrame *frame, V4L2Buffer *out, const int64_t track_ts); + + /** + * Initializes a V4L2Buffer +@@ -116,7 +132,7 @@ int ff_v4l2_buffer_avframe_to_buf(const AVFrame *frame, V4L2Buffer *out); * * @returns 0 in case of success, a negative AVERROR code otherwise */ -int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index); -+int ff_v4l2_buffer_initialize(AVBufferRef **avbuf, int index, struct V4L2Context *ctx); ++int ff_v4l2_buffer_initialize(AVBufferRef **avbuf, int index, struct V4L2Context *ctx, enum v4l2_memory mem); /** * Enqueues a V4L2Buffer +@@ -127,5 +143,12 @@ int ff_v4l2_buffer_initialize(V4L2Buffer* avbuf, int index); + */ + int ff_v4l2_buffer_enqueue(V4L2Buffer* avbuf); + ++static inline void ++ff_v4l2_buffer_set_avail(V4L2Buffer* const avbuf) ++{ ++ avbuf->status = V4L2BUF_AVAILABLE; ++ av_buffer_unref(&avbuf->ref_buf); ++} ++ + + #endif // AVCODEC_V4L2_BUFFERS_H diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c -index ff1ea8e57b..c0d257e5d3 100644 +index ff1ea8e57b..eaaec44666 100644 --- a/libavcodec/v4l2_context.c +++ b/libavcodec/v4l2_context.c @@ -27,11 +27,13 @@ @@ -50556,49 +51180,191 @@ index ff1ea8e57b..c0d257e5d3 100644 struct v4l2_format_update { uint32_t v4l2_fmt; -@@ -41,28 +43,18 @@ struct v4l2_format_update { +@@ -41,26 +43,168 @@ struct v4l2_format_update { int update_avfmt; }; -static inline V4L2m2mContext *ctx_to_m2mctx(V4L2Context *ctx) -+static inline V4L2m2mContext *ctx_to_m2mctx(const V4L2Context *ctx) ++ ++static inline int64_t track_to_pts(AVCodecContext *avctx, unsigned int n) { - return V4L2_TYPE_IS_OUTPUT(ctx->type) ? - container_of(ctx, V4L2m2mContext, output) : - container_of(ctx, V4L2m2mContext, capture); +- return V4L2_TYPE_IS_OUTPUT(ctx->type) ? +- container_of(ctx, V4L2m2mContext, output) : +- container_of(ctx, V4L2m2mContext, capture); ++ return (int64_t)n; } -static inline AVCodecContext *logger(V4L2Context *ctx) -+static inline AVCodecContext *logger(const V4L2Context *ctx) ++static inline unsigned int pts_to_track(AVCodecContext *avctx, const int64_t pts) { - return ctx_to_m2mctx(ctx)->avctx; +- return ctx_to_m2mctx(ctx)->avctx; ++ return (unsigned int)pts; } -static inline unsigned int v4l2_get_width(struct v4l2_format *fmt) --{ -- return V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? fmt->fmt.pix_mp.width : fmt->fmt.pix.width; --} -- --static inline unsigned int v4l2_get_height(struct v4l2_format *fmt) --{ -- return V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? fmt->fmt.pix_mp.height : fmt->fmt.pix.height; --} -- - static AVRational v4l2_get_sar(V4L2Context *ctx) ++// FFmpeg requires us to propagate a number of vars from the coded pkt into ++// the decoded frame. The only thing that tracks like that in V4L2 stateful ++// is timestamp. PTS maps to timestamp for this decode. FFmpeg makes no ++// guarantees about PTS being unique or specified for every frame so replace ++// the supplied PTS with a simple incrementing number and keep a circular ++// buffer of all the things we want preserved (including the original PTS) ++// indexed by the tracking no. ++static int64_t ++xlat_pts_pkt_in(AVCodecContext *const avctx, xlat_track_t *const x, const AVPacket *const avpkt) { - struct AVRational sar = { 0, 1 }; -@@ -81,21 +73,29 @@ static AVRational v4l2_get_sar(V4L2Context *ctx) +- return V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? fmt->fmt.pix_mp.width : fmt->fmt.pix.width; ++ int64_t track_pts; ++ ++ // Avoid 0 ++ if (++x->track_no == 0) ++ x->track_no = 1; ++ ++ track_pts = track_to_pts(avctx, x->track_no); ++ ++ av_log(avctx, AV_LOG_TRACE, "In pkt PTS=%" PRId64 ", DTS=%" PRId64 ", track=%" PRId64 ", n=%u\n", avpkt->pts, avpkt->dts, track_pts, x->track_no); ++ x->track_els[x->track_no % FF_V4L2_M2M_TRACK_SIZE] = (V4L2m2mTrackEl){ ++ .discard = 0, ++ .pending = 1, ++ .pkt_size = avpkt->size, ++ .pts = avpkt->pts, ++ .dts = avpkt->dts, ++ .reordered_opaque = avctx->reordered_opaque, ++ .pkt_pos = avpkt->pos, ++ .pkt_duration = avpkt->duration, ++ .track_pts = track_pts ++ }; ++ return track_pts; + } + +-static inline unsigned int v4l2_get_height(struct v4l2_format *fmt) ++static int64_t ++xlat_pts_frame_in(AVCodecContext *const avctx, xlat_track_t *const x, const AVFrame *const frame) + { +- return V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? fmt->fmt.pix_mp.height : fmt->fmt.pix.height; ++ int64_t track_pts; ++ ++ // Avoid 0 ++ if (++x->track_no == 0) ++ x->track_no = 1; ++ ++ track_pts = track_to_pts(avctx, x->track_no); ++ ++ av_log(avctx, AV_LOG_TRACE, "In frame PTS=%" PRId64 ", track=%" PRId64 ", n=%u\n", frame->pts, track_pts, x->track_no); ++ x->track_els[x->track_no % FF_V4L2_M2M_TRACK_SIZE] = (V4L2m2mTrackEl){ ++ .discard = 0, ++ .pending = 1, ++ .pkt_size = 0, ++ .pts = frame->pts, ++ .dts = AV_NOPTS_VALUE, ++ .reordered_opaque = frame->reordered_opaque, ++ .pkt_pos = frame->pkt_pos, ++ .pkt_duration = frame->pkt_duration, ++ .track_pts = track_pts ++ }; ++ return track_pts; ++} ++ ++ ++// Returns -1 if we should discard the frame ++static int ++xlat_pts_frame_out(AVCodecContext *const avctx, ++ xlat_track_t * const x, ++ AVFrame *const frame) ++{ ++ unsigned int n = pts_to_track(avctx, frame->pts) % FF_V4L2_M2M_TRACK_SIZE; ++ V4L2m2mTrackEl *const t = x->track_els + n; ++ if (frame->pts == AV_NOPTS_VALUE || frame->pts != t->track_pts) ++ { ++ av_log(avctx, frame->pts == AV_NOPTS_VALUE ? AV_LOG_DEBUG : AV_LOG_WARNING, ++ "Frame tracking failure: pts=%" PRId64 ", track[%d]=%" PRId64 "\n", frame->pts, n, t->track_pts); ++ frame->pts = AV_NOPTS_VALUE; ++ frame->pkt_dts = AV_NOPTS_VALUE; ++ frame->reordered_opaque = x->last_opaque; ++ frame->pkt_pos = -1; ++ frame->pkt_duration = 0; ++ frame->pkt_size = -1; ++ } ++ else if (!t->discard) ++ { ++ frame->pts = t->pending ? t->pts : AV_NOPTS_VALUE; ++ frame->pkt_dts = t->dts; ++ frame->reordered_opaque = t->reordered_opaque; ++ frame->pkt_pos = t->pkt_pos; ++ frame->pkt_duration = t->pkt_duration; ++ frame->pkt_size = t->pkt_size; ++ ++ x->last_opaque = x->track_els[n].reordered_opaque; ++ if (frame->pts != AV_NOPTS_VALUE) ++ x->last_pts = frame->pts; ++ t->pending = 0; ++ } ++ else ++ { ++ av_log(avctx, AV_LOG_DEBUG, "Discard frame (flushed): pts=%" PRId64 ", track[%d]=%" PRId64 "\n", frame->pts, n, t->track_pts); ++ return -1; ++ } ++ ++ av_log(avctx, AV_LOG_TRACE, "Out frame PTS=%" PRId64 "/%"PRId64", DTS=%" PRId64 ", track=%"PRId64", n=%d\n", ++ frame->pts, frame->best_effort_timestamp, frame->pkt_dts, t->track_pts, n); ++ return 0; ++} ++ ++// Returns -1 if we should discard the frame ++static int ++xlat_pts_pkt_out(AVCodecContext *const avctx, ++ xlat_track_t * const x, ++ AVPacket *const pkt) ++{ ++ unsigned int n = pts_to_track(avctx, pkt->pts) % FF_V4L2_M2M_TRACK_SIZE; ++ V4L2m2mTrackEl *const t = x->track_els + n; ++ if (pkt->pts == AV_NOPTS_VALUE || pkt->pts != t->track_pts) ++ { ++ av_log(avctx, pkt->pts == AV_NOPTS_VALUE ? AV_LOG_DEBUG : AV_LOG_WARNING, ++ "Pkt tracking failure: pts=%" PRId64 ", track[%d]=%" PRId64 "\n", pkt->pts, n, t->track_pts); ++ pkt->pts = AV_NOPTS_VALUE; ++ } ++ else if (!t->discard) ++ { ++ pkt->pts = t->pending ? t->pts : AV_NOPTS_VALUE; ++ ++ x->last_opaque = x->track_els[n].reordered_opaque; ++ if (pkt->pts != AV_NOPTS_VALUE) ++ x->last_pts = pkt->pts; ++ t->pending = 0; ++ } ++ else ++ { ++ av_log(avctx, AV_LOG_DEBUG, "Discard packet (flushed): pts=%" PRId64 ", track[%d]=%" PRId64 "\n", pkt->pts, n, t->track_pts); ++ return -1; ++ } ++ ++ // * Would like something much better than this...xlat(offset + out_count)? ++ pkt->dts = pkt->pts; ++ av_log(avctx, AV_LOG_TRACE, "Out pkt PTS=%" PRId64 ", track=%"PRId64", n=%d\n", ++ pkt->pts, t->track_pts, n); ++ return 0; ++} ++ ++ ++static inline V4L2m2mContext *ctx_to_m2mctx(const V4L2Context *ctx) ++{ ++ return V4L2_TYPE_IS_OUTPUT(ctx->type) ? ++ container_of(ctx, V4L2m2mContext, output) : ++ container_of(ctx, V4L2m2mContext, capture); ++} ++ ++static inline AVCodecContext *logger(const V4L2Context *ctx) ++{ ++ return ctx_to_m2mctx(ctx)->avctx; + } + + static AVRational v4l2_get_sar(V4L2Context *ctx) +@@ -81,21 +225,29 @@ static AVRational v4l2_get_sar(V4L2Context *ctx) return sar; } -static inline unsigned int v4l2_resolution_changed(V4L2Context *ctx, struct v4l2_format *fmt2) +static inline int ctx_buffers_alloced(const V4L2Context * const ctx) -+{ -+ return ctx->bufrefs != NULL; -+} -+ -+// Width/Height changed or we don't have an alloc in the first place? -+static int ctx_resolution_changed(const V4L2Context *ctx, const struct v4l2_format *fmt2) { - struct v4l2_format *fmt1 = &ctx->format; - int ret = V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ? @@ -50607,6 +51373,12 @@ index ff1ea8e57b..c0d257e5d3 100644 - : - fmt1->fmt.pix.width != fmt2->fmt.pix.width || - fmt1->fmt.pix.height != fmt2->fmt.pix.height; ++ return ctx->bufrefs != NULL; ++} ++ ++// Width/Height changed or we don't have an alloc in the first place? ++static int ctx_resolution_changed(const V4L2Context *ctx, const struct v4l2_format *fmt2) ++{ + const struct v4l2_format *fmt1 = &ctx->format; + int ret = !ctx_buffers_alloced(ctx) || + (V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ? @@ -50628,7 +51400,7 @@ index ff1ea8e57b..c0d257e5d3 100644 return ret; } -@@ -153,90 +153,110 @@ static inline void v4l2_save_to_context(V4L2Context* ctx, struct v4l2_format_upd +@@ -153,90 +305,110 @@ static inline void v4l2_save_to_context(V4L2Context* ctx, struct v4l2_format_upd } } @@ -50699,12 +51471,12 @@ index ff1ea8e57b..c0d257e5d3 100644 - s->output.sample_aspect_ratio = v4l2_get_sar(&s->output); - } + get_default_selection(&s->capture, &s->capture.selection); - -- reinit = v4l2_resolution_changed(&s->capture, &cap_fmt); ++ + reinit = ctx_resolution_changed(&s->capture, &cap_fmt); + if ((s->quirks & FF_V4L2_QUIRK_REINIT_ALWAYS) != 0) + reinit = 1; -+ + +- reinit = v4l2_resolution_changed(&s->capture, &cap_fmt); + s->capture.format = cap_fmt; if (reinit) { - s->capture.height = v4l2_get_height(&cap_fmt); @@ -50793,7 +51565,7 @@ index ff1ea8e57b..c0d257e5d3 100644 return 1; } -@@ -280,171 +300,275 @@ static int v4l2_stop_encode(V4L2Context *ctx) +@@ -280,171 +452,282 @@ static int v4l2_stop_encode(V4L2Context *ctx) return 0; } @@ -50879,16 +51651,18 @@ index ff1ea8e57b..c0d257e5d3 100644 } - ctx->done = 1; - return NULL; -+ } + } + atomic_fetch_sub(&ctx->q_count, 1); + + avbuf = (V4L2Buffer *)ctx->bufrefs[buf.index]->data; -+ avbuf->status = V4L2BUF_AVAILABLE; ++ ff_v4l2_buffer_set_avail(avbuf); + avbuf->buf = buf; + if (is_mp) { + memcpy(avbuf->planes, planes, sizeof(planes)); + avbuf->buf.m.planes = avbuf->planes; - } ++ } ++ // Done with any attached buffer ++ av_buffer_unref(&avbuf->ref_buf); -start: - if (V4L2_TYPE_IS_OUTPUT(ctx->type)) @@ -51165,6 +51939,15 @@ index ff1ea8e57b..c0d257e5d3 100644 + buf->sequence = 0; + + return avbuf; ++} ++ ++void ++ff_v4l2_dq_all(V4L2Context *const ctx) ++{ ++ V4L2Buffer * avbuf; ++ do { ++ get_qbuf(ctx, &avbuf, 0); ++ } while (avbuf); } static V4L2Buffer* v4l2_getfree_v4l2buf(V4L2Context *ctx) @@ -51173,14 +51956,12 @@ index ff1ea8e57b..c0d257e5d3 100644 int i; /* get back as many output buffers as possible */ - if (V4L2_TYPE_IS_OUTPUT(ctx->type)) { +- if (V4L2_TYPE_IS_OUTPUT(ctx->type)) { - do { - } while (v4l2_dequeue_v4l2buf(ctx, timeout)); -+ V4L2Buffer * avbuf; -+ do { -+ get_qbuf(ctx, &avbuf, 0); -+ } while (avbuf); - } +- } ++ if (V4L2_TYPE_IS_OUTPUT(ctx->type)) ++ ff_v4l2_dq_all(ctx); for (i = 0; i < ctx->num_buffers; i++) { - if (ctx->buffers[i].status == V4L2BUF_AVAILABLE) @@ -51191,7 +51972,7 @@ index ff1ea8e57b..c0d257e5d3 100644 } return NULL; -@@ -452,25 +576,45 @@ static V4L2Buffer* v4l2_getfree_v4l2buf(V4L2Context *ctx) +@@ -452,25 +735,45 @@ static V4L2Buffer* v4l2_getfree_v4l2buf(V4L2Context *ctx) static int v4l2_release_buffers(V4L2Context* ctx) { @@ -51221,16 +52002,16 @@ index ff1ea8e57b..c0d257e5d3 100644 + .type = ctx->type, + .count = 0, /* 0 -> unmap all buffers from the driver */ + }; -+ -+ while ((ret = ioctl(fd, VIDIOC_REQBUFS, &req)) == -1) { -+ if (errno == EINTR) -+ continue; - for (j = 0; j < buffer->num_planes; j++) { - struct V4L2Plane_info *p = &buffer->plane_info[j]; - if (p->mm_addr && p->length) - if (munmap(p->mm_addr, p->length) < 0) - av_log(logger(ctx), AV_LOG_ERROR, "%s unmap plane (%s))\n", ctx->name, av_err2str(AVERROR(errno))); ++ while ((ret = ioctl(fd, VIDIOC_REQBUFS, &req)) == -1) { ++ if (errno == EINTR) ++ continue; ++ + ret = AVERROR(errno); + + av_log(logger(ctx), AV_LOG_ERROR, "release all %s buffers (%s)\n", @@ -51251,7 +52032,7 @@ index ff1ea8e57b..c0d257e5d3 100644 } static inline int v4l2_try_raw_format(V4L2Context* ctx, enum AVPixelFormat pixfmt) -@@ -499,6 +643,8 @@ static inline int v4l2_try_raw_format(V4L2Context* ctx, enum AVPixelFormat pixfm +@@ -499,6 +802,8 @@ static inline int v4l2_try_raw_format(V4L2Context* ctx, enum AVPixelFormat pixfm static int v4l2_get_raw_format(V4L2Context* ctx, enum AVPixelFormat *p) { @@ -51260,7 +52041,7 @@ index ff1ea8e57b..c0d257e5d3 100644 enum AVPixelFormat pixfmt = ctx->av_pix_fmt; struct v4l2_fmtdesc fdesc; int ret; -@@ -517,6 +663,13 @@ static int v4l2_get_raw_format(V4L2Context* ctx, enum AVPixelFormat *p) +@@ -517,6 +822,13 @@ static int v4l2_get_raw_format(V4L2Context* ctx, enum AVPixelFormat *p) if (ret) return AVERROR(EINVAL); @@ -51274,7 +52055,7 @@ index ff1ea8e57b..c0d257e5d3 100644 pixfmt = ff_v4l2_format_v4l2_to_avfmt(fdesc.pixelformat, AV_CODEC_ID_RAWVIDEO); ret = v4l2_try_raw_format(ctx, pixfmt); if (ret){ -@@ -569,18 +722,83 @@ static int v4l2_get_coded_format(V4L2Context* ctx, uint32_t *p) +@@ -569,30 +881,99 @@ static int v4l2_get_coded_format(V4L2Context* ctx, uint32_t *p) * *****************************************************************************/ @@ -51289,7 +52070,7 @@ index ff1ea8e57b..c0d257e5d3 100644 + for (i = 0; i < ctx->num_buffers; ++i) { + struct V4L2Buffer * const buf = (struct V4L2Buffer *)ctx->bufrefs[i]->data; + if (buf->status == V4L2BUF_IN_DRIVER) -+ buf->status = V4L2BUF_AVAILABLE; ++ ff_v4l2_buffer_set_avail(buf); + } + atomic_store(&ctx->q_count, 0); +} @@ -51349,6 +52130,8 @@ index ff1ea8e57b..c0d257e5d3 100644 + { + if (cmd == VIDIOC_STREAMOFF) + flush_all_buffers_status(ctx); ++ else ++ ctx->first_buf = 1; + + ctx->streamon = (cmd == VIDIOC_STREAMON); + av_log(avctx, AV_LOG_DEBUG, "%s set status %d (%s) OK\n", ctx->name, @@ -51364,7 +52147,33 @@ index ff1ea8e57b..c0d257e5d3 100644 } int ff_v4l2_context_enqueue_frame(V4L2Context* ctx, const AVFrame* frame) -@@ -608,7 +826,8 @@ int ff_v4l2_context_enqueue_frame(V4L2Context* ctx, const AVFrame* frame) + { +- V4L2m2mContext *s = ctx_to_m2mctx(ctx); ++ V4L2m2mContext *const s = ctx_to_m2mctx(ctx); ++ AVCodecContext *const avctx = s->avctx; ++ int64_t track_ts; + V4L2Buffer* avbuf; + int ret; + + if (!frame) { + ret = v4l2_stop_encode(ctx); + if (ret) +- av_log(logger(ctx), AV_LOG_ERROR, "%s stop_encode\n", ctx->name); ++ av_log(avctx, AV_LOG_ERROR, "%s stop_encode\n", ctx->name); + s->draining= 1; + return 0; + } +@@ -601,23 +982,29 @@ int ff_v4l2_context_enqueue_frame(V4L2Context* ctx, const AVFrame* frame) + if (!avbuf) + return AVERROR(EAGAIN); + +- ret = ff_v4l2_buffer_avframe_to_buf(frame, avbuf); ++ track_ts = xlat_pts_frame_in(avctx, &s->xlat, frame); ++ ++ ret = ff_v4l2_buffer_avframe_to_buf(frame, avbuf, track_ts); + if (ret) + return ret; + return ff_v4l2_buffer_enqueue(avbuf); } @@ -51373,25 +52182,29 @@ index ff1ea8e57b..c0d257e5d3 100644 + const void * extdata, size_t extlen) { V4L2m2mContext *s = ctx_to_m2mctx(ctx); ++ AVCodecContext *const avctx = s->avctx; V4L2Buffer* avbuf; -@@ -616,8 +835,9 @@ int ff_v4l2_context_enqueue_packet(V4L2Context* ctx, const AVPacket* pkt) + int ret; ++ int64_t track_ts; if (!pkt->size) { ret = v4l2_stop_decode(ctx); + // Log but otherwise ignore stop failure if (ret) - av_log(logger(ctx), AV_LOG_ERROR, "%s stop_decode\n", ctx->name); -+ av_log(logger(ctx), AV_LOG_ERROR, "%s stop_decode failed: err=%d\n", ctx->name, ret); ++ av_log(avctx, AV_LOG_ERROR, "%s stop_decode failed: err=%d\n", ctx->name, ret); s->draining = 1; return 0; } -@@ -626,8 +846,11 @@ int ff_v4l2_context_enqueue_packet(V4L2Context* ctx, const AVPacket* pkt) +@@ -626,8 +1013,13 @@ int ff_v4l2_context_enqueue_packet(V4L2Context* ctx, const AVPacket* pkt) if (!avbuf) return AVERROR(EAGAIN); - ret = ff_v4l2_buffer_avpkt_to_buf(pkt, avbuf); - if (ret) -+ ret = ff_v4l2_buffer_avpkt_to_buf_ext(pkt, avbuf, extdata, extlen); ++ track_ts = xlat_pts_pkt_in(avctx, &s->xlat, pkt); ++ ++ ret = ff_v4l2_buffer_avpkt_to_buf_ext(pkt, avbuf, extdata, extlen, track_ts); + if (ret == AVERROR(ENOMEM)) + av_log(logger(ctx), AV_LOG_ERROR, "Buffer overflow in %s: pkt->size=%d > buf->length=%d\n", + __func__, pkt->size, avbuf->planes[0].length); @@ -51399,9 +52212,12 @@ index ff1ea8e57b..c0d257e5d3 100644 return ret; return ff_v4l2_buffer_enqueue(avbuf); -@@ -636,19 +859,10 @@ int ff_v4l2_context_enqueue_packet(V4L2Context* ctx, const AVPacket* pkt) +@@ -635,42 +1027,36 @@ int ff_v4l2_context_enqueue_packet(V4L2Context* ctx, const AVPacket* pkt) + int ff_v4l2_context_dequeue_frame(V4L2Context* ctx, AVFrame* frame, int timeout) { ++ V4L2m2mContext *s = ctx_to_m2mctx(ctx); ++ AVCodecContext *const avctx = s->avctx; V4L2Buffer *avbuf; + int rv; @@ -51417,14 +52233,21 @@ index ff1ea8e57b..c0d257e5d3 100644 - - return AVERROR(EAGAIN); - } -+ if ((rv = get_qbuf(ctx, &avbuf, timeout)) != 0) -+ return rv; ++ do { ++ if ((rv = get_qbuf(ctx, &avbuf, timeout)) != 0) ++ return rv; ++ if ((rv = ff_v4l2_buffer_buf_to_avframe(frame, avbuf)) != 0) ++ return rv; ++ } while (xlat_pts_frame_out(avctx, &s->xlat, frame) != 0); - return ff_v4l2_buffer_buf_to_avframe(frame, avbuf); +- return ff_v4l2_buffer_buf_to_avframe(frame, avbuf); ++ return 0; } -@@ -656,19 +870,10 @@ int ff_v4l2_context_dequeue_frame(V4L2Context* ctx, AVFrame* frame, int timeout) + int ff_v4l2_context_dequeue_packet(V4L2Context* ctx, AVPacket* pkt) { ++ V4L2m2mContext *s = ctx_to_m2mctx(ctx); ++ AVCodecContext *const avctx = s->avctx; V4L2Buffer *avbuf; + int rv; @@ -51440,12 +52263,19 @@ index ff1ea8e57b..c0d257e5d3 100644 - - return AVERROR(EAGAIN); - } -+ if ((rv = get_qbuf(ctx, &avbuf, -1)) != 0) -+ return rv == AVERROR(ENOSPC) ? AVERROR(EAGAIN) : rv; // Caller not currently expecting ENOSPC ++ do { ++ if ((rv = get_qbuf(ctx, &avbuf, -1)) != 0) ++ return rv == AVERROR(ENOSPC) ? AVERROR(EAGAIN) : rv; // Caller not currently expecting ENOSPC ++ if ((rv = ff_v4l2_buffer_buf_to_avpkt(pkt, avbuf)) != 0) ++ return rv; ++ } while (xlat_pts_pkt_out(avctx, &s->xlat, pkt) != 0); - return ff_v4l2_buffer_buf_to_avpkt(pkt, avbuf); +- return ff_v4l2_buffer_buf_to_avpkt(pkt, avbuf); ++ return 0; } -@@ -702,78 +907,160 @@ int ff_v4l2_context_get_format(V4L2Context* ctx, int probe) + + int ff_v4l2_context_get_format(V4L2Context* ctx, int probe) +@@ -702,78 +1088,179 @@ int ff_v4l2_context_get_format(V4L2Context* ctx, int probe) int ff_v4l2_context_set_format(V4L2Context* ctx) { @@ -51497,7 +52327,7 @@ index ff1ea8e57b..c0d257e5d3 100644 -int ff_v4l2_context_init(V4L2Context* ctx) + -+static int create_buffers(V4L2Context* const ctx, const unsigned int req_buffers) ++static int create_buffers(V4L2Context* const ctx, const unsigned int req_buffers, const enum v4l2_memory mem) { - V4L2m2mContext *s = ctx_to_m2mctx(ctx); + V4L2m2mContext * const s = ctx_to_m2mctx(ctx); @@ -51518,8 +52348,9 @@ index ff1ea8e57b..c0d257e5d3 100644 memset(&req, 0, sizeof(req)); - req.count = ctx->num_buffers; +- req.memory = V4L2_MEMORY_MMAP; + req.count = req_buffers; - req.memory = V4L2_MEMORY_MMAP; ++ req.memory = mem; req.type = ctx->type; - ret = ioctl(s->fd, VIDIOC_REQBUFS, &req); - if (ret < 0) { @@ -51554,7 +52385,7 @@ index ff1ea8e57b..c0d257e5d3 100644 + } + + for (i = 0; i < ctx->num_buffers; i++) { -+ ret = ff_v4l2_buffer_initialize(&ctx->bufrefs[i], i, ctx); ++ ret = ff_v4l2_buffer_initialize(&ctx->bufrefs[i], i, ctx, mem); + if (ret) { av_log(logger(ctx), AV_LOG_ERROR, "%s buffer[%d] initialization (%s)\n", ctx->name, i, av_err2str(ret)); - goto error; @@ -51583,6 +52414,7 @@ index ff1ea8e57b..c0d257e5d3 100644 + +int ff_v4l2_context_init(V4L2Context* ctx) +{ ++ struct v4l2_queryctrl qctrl; + V4L2m2mContext * const s = ctx_to_m2mctx(ctx); + int ret; + @@ -51597,7 +52429,8 @@ index ff1ea8e57b..c0d257e5d3 100644 + ff_mutex_init(&ctx->lock, NULL); + pthread_cond_init(&ctx->cond, NULL); + atomic_init(&ctx->q_count, 0); -+ + +- av_freep(&ctx->buffers); + if (s->output_drm) { + AVHWFramesContext *hwframes; + @@ -51616,8 +52449,7 @@ index ff1ea8e57b..c0d257e5d3 100644 + if (ret < 0) + goto fail_unref_hwframes; + } - -- av_freep(&ctx->buffers); ++ + ret = ioctl(s->fd, VIDIOC_G_FMT, &ctx->format); + if (ret) { + ret = AVERROR(errno); @@ -51625,7 +52457,25 @@ index ff1ea8e57b..c0d257e5d3 100644 + goto fail_unref_hwframes; + } + -+ ret = create_buffers(ctx, ctx->num_buffers); ++ memset(&qctrl, 0, sizeof(qctrl)); ++ qctrl.id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT; ++ if (ioctl(s->fd, VIDIOC_QUERYCTRL, &qctrl) != 0) { ++ ret = AVERROR(errno); ++ if (ret != AVERROR(EINVAL)) { ++ av_log(logger(ctx), AV_LOG_ERROR, "%s VIDIOC_QUERCTRL failed: %s\n", ctx->name, av_err2str(ret)); ++ goto fail_unref_hwframes; ++ } ++ // Control unsupported - set default if wanted ++ if (ctx->num_buffers < 2) ++ ctx->num_buffers = 4; ++ } ++ else { ++ if (ctx->num_buffers < 2) ++ ctx->num_buffers = qctrl.minimum + 2; ++ ctx->num_buffers = av_clip(ctx->num_buffers, qctrl.minimum, qctrl.maximum); ++ } ++ ++ ret = create_buffers(ctx, ctx->num_buffers, ctx->buf_mem); + if (ret < 0) + goto fail_unref_hwframes; + @@ -51638,7 +52488,7 @@ index ff1ea8e57b..c0d257e5d3 100644 return ret; } diff --git a/libavcodec/v4l2_context.h b/libavcodec/v4l2_context.h -index 22a9532444..a56216e990 100644 +index 22a9532444..311b6f10a4 100644 --- a/libavcodec/v4l2_context.h +++ b/libavcodec/v4l2_context.h @@ -31,6 +31,7 @@ @@ -51649,7 +52499,7 @@ index 22a9532444..a56216e990 100644 #include "v4l2_buffers.h" typedef struct V4L2Context { -@@ -70,11 +71,18 @@ typedef struct V4L2Context { +@@ -70,28 +71,57 @@ typedef struct V4L2Context { */ int width, height; AVRational sample_aspect_ratio; @@ -51670,18 +52520,35 @@ index 22a9532444..a56216e990 100644 /** * Readonly after init. -@@ -92,6 +100,21 @@ typedef struct V4L2Context { + */ + int num_buffers; + ++ /** ++ * Buffer memory type V4L2_MEMORY_MMAP or V4L2_MEMORY_DMABUF ++ */ ++ enum v4l2_memory buf_mem; ++ + /** + * Whether the stream has been started (VIDIOC_STREAMON has been sent). + */ + int streamon; + ++ /* 1st buffer after stream on */ ++ int first_buf; ++ + /** + * Either no more buffers available or an unrecoverable error was notified + * by the V4L2 kernel driver: once set the context has to be exited. */ int done; + int flag_last; + + /** -+ * PTS rescale not wanted -+ * If the PTS is just a dummy frame count then rescale is -+ * actively harmful ++ * If NZ then when Qing frame/pkt use this rather than the ++ * "real" PTS + */ -+ int no_pts_rescale; ++ uint64_t track_ts; + + AVBufferRef *frames_ref; + atomic_int q_count; @@ -51692,7 +52559,7 @@ index 22a9532444..a56216e990 100644 } V4L2Context; /** -@@ -156,7 +179,10 @@ int ff_v4l2_context_dequeue_packet(V4L2Context* ctx, AVPacket* pkt); +@@ -156,7 +186,10 @@ int ff_v4l2_context_dequeue_packet(V4L2Context* ctx, AVPacket* pkt); * @param[in] ctx The V4L2Context to dequeue from. * @param[inout] f The AVFrame to dequeue to. * @param[in] timeout The timeout for dequeue (-1 to block, 0 to return immediately, or milliseconds) @@ -51703,7 +52570,7 @@ index 22a9532444..a56216e990 100644 */ int ff_v4l2_context_dequeue_frame(V4L2Context* ctx, AVFrame* f, int timeout); -@@ -170,7 +196,7 @@ int ff_v4l2_context_dequeue_frame(V4L2Context* ctx, AVFrame* f, int timeout); +@@ -170,7 +203,7 @@ int ff_v4l2_context_dequeue_frame(V4L2Context* ctx, AVFrame* f, int timeout); * @param[in] pkt A pointer to an AVPacket. * @return 0 in case of success, a negative error otherwise. */ @@ -51712,11 +52579,43 @@ index 22a9532444..a56216e990 100644 /** * Enqueues a buffer to a V4L2Context from an AVFrame +@@ -183,4 +216,6 @@ int ff_v4l2_context_enqueue_packet(V4L2Context* ctx, const AVPacket* pkt); + */ + int ff_v4l2_context_enqueue_frame(V4L2Context* ctx, const AVFrame* f); + ++void ff_v4l2_dq_all(V4L2Context *const ctx); ++ + #endif // AVCODEC_V4L2_CONTEXT_H diff --git a/libavcodec/v4l2_m2m.c b/libavcodec/v4l2_m2m.c -index cdfd579810..f14ed0b708 100644 +index cdfd579810..77fe5fc4e3 100644 --- a/libavcodec/v4l2_m2m.c +++ b/libavcodec/v4l2_m2m.c -@@ -215,13 +215,7 @@ int ff_v4l2_m2m_codec_reinit(V4L2m2mContext *s) +@@ -36,6 +36,14 @@ + #include "v4l2_fmt.h" + #include "v4l2_m2m.h" + ++static void ++xlat_init(xlat_track_t * const x) ++{ ++ memset(x, 0, sizeof(*x)); ++ x->last_pts = AV_NOPTS_VALUE; ++} ++ ++ + static inline int v4l2_splane_video(struct v4l2_capability *cap) + { + if (cap->capabilities & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT) && +@@ -68,7 +76,9 @@ static int v4l2_prepare_contexts(V4L2m2mContext *s, int probe) + + s->capture.done = s->output.done = 0; + s->capture.name = "capture"; ++ s->capture.buf_mem = V4L2_MEMORY_MMAP; + s->output.name = "output"; ++ s->output.buf_mem = s->input_drm ? V4L2_MEMORY_DMABUF : V4L2_MEMORY_MMAP; + atomic_init(&s->refcount, 0); + sem_init(&s->refsync, 0, 0); + +@@ -215,13 +225,7 @@ int ff_v4l2_m2m_codec_reinit(V4L2m2mContext *s) av_log(log_ctx, AV_LOG_ERROR, "capture VIDIOC_STREAMOFF\n"); /* 2. unmap the capture buffers (v4l2 and ffmpeg): @@ -51730,7 +52629,7 @@ index cdfd579810..f14ed0b708 100644 ff_v4l2_context_release(&s->capture); /* 3. get the new capture format */ -@@ -240,7 +234,6 @@ int ff_v4l2_m2m_codec_reinit(V4L2m2mContext *s) +@@ -240,7 +244,6 @@ int ff_v4l2_m2m_codec_reinit(V4L2m2mContext *s) /* 5. complete reinit */ s->draining = 0; @@ -51738,7 +52637,7 @@ index cdfd579810..f14ed0b708 100644 return 0; } -@@ -274,7 +267,6 @@ int ff_v4l2_m2m_codec_full_reinit(V4L2m2mContext *s) +@@ -274,7 +277,6 @@ int ff_v4l2_m2m_codec_full_reinit(V4L2m2mContext *s) /* start again now that we know the stream dimensions */ s->draining = 0; @@ -51746,7 +52645,7 @@ index cdfd579810..f14ed0b708 100644 ret = ff_v4l2_context_get_format(&s->output, 0); if (ret) { -@@ -328,10 +320,14 @@ static void v4l2_m2m_destroy_context(void *opaque, uint8_t *context) +@@ -328,10 +330,14 @@ static void v4l2_m2m_destroy_context(void *opaque, uint8_t *context) ff_v4l2_context_release(&s->capture); sem_destroy(&s->refsync); @@ -51762,7 +52661,7 @@ index cdfd579810..f14ed0b708 100644 av_free(s); } -@@ -344,6 +340,11 @@ int ff_v4l2_m2m_codec_end(V4L2m2mPriv *priv) +@@ -344,6 +350,11 @@ int ff_v4l2_m2m_codec_end(V4L2m2mPriv *priv) if (!s) return 0; @@ -51774,7 +52673,7 @@ index cdfd579810..f14ed0b708 100644 if (s->fd >= 0) { ret = ff_v4l2_context_set_status(&s->output, VIDIOC_STREAMOFF); if (ret) -@@ -356,7 +357,14 @@ int ff_v4l2_m2m_codec_end(V4L2m2mPriv *priv) +@@ -356,7 +367,14 @@ int ff_v4l2_m2m_codec_end(V4L2m2mPriv *priv) ff_v4l2_context_release(&s->output); @@ -51789,8 +52688,59 @@ index cdfd579810..f14ed0b708 100644 av_buffer_unref(&priv->context_ref); return 0; +@@ -400,35 +418,38 @@ int ff_v4l2_m2m_codec_init(V4L2m2mPriv *priv) + return v4l2_configure_contexts(s); + } + +-int ff_v4l2_m2m_create_context(V4L2m2mPriv *priv, V4L2m2mContext **s) ++int ff_v4l2_m2m_create_context(V4L2m2mPriv *priv, V4L2m2mContext **pps) + { +- *s = av_mallocz(sizeof(V4L2m2mContext)); +- if (!*s) ++ V4L2m2mContext * const s = av_mallocz(sizeof(V4L2m2mContext)); ++ ++ *pps = NULL; ++ if (!s) + return AVERROR(ENOMEM); + +- priv->context_ref = av_buffer_create((uint8_t *) *s, sizeof(V4L2m2mContext), ++ priv->context_ref = av_buffer_create((uint8_t *)s, sizeof(*s), + &v4l2_m2m_destroy_context, NULL, 0); + if (!priv->context_ref) { +- av_freep(s); ++ av_free(s); + return AVERROR(ENOMEM); + } + + /* assign the context */ +- priv->context = *s; +- (*s)->priv = priv; ++ priv->context = s; ++ s->priv = priv; + + /* populate it */ +- priv->context->capture.num_buffers = priv->num_capture_buffers; +- priv->context->output.num_buffers = priv->num_output_buffers; +- priv->context->self_ref = priv->context_ref; +- priv->context->fd = -1; ++ s->capture.num_buffers = priv->num_capture_buffers; ++ s->output.num_buffers = priv->num_output_buffers; ++ s->self_ref = priv->context_ref; ++ s->fd = -1; ++ xlat_init(&s->xlat); + + priv->context->frame = av_frame_alloc(); + if (!priv->context->frame) { + av_buffer_unref(&priv->context_ref); +- *s = NULL; /* freed when unreferencing context_ref */ + return AVERROR(ENOMEM); + } + ++ *pps = s; + return 0; + } diff --git a/libavcodec/v4l2_m2m.h b/libavcodec/v4l2_m2m.h -index b67b216331..19d618698d 100644 +index b67b216331..babf101d65 100644 --- a/libavcodec/v4l2_m2m.h +++ b/libavcodec/v4l2_m2m.h @@ -30,6 +30,7 @@ @@ -51801,7 +52751,7 @@ index b67b216331..19d618698d 100644 #include "v4l2_context.h" #define container_of(ptr, type, member) ({ \ -@@ -38,7 +39,38 @@ +@@ -38,7 +39,37 @@ #define V4L_M2M_DEFAULT_OPTS \ { "num_output_buffers", "Number of buffers in the output context",\ @@ -51834,14 +52784,13 @@ index b67b216331..19d618698d 100644 +typedef struct xlat_track_s { + unsigned int track_no; + int64_t last_pts; -+ int64_t last_pkt_dts; + int64_t last_opaque; + V4L2m2mTrackEl track_els[FF_V4L2_M2M_TRACK_SIZE]; +} xlat_track_t; typedef struct V4L2m2mContext { char devname[PATH_MAX]; -@@ -52,7 +84,6 @@ typedef struct V4L2m2mContext { +@@ -52,7 +83,6 @@ typedef struct V4L2m2mContext { AVCodecContext *avctx; sem_t refsync; atomic_uint refcount; @@ -51849,7 +52798,7 @@ index b67b216331..19d618698d 100644 /* null frame/packet received */ int draining; -@@ -66,6 +97,33 @@ typedef struct V4L2m2mContext { +@@ -66,6 +96,36 @@ typedef struct V4L2m2mContext { /* reference back to V4L2m2mPriv */ void *priv; @@ -51859,6 +52808,9 @@ index b67b216331..19d618698d 100644 + /* generate DRM frames */ + int output_drm; + ++ /* input frames are drmprime */ ++ int input_drm; ++ + /* Frame tracking */ + xlat_track_t xlat; + int pending_hw; @@ -51872,7 +52824,7 @@ index b67b216331..19d618698d 100644 + /* Ext data sent */ + int extdata_sent; + /* Ext data sent in packet - overrides ctx */ -+ uint8_t * extdata_data; ++ void * extdata_data; + size_t extdata_size; + +#define FF_V4L2_QUIRK_REINIT_ALWAYS 1 @@ -51883,7 +52835,7 @@ index b67b216331..19d618698d 100644 } V4L2m2mContext; typedef struct V4L2m2mPriv { -@@ -76,6 +134,7 @@ typedef struct V4L2m2mPriv { +@@ -76,6 +136,7 @@ typedef struct V4L2m2mPriv { int num_output_buffers; int num_capture_buffers; @@ -51891,7 +52843,7 @@ index b67b216331..19d618698d 100644 } V4L2m2mPriv; /** -@@ -129,4 +188,26 @@ int ff_v4l2_m2m_codec_reinit(V4L2m2mContext *ctx); +@@ -129,4 +190,26 @@ int ff_v4l2_m2m_codec_reinit(V4L2m2mContext *ctx); */ int ff_v4l2_m2m_codec_full_reinit(V4L2m2mContext *ctx); @@ -51919,7 +52871,7 @@ index b67b216331..19d618698d 100644 + #endif /* AVCODEC_V4L2_M2M_H */ diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c -index ab07c0a24a..dd383f31e5 100644 +index ab07c0a24a..18f3bc7ff2 100644 --- a/libavcodec/v4l2_m2m_dec.c +++ b/libavcodec/v4l2_m2m_dec.c @@ -23,6 +23,10 @@ @@ -51933,7 +52885,7 @@ index ab07c0a24a..dd383f31e5 100644 #include "libavutil/pixfmt.h" #include "libavutil/pixdesc.h" #include "libavutil/opt.h" -@@ -30,75 +34,107 @@ +@@ -30,75 +34,264 @@ #include "libavcodec/decode.h" #include "libavcodec/internal.h" @@ -51950,18 +52902,22 @@ index ab07c0a24a..dd383f31e5 100644 +#define STATS_LAST_COUNT_MAX 64 +#define STATS_INTERVAL_MAX (1 << 30) + -+static int64_t pts_stats_guess(const pts_stats_t * const stats) ++#ifndef FF_API_BUFFER_SIZE_T ++#define FF_API_BUFFER_SIZE_T 1 ++#endif ++ ++#define DUMP_FAILED_EXTRADATA 0 ++ ++#if DUMP_FAILED_EXTRADATA ++static inline char hex1(unsigned int x) { - V4L2m2mContext *s = ((V4L2m2mPriv*)avctx->priv_data)->context; - V4L2Context *const capture = &s->capture; - V4L2Context *const output = &s->output; - struct v4l2_selection selection = { 0 }; - int ret; -+ if (stats->last_pts == AV_NOPTS_VALUE || -+ stats->last_interval == 0 || -+ stats->last_count >= STATS_LAST_COUNT_MAX) -+ return AV_NOPTS_VALUE; -+ return stats->last_pts + (int64_t)(stats->last_count - 1) * (int64_t)stats->last_interval; ++ x &= 0xf; ++ return x <= 9 ? '0' + x : 'a' + x - 10; +} - /* 1. start the output process */ @@ -51970,17 +52926,104 @@ index ab07c0a24a..dd383f31e5 100644 - if (ret < 0) { - av_log(avctx, AV_LOG_DEBUG, "VIDIOC_STREAMON on output context\n"); - return ret; +- } ++static inline char * hex2(char * s, unsigned int x) ++{ ++ *s++ = hex1(x >> 4); ++ *s++ = hex1(x); ++ return s; ++} ++ ++static inline char * hex4(char * s, unsigned int x) ++{ ++ s = hex2(s, x >> 8); ++ s = hex2(s, x); ++ return s; ++} ++ ++static inline char * dash2(char * s) ++{ ++ *s++ = '-'; ++ *s++ = '-'; ++ return s; ++} ++ ++static void ++data16(char * s, const unsigned int offset, const uint8_t * m, const size_t len) ++{ ++ size_t i; ++ s = hex4(s, offset); ++ m += offset; ++ for (i = 0; i != 8; ++i) { ++ *s++ = ' '; ++ s = len > i + offset ? hex2(s, *m++) : dash2(s); ++ } ++ *s++ = ' '; ++ *s++ = ':'; ++ for (; i != 16; ++i) { ++ *s++ = ' '; ++ s = len > i + offset ? hex2(s, *m++) : dash2(s); + } ++ *s++ = 0; ++} + +- if (capture->streamon) +- return 0; ++static void ++log_dump(void * logctx, int lvl, const void * const data, const size_t len) ++{ ++ size_t i; ++ for (i = 0; i < len; i += 16) { ++ char buf[80]; ++ data16(buf, i, data, len); ++ av_log(logctx, lvl, "%s\n", buf); ++ } ++} ++#endif + +- /* 2. get the capture format */ +- capture->format.type = capture->type; +- ret = ioctl(s->fd, VIDIOC_G_FMT, &capture->format); +- if (ret) { +- av_log(avctx, AV_LOG_WARNING, "VIDIOC_G_FMT ioctl\n"); +- return ret; ++static int64_t pts_stats_guess(const pts_stats_t * const stats) ++{ ++ if (stats->last_pts == AV_NOPTS_VALUE || ++ stats->last_interval == 0 || ++ stats->last_count >= STATS_LAST_COUNT_MAX) ++ return AV_NOPTS_VALUE; ++ return stats->last_pts + (int64_t)(stats->last_count - 1) * (int64_t)stats->last_interval; ++} ++ +static void pts_stats_add(pts_stats_t * const stats, int64_t pts) +{ + if (pts == AV_NOPTS_VALUE || pts == stats->last_pts) { + if (stats->last_count < STATS_LAST_COUNT_MAX) + ++stats->last_count; + return; -+ } -+ + } + +- /* 2.1 update the AVCodecContext */ +- avctx->pix_fmt = ff_v4l2_format_v4l2_to_avfmt(capture->format.fmt.pix_mp.pixelformat, AV_CODEC_ID_RAWVIDEO); +- capture->av_pix_fmt = avctx->pix_fmt; + if (stats->last_pts != AV_NOPTS_VALUE) { + const int64_t interval = pts - stats->last_pts; -+ + +- /* 3. set the crop parameters */ +- selection.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; +- selection.r.height = avctx->coded_height; +- selection.r.width = avctx->coded_width; +- ret = ioctl(s->fd, VIDIOC_S_SELECTION, &selection); +- if (!ret) { +- ret = ioctl(s->fd, VIDIOC_G_SELECTION, &selection); +- if (ret) { +- av_log(avctx, AV_LOG_WARNING, "VIDIOC_G_SELECTION ioctl\n"); +- } else { +- av_log(avctx, AV_LOG_DEBUG, "crop output %dx%d\n", selection.r.width, selection.r.height); +- /* update the size of the resulting frame */ +- capture->height = selection.r.height; +- capture->width = selection.r.width; + if (interval < 0 || interval >= STATS_INTERVAL_MAX || + stats->last_count >= STATS_LAST_COUNT_MAX) { + if (stats->last_interval != 0) @@ -51998,7 +53041,12 @@ index ab07c0a24a..dd383f31e5 100644 } } -- if (capture->streamon) +- /* 4. init the capture context now that we have the capture format */ +- if (!capture->buffers) { +- ret = ff_v4l2_context_init(capture); +- if (ret) { +- av_log(avctx, AV_LOG_ERROR, "can't request capture buffers\n"); +- return AVERROR(ENOMEM); + stats->last_pts = pts; + stats->last_count = 1; +} @@ -52014,6 +53062,102 @@ index ab07c0a24a..dd383f31e5 100644 + }; +} + ++// If abdata == NULL then this just counts space required ++// Unpacks avcC if detected ++static int ++h264_xd_copy(const uint8_t * const extradata, const int extrasize, uint8_t * abdata) ++{ ++ const uint8_t * const xdend = extradata + extrasize; ++ const uint8_t * p = extradata; ++ uint8_t * d = abdata; ++ unsigned int n; ++ unsigned int len; ++ const unsigned int hdrlen = 4; ++ unsigned int need_pps = 1; ++ ++ if (extrasize < 8) ++ return AVERROR(EINVAL); ++ ++ if (p[0] == 0 && p[1] == 0) { ++ // Assume a couple of leading zeros are good enough to indicate NAL ++ if (abdata) ++ memcpy(d, p, extrasize); ++ return extrasize; ++ } ++ ++ // avcC starts with a 1 ++ if (p[0] != 1) ++ return AVERROR(EINVAL); ++ ++ p += 5; ++ n = *p++ & 0x1f; ++ ++doxps: ++ while (n--) { ++ if (xdend - p < 2) ++ return AVERROR(EINVAL); ++ len = (p[0] << 8) | p[1]; ++ p += 2; ++ if (xdend - p < (ptrdiff_t)len) ++ return AVERROR(EINVAL); ++ if (abdata) { ++ d[0] = 0; ++ d[1] = 0; ++ d[2] = 0; ++ d[3] = 1; ++ memcpy(d + 4, p, len); + } ++ d += len + hdrlen; ++ p += len; ++ } ++ if (need_pps) { ++ need_pps = 0; ++ if (p >= xdend) ++ return AVERROR(EINVAL); ++ n = *p++; ++ goto doxps; + } + +- /* 5. start the capture process */ +- ret = ff_v4l2_context_set_status(capture, VIDIOC_STREAMON); +- if (ret) { +- av_log(avctx, AV_LOG_DEBUG, "VIDIOC_STREAMON, on capture context\n"); ++ return d - abdata; ++} ++ ++static int ++copy_extradata(AVCodecContext * const avctx, ++ const void * const src_data, const int src_len, ++ void ** const pdst_data, size_t * const pdst_len) ++{ ++ int len; ++ ++ *pdst_len = 0; ++ av_freep(pdst_data); ++ ++ if (avctx->codec_id == AV_CODEC_ID_H264) ++ len = h264_xd_copy(src_data, src_len, NULL); ++ else ++ len = src_len < 0 ? AVERROR(EINVAL) : src_len; ++ ++ // Zero length is OK but we swant to stop - -ve is error val ++ if (len <= 0) ++ return len; ++ ++ if ((*pdst_data = av_malloc(len + AV_INPUT_BUFFER_PADDING_SIZE)) == NULL) ++ return AVERROR(ENOMEM); ++ ++ if (avctx->codec_id == AV_CODEC_ID_H264) ++ h264_xd_copy(src_data, src_len, *pdst_data); ++ else ++ memcpy(*pdst_data, src_data, len); ++ *pdst_len = len; ++ ++ return 0; ++} ++ ++ ++ +static int check_output_streamon(AVCodecContext *const avctx, V4L2m2mContext *const s) +{ + int ret; @@ -52023,163 +53167,47 @@ index ab07c0a24a..dd383f31e5 100644 + }; + + if (s->output.streamon) - return 0; - -- /* 2. get the capture format */ -- capture->format.type = capture->type; -- ret = ioctl(s->fd, VIDIOC_G_FMT, &capture->format); -- if (ret) { -- av_log(avctx, AV_LOG_WARNING, "VIDIOC_G_FMT ioctl\n"); ++ return 0; ++ + ret = ff_v4l2_context_set_status(&s->output, VIDIOC_STREAMON); + if (ret != 0) { + av_log(avctx, AV_LOG_ERROR, "VIDIOC_STREAMON on output context: %s\n", av_err2str(ret)); return ret; } -- /* 2.1 update the AVCodecContext */ -- avctx->pix_fmt = ff_v4l2_format_v4l2_to_avfmt(capture->format.fmt.pix_mp.pixelformat, AV_CODEC_ID_RAWVIDEO); -- capture->av_pix_fmt = avctx->pix_fmt; -- -- /* 3. set the crop parameters */ -- selection.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -- selection.r.height = avctx->coded_height; -- selection.r.width = avctx->coded_width; -- ret = ioctl(s->fd, VIDIOC_S_SELECTION, &selection); -- if (!ret) { -- ret = ioctl(s->fd, VIDIOC_G_SELECTION, &selection); -- if (ret) { -- av_log(avctx, AV_LOG_WARNING, "VIDIOC_G_SELECTION ioctl\n"); -- } else { -- av_log(avctx, AV_LOG_DEBUG, "crop output %dx%d\n", selection.r.width, selection.r.height); -- /* update the size of the resulting frame */ -- capture->height = selection.r.height; -- capture->width = selection.r.width; -- } + // STREAMON should do implicit START so this just for those that don't. + // It is optional so don't worry if it fails + if (ioctl(s->fd, VIDIOC_DECODER_CMD, &cmd) < 0) { + ret = AVERROR(errno); + av_log(avctx, AV_LOG_WARNING, "VIDIOC_DECODER_CMD start error: %s\n", av_err2str(ret)); - } -- -- /* 4. init the capture context now that we have the capture format */ -- if (!capture->buffers) { -- ret = ff_v4l2_context_init(capture); -- if (ret) { -- av_log(avctx, AV_LOG_ERROR, "can't request capture buffers\n"); -- return AVERROR(ENOMEM); -- } ++ } + else { + av_log(avctx, AV_LOG_TRACE, "VIDIOC_DECODER_CMD start OK\n"); - } ++ } + return 0; +} - -- /* 5. start the capture process */ -- ret = ff_v4l2_context_set_status(capture, VIDIOC_STREAMON); -- if (ret) { -- av_log(avctx, AV_LOG_DEBUG, "VIDIOC_STREAMON, on capture context\n"); -- return ret; -- } ++ +static int v4l2_try_start(AVCodecContext *avctx) +{ + V4L2m2mContext * const s = ((V4L2m2mPriv*)avctx->priv_data)->context; + int ret; - ++ + /* 1. start the output process */ + if ((ret = check_output_streamon(avctx, s)) != 0) + return ret; return 0; } -@@ -133,58 +169,637 @@ static int v4l2_prepare_decoder(V4L2m2mContext *s) +@@ -133,58 +326,548 @@ static int v4l2_prepare_decoder(V4L2m2mContext *s) return 0; } -static int v4l2_receive_frame(AVCodecContext *avctx, AVFrame *frame) -+static inline int64_t track_to_pts(AVCodecContext *avctx, unsigned int n) -+{ -+ return (int64_t)n; -+} -+ -+static inline unsigned int pts_to_track(AVCodecContext *avctx, const int64_t pts) -+{ -+ return (unsigned int)pts; -+} -+ -+// FFmpeg requires us to propagate a number of vars from the coded pkt into -+// the decoded frame. The only thing that tracks like that in V4L2 stateful -+// is timestamp. PTS maps to timestamp for this decode. FFmpeg makes no -+// guarantees about PTS being unique or specified for every frame so replace -+// the supplied PTS with a simple incrementing number and keep a circular -+// buffer of all the things we want preserved (including the original PTS) -+// indexed by the tracking no. +static void -+xlat_pts_in(AVCodecContext *const avctx, xlat_track_t *const x, AVPacket *const avpkt) -+{ -+ int64_t track_pts; -+ -+ // Avoid 0 -+ if (++x->track_no == 0) -+ x->track_no = 1; -+ -+ track_pts = track_to_pts(avctx, x->track_no); -+ -+ av_log(avctx, AV_LOG_TRACE, "In PTS=%" PRId64 ", DTS=%" PRId64 ", track=%" PRId64 ", n=%u\n", avpkt->pts, avpkt->dts, track_pts, x->track_no); -+ x->last_pkt_dts = avpkt->dts; -+ x->track_els[x->track_no % FF_V4L2_M2M_TRACK_SIZE] = (V4L2m2mTrackEl){ -+ .discard = 0, -+ .pending = 1, -+ .pkt_size = avpkt->size, -+ .pts = avpkt->pts, -+ .dts = avpkt->dts, -+ .reordered_opaque = avctx->reordered_opaque, -+ .pkt_pos = avpkt->pos, -+ .pkt_duration = avpkt->duration, -+ .track_pts = track_pts -+ }; -+ avpkt->pts = track_pts; -+} -+ -+// Returns -1 if we should discard the frame -+static int -+xlat_pts_out(AVCodecContext *const avctx, -+ xlat_track_t * const x, ++set_best_effort_pts(AVCodecContext *const avctx, + pts_stats_t * const ps, + AVFrame *const frame) +{ -+ unsigned int n = pts_to_track(avctx, frame->pts) % FF_V4L2_M2M_TRACK_SIZE; -+ V4L2m2mTrackEl *const t = x->track_els + n; -+ if (frame->pts == AV_NOPTS_VALUE || frame->pts != t->track_pts) -+ { -+ av_log(avctx, AV_LOG_INFO, "Tracking failure: pts=%" PRId64 ", track[%d]=%" PRId64 "\n", frame->pts, n, t->track_pts); -+ frame->pts = AV_NOPTS_VALUE; -+ frame->pkt_dts = x->last_pkt_dts; -+ frame->reordered_opaque = x->last_opaque; -+ frame->pkt_pos = -1; -+ frame->pkt_duration = 0; -+ frame->pkt_size = -1; -+ } -+ else if (!t->discard) -+ { -+ frame->pts = t->pending ? t->pts : AV_NOPTS_VALUE; -+ frame->pkt_dts = x->last_pkt_dts; -+ frame->reordered_opaque = t->reordered_opaque; -+ frame->pkt_pos = t->pkt_pos; -+ frame->pkt_duration = t->pkt_duration; -+ frame->pkt_size = t->pkt_size; -+ -+ x->last_opaque = x->track_els[n].reordered_opaque; -+ if (frame->pts != AV_NOPTS_VALUE) -+ x->last_pts = frame->pts; -+ t->pending = 0; -+ } -+ else -+ { -+ av_log(avctx, AV_LOG_DEBUG, "Discard frame (flushed): pts=%" PRId64 ", track[%d]=%" PRId64 "\n", frame->pts, n, t->track_pts); -+ return -1; -+ } -+ + pts_stats_add(ps, frame->pts); + +#if FF_API_PKT_PTS @@ -52188,10 +53216,15 @@ index ab07c0a24a..dd383f31e5 100644 +FF_ENABLE_DEPRECATION_WARNINGS +#endif + frame->best_effort_timestamp = pts_stats_guess(ps); -+ frame->pkt_dts = frame->pts; // We can't emulate what s/w does in a useful manner? -+ av_log(avctx, AV_LOG_TRACE, "Out PTS=%" PRId64 "/%"PRId64", DTS=%" PRId64 ", track=%"PRId64", n=%d\n", -+ frame->pts, frame->best_effort_timestamp, frame->pkt_dts, t->track_pts, n); -+ return 0; ++ // If we can't guess from just PTS - try DTS ++ if (frame->best_effort_timestamp == AV_NOPTS_VALUE) ++ frame->best_effort_timestamp = frame->pkt_dts; ++ ++ // We can't emulate what s/w does in a useful manner and using the ++ // "correct" answer seems to just confuse things. ++ frame->pkt_dts = frame->pts; ++ av_log(avctx, AV_LOG_TRACE, "Out PTS=%" PRId64 "/%"PRId64", DTS=%" PRId64 "\n", ++ frame->pts, frame->best_effort_timestamp, frame->pkt_dts); +} + +static void @@ -52205,13 +53238,6 @@ index ab07c0a24a..dd383f31e5 100644 + x->last_pts = AV_NOPTS_VALUE; +} + -+static void -+xlat_init(xlat_track_t * const x) -+{ -+ memset(x, 0, sizeof(*x)); -+ x->last_pts = AV_NOPTS_VALUE; -+} -+ +static int +xlat_pending(const xlat_track_t * const x) +{ @@ -52286,8 +53312,11 @@ index ab07c0a24a..dd383f31e5 100644 + + for (i = 0; i < 256; ++i) { + uint8_t * side_data; ++#if FF_API_BUFFER_SIZE_T ++ int side_size; ++#else + size_t side_size; -+ ++#endif + ret = ff_decode_get_packet(avctx, &s->buf_pkt); + if (ret != 0) + break; @@ -52296,13 +53325,8 @@ index ab07c0a24a..dd383f31e5 100644 + side_data = av_packet_get_side_data(&s->buf_pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size); + if (side_data) { + av_log(avctx, AV_LOG_DEBUG, "New extradata\n"); -+ av_freep(&s->extdata_data); -+ if ((s->extdata_data = av_malloc(side_size ? side_size : 1)) == NULL) { -+ av_log(avctx, AV_LOG_ERROR, "Failed to alloc %zd bytes of extra data\n", side_size); -+ return AVERROR(ENOMEM); -+ } -+ memcpy(s->extdata_data, side_data, side_size); -+ s->extdata_size = side_size; ++ if ((ret = copy_extradata(avctx, side_data, (int)side_size, &s->extdata_data, &s->extdata_size)) < 0) ++ av_log(avctx, AV_LOG_WARNING, "Failed to copy new extra data: %s\n", av_err2str(ret)); + s->extdata_sent = 0; + } + @@ -52358,8 +53382,6 @@ index ab07c0a24a..dd383f31e5 100644 + av_log(avctx, AV_LOG_ERROR, "Failed to get coded packet: err=%d\n", ret); return ret; + } -+ -+ xlat_pts_in(avctx, &s->xlat, &s->buf_pkt); + } + + if (s->draining) { @@ -52374,19 +53396,17 @@ index ab07c0a24a..dd383f31e5 100644 - goto dequeue; + if (!s->buf_pkt.size) + return NQ_NONE; -+ -+ if ((ret = check_output_streamon(avctx, s)) != 0) -+ return ret; - ret = ff_v4l2_context_enqueue_packet(output, &s->buf_pkt); - if (ret < 0 && ret != AVERROR(EAGAIN)) - goto fail; ++ if ((ret = check_output_streamon(avctx, s)) != 0) ++ return ret; ++ + if (s->extdata_sent) + ret = ff_v4l2_context_enqueue_packet(&s->output, &s->buf_pkt, NULL, 0); + else if (s->extdata_data) + ret = ff_v4l2_context_enqueue_packet(&s->output, &s->buf_pkt, s->extdata_data, s->extdata_size); -+ else -+ ret = ff_v4l2_context_enqueue_packet(&s->output, &s->buf_pkt, avctx->extradata, avctx->extradata_size); - /* if EAGAIN don't unref packet and try to enqueue in the next iteration */ - if (ret != AVERROR(EAGAIN)) @@ -52494,53 +53514,51 @@ index ab07c0a24a..dd383f31e5 100644 + if (dst_rv != 0 && TRY_DQ(src_rv)) { + // Pick a timeout depending on state + const int t = ++ src_rv == NQ_Q_FULL ? -1 : + src_rv == NQ_DRAINING ? 300 : -+ prefer_dq ? 5 : -+ src_rv == NQ_Q_FULL ? -1 : 0; ++ prefer_dq ? 5 : 0; + -+ do { -+ // Dequeue frame will unref any previous contents of frame -+ // if it returns success so we don't need an explicit unref -+ // when discarding -+ // This returns AVERROR(EAGAIN) on timeout or if -+ // there is room in the input Q and timeout == -1 -+ dst_rv = ff_v4l2_context_dequeue_frame(&s->capture, frame, t); ++ // Dequeue frame will unref any previous contents of frame ++ // if it returns success so we don't need an explicit unref ++ // when discarding ++ // This returns AVERROR(EAGAIN) on timeout or if ++ // there is room in the input Q and timeout == -1 ++ dst_rv = ff_v4l2_context_dequeue_frame(&s->capture, frame, t); + -+ // Failure due to no buffer in Q? -+ if (dst_rv == AVERROR(ENOSPC)) { -+ // Wait & retry -+ if ((dst_rv = qbuf_wait(avctx, &s->capture)) == 0) { -+ dst_rv = ff_v4l2_context_dequeue_frame(&s->capture, frame, t); -+ } ++ // Failure due to no buffer in Q? ++ if (dst_rv == AVERROR(ENOSPC)) { ++ // Wait & retry ++ if ((dst_rv = qbuf_wait(avctx, &s->capture)) == 0) { ++ dst_rv = ff_v4l2_context_dequeue_frame(&s->capture, frame, t); + } ++ } + -+ // Adjust dynamic pending threshold -+ if (dst_rv == 0) { -+ if (--s->pending_hw < PENDING_HW_MIN) -+ s->pending_hw = PENDING_HW_MIN; ++ // Adjust dynamic pending threshold ++ if (dst_rv == 0) { ++ if (--s->pending_hw < PENDING_HW_MIN) ++ s->pending_hw = PENDING_HW_MIN; ++ s->pending_n = 0; ++ ++ set_best_effort_pts(avctx, &s->pts_stat, frame); ++ } ++ else if (dst_rv == AVERROR(EAGAIN)) { ++ if (prefer_dq && ++s->pending_n > PENDING_N_THRESHOLD) { ++ s->pending_hw = pending * 16 + PENDING_HW_OFFSET; + s->pending_n = 0; + } -+ else if (dst_rv == AVERROR(EAGAIN)) { -+ if (prefer_dq && ++s->pending_n > PENDING_N_THRESHOLD) { -+ s->pending_hw = pending * 16 + PENDING_HW_OFFSET; -+ s->pending_n = 0; -+ } -+ } ++ } + -+ if (dst_rv == AVERROR(EAGAIN) && src_rv == NQ_DRAINING) { -+ av_log(avctx, AV_LOG_WARNING, "Timeout in drain - assume EOF"); -+ dst_rv = AVERROR_EOF; -+ s->capture.done = 1; -+ } -+ else if (dst_rv == AVERROR_EOF && (s->draining || s->capture.done)) -+ av_log(avctx, AV_LOG_DEBUG, "Dequeue EOF: draining=%d, cap.done=%d\n", -+ s->draining, s->capture.done); -+ else if (dst_rv && dst_rv != AVERROR(EAGAIN)) -+ av_log(avctx, AV_LOG_ERROR, "Packet dequeue failure: draining=%d, cap.done=%d, err=%d\n", -+ s->draining, s->capture.done, dst_rv); -+ -+ // Go again if we got a frame that we need to discard -+ } while (dst_rv == 0 && xlat_pts_out(avctx, &s->xlat, &s->pts_stat, frame)); ++ if (dst_rv == AVERROR(EAGAIN) && src_rv == NQ_DRAINING) { ++ av_log(avctx, AV_LOG_WARNING, "Timeout in drain - assume EOF"); ++ dst_rv = AVERROR_EOF; ++ s->capture.done = 1; ++ } ++ else if (dst_rv == AVERROR_EOF && (s->draining || s->capture.done)) ++ av_log(avctx, AV_LOG_DEBUG, "Dequeue EOF: draining=%d, cap.done=%d\n", ++ s->draining, s->capture.done); ++ else if (dst_rv && dst_rv != AVERROR(EAGAIN)) ++ av_log(avctx, AV_LOG_ERROR, "Packet dequeue failure: draining=%d, cap.done=%d, err=%d\n", ++ s->draining, s->capture.done, dst_rv); + } + + ++i; @@ -52747,14 +53765,13 @@ index ab07c0a24a..dd383f31e5 100644 if (ret < 0) return ret; -+ xlat_init(&s->xlat); + pts_stats_init(&s->pts_stat, avctx, "decoder"); + s->pending_hw = PENDING_HW_MIN; + capture = &s->capture; output = &s->output; -@@ -192,14 +807,53 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx) +@@ -192,14 +875,51 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx) * by the v4l2 driver; this event will trigger a full pipeline reconfig and * the proper values will be retrieved from the kernel driver. */ @@ -52768,12 +53785,10 @@ index ab07c0a24a..dd383f31e5 100644 output->av_codec_id = avctx->codec_id; output->av_pix_fmt = AV_PIX_FMT_NONE; + output->min_buf_size = max_coded_size(avctx); -+ output->no_pts_rescale = 1; capture->av_codec_id = AV_CODEC_ID_RAWVIDEO; capture->av_pix_fmt = avctx->pix_fmt; + capture->min_buf_size = 0; -+ capture->no_pts_rescale = 1; + + /* the client requests the codec to generate DRM frames: + * - data[0] will therefore point to the returned AVDRMFrameDescriptor @@ -52810,11 +53825,20 @@ index ab07c0a24a..dd383f31e5 100644 s->avctx = avctx; ret = ff_v4l2_m2m_codec_init(priv); -@@ -208,12 +862,74 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx) +@@ -208,12 +928,83 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx) return ret; } - return v4l2_prepare_decoder(s); ++ if (avctx->extradata && ++ (ret = copy_extradata(avctx, avctx->extradata, avctx->extradata_size, &s->extdata_data, &s->extdata_size)) != 0) { ++ av_log(avctx, AV_LOG_ERROR, "Failed to copy extradata from context: %s\n", av_err2str(ret)); ++#if DUMP_FAILED_EXTRADATA ++ log_dump(avctx, AV_LOG_INFO, avctx->extradata, avctx->extradata_size); ++#endif ++ return ret; ++ } ++ + if ((ret = v4l2_prepare_decoder(s)) < 0) + return ret; + @@ -52887,7 +53911,7 @@ index ab07c0a24a..dd383f31e5 100644 } #define OFFSET(x) offsetof(V4L2m2mPriv, x) -@@ -222,10 +938,16 @@ static av_cold int v4l2_decode_close(AVCodecContext *avctx) +@@ -222,10 +1013,16 @@ static av_cold int v4l2_decode_close(AVCodecContext *avctx) static const AVOption options[] = { V4L_M2M_DEFAULT_OPTS, { "num_capture_buffers", "Number of buffers in the capture context", @@ -52905,7 +53929,7 @@ index ab07c0a24a..dd383f31e5 100644 #define M2MDEC_CLASS(NAME) \ static const AVClass v4l2_m2m_ ## NAME ## _dec_class = { \ .class_name = #NAME "_v4l2m2m_decoder", \ -@@ -246,9 +968,15 @@ static const AVOption options[] = { +@@ -246,9 +1043,15 @@ static const AVOption options[] = { .init = v4l2_decode_init, \ .receive_frame = v4l2_receive_frame, \ .close = v4l2_decode_close, \ @@ -52921,6 +53945,408 @@ index ab07c0a24a..dd383f31e5 100644 .wrapper_name = "v4l2m2m", \ } +diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c +index f644b50133..7e8c896b66 100644 +--- a/libavcodec/v4l2_m2m_enc.c ++++ b/libavcodec/v4l2_m2m_enc.c +@@ -24,6 +24,8 @@ + #include + #include + #include ++#include ++ + #include "encode.h" + #include "libavcodec/avcodec.h" + #include "libavcodec/internal.h" +@@ -38,6 +40,34 @@ + #define MPEG_CID(x) V4L2_CID_MPEG_VIDEO_##x + #define MPEG_VIDEO(x) V4L2_MPEG_VIDEO_##x + ++// P030 should be defined in drm_fourcc.h and hopefully will be sometime ++// in the future but until then... ++#ifndef DRM_FORMAT_P030 ++#define DRM_FORMAT_P030 fourcc_code('P', '0', '3', '0') ++#endif ++ ++#ifndef DRM_FORMAT_NV15 ++#define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') ++#endif ++ ++#ifndef DRM_FORMAT_NV20 ++#define DRM_FORMAT_NV20 fourcc_code('N', 'V', '2', '0') ++#endif ++ ++#ifndef V4L2_CID_CODEC_BASE ++#define V4L2_CID_CODEC_BASE V4L2_CID_MPEG_BASE ++#endif ++ ++// V4L2_PIX_FMT_NV12_10_COL128 and V4L2_PIX_FMT_NV12_COL128 should be defined ++// in videodev2.h hopefully will be sometime in the future but until then... ++#ifndef V4L2_PIX_FMT_NV12_10_COL128 ++#define V4L2_PIX_FMT_NV12_10_COL128 v4l2_fourcc('N', 'C', '3', '0') ++#endif ++ ++#ifndef V4L2_PIX_FMT_NV12_COL128 ++#define V4L2_PIX_FMT_NV12_COL128 v4l2_fourcc('N', 'C', '1', '2') /* 12 Y/CbCr 4:2:0 128 pixel wide column */ ++#endif ++ + static inline void v4l2_set_timeperframe(V4L2m2mContext *s, unsigned int num, unsigned int den) + { + struct v4l2_streamparm parm = { 0 }; +@@ -148,15 +178,14 @@ static inline int v4l2_mpeg4_profile_from_ff(int p) + static int v4l2_check_b_frame_support(V4L2m2mContext *s) + { + if (s->avctx->max_b_frames) +- av_log(s->avctx, AV_LOG_WARNING, "Encoder does not support b-frames yet\n"); ++ av_log(s->avctx, AV_LOG_WARNING, "Encoder does not support %d b-frames yet\n", s->avctx->max_b_frames); + +- v4l2_set_ext_ctrl(s, MPEG_CID(B_FRAMES), 0, "number of B-frames", 0); ++ v4l2_set_ext_ctrl(s, MPEG_CID(B_FRAMES), s->avctx->max_b_frames, "number of B-frames", 1); + v4l2_get_ext_ctrl(s, MPEG_CID(B_FRAMES), &s->avctx->max_b_frames, "number of B-frames", 0); + if (s->avctx->max_b_frames == 0) + return 0; + + avpriv_report_missing_feature(s->avctx, "DTS/PTS calculation for V4L2 encoding"); +- + return AVERROR_PATCHWELCOME; + } + +@@ -271,13 +300,186 @@ static int v4l2_prepare_encoder(V4L2m2mContext *s) + return 0; + } + ++static int avdrm_to_v4l2(struct v4l2_format * const format, const AVFrame * const frame) ++{ ++ const AVDRMFrameDescriptor *const src = (const AVDRMFrameDescriptor *)frame->data[0]; ++ ++ const uint32_t drm_fmt = src->layers[0].format; ++ // Treat INVALID as LINEAR ++ const uint64_t mod = src->objects[0].format_modifier == DRM_FORMAT_MOD_INVALID ? ++ DRM_FORMAT_MOD_LINEAR : src->objects[0].format_modifier; ++ uint32_t pix_fmt = 0; ++ uint32_t w = 0; ++ uint32_t h = 0; ++ uint32_t bpl = src->layers[0].planes[0].pitch; ++ ++ // We really don't expect multiple layers ++ // All formats that we currently cope with are single object ++ ++ if (src->nb_layers != 1 || src->nb_objects != 1) ++ return AVERROR(EINVAL); ++ ++ switch (drm_fmt) { ++ case DRM_FORMAT_YUV420: ++ if (mod == DRM_FORMAT_MOD_LINEAR) { ++ if (src->layers[0].nb_planes != 3) ++ break; ++ pix_fmt = V4L2_PIX_FMT_YUV420; ++ h = src->layers[0].planes[1].offset / bpl; ++ w = bpl; ++ } ++ break; ++ ++ case DRM_FORMAT_NV12: ++ if (mod == DRM_FORMAT_MOD_LINEAR) { ++ if (src->layers[0].nb_planes != 2) ++ break; ++ pix_fmt = V4L2_PIX_FMT_NV12; ++ h = src->layers[0].planes[1].offset / bpl; ++ w = bpl; ++ } ++ else if (fourcc_mod_broadcom_mod(mod) == DRM_FORMAT_MOD_BROADCOM_SAND128) { ++ if (src->layers[0].nb_planes != 2) ++ break; ++ pix_fmt = V4L2_PIX_FMT_NV12_COL128; ++ w = bpl; ++ h = src->layers[0].planes[1].offset / 128; ++ bpl = fourcc_mod_broadcom_param(mod); ++ } ++ break; ++ ++ case DRM_FORMAT_P030: ++ if (fourcc_mod_broadcom_mod(mod) == DRM_FORMAT_MOD_BROADCOM_SAND128) { ++ if (src->layers[0].nb_planes != 2) ++ break; ++ pix_fmt = V4L2_PIX_FMT_NV12_10_COL128; ++ w = bpl / 2; // Matching lie to how we construct this ++ h = src->layers[0].planes[1].offset / 128; ++ bpl = fourcc_mod_broadcom_param(mod); ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ if (!pix_fmt) ++ return AVERROR(EINVAL); ++ ++ if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) { ++ struct v4l2_pix_format_mplane *const pix = &format->fmt.pix_mp; ++ ++ pix->width = w; ++ pix->height = h; ++ pix->pixelformat = pix_fmt; ++ pix->plane_fmt[0].bytesperline = bpl; ++ pix->num_planes = 1; ++ } ++ else { ++ struct v4l2_pix_format *const pix = &format->fmt.pix; ++ ++ pix->width = w; ++ pix->height = h; ++ pix->pixelformat = pix_fmt; ++ pix->bytesperline = bpl; ++ } ++ ++ return 0; ++} ++ ++// Do we have similar enough formats to be usable? ++static int fmt_eq(const struct v4l2_format * const a, const struct v4l2_format * const b) ++{ ++ if (a->type != b->type) ++ return 0; ++ ++ if (V4L2_TYPE_IS_MULTIPLANAR(a->type)) { ++ const struct v4l2_pix_format_mplane *const pa = &a->fmt.pix_mp; ++ const struct v4l2_pix_format_mplane *const pb = &b->fmt.pix_mp; ++ unsigned int i; ++ if (pa->pixelformat != pb->pixelformat || ++ pa->num_planes != pb->num_planes) ++ return 0; ++ for (i = 0; i != pa->num_planes; ++i) { ++ if (pa->plane_fmt[i].bytesperline != pb->plane_fmt[i].bytesperline) ++ return 0; ++ } ++ } ++ else { ++ const struct v4l2_pix_format *const pa = &a->fmt.pix; ++ const struct v4l2_pix_format *const pb = &b->fmt.pix; ++ if (pa->pixelformat != pb->pixelformat || ++ pa->bytesperline != pb->bytesperline) ++ return 0; ++ } ++ return 1; ++} ++ ++ + static int v4l2_send_frame(AVCodecContext *avctx, const AVFrame *frame) + { + V4L2m2mContext *s = ((V4L2m2mPriv*)avctx->priv_data)->context; + V4L2Context *const output = &s->output; + ++ ff_v4l2_dq_all(output); ++ ++ // Signal EOF if needed ++ if (!frame) { ++ return ff_v4l2_context_enqueue_frame(output, frame); ++ } ++ ++ if (s->input_drm && !output->streamon) { ++ int rv; ++ struct v4l2_format req_format = {.type = output->format.type}; ++ ++ // Set format when we first get a buffer ++ if ((rv = avdrm_to_v4l2(&req_format, frame)) != 0) { ++ av_log(avctx, AV_LOG_ERROR, "Failed to get V4L2 format from DRM_PRIME frame\n"); ++ return rv; ++ } ++ ++ ff_v4l2_context_release(output); ++ ++ output->format = req_format; ++ ++ if ((rv = ff_v4l2_context_set_format(output)) != 0) { ++ av_log(avctx, AV_LOG_ERROR, "Failed to set V4L2 format\n"); ++ return rv; ++ } ++ ++ if (!fmt_eq(&req_format, &output->format)) { ++ av_log(avctx, AV_LOG_ERROR, "Format mismatch after setup\n"); ++ return AVERROR(EINVAL); ++ } ++ ++ output->selection.top = frame->crop_top; ++ output->selection.left = frame->crop_left; ++ output->selection.width = av_frame_cropped_width(frame); ++ output->selection.height = av_frame_cropped_height(frame); ++ ++ if ((rv = ff_v4l2_context_init(output)) != 0) { ++ av_log(avctx, AV_LOG_ERROR, "Failed to (re)init context\n"); ++ return rv; ++ } ++ ++ { ++ struct v4l2_selection selection = { ++ .type = V4L2_BUF_TYPE_VIDEO_OUTPUT, ++ .target = V4L2_SEL_TGT_CROP, ++ .r = output->selection ++ }; ++ if (ioctl(s->fd, VIDIOC_S_SELECTION, &selection) != 0) { ++ av_log(avctx, AV_LOG_WARNING, "S_SELECTION (CROP) %dx%d @ %d,%d failed: %s\n", ++ selection.r.width, selection.r.height, selection.r.left, selection.r.top, ++ av_err2str(AVERROR(errno))); ++ } ++ av_log(avctx, AV_LOG_TRACE, "S_SELECTION (CROP) %dx%d @ %d,%d OK\n", ++ selection.r.width, selection.r.height, selection.r.left, selection.r.top); ++ } ++ } ++ + #ifdef V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME +- if (frame && frame->pict_type == AV_PICTURE_TYPE_I) ++ if (frame->pict_type == AV_PICTURE_TYPE_I) + v4l2_set_ext_ctrl(s, MPEG_CID(FORCE_KEY_FRAME), 0, "force key frame", 1); + #endif + +@@ -292,6 +494,8 @@ static int v4l2_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) + AVFrame *frame = s->frame; + int ret; + ++ ff_v4l2_dq_all(output); ++ + if (s->draining) + goto dequeue; + +@@ -328,7 +532,87 @@ static int v4l2_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) + } + + dequeue: +- return ff_v4l2_context_dequeue_packet(capture, avpkt); ++ ret = ff_v4l2_context_dequeue_packet(capture, avpkt); ++ ff_v4l2_dq_all(output); ++ if (ret) ++ return ret; ++ ++ if (capture->first_buf == 1) { ++ uint8_t * data; ++ const int len = avpkt->size; ++ ++ // 1st buffer after streamon should be SPS/PPS ++ capture->first_buf = 2; ++ ++ // Clear both possible stores so there is no chance of confusion ++ av_freep(&s->extdata_data); ++ s->extdata_size = 0; ++ av_freep(&avctx->extradata); ++ avctx->extradata_size = 0; ++ ++ if ((data = av_malloc(len + AV_INPUT_BUFFER_PADDING_SIZE)) == NULL) ++ goto fail_no_mem; ++ ++ memcpy(data, avpkt->data, len); ++ av_packet_unref(avpkt); ++ ++ // We need to copy the header, but keep local if not global ++ if ((avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) != 0) { ++ avctx->extradata = data; ++ avctx->extradata_size = len; ++ } ++ else { ++ s->extdata_data = data; ++ s->extdata_size = len; ++ } ++ ++ ret = ff_v4l2_context_dequeue_packet(capture, avpkt); ++ ff_v4l2_dq_all(output); ++ if (ret) ++ return ret; ++ } ++ ++ // First frame must be key so mark as such even if encoder forgot ++ if (capture->first_buf == 2) { ++ avpkt->flags |= AV_PKT_FLAG_KEY; ++ ++ // Add any extradata to the 1st packet we emit as we cannot create it at init ++ if (avctx->extradata_size > 0 && avctx->extradata) { ++ void * const side = av_packet_new_side_data(avpkt, ++ AV_PKT_DATA_NEW_EXTRADATA, ++ avctx->extradata_size); ++ if (!side) ++ goto fail_no_mem; ++ ++ memcpy(side, avctx->extradata, avctx->extradata_size); ++ } ++ } ++ ++ // Add SPS/PPS to the start of every key frame if non-global headers ++ if ((avpkt->flags & AV_PKT_FLAG_KEY) != 0 && s->extdata_size != 0) { ++ const size_t newlen = s->extdata_size + avpkt->size; ++ AVBufferRef * const buf = av_buffer_alloc(newlen + AV_INPUT_BUFFER_PADDING_SIZE); ++ ++ if (buf == NULL) ++ goto fail_no_mem; ++ ++ memcpy(buf->data, s->extdata_data, s->extdata_size); ++ memcpy(buf->data + s->extdata_size, avpkt->data, avpkt->size); ++ ++ av_buffer_unref(&avpkt->buf); ++ avpkt->buf = buf; ++ avpkt->data = buf->data; ++ avpkt->size = newlen; ++ } ++ ++// av_log(avctx, AV_LOG_INFO, "%s: PTS out=%"PRId64", size=%d, ret=%d\n", __func__, avpkt->pts, avpkt->size, ret); ++ capture->first_buf = 0; ++ return 0; ++ ++fail_no_mem: ++ ret = AVERROR(ENOMEM); ++ av_packet_unref(avpkt); ++ return ret; + } + + static av_cold int v4l2_encode_init(AVCodecContext *avctx) +@@ -340,6 +624,8 @@ static av_cold int v4l2_encode_init(AVCodecContext *avctx) + uint32_t v4l2_fmt_output; + int ret; + ++ av_log(avctx, AV_LOG_INFO, " <<< %s: fmt=%d/%d\n", __func__, avctx->pix_fmt, avctx->sw_pix_fmt); ++ + ret = ff_v4l2_m2m_create_context(priv, &s); + if (ret < 0) + return ret; +@@ -347,13 +633,17 @@ static av_cold int v4l2_encode_init(AVCodecContext *avctx) + capture = &s->capture; + output = &s->output; + ++ s->input_drm = (avctx->pix_fmt == AV_PIX_FMT_DRM_PRIME); ++ + /* common settings output/capture */ + output->height = capture->height = avctx->height; + output->width = capture->width = avctx->width; + + /* output context */ + output->av_codec_id = AV_CODEC_ID_RAWVIDEO; +- output->av_pix_fmt = avctx->pix_fmt; ++ output->av_pix_fmt = !s->input_drm ? avctx->pix_fmt : ++ avctx->sw_pix_fmt != AV_PIX_FMT_NONE ? avctx->sw_pix_fmt : ++ AV_PIX_FMT_YUV420P; + + /* capture context */ + capture->av_codec_id = avctx->codec_id; +@@ -372,7 +662,7 @@ static av_cold int v4l2_encode_init(AVCodecContext *avctx) + v4l2_fmt_output = output->format.fmt.pix.pixelformat; + + pix_fmt_output = ff_v4l2_format_v4l2_to_avfmt(v4l2_fmt_output, AV_CODEC_ID_RAWVIDEO); +- if (pix_fmt_output != avctx->pix_fmt) { ++ if (!s->input_drm && pix_fmt_output != avctx->pix_fmt) { + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt_output); + av_log(avctx, AV_LOG_ERROR, "Encoder requires %s pixel format.\n", desc->name); + return AVERROR(EINVAL); +@@ -390,9 +680,10 @@ static av_cold int v4l2_encode_close(AVCodecContext *avctx) + #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM + + #define V4L_M2M_CAPTURE_OPTS \ +- V4L_M2M_DEFAULT_OPTS,\ ++ { "num_output_buffers", "Number of buffers in the output context",\ ++ OFFSET(num_output_buffers), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },\ + { "num_capture_buffers", "Number of buffers in the capture context", \ +- OFFSET(num_capture_buffers), AV_OPT_TYPE_INT, {.i64 = 4 }, 4, INT_MAX, FLAGS } ++ OFFSET(num_capture_buffers), AV_OPT_TYPE_INT, {.i64 = 8 }, 8, INT_MAX, FLAGS } + + static const AVOption mpeg4_options[] = { + V4L_M2M_CAPTURE_OPTS, diff --git a/libavcodec/v4l2_req_decode_q.c b/libavcodec/v4l2_req_decode_q.c new file mode 100644 index 0000000000..5b3fb958fa @@ -53499,13 +54925,15 @@ index 0000000000..cfa94d55c4 + diff --git a/libavcodec/v4l2_req_devscan.h b/libavcodec/v4l2_req_devscan.h new file mode 100644 -index 0000000000..0baef36535 +index 0000000000..956d9234f1 --- /dev/null +++ b/libavcodec/v4l2_req_devscan.h -@@ -0,0 +1,21 @@ +@@ -0,0 +1,23 @@ +#ifndef _DEVSCAN_H_ +#define _DEVSCAN_H_ + ++#include ++ +struct devscan; +struct decdev; +enum v4l2_buf_type; @@ -53526,10 +54954,10 @@ index 0000000000..0baef36535 +#endif diff --git a/libavcodec/v4l2_req_dmabufs.c b/libavcodec/v4l2_req_dmabufs.c new file mode 100644 -index 0000000000..ae6c648369 +index 0000000000..c4bbed18c6 --- /dev/null +++ b/libavcodec/v4l2_req_dmabufs.c -@@ -0,0 +1,266 @@ +@@ -0,0 +1,288 @@ +#include +#include +#include @@ -53568,6 +54996,26 @@ index 0000000000..ae6c648369 +static size_t total_size = 0; +#endif + ++struct dmabuf_h * dmabuf_import_mmap(void * mapptr, size_t size) ++{ ++ struct dmabuf_h *dh; ++ ++ if (mapptr == MAP_FAILED) ++ return NULL; ++ ++ dh = malloc(sizeof(*dh)); ++ if (!dh) ++ return NULL; ++ ++ *dh = (struct dmabuf_h) { ++ .fd = -1, ++ .size = size, ++ .mapptr = mapptr ++ }; ++ ++ return dh; ++} ++ +struct dmabuf_h * dmabuf_import(int fd, size_t size) +{ + struct dmabuf_h *dh; @@ -53654,6 +55102,8 @@ index 0000000000..ae6c648369 + struct dma_buf_sync sync = { + .flags = flags + }; ++ if (dh->fd == -1) ++ return 0; + while (ioctl(dh->fd, DMA_BUF_IOCTL_SYNC, &sync) == -1) { + const int err = errno; + if (errno == EINTR) @@ -53798,13 +55248,15 @@ index 0000000000..ae6c648369 + diff --git a/libavcodec/v4l2_req_dmabufs.h b/libavcodec/v4l2_req_dmabufs.h new file mode 100644 -index 0000000000..8d909c4297 +index 0000000000..c1d3d8c8d7 --- /dev/null +++ b/libavcodec/v4l2_req_dmabufs.h -@@ -0,0 +1,38 @@ +@@ -0,0 +1,43 @@ +#ifndef DMABUFS_H +#define DMABUFS_H + ++#include ++ +struct dmabufs_ctl; +struct dmabuf_h; + @@ -53820,6 +55272,9 @@ index 0000000000..8d909c4297 +} +/* Create from existing fd - dups(fd) */ +struct dmabuf_h * dmabuf_import(int fd, size_t size); ++/* Import an MMAP - return NULL if mapptr = MAP_FAIL */ ++struct dmabuf_h * dmabuf_import_mmap(void * mapptr, size_t size); ++ +void * dmabuf_map(struct dmabuf_h * const dh); + +/* flags from linux/dmabuf.h DMA_BUF_SYNC_xxx */ @@ -53867,20 +55322,27 @@ index 0000000000..dcc8d95632 +#define HEVC_CTRLS_VERSION 3 +#include "v4l2_req_hevc_vx.c" + +diff --git a/libavcodec/v4l2_req_hevc_v4.c b/libavcodec/v4l2_req_hevc_v4.c +new file mode 100644 +index 0000000000..c35579d8e0 +--- /dev/null ++++ b/libavcodec/v4l2_req_hevc_v4.c +@@ -0,0 +1,3 @@ ++#define HEVC_CTRLS_VERSION 4 ++#include "v4l2_req_hevc_vx.c" ++ diff --git a/libavcodec/v4l2_req_hevc_vx.c b/libavcodec/v4l2_req_hevc_vx.c new file mode 100644 -index 0000000000..55c41ae679 +index 0000000000..b98d8464ca --- /dev/null +++ b/libavcodec/v4l2_req_hevc_vx.c -@@ -0,0 +1,1228 @@ +@@ -0,0 +1,1360 @@ +// File included by v4l2_req_hevc_v* - not compiled on its own + +#include "decode.h" +#include "hevcdec.h" +#include "hwconfig.h" + -+#include "v4l2_request_hevc.h" -+ +#if HEVC_CTRLS_VERSION == 1 +#include "hevc-ctrls-v1.h" + @@ -53891,10 +55353,32 @@ index 0000000000..55c41ae679 +#include "hevc-ctrls-v2.h" +#elif HEVC_CTRLS_VERSION == 3 +#include "hevc-ctrls-v3.h" ++#elif HEVC_CTRLS_VERSION == 4 ++#include ++#if !defined(V4L2_CID_STATELESS_HEVC_SPS) ++#include "hevc-ctrls-v4.h" ++#endif +#else +#error Unknown HEVC_CTRLS_VERSION +#endif + ++#ifndef V4L2_CID_STATELESS_HEVC_SPS ++#define V4L2_CID_STATELESS_HEVC_SPS V4L2_CID_MPEG_VIDEO_HEVC_SPS ++#define V4L2_CID_STATELESS_HEVC_PPS V4L2_CID_MPEG_VIDEO_HEVC_PPS ++#define V4L2_CID_STATELESS_HEVC_SLICE_PARAMS V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS ++#define V4L2_CID_STATELESS_HEVC_SCALING_MATRIX V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX ++#define V4L2_CID_STATELESS_HEVC_DECODE_PARAMS V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS ++#define V4L2_CID_STATELESS_HEVC_DECODE_MODE V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE ++#define V4L2_CID_STATELESS_HEVC_START_CODE V4L2_CID_MPEG_VIDEO_HEVC_START_CODE ++ ++#define V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED ++#define V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_FRAME_BASED ++#define V4L2_STATELESS_HEVC_START_CODE_NONE V4L2_MPEG_VIDEO_HEVC_START_CODE_NONE ++#define V4L2_STATELESS_HEVC_START_CODE_ANNEX_B V4L2_MPEG_VIDEO_HEVC_START_CODE_ANNEX_B ++#endif ++ ++#include "v4l2_request_hevc.h" ++ +#include "libavutil/hwcontext_drm.h" + +#include @@ -53930,11 +55414,16 @@ index 0000000000..55c41ae679 + struct v4l2_ctrl_hevc_slice_params * slice_params; + struct slice_info * slices; + ++ size_t num_offsets; ++ size_t alloced_offsets; ++ uint32_t *offsets; ++ +} V4L2MediaReqDescriptor; + +struct slice_info { + const uint8_t * ptr; + size_t len; // bytes ++ size_t n_offsets; +}; + +// Handy container for accumulating controls before setting @@ -54093,7 +55582,7 @@ index 0000000000..55c41ae679 + if (rd->num_slices >= rd->alloced_slices) { + struct v4l2_ctrl_hevc_slice_params * p2; + struct slice_info * s2; -+ size_t n2 = rd->num_slices == 0 ? 8 : rd->num_slices * 2; ++ size_t n2 = rd->alloced_slices == 0 ? 8 : rd->alloced_slices * 2; + + p2 = av_realloc_array(rd->slice_params, n2, sizeof(*p2)); + if (p2 == NULL) @@ -54111,6 +55600,23 @@ index 0000000000..55c41ae679 + return 0; +} + ++static int offsets_add(V4L2MediaReqDescriptor *const rd, const size_t n, const unsigned * const offsets) ++{ ++ if (rd->num_offsets + n > rd->alloced_offsets) { ++ size_t n2 = rd->alloced_slices == 0 ? 128 : rd->alloced_slices * 2; ++ void * p2; ++ while (rd->num_offsets + n > n2) ++ n2 *= 2; ++ if ((p2 = av_realloc_array(rd->offsets, n2, sizeof(*rd->offsets))) == NULL) ++ return AVERROR(ENOMEM); ++ rd->offsets = p2; ++ rd->alloced_offsets = n2; ++ } ++ for (size_t i = 0; i != n; ++i) ++ rd->offsets[rd->num_offsets++] = offsets[i] - 1; ++ return 0; ++} ++ +static unsigned int +fill_dpb_entries(const HEVCContext * const h, struct v4l2_hevc_dpb_entry * const entries) +{ @@ -54132,9 +55638,13 @@ index 0000000000..55c41ae679 +#endif + entry->field_pic = frame->frame->interlaced_frame; + ++#if HEVC_CTRLS_VERSION <= 3 + /* TODO: Interleaved: Get the POC for each field. */ + entry->pic_order_cnt[0] = frame->poc; + entry->pic_order_cnt[1] = frame->poc; ++#else ++ entry->pic_order_cnt_val = frame->poc; ++#endif + } + } + return n; @@ -54160,8 +55670,11 @@ index 0000000000..55c41ae679 + + *slice_params = (struct v4l2_ctrl_hevc_slice_params) { + .bit_size = bit_size, ++#if HEVC_CTRLS_VERSION <= 3 + .data_bit_offset = bit_offset, -+ ++#else ++ .data_byte_offset = bit_offset / 8 + 1, ++#endif + /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ + .slice_segment_addr = sh->slice_segment_addr, + @@ -54244,6 +55757,7 @@ index 0000000000..55c41ae679 + fill_pred_table(h, &slice_params->pred_weight_table); + + slice_params->num_entry_point_offsets = sh->num_entry_point_offsets; ++#if HEVC_CTRLS_VERSION <= 3 + if (slice_params->num_entry_point_offsets > 256) { + slice_params->num_entry_point_offsets = 256; + av_log(NULL, AV_LOG_ERROR, "%s: Currently only 256 entry points are supported, but slice has %d entry points.\n", __func__, sh->num_entry_point_offsets); @@ -54251,6 +55765,7 @@ index 0000000000..55c41ae679 + + for (i = 0; i < slice_params->num_entry_point_offsets; i++) + slice_params->entry_point_offset_minus1[i] = sh->entry_point_offset[i] - 1; ++#endif +} + +#if HEVC_CTRLS_VERSION >= 2 @@ -54626,51 +56141,66 @@ index 0000000000..55c41ae679 +#if HEVC_CTRLS_VERSION >= 2 + struct v4l2_ctrl_hevc_decode_params * const dec, +#endif -+ struct v4l2_ctrl_hevc_slice_params * const slices, -+ const unsigned int slice_no, -+ const unsigned int slice_count) ++ struct v4l2_ctrl_hevc_slice_params * const slices, const unsigned int slice_count, ++ void * const offsets, const size_t offset_count) +{ + int rv; ++#if HEVC_CTRLS_VERSION >= 2 ++ unsigned int n = 3; ++#else ++ unsigned int n = 2; ++#endif + -+ struct v4l2_ext_control control[] = { ++ struct v4l2_ext_control control[6] = { + { -+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SPS, ++ .id = V4L2_CID_STATELESS_HEVC_SPS, + .ptr = &controls->sps, + .size = sizeof(controls->sps), + }, + { -+ .id = V4L2_CID_MPEG_VIDEO_HEVC_PPS, ++ .id = V4L2_CID_STATELESS_HEVC_PPS, + .ptr = &controls->pps, + .size = sizeof(controls->pps), + }, +#if HEVC_CTRLS_VERSION >= 2 + { -+ .id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS, ++ .id = V4L2_CID_STATELESS_HEVC_DECODE_PARAMS, + .ptr = dec, + .size = sizeof(*dec), + }, +#endif -+ { -+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS, -+ .ptr = slices + slice_no, -+ .size = sizeof(*slices) * slice_count, -+ }, -+ // Optional -+ { -+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX, -+ .ptr = &controls->scaling_matrix, -+ .size = sizeof(controls->scaling_matrix), -+ }, + }; + -+ rv = mediabufs_ctl_set_ext_ctrls(ctx->mbufs, mreq, control, -+ controls->has_scaling ? -+ FF_ARRAY_ELEMS(control) : -+ FF_ARRAY_ELEMS(control) - 1); ++ if (slices) ++ control[n++] = (struct v4l2_ext_control) { ++ .id = V4L2_CID_STATELESS_HEVC_SLICE_PARAMS, ++ .ptr = slices, ++ .size = sizeof(*slices) * slice_count, ++ }; ++ ++ if (controls->has_scaling) ++ control[n++] = (struct v4l2_ext_control) { ++ .id = V4L2_CID_STATELESS_HEVC_SCALING_MATRIX, ++ .ptr = &controls->scaling_matrix, ++ .size = sizeof(controls->scaling_matrix), ++ }; ++ ++#if HEVC_CTRLS_VERSION >= 4 ++ if (offsets) ++ control[n++] = (struct v4l2_ext_control) { ++ .id = V4L2_CID_STATELESS_HEVC_ENTRY_POINT_OFFSETS, ++ .ptr = offsets, ++ .size = sizeof(((struct V4L2MediaReqDescriptor *)0)->offsets[0]) * offset_count, ++ }; ++#endif ++ ++ rv = mediabufs_ctl_set_ext_ctrls(ctx->mbufs, mreq, control, n); + + return rv; +} + ++// This only works because we started out from a single coded frame buffer ++// that will remain intact until after end_frame +static int v4l2_request_hevc_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) +{ + const HEVCContext * const h = avctx->priv_data; @@ -54679,18 +56209,45 @@ index 0000000000..55c41ae679 + int bcount = get_bits_count(&h->HEVClc->gb); + uint32_t boff = (ptr_from_index(buffer, bcount/8 + 1) - (buffer + bcount/8 + 1)) * 8 + bcount; + ++ const unsigned int n = rd->num_slices; ++ const unsigned int block_start = (n / ctx->max_slices) * ctx->max_slices; ++ + int rv; + struct slice_info * si; + ++ // This looks dodgy but we know that FFmpeg has parsed this from a buffer ++ // that contains the entire frame including the start code ++ if (ctx->start_code == V4L2_STATELESS_HEVC_START_CODE_ANNEX_B) { ++ buffer -= 3; ++ size += 3; ++ boff += 24; ++ if (buffer[0] != 0 || buffer[1] != 0 || buffer[2] != 1) { ++ av_log(avctx, AV_LOG_ERROR, "Start code requested but missing %02x:%02x:%02x\n", ++ buffer[0], buffer[1], buffer[2]); ++ } ++ } ++ ++ if (ctx->decode_mode == V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED) { ++ if (rd->slices == NULL) { ++ if ((rd->slices = av_mallocz(sizeof(*rd->slices))) == NULL) ++ return AVERROR(ENOMEM); ++ rd->slices->ptr = buffer; ++ rd->num_slices = 1; ++ } ++ rd->slices->len = buffer - rd->slices->ptr + size; ++ return 0; ++ } ++ + if ((rv = slice_add(rd)) != 0) + return rv; + -+ si = rd->slices + rd->num_slices - 1; ++ si = rd->slices + n; + si->ptr = buffer; + si->len = size; ++ si->n_offsets = rd->num_offsets; + -+ if (ctx->multi_slice && rd->num_slices > 1) { -+ struct slice_info *const si0 = rd->slices; ++ if (n != block_start) { ++ struct slice_info *const si0 = rd->slices + block_start; + const size_t offset = (buffer - si0->ptr); + boff += offset * 8; + size += offset; @@ -54698,12 +56255,15 @@ index 0000000000..55c41ae679 + } + +#if HEVC_CTRLS_VERSION >= 2 -+ if (rd->num_slices == 1) ++ if (n == 0) + fill_decode_params(h, &rd->dec); -+ fill_slice_params(h, &rd->dec, rd->slice_params + rd->num_slices - 1, size * 8, boff); ++ fill_slice_params(h, &rd->dec, rd->slice_params + n, size * 8, boff); +#else -+ fill_slice_params(h, rd->slice_params + rd->num_slices - 1, size * 8, boff); ++ fill_slice_params(h, rd->slice_params + n, size * 8, boff); +#endif ++ if (ctx->max_offsets != 0 && ++ (rv = offsets_add(rd, h->sh.num_entry_point_offsets, h->sh.entry_point_offset)) != 0) ++ return rv; + + return 0; +} @@ -54729,10 +56289,13 @@ index 0000000000..55c41ae679 +{ + V4L2RequestContextHEVC * const ctx = avctx->internal->hwaccel_priv_data; + ++ const int is_last = (j == rd->num_slices); + struct slice_info *const si = rd->slices + i; + struct media_request * req = NULL; + struct qent_src * src = NULL; + MediaBufsStatus stat; ++ void * offsets = rd->offsets + rd->slices[i].n_offsets; ++ size_t n_offsets = (is_last ? rd->num_offsets : rd->slices[j].n_offsets) - rd->slices[i].n_offsets; + + if ((req = media_request_get(ctx->mpool)) == NULL) { + av_log(avctx, AV_LOG_ERROR, "%s: Failed to alloc media request\n", __func__); @@ -54744,8 +56307,8 @@ index 0000000000..55c41ae679 +#if HEVC_CTRLS_VERSION >= 2 + &rd->dec, +#endif -+ rd->slice_params, -+ i, j - i)) { ++ rd->slice_params + i, j - i, ++ offsets, n_offsets)) { + av_log(avctx, AV_LOG_ERROR, "%s: Failed to set req ctls\n", __func__); + goto fail1; + } @@ -54765,13 +56328,9 @@ index 0000000000..55c41ae679 + goto fail2; + } + -+#warning ANNEX_B start code -+// if (ctx->start_code == V4L2_MPEG_VIDEO_HEVC_START_CODE_ANNEX_B) { -+// } -+ + stat = mediabufs_start_request(ctx->mbufs, &req, &src, + i == 0 ? rd->qe_dst : NULL, -+ j == rd->num_slices); ++ is_last); + + if (stat != MEDIABUFS_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "%s: Failed to start request\n", __func__); @@ -54836,18 +56395,11 @@ index 0000000000..55c41ae679 + } + + // Send as slices -+ if (ctx->multi_slice) -+ { -+ if ((rv = send_slice(avctx, rd, &rc, 0, rd->num_slices)) != 0) ++ for (i = 0; i < rd->num_slices; i += ctx->max_slices) { ++ const unsigned int e = FFMIN(rd->num_slices, i + ctx->max_slices); ++ if ((rv = send_slice(avctx, rd, &rc, i, e)) != 0) + goto fail; + } -+ else -+ { -+ for (i = 0; i != rd->num_slices; ++i) { -+ if ((rv = send_slice(avctx, rd, &rc, i, i + 1)) != 0) -+ goto fail; -+ } -+ } + + // Set the drm_prime desriptor + drm_from_format(&rd->drm, mediabufs_dst_fmt(ctx->mbufs)); @@ -54862,6 +56414,12 @@ index 0000000000..55c41ae679 + return rv; +} + ++static inline int ++ctrl_valid(const struct v4l2_query_ext_ctrl * const c, const int64_t v) ++{ ++ return v >= c->minimum && v <= c->maximum; ++} ++ +// Initial check & init +static int +probe(AVCodecContext * const avctx, V4L2RequestContextHEVC * const ctx) @@ -54873,17 +56431,19 @@ index 0000000000..55c41ae679 + + // Check for var slice array + struct v4l2_query_ext_ctrl qc[] = { -+ { .id = V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS }, -+ { .id = V4L2_CID_MPEG_VIDEO_HEVC_SPS }, -+ { .id = V4L2_CID_MPEG_VIDEO_HEVC_PPS }, -+ { .id = V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX }, ++ { .id = V4L2_CID_STATELESS_HEVC_SLICE_PARAMS }, ++ { .id = V4L2_CID_STATELESS_HEVC_DECODE_MODE, }, ++ { .id = V4L2_CID_STATELESS_HEVC_SPS }, ++ { .id = V4L2_CID_STATELESS_HEVC_PPS }, ++ { .id = V4L2_CID_STATELESS_HEVC_SCALING_MATRIX }, +#if HEVC_CTRLS_VERSION >= 2 -+ { .id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS }, ++ { .id = V4L2_CID_STATELESS_HEVC_DECODE_PARAMS }, +#endif + }; + // Order & size must match! + static const size_t ctrl_sizes[] = { + sizeof(struct v4l2_ctrl_hevc_slice_params), ++ sizeof(int32_t), + sizeof(struct v4l2_ctrl_hevc_sps), + sizeof(struct v4l2_ctrl_hevc_pps), + sizeof(struct v4l2_ctrl_hevc_scaling_matrix), @@ -54901,11 +56461,22 @@ index 0000000000..55c41ae679 + return AVERROR(EINVAL); +#endif + -+ if (mediabufs_ctl_query_ext_ctrls(ctx->mbufs, qc, noof_ctrls)) { -+ av_log(avctx, AV_LOG_DEBUG, "Probed V%d control missing\n", HEVC_CTRLS_VERSION); ++ mediabufs_ctl_query_ext_ctrls(ctx->mbufs, qc, noof_ctrls); ++ i = 0; ++#if HEVC_CTRLS_VERSION >= 4 ++ // Skip slice check if no slice mode ++ if (qc[1].type != 0 && !ctrl_valid(qc + 1, V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED)) ++ i = 1; ++#else ++ // Fail frame mode silently for anything prior to V4 ++ if (qc[1].type == 0 || !ctrl_valid(qc + 1, V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED)) + return AVERROR(EINVAL); -+ } -+ for (i = 0; i != noof_ctrls; ++i) { ++#endif ++ for (; i != noof_ctrls; ++i) { ++ if (qc[i].type == 0) { ++ av_log(avctx, AV_LOG_DEBUG, "Probed V%d control %#x missing\n", HEVC_CTRLS_VERSION, qc[i].id); ++ return AVERROR(EINVAL); ++ } + if (ctrl_sizes[i] != (size_t)qc[i].elem_size) { + av_log(avctx, AV_LOG_DEBUG, "Probed V%d control %d size mismatch %zu != %zu\n", + HEVC_CTRLS_VERSION, i, ctrl_sizes[i], (size_t)qc[i].elem_size); @@ -54915,12 +56486,11 @@ index 0000000000..55c41ae679 + + fill_sps(&ctrl_sps, sps); + -+ if (mediabufs_set_ext_ctrl(ctx->mbufs, NULL, V4L2_CID_MPEG_VIDEO_HEVC_SPS, &ctrl_sps, sizeof(ctrl_sps))) { ++ if (mediabufs_set_ext_ctrl(ctx->mbufs, NULL, V4L2_CID_STATELESS_HEVC_SPS, &ctrl_sps, sizeof(ctrl_sps))) { + av_log(avctx, AV_LOG_ERROR, "Failed to set initial SPS\n"); + return AVERROR(EINVAL); + } + -+ ctx->multi_slice = (qc[0].flags & V4L2_CTRL_FLAG_DYNAMIC_ARRAY) != 0; + return 0; +} + @@ -54931,38 +56501,63 @@ index 0000000000..55c41ae679 + int ret; + + struct v4l2_query_ext_ctrl querys[] = { -+ { .id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE, }, -+ { .id = V4L2_CID_MPEG_VIDEO_HEVC_START_CODE, }, -+ { .id = V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS, }, ++ { .id = V4L2_CID_STATELESS_HEVC_DECODE_MODE, }, ++ { .id = V4L2_CID_STATELESS_HEVC_START_CODE, }, ++ { .id = V4L2_CID_STATELESS_HEVC_SLICE_PARAMS, }, ++#if HEVC_CTRLS_VERSION >= 4 ++ { .id = V4L2_CID_STATELESS_HEVC_ENTRY_POINT_OFFSETS, }, ++#endif + }; + + struct v4l2_ext_control ctrls[] = { -+ { .id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE, }, -+ { .id = V4L2_CID_MPEG_VIDEO_HEVC_START_CODE, }, ++ { .id = V4L2_CID_STATELESS_HEVC_DECODE_MODE, }, ++ { .id = V4L2_CID_STATELESS_HEVC_START_CODE, }, + }; + + mediabufs_ctl_query_ext_ctrls(ctx->mbufs, querys, FF_ARRAY_ELEMS(querys)); + -+ ctx->decode_mode = querys[0].default_value; ++ ctx->max_slices = (!(querys[2].flags & V4L2_CTRL_FLAG_DYNAMIC_ARRAY) || ++ querys[2].nr_of_dims != 1 || querys[2].dims[0] == 0) ? ++ 1 : querys[2].dims[0]; ++ av_log(avctx, AV_LOG_DEBUG, "%s: Max slices %d\n", __func__, ctx->max_slices); + -+ if (ctx->decode_mode != V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED && -+ ctx->decode_mode != V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_FRAME_BASED) { -+ av_log(avctx, AV_LOG_ERROR, "%s: unsupported decode mode, %d\n", __func__, ctx->decode_mode); ++#if HEVC_CTRLS_VERSION >= 4 ++ ctx->max_offsets = (querys[3].type == 0 || querys[3].nr_of_dims != 1) ? ++ 0 : querys[3].dims[0]; ++ av_log(avctx, AV_LOG_DEBUG, "%s: Entry point offsets %d\n", __func__, ctx->max_offsets); ++#else ++ ctx->max_offsets = 0; ++#endif ++ ++ if (querys[0].default_value == V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED || ++ querys[0].default_value == V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED) ++ ctx->decode_mode = querys[0].default_value; ++ else if (ctrl_valid(querys + 0, V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED)) ++ ctx->decode_mode = V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED; ++ else if (ctrl_valid(querys + 0, V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED)) ++ ctx->decode_mode = V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED; ++ else { ++ av_log(avctx, AV_LOG_ERROR, "%s: unsupported decode mode\n", __func__); + return AVERROR(EINVAL); + } + -+ ctx->start_code = querys[1].default_value; -+ if (ctx->start_code != V4L2_MPEG_VIDEO_HEVC_START_CODE_NONE && -+ ctx->start_code != V4L2_MPEG_VIDEO_HEVC_START_CODE_ANNEX_B) { -+ av_log(avctx, AV_LOG_ERROR, "%s: unsupported start code, %d\n", __func__, ctx->start_code); ++ if (querys[1].default_value == V4L2_STATELESS_HEVC_START_CODE_NONE || ++ querys[1].default_value == V4L2_STATELESS_HEVC_START_CODE_ANNEX_B) ++ ctx->start_code = querys[1].default_value; ++ else if (ctrl_valid(querys + 1, V4L2_STATELESS_HEVC_START_CODE_ANNEX_B)) ++ ctx->start_code = V4L2_STATELESS_HEVC_START_CODE_ANNEX_B; ++ else if (ctrl_valid(querys + 1, V4L2_STATELESS_HEVC_START_CODE_NONE)) ++ ctx->start_code = V4L2_STATELESS_HEVC_START_CODE_NONE; ++ else { ++ av_log(avctx, AV_LOG_ERROR, "%s: unsupported start code\n", __func__); + return AVERROR(EINVAL); + } + -+ ctx->max_slices = querys[2].elems; -+ if (ctx->max_slices > MAX_SLICES) { -+ av_log(avctx, AV_LOG_ERROR, "%s: unsupported max slices, %d\n", __func__, ctx->max_slices); -+ return AVERROR(EINVAL); -+ } ++ // If we are in slice mode & START_CODE_NONE supported then pick that ++ // as it doesn't require the slightly dodgy look backwards in our raw buffer ++ if (ctx->decode_mode == V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED && ++ ctrl_valid(querys + 1, V4L2_STATELESS_HEVC_START_CODE_NONE)) ++ ctx->start_code = V4L2_STATELESS_HEVC_START_CODE_NONE; + + ctrls[0].value = ctx->decode_mode; + ctrls[1].value = ctx->start_code; @@ -54986,6 +56581,7 @@ index 0000000000..55c41ae679 + + av_freep(&rd->slices); + av_freep(&rd->slice_params); ++ av_freep(&rd->offsets); + + av_free(rd); +} @@ -55103,10 +56699,10 @@ index 0000000000..55c41ae679 + diff --git a/libavcodec/v4l2_req_media.c b/libavcodec/v4l2_req_media.c new file mode 100644 -index 0000000000..980b306b8a +index 0000000000..1a9944774a --- /dev/null +++ b/libavcodec/v4l2_req_media.c -@@ -0,0 +1,1601 @@ +@@ -0,0 +1,1802 @@ +/* + * Copyright (C) 2018 Paul Kocialkowski + * @@ -55142,9 +56738,11 @@ index 0000000000..980b306b8a +#include +#include +#include ++#include +#include +#include +#include ++#include + +#include + @@ -55204,6 +56802,32 @@ index 0000000000..980b306b8a + struct polltask * pt; +}; + ++static inline enum v4l2_memory ++mediabufs_memory_to_v4l2(const enum mediabufs_memory m) ++{ ++ return (enum v4l2_memory)m; ++} ++ ++const char * ++mediabufs_memory_name(const enum mediabufs_memory m) ++{ ++ switch (m) { ++ case MEDIABUFS_MEMORY_UNSET: ++ return "Unset"; ++ case MEDIABUFS_MEMORY_MMAP: ++ return "MMap"; ++ case MEDIABUFS_MEMORY_USERPTR: ++ return "UserPtr"; ++ case MEDIABUFS_MEMORY_OVERLAY: ++ return "Overlay"; ++ case MEDIABUFS_MEMORY_DMABUF: ++ return "DMABuf"; ++ default: ++ break; ++ } ++ return "Unknown"; ++} ++ + +static inline int do_trywait(sem_t *const sem) +{ @@ -55224,14 +56848,14 @@ index 0000000000..980b306b8a +} + +static int request_buffers(int video_fd, unsigned int type, -+ enum v4l2_memory memory, unsigned int buffers_count) ++ enum mediabufs_memory memory, unsigned int buffers_count) +{ + struct v4l2_requestbuffers buffers; + int rc; + + memset(&buffers, 0, sizeof(buffers)); + buffers.type = type; -+ buffers.memory = memory; ++ buffers.memory = mediabufs_memory_to_v4l2(memory); + buffers.count = buffers_count; + + rc = ioctl(video_fd, VIDIOC_REQBUFS, &buffers); @@ -55433,6 +57057,7 @@ index 0000000000..980b306b8a + struct qent_base *next; + struct qent_base *prev; + enum qent_status status; ++ enum mediabufs_memory memtype; + uint32_t index; + struct dmabuf_h *dh[VIDEO_MAX_PLANES]; + struct timeval timestamp; @@ -55457,9 +57082,9 @@ index 0000000000..980b306b8a +}; + +struct buf_pool { ++ enum mediabufs_memory memtype; + pthread_mutex_t lock; + sem_t free_sem; -+ enum v4l2_buf_type buf_type; + struct qe_list_head free; + struct qe_list_head inuse; +}; @@ -55476,9 +57101,10 @@ index 0000000000..980b306b8a +} + + -+#define QENT_BASE_INITIALIZER {\ ++#define QENT_BASE_INITIALIZER(mtype) {\ + .ref_count = ATOMIC_VAR_INIT(0),\ + .status = QENT_NEW,\ ++ .memtype = (mtype),\ + .index = INDEX_UNSET\ +} + @@ -55499,13 +57125,13 @@ index 0000000000..980b306b8a + free(be_src); +} + -+static struct qent_src * qe_src_new(void) ++static struct qent_src * qe_src_new(enum mediabufs_memory mtype) +{ + struct qent_src *const be_src = malloc(sizeof(*be_src)); + if (!be_src) + return NULL; + *be_src = (struct qent_src){ -+ .base = QENT_BASE_INITIALIZER ++ .base = QENT_BASE_INITIALIZER(mtype) + }; + return be_src; +} @@ -55522,13 +57148,13 @@ index 0000000000..980b306b8a + free(be_dst); +} + -+static struct qent_dst* qe_dst_new(struct ff_weak_link_master * const wl) ++static struct qent_dst* qe_dst_new(struct ff_weak_link_master * const wl, const enum mediabufs_memory memtype) +{ + struct qent_dst *const be_dst = malloc(sizeof(*be_dst)); + if (!be_dst) + return NULL; + *be_dst = (struct qent_dst){ -+ .base = QENT_BASE_INITIALIZER, ++ .base = QENT_BASE_INITIALIZER(memtype), + .lock = PTHREAD_MUTEX_INITIALIZER, + .cond = PTHREAD_COND_INITIALIZER, + .mbc_wl = ff_weak_link_ref(wl) @@ -55662,14 +57288,14 @@ index 0000000000..980b306b8a + return buf; +} + -+static struct qent_base * queue_find_extract_fd(struct buf_pool *const bp, const int fd) ++static struct qent_base * queue_find_extract_index(struct buf_pool *const bp, const unsigned int index) +{ + struct qent_base *be; + + pthread_mutex_lock(&bp->lock); + /* Expect 1st in Q, but allow anywhere */ + for (be = bp->inuse.head; be; be = be->next) { -+ if (dmabuf_fd(be->dh[0]) == fd) { ++ if (be->index == index) { + bq_extract_inuse(bp, be); + break; + } @@ -55711,6 +57337,8 @@ index 0000000000..980b306b8a + struct pollqueue * pq; + struct ff_weak_link_master * this_wlm; + ++ enum mediabufs_memory src_memtype; ++ enum mediabufs_memory dst_memtype; + struct v4l2_format src_fmt; + struct v4l2_format dst_fmt; + struct v4l2_capability capability; @@ -55723,7 +57351,7 @@ index 0000000000..980b306b8a +{ + struct v4l2_buffer buffer = { + .type = fmt->type, -+ .memory = V4L2_MEMORY_DMABUF, ++ .memory = mediabufs_memory_to_v4l2(be->memtype), + .index = be->index + }; + struct v4l2_plane planes[VIDEO_MAX_PLANES] = {{0}}; @@ -55737,7 +57365,10 @@ index 0000000000..980b306b8a + /* *** Really need a pixdesc rather than a format so we can fill in data_offset */ + planes[i].length = dmabuf_size(be->dh[i]); + planes[i].bytesused = dmabuf_len(be->dh[i]); -+ planes[i].m.fd = dmabuf_fd(be->dh[i]); ++ if (be->memtype == MEDIABUFS_MEMORY_DMABUF) ++ planes[i].m.fd = dmabuf_fd(be->dh[i]); ++ else ++ planes[i].m.mem_offset = 0; + } + buffer.m.planes = planes; + buffer.length = i; @@ -55748,7 +57379,10 @@ index 0000000000..980b306b8a + + buffer.bytesused = dmabuf_len(be->dh[0]); + buffer.length = dmabuf_size(be->dh[0]); -+ buffer.m.fd = dmabuf_fd(be->dh[0]); ++ if (be->memtype == MEDIABUFS_MEMORY_DMABUF) ++ buffer.m.fd = dmabuf_fd(be->dh[0]); ++ else ++ buffer.m.offset = 0; + } + + if (!is_dst && mreq) { @@ -55777,14 +57411,13 @@ index 0000000000..980b306b8a + const int vfd, + const struct v4l2_format * const f) +{ -+ int fd; + struct qent_base *be; + int rc; + const bool mp = V4L2_TYPE_IS_MULTIPLANAR(f->type); + struct v4l2_plane planes[VIDEO_MAX_PLANES] = {{0}}; + struct v4l2_buffer buffer = { + .type = f->type, -+ .memory = V4L2_MEMORY_DMABUF ++ .memory = mediabufs_memory_to_v4l2(bp->memtype) + }; + if (mp) { + buffer.length = f->fmt.pix_mp.num_planes; @@ -55799,13 +57432,20 @@ index 0000000000..980b306b8a + return NULL; + } + -+ fd = mp ? planes[0].m.fd : buffer.m.fd; -+ be = queue_find_extract_fd(bp, fd); ++ be = queue_find_extract_index(bp, buffer.index); + if (!be) { -+ request_log("Failed to find fd %d in Q\n", fd); ++ request_log("Failed to find index %d in Q\n", buffer.index); + return NULL; + } + ++ if (mp) { ++ unsigned int i; ++ for (i = 0; i != buffer.length; ++i) ++ dmabuf_len_set(be->dh[i], V4L2_TYPE_IS_CAPTURE(f->type) ? planes[i].bytesused : 0); ++ } ++ else ++ dmabuf_len_set(be->dh[0], V4L2_TYPE_IS_CAPTURE(f->type) ? buffer.length : 0); ++ + be->timestamp = buffer.timestamp; + be->status = (buffer.flags & V4L2_BUF_FLAG_ERROR) ? QENT_ERROR : QENT_DONE; + return be; @@ -56213,7 +57853,7 @@ index 0000000000..980b306b8a + + struct v4l2_create_buffers cbuf = { + .count = n, -+ .memory = V4L2_MEMORY_DMABUF, ++ .memory = mediabufs_memory_to_v4l2(mbc->dst->memtype), + .format = mbc->dst_fmt, + }; + @@ -56234,12 +57874,97 @@ index 0000000000..980b306b8a + return cbuf.count; +} + ++static MediaBufsStatus ++qe_import_from_buf(struct mediabufs_ctl *const mbc, struct qent_base * const be, const struct v4l2_format *const fmt, ++ const unsigned int n, const bool x_dmabuf) ++{ ++ struct v4l2_buffer buf = { ++ .index = n, ++ .type = fmt->type, ++ }; ++ struct v4l2_plane planes[VIDEO_MAX_PLANES]; ++ int ret; ++ ++ if (be->dh[0]) ++ return 0; ++ ++ if (V4L2_TYPE_IS_MULTIPLANAR(fmt->type)) { ++ memset(planes, 0, sizeof(planes)); ++ buf.m.planes = planes; ++ buf.length = VIDEO_MAX_PLANES; ++ } ++ ++ if ((ret = ioctl(mbc->vfd, VIDIOC_QUERYBUF, &buf)) != 0) { ++ request_err(mbc->dc, "VIDIOC_QUERYBUF failed"); ++ return MEDIABUFS_ERROR_OPERATION_FAILED; ++ } ++ ++ if (V4L2_TYPE_IS_MULTIPLANAR(fmt->type)) ++ { ++ unsigned int i; ++ for (i = 0; i != buf.length; ++i) { ++ if (x_dmabuf) { ++ struct v4l2_exportbuffer xbuf = { ++ .type = buf.type, ++ .index = buf.index, ++ .plane = i, ++ .flags = O_RDWR, // *** Arguably O_RDONLY would be fine ++ }; ++ if (ioctl(mbc->vfd, VIDIOC_EXPBUF, &xbuf) == 0) ++ be->dh[i] = dmabuf_import(xbuf.fd, planes[i].length); ++ } ++ else { ++ be->dh[i] = dmabuf_import_mmap( ++ mmap(NULL, planes[i].length, ++ PROT_READ | PROT_WRITE, ++ MAP_SHARED | MAP_POPULATE, ++ mbc->vfd, planes[i].m.mem_offset), ++ planes[i].length); ++ } ++ /* On failure tidy up and die */ ++ if (!be->dh[i]) { ++ while (i--) { ++ dmabuf_free(be->dh[i]); ++ be->dh[i] = NULL; ++ } ++ return MEDIABUFS_ERROR_OPERATION_FAILED; ++ } ++ } ++ } ++ else ++ { ++ if (x_dmabuf) { ++ struct v4l2_exportbuffer xbuf = { ++ .type = buf.type, ++ .index = buf.index, ++ .flags = O_RDWR, // *** Arguably O_RDONLY would be fine ++ }; ++ if (ioctl(mbc->vfd, VIDIOC_EXPBUF, &xbuf) == 0) ++ be->dh[0] = dmabuf_import(xbuf.fd, buf.length); ++ } ++ else { ++ be->dh[0] = dmabuf_import_mmap( ++ mmap(NULL, buf.length, ++ PROT_READ | PROT_WRITE, ++ MAP_SHARED | MAP_POPULATE, ++ mbc->vfd, buf.m.offset), ++ buf.length); ++ } ++ /* On failure tidy up and die */ ++ if (!be->dh[0]) { ++ return MEDIABUFS_ERROR_OPERATION_FAILED; ++ } ++ } ++ ++ return 0; ++} ++ +struct qent_dst* mediabufs_dst_qent_alloc(struct mediabufs_ctl *const mbc, struct dmabufs_ctl *const dbsc) +{ + struct qent_dst * be_dst; + + if (mbc == NULL) { -+ be_dst = qe_dst_new(NULL); ++ be_dst = qe_dst_new(NULL, MEDIABUFS_MEMORY_DMABUF); + if (be_dst) + be_dst->base.status = QENT_IMPORT; + return be_dst; @@ -56253,7 +57978,7 @@ index 0000000000..980b306b8a + else { + be_dst = base_to_dst(queue_tryget_free(mbc->dst)); + if (!be_dst) { -+ be_dst = qe_dst_new(mbc->this_wlm); ++ be_dst = qe_dst_new(mbc->this_wlm, mbc->dst->memtype); + if (!be_dst) + return NULL; + @@ -56264,12 +57989,21 @@ index 0000000000..980b306b8a + } + } + -+ if (qe_alloc_from_fmt(&be_dst->base, dbsc, &mbc->dst_fmt)) { -+ /* Given how create buf works we can't uncreate it on alloc failure -+ * all we can do is put it on the free Q -+ */ -+ queue_put_free(mbc->dst, &be_dst->base); -+ return NULL; ++ if (mbc->dst->memtype == MEDIABUFS_MEMORY_MMAP) { ++ if (qe_import_from_buf(mbc, &be_dst->base, &mbc->dst_fmt, be_dst->base.index, true)) { ++ request_err(mbc->dc, "Failed to export as dmabuf\n"); ++ queue_put_free(mbc->dst, &be_dst->base); ++ return NULL; ++ } ++ } ++ else { ++ if (qe_alloc_from_fmt(&be_dst->base, dbsc, &mbc->dst_fmt)) { ++ /* Given how create buf works we can't uncreate it on alloc failure ++ * all we can do is put it on the free Q ++ */ ++ queue_put_free(mbc->dst, &be_dst->base); ++ return NULL; ++ } + } + + be_dst->base.status = QENT_PENDING; @@ -56317,7 +58051,7 @@ index 0000000000..980b306b8a + +// ** This is a mess if we get partial alloc but without any way to remove +// individual V4L2 Q members we are somewhat stuffed -+MediaBufsStatus mediabufs_dst_slots_create(struct mediabufs_ctl *const mbc, const unsigned int n, const bool fixed) ++MediaBufsStatus mediabufs_dst_slots_create(struct mediabufs_ctl *const mbc, const unsigned int n, const bool fixed, const enum mediabufs_memory memtype) +{ + unsigned int i; + int a = 0; @@ -56327,10 +58061,12 @@ index 0000000000..980b306b8a + if (n > 32) + return MEDIABUFS_ERROR_ALLOCATION_FAILED; + ++ mbc->dst->memtype = memtype; ++ + // Create qents first as it is hard to get rid of the V4L2 buffers on error + for (qc = 0; qc != n; ++qc) + { -+ if ((qes[qc] = qe_dst_new(mbc->this_wlm)) == NULL) ++ if ((qes[qc] = qe_dst_new(mbc->this_wlm, mbc->dst->memtype)) == NULL) + goto fail; + } + @@ -56369,19 +58105,61 @@ index 0000000000..980b306b8a + queue_put_free(mbc->src, &qe_src->base); +} + ++static MediaBufsStatus ++chk_memory_type(struct mediabufs_ctl *const mbc, ++ const struct v4l2_format * const f, ++ const enum mediabufs_memory m) ++{ ++ struct v4l2_create_buffers cbuf = { ++ .count = 0, ++ .memory = V4L2_MEMORY_MMAP, ++ .format = *f ++ }; ++ ++ if (ioctl(mbc->vfd, VIDIOC_CREATE_BUFS, &cbuf) != 0) ++ return MEDIABUFS_ERROR_OPERATION_FAILED; ++ ++ switch (m) { ++ case MEDIABUFS_MEMORY_DMABUF: ++ // 0 = Unknown but assume not in that case ++ if ((cbuf.capabilities & V4L2_BUF_CAP_SUPPORTS_DMABUF) == 0) ++ return MEDIABUFS_ERROR_UNSUPPORTED_MEMORY; ++ break; ++ case MEDIABUFS_MEMORY_MMAP: ++ break; ++ default: ++ return MEDIABUFS_ERROR_UNSUPPORTED_MEMORY; ++ } ++ ++ return MEDIABUFS_STATUS_SUCCESS; ++} ++ ++MediaBufsStatus ++mediabufs_src_chk_memtype(struct mediabufs_ctl *const mbc, const enum mediabufs_memory memtype) ++{ ++ return chk_memory_type(mbc, &mbc->src_fmt, memtype); ++} ++ ++MediaBufsStatus ++mediabufs_dst_chk_memtype(struct mediabufs_ctl *const mbc, const enum mediabufs_memory memtype) ++{ ++ return chk_memory_type(mbc, &mbc->dst_fmt, memtype); ++} ++ +/* src format must have been set up before this */ +MediaBufsStatus mediabufs_src_pool_create(struct mediabufs_ctl *const mbc, + struct dmabufs_ctl * const dbsc, -+ unsigned int n) ++ unsigned int n, const enum mediabufs_memory memtype) +{ + unsigned int i; + struct v4l2_requestbuffers req = { + .count = n, + .type = mbc->src_fmt.type, -+ .memory = V4L2_MEMORY_DMABUF ++ .memory = mediabufs_memory_to_v4l2(memtype) + }; + + bq_free_all_free_src(mbc->src); ++ + while (ioctl(mbc->vfd, VIDIOC_REQBUFS, &req) == -1) { + if (errno != EINTR) { + request_err(mbc->dc, "%s: Failed to request src bufs\n", __func__); @@ -56395,21 +58173,36 @@ index 0000000000..980b306b8a + } + + for (i = 0; i != n; ++i) { -+ struct qent_src *const be_src = qe_src_new(); ++ struct qent_src *const be_src = qe_src_new(memtype); + if (!be_src) { + request_err(mbc->dc, "Failed to create src be %d\n", i); + goto fail; + } -+ if (qe_alloc_from_fmt(&be_src->base, dbsc, &mbc->src_fmt)) { -+ qe_src_free(be_src); ++ switch (memtype) { ++ case MEDIABUFS_MEMORY_MMAP: ++ if (qe_import_from_buf(mbc, &be_src->base, &mbc->src_fmt, i, false)) { ++ qe_src_free(be_src); ++ goto fail; ++ } ++ be_src->fixed_size = 1; ++ break; ++ case MEDIABUFS_MEMORY_DMABUF: ++ if (qe_alloc_from_fmt(&be_src->base, dbsc, &mbc->src_fmt)) { ++ qe_src_free(be_src); ++ goto fail; ++ } ++ be_src->fixed_size = !mediabufs_src_resizable(mbc); ++ break; ++ default: ++ request_err(mbc->dc, "Unexpected memorty type\n"); + goto fail; + } + be_src->base.index = i; -+ be_src->fixed_size = !mediabufs_src_resizable(mbc); + + queue_put_free(mbc->src, &be_src->base); + } + ++ mbc->src->memtype = memtype; + return MEDIABUFS_STATUS_SUCCESS; + +fail: @@ -56546,9 +58339,13 @@ index 0000000000..980b306b8a + +int mediabufs_src_resizable(const struct mediabufs_ctl *const mbc) +{ ++#if 1 ++ return 0; ++#else + // Single planar OUTPUT can only take exact size buffers + // Multiplanar will take larger than negotiated + return V4L2_TYPE_IS_MULTIPLANAR(mbc->src_fmt.type); ++#endif +} + +static void mediabufs_ctl_delete(struct mediabufs_ctl *const mbc) @@ -56710,10 +58507,10 @@ index 0000000000..980b306b8a + diff --git a/libavcodec/v4l2_req_media.h b/libavcodec/v4l2_req_media.h new file mode 100644 -index 0000000000..0307a831de +index 0000000000..890947b2e2 --- /dev/null +++ b/libavcodec/v4l2_req_media.h -@@ -0,0 +1,154 @@ +@@ -0,0 +1,171 @@ +/* +e.h +* @@ -56759,6 +58556,7 @@ index 0000000000..0307a831de + MEDIABUFS_ERROR_UNSUPPORTED_BUFFERTYPE, + MEDIABUFS_ERROR_UNSUPPORTED_RT_FORMAT, + MEDIABUFS_ERROR_ALLOCATION_FAILED, ++ MEDIABUFS_ERROR_UNSUPPORTED_MEMORY, +} MediaBufsStatus; + +struct media_pool * media_pool_new(const char * const media_path, @@ -56786,6 +58584,15 @@ index 0000000000..0307a831de +struct dmabuf_h; +struct dmabufs_ctl; + ++// 1-1 mammping to V4L2 type - just defined separetely to avoid some include versioning difficulties ++enum mediabufs_memory { ++ MEDIABUFS_MEMORY_UNSET = 0, ++ MEDIABUFS_MEMORY_MMAP = 1, ++ MEDIABUFS_MEMORY_USERPTR = 2, ++ MEDIABUFS_MEMORY_OVERLAY = 3, ++ MEDIABUFS_MEMORY_DMABUF = 4, ++}; ++ +int qent_src_params_set(struct qent_src *const be, const struct timeval * timestamp); +struct timeval qent_dst_timestamp_get(const struct qent_dst *const be_dst); + @@ -56809,6 +58616,8 @@ index 0000000000..0307a831de + unsigned int plane, + int fd, size_t size); + ++const char * mediabufs_memory_name(const enum mediabufs_memory m); ++ +MediaBufsStatus mediabufs_start_request(struct mediabufs_ctl *const mbc, + struct media_request **const pmreq, + struct qent_src **const psrc_be, @@ -56822,7 +58631,7 @@ index 0000000000..0307a831de +// Create dst slots without alloc +// If fixed true then qent_alloc will only get slots from this pool and will +// block until a qent has been unrefed -+MediaBufsStatus mediabufs_dst_slots_create(struct mediabufs_ctl *const mbc, const unsigned int n, const bool fixed); ++MediaBufsStatus mediabufs_dst_slots_create(struct mediabufs_ctl *const mbc, const unsigned int n, const bool fixed, const enum mediabufs_memory memtype); + +MediaBufsStatus mediabufs_stream_on(struct mediabufs_ctl *const mbc); +MediaBufsStatus mediabufs_stream_off(struct mediabufs_ctl *const mbc); @@ -56856,7 +58665,12 @@ index 0000000000..0307a831de + +MediaBufsStatus mediabufs_src_pool_create(struct mediabufs_ctl *const rw, + struct dmabufs_ctl * const dbsc, -+ unsigned int n); ++ unsigned int n, ++ const enum mediabufs_memory memtype); ++ ++// Want to have appropriate formats set first ++MediaBufsStatus mediabufs_src_chk_memtype(struct mediabufs_ctl *const mbc, const enum mediabufs_memory memtype); ++MediaBufsStatus mediabufs_dst_chk_memtype(struct mediabufs_ctl *const mbc, const enum mediabufs_memory memtype); + +#define MEDIABUFS_DRIVER_VERSION(a, b, c) (((a) << 16) | ((b) << 8) | (c)) +unsigned int mediabufs_ctl_driver_version(struct mediabufs_ctl *const mbc); @@ -57261,10 +59075,14 @@ index 0000000000..e1182cb2fc +#endif /* POLLQUEUE_H_ */ diff --git a/libavcodec/v4l2_req_utils.h b/libavcodec/v4l2_req_utils.h new file mode 100644 -index 0000000000..cb4bd164b4 +index 0000000000..a31cc1f4ec --- /dev/null +++ b/libavcodec/v4l2_req_utils.h -@@ -0,0 +1,22 @@ +@@ -0,0 +1,27 @@ ++#ifndef AVCODEC_V4L2_REQ_UTILS_H ++#define AVCODEC_V4L2_REQ_UTILS_H ++ ++#include +#include "libavutil/log.h" + +#define request_log(...) av_log(NULL, AV_LOG_INFO, __VA_ARGS__) @@ -57287,12 +59105,13 @@ index 0000000000..cb4bd164b4 + return tbuf; +} + ++#endif diff --git a/libavcodec/v4l2_request_hevc.c b/libavcodec/v4l2_request_hevc.c new file mode 100644 -index 0000000000..0ae14db90b +index 0000000000..ebeb7bc6f6 --- /dev/null +++ b/libavcodec/v4l2_request_hevc.c -@@ -0,0 +1,311 @@ +@@ -0,0 +1,345 @@ +/* + * This file is part of FFmpeg. + * @@ -57312,7 +59131,7 @@ index 0000000000..0ae14db90b + */ + + -+ ++#include "config.h" +#include "decode.h" +#include "hevcdec.h" +#include "hwconfig.h" @@ -57436,8 +59255,10 @@ index 0000000000..0ae14db90b + const HEVCSPS * const sps = h->ps.sps; + int ret; + const struct decdev * decdev; -+ const uint32_t src_pix_fmt = V2(ff_v4l2_req_hevc, 1).src_pix_fmt_v4l2; // Assuming constant for all APIs but avoiding V4L2 includes ++ const uint32_t src_pix_fmt = V2(ff_v4l2_req_hevc, 4).src_pix_fmt_v4l2; // Assuming constant for all APIs but avoiding V4L2 includes + size_t src_size; ++ enum mediabufs_memory src_memtype; ++ enum mediabufs_memory dst_memtype; + + av_log(avctx, AV_LOG_DEBUG, "<<< %s\n", __func__); + @@ -57468,8 +59289,14 @@ index 0000000000..0ae14db90b + decdev_media_path(decdev), decdev_video_path(decdev)); + + if ((ctx->dbufs = dmabufs_ctl_new()) == NULL) { -+ av_log(avctx, AV_LOG_ERROR, "Unable to open dmabufs\n"); -+ goto fail0; ++ av_log(avctx, AV_LOG_DEBUG, "Unable to open dmabufs - try mmap buffers\n"); ++ src_memtype = MEDIABUFS_MEMORY_MMAP; ++ dst_memtype = MEDIABUFS_MEMORY_MMAP; ++ } ++ else { ++ av_log(avctx, AV_LOG_DEBUG, "Dmabufs opened - try dmabuf buffers\n"); ++ src_memtype = MEDIABUFS_MEMORY_DMABUF; ++ dst_memtype = MEDIABUFS_MEMORY_DMABUF; + } + + if ((ctx->pq = pollqueue_new()) == NULL) { @@ -57490,8 +59317,9 @@ index 0000000000..0ae14db90b + // Ask for an initial bitbuf size of max size / 4 + // We will realloc if we need more + // Must use sps->h/w as avctx contains cropped size ++retry_src_memtype: + src_size = bit_buf_size(sps->width, sps->height, sps->bit_depth - 8); -+ if (mediabufs_src_resizable(ctx->mbufs)) ++ if (src_memtype == MEDIABUFS_MEMORY_DMABUF && mediabufs_src_resizable(ctx->mbufs)) + src_size /= 4; + // Kludge for conformance tests which break Annex A limits + else if (src_size < 0x40000) @@ -57504,7 +59332,21 @@ index 0000000000..0ae14db90b + goto fail4; + } + -+ if (V2(ff_v4l2_req_hevc, 3).probe(avctx, ctx) == 0) { ++ if (mediabufs_src_chk_memtype(ctx->mbufs, src_memtype)) { ++ if (src_memtype == MEDIABUFS_MEMORY_DMABUF) { ++ src_memtype = MEDIABUFS_MEMORY_MMAP; ++ goto retry_src_memtype; ++ } ++ av_log(avctx, AV_LOG_ERROR, "Failed to get src memory type\n"); ++ goto fail4; ++ } ++ ++ if (V2(ff_v4l2_req_hevc, 4).probe(avctx, ctx) == 0) { ++ av_log(avctx, AV_LOG_DEBUG, "HEVC API version 4 probed successfully\n"); ++ ctx->fns = &V2(ff_v4l2_req_hevc, 4); ++ } ++#if CONFIG_V4L2_REQ_HEVC_VX ++ else if (V2(ff_v4l2_req_hevc, 3).probe(avctx, ctx) == 0) { + av_log(avctx, AV_LOG_DEBUG, "HEVC API version 3 probed successfully\n"); + ctx->fns = &V2(ff_v4l2_req_hevc, 3); + } @@ -57516,6 +59358,7 @@ index 0000000000..0ae14db90b + av_log(avctx, AV_LOG_DEBUG, "HEVC API version 1 probed successfully\n"); + ctx->fns = &V2(ff_v4l2_req_hevc, 1); + } ++#endif + else { + av_log(avctx, AV_LOG_ERROR, "No HEVC version probed successfully\n"); + ret = AVERROR(EINVAL); @@ -57528,7 +59371,7 @@ index 0000000000..0ae14db90b + goto fail4; + } + -+ if (mediabufs_src_pool_create(ctx->mbufs, ctx->dbufs, 6)) { ++ if (mediabufs_src_pool_create(ctx->mbufs, ctx->dbufs, 6, src_memtype)) { + av_log(avctx, AV_LOG_ERROR, "Failed to create source pool\n"); + goto fail4; + } @@ -57540,8 +59383,17 @@ index 0000000000..0ae14db90b + sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering, + avctx->thread_count, avctx->extra_hw_frames); + ++ if (mediabufs_dst_chk_memtype(ctx->mbufs, dst_memtype)) { ++ if (dst_memtype != MEDIABUFS_MEMORY_DMABUF) { ++ av_log(avctx, AV_LOG_ERROR, "Failed to get dst memory type\n"); ++ goto fail4; ++ } ++ av_log(avctx, AV_LOG_DEBUG, "Dst DMABUF not supported - trying mmap\n"); ++ dst_memtype = MEDIABUFS_MEMORY_MMAP; ++ } ++ + // extra_hw_frames is -1 if unset -+ if (mediabufs_dst_slots_create(ctx->mbufs, dst_slots, (avctx->extra_hw_frames > 0))) { ++ if (mediabufs_dst_slots_create(ctx->mbufs, dst_slots, (avctx->extra_hw_frames > 0), dst_memtype)) { + av_log(avctx, AV_LOG_ERROR, "Failed to create destination slots\n"); + goto fail4; + } @@ -57567,9 +59419,10 @@ index 0000000000..0ae14db90b + // Set our s/w format + avctx->sw_pix_fmt = ((AVHWFramesContext *)avctx->hw_frames_ctx->data)->sw_format; + -+ av_log(avctx, AV_LOG_INFO, "Hwaccel %s; devices: %s,%s\n", ++ av_log(avctx, AV_LOG_INFO, "Hwaccel %s; devices: %s,%s; buffers: src %s, dst %s\n", + ctx->fns->name, -+ decdev_media_path(decdev), decdev_video_path(decdev)); ++ decdev_media_path(decdev), decdev_video_path(decdev), ++ mediabufs_memory_name(src_memtype), mediabufs_memory_name(dst_memtype)); + + return 0; + @@ -57606,13 +59459,14 @@ index 0000000000..0ae14db90b +}; diff --git a/libavcodec/v4l2_request_hevc.h b/libavcodec/v4l2_request_hevc.h new file mode 100644 -index 0000000000..b2cb8c8584 +index 0000000000..99c90064ea --- /dev/null +++ b/libavcodec/v4l2_request_hevc.h @@ -0,0 +1,102 @@ +#ifndef AVCODEC_V4L2_REQUEST_HEVC_H +#define AVCODEC_V4L2_REQUEST_HEVC_H + ++#include +#include +#include "v4l2_req_decode_q.h" + @@ -57657,8 +59511,6 @@ index 0000000000..b2cb8c8584 +#define V4L2_CTRL_FLAG_DYNAMIC_ARRAY 0x0800 +#endif + -+#define MAX_SLICES 128 -+ +#define VCAT(name, version) name##_v##version +#define V2(n,v) VCAT(n, v) +#define V(n) V2(n, HEVC_CTRLS_VERSION) @@ -57675,10 +59527,10 @@ index 0000000000..b2cb8c8584 + + unsigned int timestamp; // ?? maybe uint64_t + -+ int multi_slice; + int decode_mode; + int start_code; -+ int max_slices; ++ unsigned int max_slices; // 0 => not wanted (frame mode) ++ unsigned int max_offsets; // 0 => not wanted + + req_decode_q decode_q; + @@ -57710,6 +59562,7 @@ index 0000000000..b2cb8c8584 +extern const v4l2_req_decode_fns V2(ff_v4l2_req_hevc, 1); +extern const v4l2_req_decode_fns V2(ff_v4l2_req_hevc, 2); +extern const v4l2_req_decode_fns V2(ff_v4l2_req_hevc, 3); ++extern const v4l2_req_decode_fns V2(ff_v4l2_req_hevc, 4); + +#endif diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c @@ -60017,7 +61870,7 @@ index b2c254ea67..144fbda652 100644 OBJS-$(CONFIG_UNSHARP_OPENCL_FILTER) += vf_unsharp_opencl.o opencl.o \ opencl/unsharp.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c -index 0872c6e0f2..8b23df9323 100644 +index 0872c6e0f2..1dd05e4d75 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -218,6 +218,7 @@ extern AVFilter ff_vf_dedot; @@ -60028,7 +61881,15 @@ index 0872c6e0f2..8b23df9323 100644 extern AVFilter ff_vf_deinterlace_vaapi; extern AVFilter ff_vf_dejudder; extern AVFilter ff_vf_delogo; -@@ -438,6 +439,7 @@ extern AVFilter ff_vf_transpose_opencl; +@@ -377,6 +378,7 @@ extern AVFilter ff_vf_scale; + extern AVFilter ff_vf_scale_cuda; + extern AVFilter ff_vf_scale_npp; + extern AVFilter ff_vf_scale_qsv; ++extern AVFilter ff_vf_scale_v4l2m2m; + extern AVFilter ff_vf_scale_vaapi; + extern AVFilter ff_vf_scale_vulkan; + extern AVFilter ff_vf_scale2ref; +@@ -438,6 +440,7 @@ extern AVFilter ff_vf_transpose_opencl; extern AVFilter ff_vf_transpose_vaapi; extern AVFilter ff_vf_trim; extern AVFilter ff_vf_unpremultiply; @@ -60181,10 +62042,10 @@ index da1cf9941e..c588ed23cb 100644 case AVMEDIA_TYPE_AUDIO: diff --git a/libavfilter/vf_deinterlace_v4l2m2m.c b/libavfilter/vf_deinterlace_v4l2m2m.c new file mode 100644 -index 0000000000..d1c714b805 +index 0000000000..986fde5955 --- /dev/null +++ b/libavfilter/vf_deinterlace_v4l2m2m.c -@@ -0,0 +1,1282 @@ +@@ -0,0 +1,1971 @@ +/* + * This file is part of FFmpeg. + * @@ -60239,33 +62100,39 @@ index 0000000000..d1c714b805 +#include "avfilter.h" +#include "formats.h" +#include "internal.h" ++#include "scale_eval.h" +#include "video.h" + ++#ifndef DRM_FORMAT_P030 ++#define DRM_FORMAT_P030 fourcc_code('P', '0', '3', '0') /* 2x2 subsampled Cr:Cb plane 10 bits per channel packed */ ++#endif ++ +typedef struct V4L2Queue V4L2Queue; +typedef struct DeintV4L2M2MContextShared DeintV4L2M2MContextShared; + -+typedef struct V4L2PlaneInfo { -+ int bytesperline; -+ size_t length; -+} V4L2PlaneInfo; ++typedef enum filter_type_v4l2_e ++{ ++ FILTER_V4L2_DEINTERLACE = 1, ++ FILTER_V4L2_SCALE, ++} filter_type_v4l2_t; + +typedef struct V4L2Buffer { + int enqueued; + int reenqueue; -+ int fd; + struct v4l2_buffer buffer; + AVFrame frame; + struct v4l2_plane planes[VIDEO_MAX_PLANES]; + int num_planes; -+ V4L2PlaneInfo plane_info[VIDEO_MAX_PLANES]; + AVDRMFrameDescriptor drm_frame; + V4L2Queue *q; +} V4L2Buffer; + +typedef struct V4L2Queue { + struct v4l2_format format; ++ struct v4l2_selection sel; + int num_buffers; + V4L2Buffer *buffers; ++ const char * name; + DeintV4L2M2MContextShared *ctx; +} V4L2Queue; + @@ -60298,11 +62165,18 @@ index 0000000000..d1c714b805 + +typedef struct DeintV4L2M2MContextShared { + void * logctx; // For logging - will be NULL when done ++ filter_type_v4l2_t filter_type; + + int fd; + int done; + int width; + int height; ++ ++ // from options ++ int output_width; ++ int output_height; ++ enum AVPixelFormat output_format; ++ + int orig_width; + int orig_height; + atomic_uint refcount; @@ -60321,8 +62195,60 @@ index 0000000000..d1c714b805 + const AVClass *class; + + DeintV4L2M2MContextShared *shared; ++ ++ char * w_expr; ++ char * h_expr; ++ char * output_format_string;; ++ ++ int force_original_aspect_ratio; ++ int force_divisible_by; ++ ++ char *colour_primaries_string; ++ char *colour_transfer_string; ++ char *colour_matrix_string; ++ int colour_range; ++ char *chroma_location_string; ++ ++ enum AVColorPrimaries colour_primaries; ++ enum AVColorTransferCharacteristic colour_transfer; ++ enum AVColorSpace colour_matrix; ++ enum AVChromaLocation chroma_location; +} DeintV4L2M2MContext; + ++// These just list the ones we know we can cope with ++static uint32_t ++fmt_av_to_v4l2(const enum AVPixelFormat avfmt) ++{ ++ switch (avfmt) { ++ case AV_PIX_FMT_YUV420P: ++ return V4L2_PIX_FMT_YUV420; ++ case AV_PIX_FMT_NV12: ++ return V4L2_PIX_FMT_NV12; ++ case AV_PIX_FMT_RPI4_8: ++ case AV_PIX_FMT_SAND128: ++ return V4L2_PIX_FMT_NV12_COL128; ++ default: ++ break; ++ } ++ return 0; ++} ++ ++static enum AVPixelFormat ++fmt_v4l2_to_av(const uint32_t pixfmt) ++{ ++ switch (pixfmt) { ++ case V4L2_PIX_FMT_YUV420: ++ return AV_PIX_FMT_YUV420P; ++ case V4L2_PIX_FMT_NV12: ++ return AV_PIX_FMT_NV12; ++ case V4L2_PIX_FMT_NV12_COL128: ++ return AV_PIX_FMT_RPI4_8; ++ default: ++ break; ++ } ++ return AV_PIX_FMT_NONE; ++} ++ +static unsigned int pts_stats_interval(const pts_stats_t * const stats) +{ + return stats->last_interval; @@ -60488,6 +62414,39 @@ index 0000000000..d1c714b805 + return 0; +} + ++static inline uint32_t ++fmt_bpl(const struct v4l2_format * const fmt, const unsigned int plane_n) ++{ ++ return V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? fmt->fmt.pix_mp.plane_fmt[plane_n].bytesperline : fmt->fmt.pix.bytesperline; ++} ++ ++static inline uint32_t ++fmt_height(const struct v4l2_format * const fmt) ++{ ++ return V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? fmt->fmt.pix_mp.height : fmt->fmt.pix.height; ++} ++ ++static inline uint32_t ++fmt_width(const struct v4l2_format * const fmt) ++{ ++ return V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? fmt->fmt.pix_mp.width : fmt->fmt.pix.width; ++} ++ ++static inline uint32_t ++fmt_pixelformat(const struct v4l2_format * const fmt) ++{ ++ return V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? fmt->fmt.pix_mp.pixelformat : fmt->fmt.pix.pixelformat; ++} ++ ++static void ++init_format(V4L2Queue * const q, const uint32_t format_type) ++{ ++ memset(&q->format, 0, sizeof(q->format)); ++ memset(&q->sel, 0, sizeof(q->sel)); ++ q->format.type = format_type; ++ q->sel.type = format_type; ++} ++ +static int deint_v4l2m2m_prepare_context(DeintV4L2M2MContextShared *ctx) +{ + struct v4l2_capability cap; @@ -60498,78 +62457,99 @@ index 0000000000..d1c714b805 + if (ret < 0) + return ret; + -+ if (!(cap.capabilities & V4L2_CAP_STREAMING)) ++ if (ctx->filter_type == FILTER_V4L2_SCALE && ++ strcmp("bcm2835-codec-isp", cap.card) != 0) ++ { ++ av_log(ctx->logctx, AV_LOG_DEBUG, "Not ISP\n"); + return AVERROR(EINVAL); ++ } + -+ if (cap.capabilities & V4L2_CAP_VIDEO_M2M) { -+ ctx->capture.format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -+ ctx->output.format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; -+ -+ return 0; ++ if (!(cap.capabilities & V4L2_CAP_STREAMING)) { ++ av_log(ctx->logctx, AV_LOG_DEBUG, "No streaming\n"); ++ return AVERROR(EINVAL); + } + + if (cap.capabilities & V4L2_CAP_VIDEO_M2M_MPLANE) { -+ ctx->capture.format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; -+ ctx->output.format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; -+ -+ return 0; ++ init_format(&ctx->capture, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); ++ init_format(&ctx->output, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); ++ } ++ else if (cap.capabilities & V4L2_CAP_VIDEO_M2M) { ++ init_format(&ctx->capture, V4L2_BUF_TYPE_VIDEO_CAPTURE); ++ init_format(&ctx->output, V4L2_BUF_TYPE_VIDEO_OUTPUT); ++ } ++ else { ++ av_log(ctx->logctx, AV_LOG_DEBUG, "Not M2M\n"); ++ return AVERROR(EINVAL); + } + -+ return AVERROR(EINVAL); ++ return 0; +} + -+static int deint_v4l2m2m_try_format(V4L2Queue *queue) ++// Just use for probe - doesn't modify q format ++static int deint_v4l2m2m_try_format(V4L2Queue *queue, const uint32_t width, const uint32_t height, const enum AVPixelFormat avfmt) +{ -+ struct v4l2_format *fmt = &queue->format; ++ struct v4l2_format fmt = {.type = queue->format.type}; + DeintV4L2M2MContextShared *ctx = queue->ctx; + int ret, field; ++ // Pick YUV to test with if not otherwise specified ++ uint32_t pixelformat = avfmt == AV_PIX_FMT_NONE ? V4L2_PIX_FMT_YUV420 : fmt_av_to_v4l2(avfmt); ++ enum AVPixelFormat r_avfmt; + -+ ret = ioctl(ctx->fd, VIDIOC_G_FMT, fmt); ++ ++ ret = ioctl(ctx->fd, VIDIOC_G_FMT, &fmt); + if (ret) + av_log(ctx->logctx, AV_LOG_ERROR, "VIDIOC_G_FMT failed: %d\n", ret); + -+ if (V4L2_TYPE_IS_OUTPUT(fmt->type)) ++ if (ctx->filter_type == FILTER_V4L2_DEINTERLACE && V4L2_TYPE_IS_OUTPUT(fmt.type)) + field = V4L2_FIELD_INTERLACED_TB; + else + field = V4L2_FIELD_NONE; + -+ if (V4L2_TYPE_IS_MULTIPLANAR(fmt->type)) { -+ fmt->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_YUV420; -+ fmt->fmt.pix_mp.field = field; -+ fmt->fmt.pix_mp.width = ctx->width; -+ fmt->fmt.pix_mp.height = ctx->height; ++ if (V4L2_TYPE_IS_MULTIPLANAR(fmt.type)) { ++ fmt.fmt.pix_mp.pixelformat = pixelformat; ++ fmt.fmt.pix_mp.field = field; ++ fmt.fmt.pix_mp.width = width; ++ fmt.fmt.pix_mp.height = height; + } else { -+ fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; -+ fmt->fmt.pix.field = field; -+ fmt->fmt.pix.width = ctx->width; -+ fmt->fmt.pix.height = ctx->height; ++ fmt.fmt.pix.pixelformat = pixelformat; ++ fmt.fmt.pix.field = field; ++ fmt.fmt.pix.width = width; ++ fmt.fmt.pix.height = height; + } + -+ av_log(ctx->logctx, AV_LOG_DEBUG, "%s: Trying format for type %d, wxh: %dx%d, fmt: %08x, size %u bpl %u pre\n", __func__, -+ fmt->type, fmt->fmt.pix_mp.width, fmt->fmt.pix_mp.height, -+ fmt->fmt.pix_mp.pixelformat, -+ fmt->fmt.pix_mp.plane_fmt[0].sizeimage, fmt->fmt.pix_mp.plane_fmt[0].bytesperline); ++ av_log(ctx->logctx, AV_LOG_TRACE, "%s: Trying format for type %d, wxh: %dx%d, fmt: %08x, size %u bpl %u pre\n", __func__, ++ fmt.type, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, ++ fmt.fmt.pix_mp.pixelformat, ++ fmt.fmt.pix_mp.plane_fmt[0].sizeimage, fmt.fmt.pix_mp.plane_fmt[0].bytesperline); + -+ ret = ioctl(ctx->fd, VIDIOC_TRY_FMT, fmt); ++ ret = ioctl(ctx->fd, VIDIOC_TRY_FMT, &fmt); + if (ret) + return AVERROR(EINVAL); + -+ av_log(ctx->logctx, AV_LOG_DEBUG, "%s: Trying format for type %d, wxh: %dx%d, fmt: %08x, size %u bpl %u post\n", __func__, -+ fmt->type, fmt->fmt.pix_mp.width, fmt->fmt.pix_mp.height, -+ fmt->fmt.pix_mp.pixelformat, -+ fmt->fmt.pix_mp.plane_fmt[0].sizeimage, fmt->fmt.pix_mp.plane_fmt[0].bytesperline); ++ av_log(ctx->logctx, AV_LOG_TRACE, "%s: Trying format for type %d, wxh: %dx%d, fmt: %08x, size %u bpl %u post\n", __func__, ++ fmt.type, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, ++ fmt.fmt.pix_mp.pixelformat, ++ fmt.fmt.pix_mp.plane_fmt[0].sizeimage, fmt.fmt.pix_mp.plane_fmt[0].bytesperline); + -+ if (V4L2_TYPE_IS_MULTIPLANAR(fmt->type)) { -+ if (fmt->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_YUV420 || -+ fmt->fmt.pix_mp.field != field) { -+ av_log(ctx->logctx, AV_LOG_DEBUG, "format not supported for type %d\n", fmt->type); ++ r_avfmt = fmt_v4l2_to_av(fmt_pixelformat(&fmt)); ++ if (r_avfmt != avfmt && avfmt != AV_PIX_FMT_NONE) { ++ av_log(ctx->logctx, AV_LOG_DEBUG, "Unable to set format %s on %s port\n", av_get_pix_fmt_name(avfmt), V4L2_TYPE_IS_CAPTURE(fmt.type) ? "dest" : "src"); ++ return AVERROR(EINVAL); ++ } ++ if (r_avfmt == AV_PIX_FMT_NONE) { ++ av_log(ctx->logctx, AV_LOG_DEBUG, "No supported format on %s port\n", V4L2_TYPE_IS_CAPTURE(fmt.type) ? "dest" : "src"); ++ return AVERROR(EINVAL); ++ } ++ ++ if (V4L2_TYPE_IS_MULTIPLANAR(fmt.type)) { ++ if (fmt.fmt.pix_mp.field != field) { ++ av_log(ctx->logctx, AV_LOG_DEBUG, "format not supported for type %d\n", fmt.type); + + return AVERROR(EINVAL); + } + } else { -+ if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_YUV420 || -+ fmt->fmt.pix.field != field) { -+ av_log(ctx->logctx, AV_LOG_DEBUG, "format not supported for type %d\n", fmt->type); ++ if (fmt.fmt.pix.field != field) { ++ av_log(ctx->logctx, AV_LOG_DEBUG, "format not supported for type %d\n", fmt.type); + + return AVERROR(EINVAL); + } @@ -60578,51 +62558,408 @@ index 0000000000..d1c714b805 + return 0; +} + -+static int deint_v4l2m2m_set_format(V4L2Queue *queue, uint32_t field, int width, int height, int pitch, int ysize) ++static int ++do_s_fmt(V4L2Queue * const q) +{ -+ struct v4l2_format *fmt = &queue->format; -+ DeintV4L2M2MContextShared *ctx = queue->ctx; ++ DeintV4L2M2MContextShared * const ctx = q->ctx; ++ const uint32_t pixelformat = fmt_pixelformat(&q->format); + int ret; + -+ struct v4l2_selection sel = { -+ .type = fmt->type, -+ .target = V4L2_TYPE_IS_OUTPUT(fmt->type) ? V4L2_SEL_TGT_CROP_BOUNDS : V4L2_SEL_TGT_COMPOSE_BOUNDS, -+ }; -+ -+ if (V4L2_TYPE_IS_MULTIPLANAR(fmt->type)) { -+ fmt->fmt.pix_mp.field = field; -+ fmt->fmt.pix_mp.width = width; -+ fmt->fmt.pix_mp.height = ysize / pitch; -+ fmt->fmt.pix_mp.plane_fmt[0].bytesperline = pitch; -+ fmt->fmt.pix_mp.plane_fmt[0].sizeimage = ysize + (ysize >> 1); -+ } else { -+ fmt->fmt.pix.field = field; -+ fmt->fmt.pix.width = width; -+ fmt->fmt.pix.height = height; -+ fmt->fmt.pix.sizeimage = 0; -+ fmt->fmt.pix.bytesperline = 0; ++ ret = ioctl(ctx->fd, VIDIOC_S_FMT, &q->format); ++ if (ret) { ++ ret = AVERROR(errno); ++ av_log(ctx->logctx, AV_LOG_ERROR, "VIDIOC_S_FMT failed: %s\n", av_err2str(ret)); ++ return ret; + } + -+ ret = ioctl(ctx->fd, VIDIOC_S_FMT, fmt); -+ if (ret) -+ av_log(ctx->logctx, AV_LOG_ERROR, "VIDIOC_S_FMT failed: %d\n", ret); ++ if (pixelformat != fmt_pixelformat(&q->format)) { ++ av_log(ctx->logctx, AV_LOG_ERROR, "Format not supported: %s; S_FMT returned %s\n", av_fourcc2str(pixelformat), av_fourcc2str(fmt_pixelformat(&q->format))); ++ return AVERROR(EINVAL); ++ } + -+ ret = ioctl(ctx->fd, VIDIOC_G_SELECTION, &sel); -+ if (ret) -+ av_log(ctx->logctx, AV_LOG_ERROR, "VIDIOC_G_SELECTION failed: %d\n", ret); ++ q->sel.target = V4L2_TYPE_IS_OUTPUT(q->sel.type) ? V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE, ++ q->sel.flags = V4L2_TYPE_IS_OUTPUT(q->sel.type) ? V4L2_SEL_FLAG_LE : V4L2_SEL_FLAG_GE; + -+ sel.r.width = width; -+ sel.r.height = height; -+ sel.r.left = 0; -+ sel.r.top = 0; -+ sel.target = V4L2_TYPE_IS_OUTPUT(fmt->type) ? V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE, -+ sel.flags = V4L2_SEL_FLAG_LE; ++ ret = ioctl(ctx->fd, VIDIOC_S_SELECTION, &q->sel); ++ if (ret) { ++ ret = AVERROR(errno); ++ av_log(ctx->logctx, AV_LOG_WARNING, "VIDIOC_S_SELECTION failed: %s\n", av_err2str(ret)); ++ } + -+ ret = ioctl(ctx->fd, VIDIOC_S_SELECTION, &sel); -+ if (ret) -+ av_log(ctx->logctx, AV_LOG_ERROR, "VIDIOC_S_SELECTION failed: %d\n", ret); ++ return 0; ++} + -+ return ret; ++static void ++set_fmt_color(struct v4l2_format *const fmt, ++ const enum AVColorPrimaries avcp, ++ const enum AVColorSpace avcs, ++ const enum AVColorTransferCharacteristic avxc) ++{ ++ enum v4l2_ycbcr_encoding ycbcr = V4L2_YCBCR_ENC_DEFAULT; ++ enum v4l2_colorspace cs = V4L2_COLORSPACE_DEFAULT; ++ enum v4l2_xfer_func xfer = V4L2_XFER_FUNC_DEFAULT; ++ ++ switch (avcp) { ++ case AVCOL_PRI_BT709: ++ cs = V4L2_COLORSPACE_REC709; ++ ycbcr = V4L2_YCBCR_ENC_709; ++ break; ++ case AVCOL_PRI_BT470M: ++ cs = V4L2_COLORSPACE_470_SYSTEM_M; ++ ycbcr = V4L2_YCBCR_ENC_601; ++ break; ++ case AVCOL_PRI_BT470BG: ++ cs = V4L2_COLORSPACE_470_SYSTEM_BG; ++ break; ++ case AVCOL_PRI_SMPTE170M: ++ cs = V4L2_COLORSPACE_SMPTE170M; ++ break; ++ case AVCOL_PRI_SMPTE240M: ++ cs = V4L2_COLORSPACE_SMPTE240M; ++ break; ++ case AVCOL_PRI_BT2020: ++ cs = V4L2_COLORSPACE_BT2020; ++ break; ++ case AVCOL_PRI_SMPTE428: ++ case AVCOL_PRI_SMPTE431: ++ case AVCOL_PRI_SMPTE432: ++ case AVCOL_PRI_EBU3213: ++ case AVCOL_PRI_RESERVED: ++ case AVCOL_PRI_FILM: ++ case AVCOL_PRI_UNSPECIFIED: ++ default: ++ break; ++ } ++ ++ switch (avcs) { ++ case AVCOL_SPC_RGB: ++ cs = V4L2_COLORSPACE_SRGB; ++ break; ++ case AVCOL_SPC_BT709: ++ cs = V4L2_COLORSPACE_REC709; ++ break; ++ case AVCOL_SPC_FCC: ++ cs = V4L2_COLORSPACE_470_SYSTEM_M; ++ break; ++ case AVCOL_SPC_BT470BG: ++ cs = V4L2_COLORSPACE_470_SYSTEM_BG; ++ break; ++ case AVCOL_SPC_SMPTE170M: ++ cs = V4L2_COLORSPACE_SMPTE170M; ++ break; ++ case AVCOL_SPC_SMPTE240M: ++ cs = V4L2_COLORSPACE_SMPTE240M; ++ break; ++ case AVCOL_SPC_BT2020_CL: ++ cs = V4L2_COLORSPACE_BT2020; ++ ycbcr = V4L2_YCBCR_ENC_BT2020_CONST_LUM; ++ break; ++ case AVCOL_SPC_BT2020_NCL: ++ cs = V4L2_COLORSPACE_BT2020; ++ break; ++ default: ++ break; ++ } ++ ++ switch (xfer) { ++ case AVCOL_TRC_BT709: ++ xfer = V4L2_XFER_FUNC_709; ++ break; ++ case AVCOL_TRC_IEC61966_2_1: ++ xfer = V4L2_XFER_FUNC_SRGB; ++ break; ++ case AVCOL_TRC_SMPTE240M: ++ xfer = V4L2_XFER_FUNC_SMPTE240M; ++ break; ++ case AVCOL_TRC_SMPTE2084: ++ xfer = V4L2_XFER_FUNC_SMPTE2084; ++ break; ++ default: ++ break; ++ } ++ ++ if (V4L2_TYPE_IS_MULTIPLANAR(fmt->type)) { ++ fmt->fmt.pix_mp.colorspace = cs; ++ fmt->fmt.pix_mp.ycbcr_enc = ycbcr; ++ fmt->fmt.pix_mp.xfer_func = xfer; ++ } else { ++ fmt->fmt.pix.colorspace = cs; ++ fmt->fmt.pix.ycbcr_enc = ycbcr; ++ fmt->fmt.pix.xfer_func = xfer; ++ } ++} ++ ++static void ++set_fmt_color_range(struct v4l2_format *const fmt, const enum AVColorRange avcr) ++{ ++ const enum v4l2_quantization q = ++ avcr == AVCOL_RANGE_MPEG ? V4L2_QUANTIZATION_LIM_RANGE : ++ avcr == AVCOL_RANGE_JPEG ? V4L2_QUANTIZATION_FULL_RANGE : ++ V4L2_QUANTIZATION_DEFAULT; ++ ++ if (V4L2_TYPE_IS_MULTIPLANAR(fmt->type)) { ++ fmt->fmt.pix_mp.quantization = q; ++ } else { ++ fmt->fmt.pix.quantization = q; ++ } ++} ++ ++static enum AVColorPrimaries get_color_primaries(const struct v4l2_format *const fmt) ++{ ++ enum v4l2_ycbcr_encoding ycbcr; ++ enum v4l2_colorspace cs; ++ ++ cs = V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? ++ fmt->fmt.pix_mp.colorspace : ++ fmt->fmt.pix.colorspace; ++ ++ ycbcr = V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? ++ fmt->fmt.pix_mp.ycbcr_enc: ++ fmt->fmt.pix.ycbcr_enc; ++ ++ switch(ycbcr) { ++ case V4L2_YCBCR_ENC_XV709: ++ case V4L2_YCBCR_ENC_709: return AVCOL_PRI_BT709; ++ case V4L2_YCBCR_ENC_XV601: ++ case V4L2_YCBCR_ENC_601:return AVCOL_PRI_BT470M; ++ default: ++ break; ++ } ++ ++ switch(cs) { ++ case V4L2_COLORSPACE_470_SYSTEM_BG: return AVCOL_PRI_BT470BG; ++ case V4L2_COLORSPACE_SMPTE170M: return AVCOL_PRI_SMPTE170M; ++ case V4L2_COLORSPACE_SMPTE240M: return AVCOL_PRI_SMPTE240M; ++ case V4L2_COLORSPACE_BT2020: return AVCOL_PRI_BT2020; ++ default: ++ break; ++ } ++ ++ return AVCOL_PRI_UNSPECIFIED; ++} ++ ++static enum AVColorSpace get_color_space(const struct v4l2_format *const fmt) ++{ ++ enum v4l2_ycbcr_encoding ycbcr; ++ enum v4l2_colorspace cs; ++ ++ cs = V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? ++ fmt->fmt.pix_mp.colorspace : ++ fmt->fmt.pix.colorspace; ++ ++ ycbcr = V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? ++ fmt->fmt.pix_mp.ycbcr_enc: ++ fmt->fmt.pix.ycbcr_enc; ++ ++ switch(cs) { ++ case V4L2_COLORSPACE_SRGB: return AVCOL_SPC_RGB; ++ case V4L2_COLORSPACE_REC709: return AVCOL_SPC_BT709; ++ case V4L2_COLORSPACE_470_SYSTEM_M: return AVCOL_SPC_FCC; ++ case V4L2_COLORSPACE_470_SYSTEM_BG: return AVCOL_SPC_BT470BG; ++ case V4L2_COLORSPACE_SMPTE170M: return AVCOL_SPC_SMPTE170M; ++ case V4L2_COLORSPACE_SMPTE240M: return AVCOL_SPC_SMPTE240M; ++ case V4L2_COLORSPACE_BT2020: ++ if (ycbcr == V4L2_YCBCR_ENC_BT2020_CONST_LUM) ++ return AVCOL_SPC_BT2020_CL; ++ else ++ return AVCOL_SPC_BT2020_NCL; ++ default: ++ break; ++ } ++ ++ return AVCOL_SPC_UNSPECIFIED; ++} ++ ++static enum AVColorTransferCharacteristic get_color_trc(const struct v4l2_format *const fmt) ++{ ++ enum v4l2_ycbcr_encoding ycbcr; ++ enum v4l2_xfer_func xfer; ++ enum v4l2_colorspace cs; ++ ++ cs = V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? ++ fmt->fmt.pix_mp.colorspace : ++ fmt->fmt.pix.colorspace; ++ ++ ycbcr = V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? ++ fmt->fmt.pix_mp.ycbcr_enc: ++ fmt->fmt.pix.ycbcr_enc; ++ ++ xfer = V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? ++ fmt->fmt.pix_mp.xfer_func: ++ fmt->fmt.pix.xfer_func; ++ ++ switch (xfer) { ++ case V4L2_XFER_FUNC_709: return AVCOL_TRC_BT709; ++ case V4L2_XFER_FUNC_SRGB: return AVCOL_TRC_IEC61966_2_1; ++ default: ++ break; ++ } ++ ++ switch (cs) { ++ case V4L2_COLORSPACE_470_SYSTEM_M: return AVCOL_TRC_GAMMA22; ++ case V4L2_COLORSPACE_470_SYSTEM_BG: return AVCOL_TRC_GAMMA28; ++ case V4L2_COLORSPACE_SMPTE170M: return AVCOL_TRC_SMPTE170M; ++ case V4L2_COLORSPACE_SMPTE240M: return AVCOL_TRC_SMPTE240M; ++ default: ++ break; ++ } ++ ++ switch (ycbcr) { ++ case V4L2_YCBCR_ENC_XV709: ++ case V4L2_YCBCR_ENC_XV601: return AVCOL_TRC_BT1361_ECG; ++ default: ++ break; ++ } ++ ++ return AVCOL_TRC_UNSPECIFIED; ++} ++ ++static enum AVColorRange get_color_range(const struct v4l2_format *const fmt) ++{ ++ enum v4l2_quantization qt; ++ ++ qt = V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? ++ fmt->fmt.pix_mp.quantization : ++ fmt->fmt.pix.quantization; ++ ++ switch (qt) { ++ case V4L2_QUANTIZATION_LIM_RANGE: return AVCOL_RANGE_MPEG; ++ case V4L2_QUANTIZATION_FULL_RANGE: return AVCOL_RANGE_JPEG; ++ default: ++ break; ++ } ++ ++ return AVCOL_RANGE_UNSPECIFIED; ++} ++ ++static int set_src_fmt(V4L2Queue * const q, const AVFrame * const frame) ++{ ++ struct v4l2_format *const format = &q->format; ++ const AVDRMFrameDescriptor *const src = (const AVDRMFrameDescriptor *)frame->data[0]; ++ ++ const uint32_t drm_fmt = src->layers[0].format; ++ // Treat INVALID as LINEAR ++ const uint64_t mod = src->objects[0].format_modifier == DRM_FORMAT_MOD_INVALID ? ++ DRM_FORMAT_MOD_LINEAR : src->objects[0].format_modifier; ++ uint32_t pix_fmt = 0; ++ uint32_t w = 0; ++ uint32_t h = 0; ++ uint32_t bpl = src->layers[0].planes[0].pitch; ++ ++ // We really don't expect multiple layers ++ // All formats that we currently cope with are single object ++ ++ if (src->nb_layers != 1 || src->nb_objects != 1) ++ return AVERROR(EINVAL); ++ ++ switch (drm_fmt) { ++ case DRM_FORMAT_YUV420: ++ if (mod == DRM_FORMAT_MOD_LINEAR) { ++ if (src->layers[0].nb_planes != 3) ++ break; ++ pix_fmt = V4L2_PIX_FMT_YUV420; ++ h = src->layers[0].planes[1].offset / bpl; ++ w = bpl; ++ } ++ break; ++ ++ case DRM_FORMAT_NV12: ++ if (mod == DRM_FORMAT_MOD_LINEAR) { ++ if (src->layers[0].nb_planes != 2) ++ break; ++ pix_fmt = V4L2_PIX_FMT_NV12; ++ h = src->layers[0].planes[1].offset / bpl; ++ w = bpl; ++ } ++ else if (fourcc_mod_broadcom_mod(mod) == DRM_FORMAT_MOD_BROADCOM_SAND128) { ++ if (src->layers[0].nb_planes != 2) ++ break; ++ pix_fmt = V4L2_PIX_FMT_NV12_COL128; ++ w = bpl; ++ h = src->layers[0].planes[1].offset / 128; ++ bpl = fourcc_mod_broadcom_param(mod); ++ } ++ break; ++ ++ case DRM_FORMAT_P030: ++ if (fourcc_mod_broadcom_mod(mod) == DRM_FORMAT_MOD_BROADCOM_SAND128) { ++ if (src->layers[0].nb_planes != 2) ++ break; ++ pix_fmt = V4L2_PIX_FMT_NV12_10_COL128; ++ w = bpl / 2; // Matching lie to how we construct this ++ h = src->layers[0].planes[1].offset / 128; ++ bpl = fourcc_mod_broadcom_param(mod); ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ if (!pix_fmt) ++ return AVERROR(EINVAL); ++ ++ if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) { ++ struct v4l2_pix_format_mplane *const pix = &format->fmt.pix_mp; ++ ++ pix->width = w; ++ pix->height = h; ++ pix->pixelformat = pix_fmt; ++ pix->plane_fmt[0].bytesperline = bpl; ++ pix->num_planes = 1; ++ } ++ else { ++ struct v4l2_pix_format *const pix = &format->fmt.pix; ++ ++ pix->width = w; ++ pix->height = h; ++ pix->pixelformat = pix_fmt; ++ pix->bytesperline = bpl; ++ } ++ ++ set_fmt_color(format, frame->color_primaries, frame->colorspace, frame->color_trc); ++ set_fmt_color_range(format, frame->color_range); ++ ++ q->sel.r.width = frame->width - (frame->crop_left + frame->crop_right); ++ q->sel.r.height = frame->height - (frame->crop_top + frame->crop_bottom); ++ q->sel.r.left = frame->crop_left; ++ q->sel.r.top = frame->crop_top; ++ ++ return 0; ++} ++ ++ ++static int set_dst_format(DeintV4L2M2MContext * const priv, V4L2Queue *queue, uint32_t pixelformat, uint32_t field, int width, int height) ++{ ++ struct v4l2_format * const fmt = &queue->format; ++ struct v4l2_selection *const sel = &queue->sel; ++ ++ memset(&fmt->fmt, 0, sizeof(fmt->fmt)); ++ ++ // Align w/h to 16 here in case there are alignment requirements at the next ++ // stage of the filter chain (also RPi deinterlace setup is bust and this ++ // fixes it) ++ if (V4L2_TYPE_IS_MULTIPLANAR(fmt->type)) { ++ fmt->fmt.pix_mp.pixelformat = pixelformat; ++ fmt->fmt.pix_mp.field = field; ++ fmt->fmt.pix_mp.width = FFALIGN(width, 16); ++ fmt->fmt.pix_mp.height = FFALIGN(height, 16); ++ } else { ++ fmt->fmt.pix.pixelformat = pixelformat; ++ fmt->fmt.pix.field = field; ++ fmt->fmt.pix.width = FFALIGN(width, 16); ++ fmt->fmt.pix.height = FFALIGN(height, 16); ++ } ++ ++ set_fmt_color(fmt, priv->colour_primaries, priv->colour_matrix, priv->colour_transfer); ++ set_fmt_color_range(fmt, priv->colour_range); ++ ++ sel->r.width = width; ++ sel->r.height = height; ++ sel->r.left = 0; ++ sel->r.top = 0; ++ ++ return do_s_fmt(queue); +} + +static int deint_v4l2m2m_probe_device(DeintV4L2M2MContextShared *ctx, char *node) @@ -60634,16 +62971,22 @@ index 0000000000..d1c714b805 + return AVERROR(errno); + + ret = deint_v4l2m2m_prepare_context(ctx); -+ if (ret) ++ if (ret) { ++ av_log(ctx->logctx, AV_LOG_DEBUG, "Failed to prepare context\n"); + goto fail; ++ } + -+ ret = deint_v4l2m2m_try_format(&ctx->capture); -+ if (ret) ++ ret = deint_v4l2m2m_try_format(&ctx->capture, ctx->output_width, ctx->output_height, ctx->output_format); ++ if (ret) { ++ av_log(ctx->logctx, AV_LOG_DEBUG, "Failed to try dst format\n"); + goto fail; ++ } + -+ ret = deint_v4l2m2m_try_format(&ctx->output); -+ if (ret) ++ ret = deint_v4l2m2m_try_format(&ctx->output, ctx->width, ctx->height, AV_PIX_FMT_NONE); ++ if (ret) { ++ av_log(ctx->logctx, AV_LOG_DEBUG, "Failed to try src format\n"); + goto fail; ++ } + + return 0; + @@ -60704,11 +63047,118 @@ index 0000000000..d1c714b805 + return 0; +} + -+static int v4l2_buffer_export_drm(V4L2Buffer* avbuf) ++static void ++drm_frame_init(AVDRMFrameDescriptor * const d) ++{ ++ unsigned int i; ++ for (i = 0; i != AV_DRM_MAX_PLANES; ++i) { ++ d->objects[i].fd = -1; ++ } ++} ++ ++static void ++drm_frame_uninit(AVDRMFrameDescriptor * const d) ++{ ++ unsigned int i; ++ for (i = 0; i != d->nb_objects; ++i) { ++ if (d->objects[i].fd != -1) { ++ close(d->objects[i].fd); ++ d->objects[i].fd = -1; ++ } ++ } ++} ++ ++static void ++avbufs_delete(V4L2Buffer** ppavbufs, const unsigned int n) ++{ ++ unsigned int i; ++ V4L2Buffer* const avbufs = *ppavbufs; ++ ++ if (avbufs == NULL) ++ return; ++ *ppavbufs = NULL; ++ ++ for (i = 0; i != n; ++i) { ++ V4L2Buffer* const avbuf = avbufs + i; ++ drm_frame_uninit(&avbuf->drm_frame); ++ } ++ ++ av_free(avbufs); ++} ++ ++static int v4l2_buffer_export_drm(V4L2Queue * const q, V4L2Buffer * const avbuf) +{ + struct v4l2_exportbuffer expbuf; + int i, ret; ++ uint64_t mod = DRM_FORMAT_MOD_LINEAR; + ++ AVDRMFrameDescriptor * const drm_desc = &avbuf->drm_frame; ++ AVDRMLayerDescriptor * const layer = &drm_desc->layers[0]; ++ const struct v4l2_format *const fmt = &q->format; ++ const uint32_t height = fmt_height(fmt); ++ const uint32_t width = fmt_width(fmt); ++ ptrdiff_t bpl0; ++ ++ /* fill the DRM frame descriptor */ ++ drm_desc->nb_layers = 1; ++ layer->nb_planes = avbuf->num_planes; ++ ++ for (int i = 0; i < avbuf->num_planes; i++) { ++ layer->planes[i].object_index = i; ++ layer->planes[i].offset = 0; ++ layer->planes[i].pitch = fmt_bpl(fmt, i); ++ } ++ bpl0 = layer->planes[0].pitch; ++ ++ switch (fmt_pixelformat(fmt)) { ++ ++ case V4L2_PIX_FMT_NV12_COL128: ++ mod = DRM_FORMAT_MOD_BROADCOM_SAND128_COL_HEIGHT(bpl0); ++ layer->format = V4L2_PIX_FMT_NV12; ++ ++ if (avbuf->num_planes > 1) ++ break; ++ ++ layer->nb_planes = 2; ++ layer->planes[1].object_index = 0; ++ layer->planes[1].offset = height * 128; ++ layer->planes[0].pitch = width; ++ layer->planes[1].pitch = width; ++ break; ++ ++ case DRM_FORMAT_NV12: ++ layer->format = V4L2_PIX_FMT_NV12; ++ ++ if (avbuf->num_planes > 1) ++ break; ++ ++ layer->nb_planes = 2; ++ layer->planes[1].object_index = 0; ++ layer->planes[1].offset = bpl0 * height; ++ layer->planes[1].pitch = bpl0; ++ break; ++ ++ case V4L2_PIX_FMT_YUV420: ++ layer->format = DRM_FORMAT_YUV420; ++ ++ if (avbuf->num_planes > 1) ++ break; ++ ++ layer->nb_planes = 3; ++ layer->planes[1].object_index = 0; ++ layer->planes[1].offset = bpl0 * height; ++ layer->planes[1].pitch = bpl0 / 2; ++ layer->planes[2].object_index = 0; ++ layer->planes[2].offset = layer->planes[1].offset + ((bpl0 * height) / 4); ++ layer->planes[2].pitch = bpl0 / 2; ++ break; ++ ++ default: ++ drm_desc->nb_layers = 0; ++ return AVERROR(EINVAL); ++ } ++ ++ drm_desc->nb_objects = 0; + for (i = 0; i < avbuf->num_planes; i++) { + memset(&expbuf, 0, sizeof(expbuf)); + @@ -60720,19 +63170,11 @@ index 0000000000..d1c714b805 + if (ret < 0) + return AVERROR(errno); + -+ avbuf->fd = expbuf.fd; -+ -+ if (V4L2_TYPE_IS_MULTIPLANAR(avbuf->buffer.type)) { -+ /* drm frame */ -+ avbuf->drm_frame.objects[i].size = avbuf->buffer.m.planes[i].length; -+ avbuf->drm_frame.objects[i].fd = expbuf.fd; -+ avbuf->drm_frame.objects[i].format_modifier = DRM_FORMAT_MOD_LINEAR; -+ } else { -+ /* drm frame */ -+ avbuf->drm_frame.objects[0].size = avbuf->buffer.length; -+ avbuf->drm_frame.objects[0].fd = expbuf.fd; -+ avbuf->drm_frame.objects[0].format_modifier = DRM_FORMAT_MOD_LINEAR; -+ } ++ drm_desc->objects[i].size = V4L2_TYPE_IS_MULTIPLANAR(avbuf->buffer.type) ? ++ avbuf->buffer.m.planes[i].length : avbuf->buffer.length; ++ drm_desc->objects[i].fd = expbuf.fd; ++ drm_desc->objects[i].format_modifier = mod; ++ drm_desc->nb_objects = i + 1; + } + + return 0; @@ -60743,7 +63185,7 @@ index 0000000000..d1c714b805 + struct v4l2_format *fmt = &queue->format; + DeintV4L2M2MContextShared *ctx = queue->ctx; + struct v4l2_requestbuffers req; -+ int ret, i, j, multiplanar; ++ int ret, i, multiplanar; + uint32_t memory; + + memory = V4L2_TYPE_IS_OUTPUT(fmt->type) ? @@ -60772,10 +63214,9 @@ index 0000000000..d1c714b805 + } + + for (i = 0; i < queue->num_buffers; i++) { -+ V4L2Buffer *buf = &queue->buffers[i]; ++ V4L2Buffer * const buf = &queue->buffers[i]; + + buf->enqueued = 0; -+ buf->fd = -1; + buf->q = queue; + + buf->buffer.type = fmt->type; @@ -60787,6 +63228,12 @@ index 0000000000..d1c714b805 + buf->buffer.m.planes = buf->planes; + } + ++ drm_frame_init(&buf->drm_frame); ++ } ++ ++ for (i = 0; i < queue->num_buffers; i++) { ++ V4L2Buffer * const buf = &queue->buffers[i]; ++ + ret = ioctl(ctx->fd, VIDIOC_QUERYBUF, &buf->buffer); + if (ret < 0) { + ret = AVERROR(errno); @@ -60794,29 +63241,14 @@ index 0000000000..d1c714b805 + goto fail; + } + -+ if (multiplanar) -+ buf->num_planes = buf->buffer.length; -+ else -+ buf->num_planes = 1; -+ -+ for (j = 0; j < buf->num_planes; j++) { -+ V4L2PlaneInfo *info = &buf->plane_info[j]; -+ -+ if (multiplanar) { -+ info->bytesperline = fmt->fmt.pix_mp.plane_fmt[j].bytesperline; -+ info->length = buf->buffer.m.planes[j].length; -+ } else { -+ info->bytesperline = fmt->fmt.pix.bytesperline; -+ info->length = buf->buffer.length; -+ } -+ } ++ buf->num_planes = multiplanar ? buf->buffer.length : 1; + + if (!V4L2_TYPE_IS_OUTPUT(fmt->type)) { + ret = deint_v4l2m2m_enqueue_buffer(buf); + if (ret) + goto fail; + -+ ret = v4l2_buffer_export_drm(buf); ++ ret = v4l2_buffer_export_drm(queue, buf); + if (ret) + goto fail; + } @@ -60825,12 +63257,8 @@ index 0000000000..d1c714b805 + return 0; + +fail: -+ for (i = 0; i < queue->num_buffers; i++) -+ if (queue->buffers[i].fd >= 0) -+ close(queue->buffers[i].fd); -+ av_free(queue->buffers); -+ queue->buffers = NULL; -+ ++ avbufs_delete(&queue->buffers, queue->num_buffers); ++ queue->num_buffers = 0; + return ret; +} + @@ -61017,7 +63445,6 @@ index 0000000000..d1c714b805 + if (atomic_fetch_sub(&ctx->refcount, 1) == 1) { + V4L2Queue *capture = &ctx->capture; + V4L2Queue *output = &ctx->output; -+ int i; + + av_log(NULL, AV_LOG_DEBUG, "%s - destroying context\n", __func__); + @@ -61026,12 +63453,7 @@ index 0000000000..d1c714b805 + deint_v4l2m2m_streamoff(output); + } + -+ if (capture->buffers) -+ for (i = 0; i < capture->num_buffers; i++) { -+ capture->buffers[i].q = NULL; -+ if (capture->buffers[i].fd >= 0) -+ close(capture->buffers[i].fd); -+ } ++ avbufs_delete(&capture->buffers, capture->num_buffers); + + deint_v4l2m2m_unref_queued(output); + @@ -61063,84 +63485,15 @@ index 0000000000..d1c714b805 + deint_v4l2m2m_destroy_context(ctx); +} + -+static uint8_t * v4l2_get_drm_frame(V4L2Buffer *avbuf, int height) -+{ -+ int av_pix_fmt = AV_PIX_FMT_YUV420P; -+ AVDRMFrameDescriptor *drm_desc = &avbuf->drm_frame; -+ AVDRMLayerDescriptor *layer; -+ -+ /* fill the DRM frame descriptor */ -+ drm_desc->nb_objects = avbuf->num_planes; -+ drm_desc->nb_layers = 1; -+ -+ layer = &drm_desc->layers[0]; -+ layer->nb_planes = avbuf->num_planes; -+ -+ for (int i = 0; i < avbuf->num_planes; i++) { -+ layer->planes[i].object_index = i; -+ layer->planes[i].offset = 0; -+ layer->planes[i].pitch = avbuf->plane_info[i].bytesperline; -+ } -+ -+ switch (av_pix_fmt) { -+ case AV_PIX_FMT_YUYV422: -+ -+ layer->format = DRM_FORMAT_YUYV; -+ layer->nb_planes = 1; -+ -+ break; -+ -+ case AV_PIX_FMT_NV12: -+ case AV_PIX_FMT_NV21: -+ -+ layer->format = av_pix_fmt == AV_PIX_FMT_NV12 ? -+ DRM_FORMAT_NV12 : DRM_FORMAT_NV21; -+ -+ if (avbuf->num_planes > 1) -+ break; -+ -+ layer->nb_planes = 2; -+ -+ layer->planes[1].object_index = 0; -+ layer->planes[1].offset = avbuf->plane_info[0].bytesperline * -+ height; -+ layer->planes[1].pitch = avbuf->plane_info[0].bytesperline; -+ break; -+ -+ case AV_PIX_FMT_YUV420P: -+ -+ layer->format = DRM_FORMAT_YUV420; -+ -+ if (avbuf->num_planes > 1) -+ break; -+ -+ layer->nb_planes = 3; -+ -+ layer->planes[1].object_index = 0; -+ layer->planes[1].offset = avbuf->plane_info[0].bytesperline * -+ height; -+ layer->planes[1].pitch = avbuf->plane_info[0].bytesperline >> 1; -+ -+ layer->planes[2].object_index = 0; -+ layer->planes[2].offset = layer->planes[1].offset + -+ ((avbuf->plane_info[0].bytesperline * -+ height) >> 2); -+ layer->planes[2].pitch = avbuf->plane_info[0].bytesperline >> 1; -+ break; -+ -+ default: -+ drm_desc->nb_layers = 0; -+ break; -+ } -+ -+ return (uint8_t *) drm_desc; -+} -+ +// timeout in ms +static int deint_v4l2m2m_dequeue_frame(V4L2Queue *queue, AVFrame* frame, int timeout) +{ + DeintV4L2M2MContextShared *ctx = queue->ctx; + V4L2Buffer* avbuf; ++ enum AVColorPrimaries color_primaries; ++ enum AVColorSpace colorspace; ++ enum AVColorTransferCharacteristic color_trc; ++ enum AVColorRange color_range; + + av_log(ctx->logctx, AV_LOG_TRACE, "<<< %s\n", __func__); + @@ -61151,8 +63504,6 @@ index 0000000000..d1c714b805 + } + + // Fill in PTS and anciliary info from src frame -+ // we will want to overwrite some fields as only the pts/dts -+ // fields are updated with new timing in this fn + pts_track_get_frame(&ctx->track, avbuf->buffer.timestamp, frame); + + frame->buf[0] = av_buffer_create((uint8_t *) &avbuf->drm_frame, @@ -61165,18 +63516,36 @@ index 0000000000..d1c714b805 + + atomic_fetch_add(&ctx->refcount, 1); + -+ frame->data[0] = (uint8_t *)v4l2_get_drm_frame(avbuf, ctx->orig_height); ++ frame->data[0] = (uint8_t *)&avbuf->drm_frame; + frame->format = AV_PIX_FMT_DRM_PRIME; + if (ctx->hw_frames_ctx) + frame->hw_frames_ctx = av_buffer_ref(ctx->hw_frames_ctx); -+ frame->height = ctx->height; -+ frame->width = ctx->width; ++ frame->height = ctx->output_height; ++ frame->width = ctx->output_width; + -+ // Not interlaced now -+ frame->interlaced_frame = 0; -+ frame->top_field_first = 0; -+ // Pkt duration halved -+ frame->pkt_duration /= 2; ++ color_primaries = get_color_primaries(&ctx->capture.format); ++ colorspace = get_color_space(&ctx->capture.format); ++ color_trc = get_color_trc(&ctx->capture.format); ++ color_range = get_color_range(&ctx->capture.format); ++ ++ // If the color parameters are unspecified by V4L2 then leave alone as they ++ // will have been copied from src ++ if (color_primaries != AVCOL_PRI_UNSPECIFIED) ++ frame->color_primaries = color_primaries; ++ if (colorspace != AVCOL_SPC_UNSPECIFIED) ++ frame->colorspace = colorspace; ++ if (color_trc != AVCOL_TRC_UNSPECIFIED) ++ frame->color_trc = color_trc; ++ if (color_range != AVCOL_RANGE_UNSPECIFIED) ++ frame->color_range = color_range; ++ ++ if (ctx->filter_type == FILTER_V4L2_DEINTERLACE) { ++ // Not interlaced now ++ frame->interlaced_frame = 0; // *** Fill in from dst buffer? ++ frame->top_field_first = 0; ++ // Pkt duration halved ++ frame->pkt_duration /= 2; ++ } + + if (avbuf->buffer.flags & V4L2_BUF_FLAG_ERROR) { + av_log(ctx->logctx, AV_LOG_ERROR, "driver decode error\n"); @@ -61198,14 +63567,36 @@ index 0000000000..d1c714b805 + ctx->height = avctx->inputs[0]->h; + ctx->width = avctx->inputs[0]->w; + -+ av_log(priv, AV_LOG_DEBUG, "%s: %dx%d\n", __func__, ctx->width, ctx->height); ++ if (ctx->filter_type == FILTER_V4L2_SCALE) { ++ if ((ret = ff_scale_eval_dimensions(priv, ++ priv->w_expr, priv->h_expr, ++ inlink, outlink, ++ &ctx->output_width, &ctx->output_height)) < 0) ++ return ret; ++ ++ ff_scale_adjust_dimensions(inlink, &ctx->output_width, &ctx->output_height, ++ priv->force_original_aspect_ratio, priv->force_divisible_by); ++ } ++ else { ++ ctx->output_width = ctx->width; ++ ctx->output_height = ctx->height; ++ } ++ ++ av_log(priv, AV_LOG_DEBUG, "%s: %dx%d->%dx%d FR: %d/%d->%d/%d\n", __func__, ++ ctx->width, ctx->height, ctx->output_width, ctx->output_height, ++ inlink->frame_rate.num, inlink->frame_rate.den, outlink->frame_rate.num, outlink->frame_rate.den); + + outlink->time_base = inlink->time_base; -+ outlink->w = inlink->w; -+ outlink->h = inlink->h; -+ outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; ++ outlink->w = ctx->output_width; ++ outlink->h = ctx->output_height; + outlink->format = inlink->format; -+ outlink->frame_rate = (AVRational) {1, 0}; // Deny knowledge of frame rate ++ if (ctx->filter_type == FILTER_V4L2_DEINTERLACE && inlink->frame_rate.den != 0) ++ outlink->frame_rate = (AVRational){inlink->frame_rate.num * 2, inlink->frame_rate.den}; ++ ++ if (inlink->sample_aspect_ratio.num) ++ outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h * inlink->w, outlink->w * inlink->h}, inlink->sample_aspect_ratio); ++ else ++ outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; + + ret = deint_v4l2m2m_find_device(ctx); + if (ret) @@ -61223,13 +63614,34 @@ index 0000000000..d1c714b805 +{ + static const enum AVPixelFormat pixel_formats[] = { + AV_PIX_FMT_DRM_PRIME, -+ AV_PIX_FMT_YUV420P, ++// AV_PIX_FMT_YUV420P, + AV_PIX_FMT_NONE, + }; + + return ff_set_common_formats(avctx, ff_make_format_list(pixel_formats)); +} + ++static uint32_t desc_pixelformat(const AVDRMFrameDescriptor * const drm_desc) ++{ ++ const uint64_t mod = drm_desc->objects[0].format_modifier; ++ const int is_linear = (mod == DRM_FORMAT_MOD_LINEAR || mod == DRM_FORMAT_MOD_INVALID); ++ ++ // Only currently support single object things ++ if (drm_desc->nb_objects != 1) ++ return 0; ++ ++ switch (drm_desc->layers[0].format) { ++ case DRM_FORMAT_YUV420: ++ return is_linear ? V4L2_PIX_FMT_YUV420 : 0; ++ case DRM_FORMAT_NV12: ++ return is_linear ? V4L2_PIX_FMT_NV12 : ++ fourcc_mod_broadcom_mod(mod) == DRM_FORMAT_MOD_BROADCOM_SAND128 ? V4L2_PIX_FMT_NV12_COL128 : 0; ++ default: ++ break; ++ } ++ return 0; ++} ++ +static int deint_v4l2m2m_filter_frame(AVFilterLink *link, AVFrame *in) +{ + AVFilterContext *avctx = link->dst; @@ -61245,41 +63657,71 @@ index 0000000000..d1c714b805 + avctx->inputs[0]->status_in, avctx->inputs[0]->status_out, avctx->outputs[0]->status_in, avctx->outputs[0]->status_out); + + if (ctx->field_order == V4L2_FIELD_ANY) { -+ AVDRMFrameDescriptor *drm_desc = (AVDRMFrameDescriptor *)in->data[0]; ++ const AVDRMFrameDescriptor * const drm_desc = (AVDRMFrameDescriptor *)in->data[0]; ++ uint32_t pixelformat = desc_pixelformat(drm_desc); ++ ++ if (pixelformat == 0) { ++ av_log(avctx, AV_LOG_ERROR, "Unsupported DRM format %s in %d objects, modifier %#" PRIx64 "\n", ++ av_fourcc2str(drm_desc->layers[0].format), ++ drm_desc->nb_objects, drm_desc->objects[0].format_modifier); ++ return AVERROR(EINVAL); ++ } ++ + ctx->orig_width = drm_desc->layers[0].planes[0].pitch; + ctx->orig_height = drm_desc->layers[0].planes[1].offset / ctx->orig_width; + -+ av_log(priv, AV_LOG_DEBUG, "%s: %dx%d (%d,%d)\n", __func__, ctx->width, ctx->height, ++ av_log(priv, AV_LOG_DEBUG, "%s: %dx%d (%td,%td)\n", __func__, ctx->width, ctx->height, + drm_desc->layers[0].planes[0].pitch, drm_desc->layers[0].planes[1].offset); + ++ if ((ret = set_src_fmt(output, in)) != 0) { ++ av_log(avctx, AV_LOG_WARNING, "Unknown input DRM format: %s mod: %#" PRIx64 "\n", ++ av_fourcc2str(drm_desc->layers[0].format), drm_desc->objects[0].format_modifier); ++ return ret; ++ } ++ ++ ret = do_s_fmt(output); ++ if (ret) { ++ av_log(avctx, AV_LOG_WARNING, "Failed to set source format\n"); ++ return ret; ++ } ++ ++ if (ctx->output_format != AV_PIX_FMT_NONE) ++ pixelformat = fmt_av_to_v4l2(ctx->output_format); ++ ret = set_dst_format(priv, capture, pixelformat, V4L2_FIELD_NONE, ctx->output_width, ctx->output_height); ++ if (ret) { ++ av_log(avctx, AV_LOG_WARNING, "Failed to set destination format\n"); ++ return ret; ++ } ++ ++ ret = deint_v4l2m2m_allocate_buffers(capture); ++ if (ret) { ++ av_log(avctx, AV_LOG_WARNING, "Failed to allocate destination buffers\n"); ++ return ret; ++ } ++ ++ ret = deint_v4l2m2m_streamon(capture); ++ if (ret) { ++ av_log(avctx, AV_LOG_WARNING, "Failed set destination streamon: %s\n", av_err2str(ret)); ++ return ret; ++ } ++ ++ ret = deint_v4l2m2m_allocate_buffers(output); ++ if (ret) { ++ av_log(avctx, AV_LOG_WARNING, "Failed to allocate src buffers\n"); ++ return ret; ++ } ++ ++ ret = deint_v4l2m2m_streamon(output); ++ if (ret) { ++ av_log(avctx, AV_LOG_WARNING, "Failed set src streamon: %s\n", av_err2str(ret)); ++ return ret; ++ } ++ + if (in->top_field_first) + ctx->field_order = V4L2_FIELD_INTERLACED_TB; + else + ctx->field_order = V4L2_FIELD_INTERLACED_BT; + -+ ret = deint_v4l2m2m_set_format(output, ctx->field_order, ctx->width, ctx->height, ctx->orig_width, drm_desc->layers[0].planes[1].offset); -+ if (ret) -+ return ret; -+ -+ ret = deint_v4l2m2m_set_format(capture, V4L2_FIELD_NONE, ctx->width, ctx->height, ctx->orig_width, drm_desc->layers[0].planes[1].offset); -+ if (ret) -+ return ret; -+ -+ ret = deint_v4l2m2m_allocate_buffers(capture); -+ if (ret) -+ return ret; -+ -+ ret = deint_v4l2m2m_streamon(capture); -+ if (ret) -+ return ret; -+ -+ ret = deint_v4l2m2m_allocate_buffers(output); -+ if (ret) -+ return ret; -+ -+ ret = deint_v4l2m2m_streamon(output); -+ if (ret) -+ return ret; + } + + ret = deint_v4l2m2m_enqueue_frame(output, in); @@ -61355,28 +63797,31 @@ index 0000000000..d1c714b805 + return 0; + } + -+ { ++ recycle_q(&s->output); ++ n = count_enqueued(&s->output); ++ ++ while (n < 6) { + AVFrame * frame; + int rv; + -+ recycle_q(&s->output); -+ n = count_enqueued(&s->output); -+ -+ while (n < 6) { -+ if ((rv = ff_inlink_consume_frame(inlink, &frame)) < 0) { -+ av_log(priv, AV_LOG_ERROR, "%s: consume in failed: %s\n", __func__, av_err2str(rv)); -+ return rv; -+ } -+ -+ if (frame == NULL) { -+ av_log(priv, AV_LOG_TRACE, "%s: No frame\n", __func__); -+ break; -+ } -+ -+ deint_v4l2m2m_filter_frame(inlink, frame); -+ av_log(priv, AV_LOG_TRACE, "%s: Q frame\n", __func__); -+ ++n; ++ if ((rv = ff_inlink_consume_frame(inlink, &frame)) < 0) { ++ av_log(priv, AV_LOG_ERROR, "%s: consume in failed: %s\n", __func__, av_err2str(rv)); ++ return rv; + } ++ ++ if (frame == NULL) { ++ av_log(priv, AV_LOG_TRACE, "%s: No frame\n", __func__); ++ break; ++ } ++ ++ rv = deint_v4l2m2m_filter_frame(inlink, frame); ++ av_frame_free(&frame); ++ ++ if (rv != 0) ++ return rv; ++ ++ av_log(priv, AV_LOG_TRACE, "%s: Q frame\n", __func__); ++ ++n; + } + + if (n < 6) { @@ -61395,7 +63840,7 @@ index 0000000000..d1c714b805 + return did_something ? 0 : FFERROR_NOT_READY; +} + -+static av_cold int deint_v4l2m2m_init(AVFilterContext *avctx) ++static av_cold int common_v4l2m2m_init(AVFilterContext * const avctx, const filter_type_v4l2_t filter_type) +{ + DeintV4L2M2MContext * const priv = avctx->priv; + DeintV4L2M2MContextShared * const ctx = av_mallocz(sizeof(DeintV4L2M2MContextShared)); @@ -61406,11 +63851,14 @@ index 0000000000..d1c714b805 + } + priv->shared = ctx; + ctx->logctx = priv; ++ ctx->filter_type = filter_type; + ctx->fd = -1; + ctx->output.ctx = ctx; + ctx->output.num_buffers = 8; ++ ctx->output.name = "OUTPUT"; + ctx->capture.ctx = ctx; + ctx->capture.num_buffers = 12; ++ ctx->capture.name = "CAPTURE"; + ctx->done = 0; + ctx->field_order = V4L2_FIELD_ANY; + @@ -61418,9 +63866,52 @@ index 0000000000..d1c714b805 + + atomic_init(&ctx->refcount, 1); + ++ if (priv->output_format_string) { ++ ctx->output_format = av_get_pix_fmt(priv->output_format_string); ++ if (ctx->output_format == AV_PIX_FMT_NONE) { ++ av_log(avctx, AV_LOG_ERROR, "Invalid ffmpeg output format '%s'.\n", priv->output_format_string); ++ return AVERROR(EINVAL); ++ } ++ if (fmt_av_to_v4l2(ctx->output_format) == 0) { ++ av_log(avctx, AV_LOG_ERROR, "Unsupported output format for V4L2: %s.\n", av_get_pix_fmt_name(ctx->output_format)); ++ return AVERROR(EINVAL); ++ } ++ } else { ++ // Use the input format once that is configured. ++ ctx->output_format = AV_PIX_FMT_NONE; ++ } ++ ++#define STRING_OPTION(var_name, func_name, default_value) do { \ ++ if (priv->var_name ## _string) { \ ++ int var = av_ ## func_name ## _from_name(priv->var_name ## _string); \ ++ if (var < 0) { \ ++ av_log(avctx, AV_LOG_ERROR, "Invalid %s.\n", #var_name); \ ++ return AVERROR(EINVAL); \ ++ } \ ++ priv->var_name = var; \ ++ } else { \ ++ priv->var_name = default_value; \ ++ } \ ++ } while (0) ++ ++ STRING_OPTION(colour_primaries, color_primaries, AVCOL_PRI_UNSPECIFIED); ++ STRING_OPTION(colour_transfer, color_transfer, AVCOL_TRC_UNSPECIFIED); ++ STRING_OPTION(colour_matrix, color_space, AVCOL_SPC_UNSPECIFIED); ++ STRING_OPTION(chroma_location, chroma_location, AVCHROMA_LOC_UNSPECIFIED); ++ + return 0; +} + ++static av_cold int deint_v4l2m2m_init(AVFilterContext *avctx) ++{ ++ return common_v4l2m2m_init(avctx, FILTER_V4L2_DEINTERLACE); ++} ++ ++static av_cold int scale_v4l2m2m_init(AVFilterContext *avctx) ++{ ++ return common_v4l2m2m_init(avctx, FILTER_V4L2_SCALE); ++} ++ +static void deint_v4l2m2m_uninit(AVFilterContext *avctx) +{ + DeintV4L2M2MContext *priv = avctx->priv; @@ -61438,6 +63929,51 @@ index 0000000000..d1c714b805 + +AVFILTER_DEFINE_CLASS(deinterlace_v4l2m2m); + ++#define OFFSET(x) offsetof(DeintV4L2M2MContext, x) ++#define FLAGS (AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM) ++ ++static const AVOption scale_v4l2m2m_options[] = { ++ { "w", "Output video width", ++ OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, .flags = FLAGS }, ++ { "h", "Output video height", ++ OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, .flags = FLAGS }, ++ { "format", "Output video format (software format of hardware frames)", ++ OFFSET(output_format_string), AV_OPT_TYPE_STRING, .flags = FLAGS }, ++ // These colour properties match the ones of the same name in vf_scale. ++ { "out_color_matrix", "Output colour matrix coefficient set", ++ OFFSET(colour_matrix_string), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS }, ++ { "out_range", "Output colour range", ++ OFFSET(colour_range), AV_OPT_TYPE_INT, { .i64 = AVCOL_RANGE_UNSPECIFIED }, ++ AVCOL_RANGE_UNSPECIFIED, AVCOL_RANGE_JPEG, FLAGS, "range" }, ++ { "full", "Full range", ++ 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, "range" }, ++ { "limited", "Limited range", ++ 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, "range" }, ++ { "jpeg", "Full range", ++ 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, "range" }, ++ { "mpeg", "Limited range", ++ 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, "range" }, ++ { "tv", "Limited range", ++ 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, "range" }, ++ { "pc", "Full range", ++ 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, "range" }, ++ // These colour properties match the ones in the VAAPI scaler ++ { "out_color_primaries", "Output colour primaries", ++ OFFSET(colour_primaries_string), AV_OPT_TYPE_STRING, ++ { .str = NULL }, .flags = FLAGS }, ++ { "out_color_transfer", "Output colour transfer characteristics", ++ OFFSET(colour_transfer_string), AV_OPT_TYPE_STRING, ++ { .str = NULL }, .flags = FLAGS }, ++ { "out_chroma_location", "Output chroma sample location", ++ OFFSET(chroma_location_string), AV_OPT_TYPE_STRING, ++ { .str = NULL }, .flags = FLAGS }, ++ { "force_original_aspect_ratio", "decrease or increase w/h if necessary to keep the original AR", OFFSET(force_original_aspect_ratio), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 2, FLAGS, "force_oar" }, ++ { "force_divisible_by", "enforce that the output resolution is divisible by a defined integer when force_original_aspect_ratio is used", OFFSET(force_divisible_by), AV_OPT_TYPE_INT, { .i64 = 1}, 1, 256, FLAGS }, ++ { NULL }, ++}; ++ ++AVFILTER_DEFINE_CLASS(scale_v4l2m2m); ++ +static const AVFilterPad deint_v4l2m2m_inputs[] = { + { + .name = "default", @@ -61467,6 +64003,20 @@ index 0000000000..d1c714b805 + .priv_class = &deinterlace_v4l2m2m_class, + .activate = deint_v4l2m2m_activate, +}; ++ ++AVFilter ff_vf_scale_v4l2m2m = { ++ .name = "scale_v4l2m2m", ++ .description = NULL_IF_CONFIG_SMALL("V4L2 M2M scaler"), ++ .priv_size = sizeof(DeintV4L2M2MContext), ++ .init = &scale_v4l2m2m_init, ++ .uninit = &deint_v4l2m2m_uninit, ++ .query_formats = &deint_v4l2m2m_query_formats, ++ .inputs = deint_v4l2m2m_inputs, ++ .outputs = deint_v4l2m2m_outputs, ++ .priv_class = &scale_v4l2m2m_class, ++ .activate = deint_v4l2m2m_activate, ++}; ++ diff --git a/libavfilter/vf_unsand.c b/libavfilter/vf_unsand.c new file mode 100644 index 0000000000..61c03a385c @@ -61702,6 +64252,97 @@ index 0000000000..61c03a385c + .outputs = avfilter_vf_unsand_outputs, +}; + +diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c +index bbf231f2a4..22571c89a3 100644 +--- a/libavformat/matroskaenc.c ++++ b/libavformat/matroskaenc.c +@@ -58,6 +58,9 @@ + * Info, Tracks, Chapters, Attachments, Tags (potentially twice) and Cues */ + #define MAX_SEEKHEAD_ENTRIES 7 + ++/* Reserved size for H264 headers if not extant at init time */ ++#define MAX_H264_HEADER_SIZE 1024 ++ + #define IS_SEEKABLE(pb, mkv) (((pb)->seekable & AVIO_SEEKABLE_NORMAL) && \ + !(mkv)->is_live) + +@@ -721,8 +724,12 @@ static int mkv_write_native_codecprivate(AVFormatContext *s, AVIOContext *pb, + case AV_CODEC_ID_WAVPACK: + return put_wv_codecpriv(dyn_cp, par); + case AV_CODEC_ID_H264: +- return ff_isom_write_avcc(dyn_cp, par->extradata, +- par->extradata_size); ++ if (par->extradata_size) ++ return ff_isom_write_avcc(dyn_cp, par->extradata, ++ par->extradata_size); ++ else ++ put_ebml_void(pb, MAX_H264_HEADER_SIZE); ++ break; + case AV_CODEC_ID_HEVC: + return ff_isom_write_hvcc(dyn_cp, par->extradata, + par->extradata_size, 0); +@@ -2258,7 +2265,9 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt) + break; + // FIXME: Remove the following once libaom starts propagating extradata during init() + // See https://bugs.chromium.org/p/aomedia/issues/detail?id=2012 ++ // H264 V4L2 has a similar issue + case AV_CODEC_ID_AV1: ++ case AV_CODEC_ID_H264: + if (side_data_size && mkv->track.bc && !par->extradata_size) { + AVIOContext *dyn_cp; + uint8_t *codecpriv; +@@ -2266,7 +2275,10 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt) + ret = avio_open_dyn_buf(&dyn_cp); + if (ret < 0) + return ret; +- ff_isom_write_av1c(dyn_cp, side_data, side_data_size); ++ if (par->codec_id == AV_CODEC_ID_H264) ++ ff_isom_write_avcc(dyn_cp, side_data, side_data_size); ++ else ++ ff_isom_write_av1c(dyn_cp, side_data, side_data_size); + codecpriv_size = avio_get_dyn_buf(dyn_cp, &codecpriv); + if ((ret = dyn_cp->error) < 0 || + !codecpriv_size && (ret = AVERROR_INVALIDDATA)) { +@@ -2274,8 +2286,25 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt) + return ret; + } + avio_seek(mkv->track.bc, track->codecpriv_offset, SEEK_SET); +- // Do not write the OBUs as we don't have space saved for them +- put_ebml_binary(mkv->track.bc, MATROSKA_ID_CODECPRIVATE, codecpriv, 4); ++ if (par->codec_id == AV_CODEC_ID_H264) { ++ int filler; ++ // Up to 6 bytes for header and the filler must be at least 2 ++ if (codecpriv_size > MAX_H264_HEADER_SIZE - 8) { ++ av_log(s, AV_LOG_ERROR, "H264 header size %d > %d bytes\n", codecpriv_size, MAX_H264_HEADER_SIZE - 8); ++ return AVERROR_INVALIDDATA; ++ } ++ put_ebml_binary(mkv->track.bc, MATROSKA_ID_CODECPRIVATE, codecpriv, codecpriv_size); ++ filler = MAX_H264_HEADER_SIZE - (avio_tell(mkv->track.bc) - track->codecpriv_offset); ++ if (filler < 2) { ++ av_log(s, AV_LOG_ERROR, "Unexpected SPS/PPS filler length: %d\n", filler); ++ return AVERROR_BUG; ++ } ++ put_ebml_void(mkv->track.bc, filler); ++ } ++ else { ++ // Do not write the OBUs as we don't have space saved for them ++ put_ebml_binary(mkv->track.bc, MATROSKA_ID_CODECPRIVATE, codecpriv, 4); ++ } + ffio_free_dyn_buf(&dyn_cp); + ret = ff_alloc_extradata(par, side_data_size); + if (ret < 0) +diff --git a/libavformat/movenc.c b/libavformat/movenc.c +index bade57dcea..d23101b23f 100644 +--- a/libavformat/movenc.c ++++ b/libavformat/movenc.c +@@ -5913,6 +5913,7 @@ static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt) + if (trk->par->codec_id == AV_CODEC_ID_MP4ALS || + trk->par->codec_id == AV_CODEC_ID_AAC || + trk->par->codec_id == AV_CODEC_ID_AV1 || ++ trk->par->codec_id == AV_CODEC_ID_H264 || + trk->par->codec_id == AV_CODEC_ID_FLAC) { + buffer_size_t side_size; + uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size); diff --git a/libavformat/utils.c b/libavformat/utils.c index 1384b56771..27479e3c40 100644 --- a/libavformat/utils.c @@ -61841,10 +64482,10 @@ index 5613813ba8..ab8bcfcf34 100644 + diff --git a/libavutil/aarch64/rpi_sand_neon.S b/libavutil/aarch64/rpi_sand_neon.S new file mode 100644 -index 0000000000..cdcf71ee67 +index 0000000000..2f07d9674c --- /dev/null +++ b/libavutil/aarch64/rpi_sand_neon.S -@@ -0,0 +1,676 @@ +@@ -0,0 +1,781 @@ +/* +Copyright (c) 2021 Michael Eiler + @@ -62095,228 +64736,6 @@ index 0000000000..cdcf71ee67 + ret +endfunc + -+//void ff_rpi_sand30_lines_to_planar_y16( -+// uint8_t * dest, // [x0] -+// unsigned int dst_stride, // [w1] -> assumed to be equal to _w -+// const uint8_t * src, // [x2] -+// unsigned int src_stride1, // [w3] -> 128 -+// unsigned int src_stride2, // [w4] -+// unsigned int _x, // [w5] -+// unsigned int y, // [w6] -+// unsigned int _w, // [w7] -+// unsigned int h); // [sp, #0] -+ -+function ff_rpi_sand30_lines_to_planar_y16, export=1 -+ stp x19, x20, [sp, #-48]! -+ stp x21, x22, [sp, #16] -+ stp x23, x24, [sp, #32] -+ -+ // w6 = argument h -+ ldr w6, [sp, #48] -+ -+ // slice_inc = ((stride2 - 1) * stride1) -+ mov w5, w4 -+ sub w5, w5, #1 -+ lsl w5, w5, #7 -+ -+ // total number of bytes per row = (width / 3) * 4 -+ mov w8, w7 -+ mov w9, #3 -+ udiv w8, w8, w9 -+ lsl w8, w8, #2 -+ -+ // number of full 128 byte blocks to be processed -+ mov w9, #96 -+ udiv w9, w7, w9 // = (width * 4) / (3*128) = width/96 -+ -+ // w10 = number of full integers to process (4 bytes) -+ // w11 = remaning zero to two 10bit values still to copy over -+ mov w12, #96 -+ mul w12, w9, w12 -+ sub w12, w7, w12 // width - blocks*96 = remaining points per row -+ mov w11, #3 -+ udiv w10, w12, w11 // full integers to process = w12 / 3 -+ mul w11, w10, w11 // #integers *3 -+ sub w11, w12, w11 // remaining 0-2 points = remaining points - integers*3 -+ -+ // increase w9 by one if w10+w11 is not zero, and decrease the row count by one -+ // this is to efficiently copy incomplete blocks at the end of the rows -+ // the last row is handled explicitly to avoid writing out of bounds -+ add w22, w10, w11 -+ cmp w22, #0 -+ cset w22, ne // 1 iff w10+w11 not zero, 0 otherwise -+ add w9, w9, w22 -+ sub w6, w6, #1 -+ -+ // store the number of bytes in w20 which we copy too much for every row -+ // when the width of the frame is not a multiple of 96 (128bytes storing 96 10bit values) -+ mov w20, #96*2 -+ mul w20, w20, w9 -+ sub w20, w1, w20 -+ -+ mov w23, #0 // flag to check whether the last line had already been processed -+ -+ // bitmask to clear the uppper 6bits of the result values -+ mov x19, #0x03ff03ff03ff03ff -+ dup v22.2d, x19 -+ -+ // row counter = 0 -+ eor w12, w12, w12 -+row_loop_y16: -+ cmp w12, w6 // jump to row_loop_y16_fin if we processed all rows -+ bge row_loop_y16_fin -+ -+ mov x13, x2 // row src -+ eor w14, w14, w14 // full block counter -+block_loop_y16: -+ cmp w14, w9 -+ bge block_loop_y16_fin -+ -+ // load 64 bytes -+ ld1 { v0.4s, v1.4s, v2.4s, v3.4s }, [x13], #64 -+ -+ // process v0 and v1 -+ xtn v16.4h, v0.4s -+ ushr v0.4s, v0.4s, #10 -+ xtn v17.4h, v0.4s -+ ushr v0.4s, v0.4s, #10 -+ xtn v18.4h, v0.4s -+ -+ xtn2 v16.8h, v1.4s -+ and v16.16b, v16.16b, v22.16b -+ ushr v1.4s, v1.4s, #10 -+ xtn2 v17.8h, v1.4s -+ and v17.16b, v17.16b, v22.16b -+ ushr v1.4s, v1.4s, #10 -+ xtn2 v18.8h, v1.4s -+ and v18.16b, v18.16b, v22.16b -+ -+ st3 { v16.8h, v17.8h, v18.8h }, [x0], #48 -+ -+ // process v2 and v3 -+ xtn v23.4h, v2.4s -+ ushr v2.4s, v2.4s, #10 -+ xtn v24.4h, v2.4s -+ ushr v2.4s, v2.4s, #10 -+ xtn v25.4h, v2.4s -+ -+ xtn2 v23.8h, v3.4s -+ and v23.16b, v23.16b, v22.16b -+ ushr v3.4s, v3.4s, #10 -+ xtn2 v24.8h, v3.4s -+ and v24.16b, v24.16b, v22.16b -+ ushr v3.4s, v3.4s, #10 -+ xtn2 v25.8h, v3.4s -+ and v25.16b, v25.16b, v22.16b -+ -+ st3 { v23.8h, v24.8h, v25.8h }, [x0], #48 -+ -+ // load the second half of the block -> 64 bytes into registers v4-v7 -+ ld1 { v4.4s, v5.4s, v6.4s, v7.4s }, [x13], #64 -+ -+ // process v4 and v5 -+ xtn v16.4h, v4.4s -+ ushr v4.4s, v4.4s, #10 -+ xtn v17.4h, v4.4s -+ ushr v4.4s, v4.4s, #10 -+ xtn v18.4h, v4.4s -+ -+ xtn2 v16.8h, v5.4s -+ and v16.16b, v16.16b, v22.16b -+ ushr v5.4s, v5.4s, #10 -+ xtn2 v17.8h, v5.4s -+ and v17.16b, v17.16b, v22.16b -+ ushr v5.4s, v5.4s, #10 -+ xtn2 v18.8h, v5.4s -+ and v18.16b, v18.16b, v22.16b -+ -+ st3 { v16.8h, v17.8h, v18.8h }, [x0], #48 -+ -+ // v6 and v7 -+ xtn v23.4h, v6.4s -+ ushr v6.4s, v6.4s, #10 -+ xtn v24.4h, v6.4s -+ ushr v6.4s, v6.4s, #10 -+ xtn v25.4h, v6.4s -+ -+ xtn2 v23.8h, v7.4s -+ and v23.16b, v23.16b, v22.16b -+ ushr v7.4s, v7.4s, #10 -+ xtn2 v24.8h, v7.4s -+ and v24.16b, v24.16b, v22.16b -+ ushr v7.4s, v7.4s, #10 -+ xtn2 v25.8h, v7.4s -+ and v25.16b, v25.16b, v22.16b -+ -+ st3 { v23.8h, v24.8h, v25.8h }, [x0], #48 -+ -+ add x13, x13, x5 // row src += slice_inc -+ add w14, w14, #1 -+ b block_loop_y16 -+block_loop_y16_fin: -+ -+ -+ -+ -+ add x2, x2, #128 // src += stride1 (start of the next row) -+ add x0, x0, w20, sxtw // subtract the bytes we copied too much from dst -+ add w12, w12, #1 -+ b row_loop_y16 -+row_loop_y16_fin: -+ -+ // check whether we have incomplete blocks at the end of every row -+ // in that case decrease row block count by one -+ // change height back to it's original value (meaning increase it by 1) -+ // and jump back to another iteration of row_loop_y16 -+ -+ cmp w23, #1 -+ beq row_loop_y16_fin2 // don't continue here if we already processed the last row -+ add w6, w6, #1 // increase height to the original value -+ sub w9, w9, w22 // block count - 1 or 0, depending on the remaining bytes count -+ mov w23, #1 -+ b row_loop_y16 -+row_loop_y16_fin2: -+ -+ sub x0, x0, w20, sxtw // with the last row we didn't actually move the dst ptr to far ahead, therefore readd the diference -+ -+ // now we've got to handle the last block in the last row -+ eor w12, w12, w12 // w12 = 0 = counter -+integer_loop_y16: -+ cmp w12, w10 -+ bge integer_loop_y16_fin -+ ldr w14, [x13], #4 -+ and w15, w14, #0x3ff -+ strh w15, [x0], #2 -+ lsr w14, w14, #10 -+ and w15, w14, #0x3ff -+ strh w15, [x0], #2 -+ lsr w14, w14, #10 -+ and w15, w14, #0x3ff -+ strh w15, [x0], #2 -+ add w12, w12, #1 -+ b integer_loop_y16 -+integer_loop_y16_fin: -+ -+final_values_y16: -+ // remaining point count = w11 -+ ldr w14, [x13], #4 -+ cmp w11, #0 -+ beq final_values_y16_fin -+ and w15, w14, #0x3ff -+ strh w15, [x0], #2 -+ cmp w11, #1 -+ beq final_values_y16_fin -+ lsr w14, w14, #10 -+ and w15, w14, #0x3ff -+ strh w15, [x0], #2 -+final_values_y16_fin: -+ -+ ldp x23, x24, [sp, #32] -+ ldp x21, x22, [sp, #16] -+ ldp x19, x20, [sp], #48 -+ ret -+endfunc -+ +//void ff_rpi_sand30_lines_to_planar_c16( +// uint8_t * dst_u, // [x0] +// unsigned int dst_stride_u, // [w1] == _w*2 @@ -62521,12 +64940,339 @@ index 0000000000..cdcf71ee67 +// unsigned int _w, +// unsigned int h); + ++// void ff_rpi_sand30_lines_to_planar_y8( ++// uint8_t * dest, : x0 ++// unsigned int dst_stride, : w1 ++// const uint8_t * src, : x2 ++// unsigned int src_stride1, : w3, always 128 ++// unsigned int src_stride2, : w4 ++// unsigned int _x, : w5 ++// unsigned int y, : w6 ++// unsigned int _w, : w7 ++// unsigned int h); : [sp, #0] ++// ++// Assumes that we are starting on a stripe boundary and that overreading ++// within the stripe is OK. However it does respect the dest size for wri ++ ++function ff_rpi_sand30_lines_to_planar_y16, export=1 ++ lsl w4, w4, #7 ++ sub w4, w4, #64 ++ sub w1, w1, w7, lsl #1 ++ uxtw x6, w6 ++ add x8, x2, x6, lsl #7 ++ ldr w6, [sp, #0] ++ ++10: ++ mov x2, x8 ++ mov w5, w7 ++1: ++ ld1 {v0.4s, v1.4s, v2.4s, v3.4s}, [x2], #64 ++ ld1 {v4.4s, v5.4s, v6.4s, v7.4s}, [x2], x4 ++ ++ subs w5, w5, #96 ++ ++ // v0, v1 ++ ++ shrn v18.4h, v0.4s, #14 ++ xtn v16.4h, v0.4s ++ shrn v17.4h, v0.4s, #10 ++ ++ shrn2 v18.8h, v1.4s, #14 ++ xtn2 v16.8h, v1.4s ++ shrn2 v17.8h, v1.4s, #10 ++ ++ ushr v18.8h, v18.8h, #6 ++ bic v16.8h, #0xfc, lsl #8 ++ bic v17.8h, #0xfc, lsl #8 ++ ++ // v2, v3 ++ ++ shrn v21.4h, v2.4s, #14 ++ xtn v19.4h, v2.4s ++ shrn v20.4h, v2.4s, #10 ++ ++ shrn2 v21.8h, v3.4s, #14 ++ xtn2 v19.8h, v3.4s ++ shrn2 v20.8h, v3.4s, #10 ++ ++ ushr v21.8h, v21.8h, #6 ++ bic v19.8h, #0xfc, lsl #8 ++ bic v20.8h, #0xfc, lsl #8 ++ ++ // v4, v5 ++ ++ shrn v24.4h, v4.4s, #14 ++ xtn v22.4h, v4.4s ++ shrn v23.4h, v4.4s, #10 ++ ++ shrn2 v24.8h, v5.4s, #14 ++ xtn2 v22.8h, v5.4s ++ shrn2 v23.8h, v5.4s, #10 ++ ++ ushr v24.8h, v24.8h, #6 ++ bic v22.8h, #0xfc, lsl #8 ++ bic v23.8h, #0xfc, lsl #8 ++ ++ // v6, v7 ++ ++ shrn v27.4h, v6.4s, #14 ++ xtn v25.4h, v6.4s ++ shrn v26.4h, v6.4s, #10 ++ ++ shrn2 v27.8h, v7.4s, #14 ++ xtn2 v25.8h, v7.4s ++ shrn2 v26.8h, v7.4s, #10 ++ ++ ushr v27.8h, v27.8h, #6 ++ bic v25.8h, #0xfc, lsl #8 ++ bic v26.8h, #0xfc, lsl #8 ++ ++ blt 2f ++ ++ st3 {v16.8h, v17.8h, v18.8h}, [x0], #48 ++ st3 {v19.8h, v20.8h, v21.8h}, [x0], #48 ++ st3 {v22.8h, v23.8h, v24.8h}, [x0], #48 ++ st3 {v25.8h, v26.8h, v27.8h}, [x0], #48 ++ ++ bne 1b ++ ++11: ++ subs w6, w6, #1 ++ add x0, x0, w1, uxtw ++ add x8, x8, #128 ++ bne 10b ++ ++ ret ++ ++// Partial final write ++2: ++ cmp w5, #48-96 ++ blt 1f ++ st3 {v16.8h, v17.8h, v18.8h}, [x0], #48 ++ st3 {v19.8h, v20.8h, v21.8h}, [x0], #48 ++ beq 11b ++ mov v16.16b, v22.16b ++ mov v17.16b, v23.16b ++ sub w5, w5, #48 ++ mov v18.16b, v24.16b ++ mov v19.16b, v25.16b ++ mov v20.16b, v26.16b ++ mov v21.16b, v27.16b ++1: ++ cmp w5, #24-96 ++ blt 1f ++ st3 {v16.8h, v17.8h, v18.8h}, [x0], #48 ++ beq 11b ++ mov v16.16b, v19.16b ++ mov v17.16b, v20.16b ++ sub w5, w5, #24 ++ mov v18.16b, v21.16b ++1: ++ cmp w5, #12-96 ++ blt 1f ++ st3 {v16.4h, v17.4h, v18.4h}, [x0], #24 ++ beq 11b ++ mov v16.2d[0], v16.2d[1] ++ sub w5, w5, #12 ++ mov v17.2d[0], v17.2d[1] ++ mov v18.2d[0], v18.2d[1] ++1: ++ cmp w5, #6-96 ++ blt 1f ++ st3 {v16.h, v17.h, v18.h}[0], [x0], #6 ++ st3 {v16.h, v17.h, v18.h}[1], [x0], #6 ++ beq 11b ++ mov v16.2s[0], v16.2s[1] ++ sub w5, w5, #6 ++ mov v17.2s[0], v17.2s[1] ++ mov v18.2s[0], v18.2s[1] ++1: ++ cmp w5, #3-96 ++ blt 1f ++ st3 {v16.h, v17.h, v18.h}[0], [x0], #6 ++ beq 11b ++ mov v16.4h[0], v16.4h[1] ++ sub w5, w5, #3 ++ mov v17.4h[0], v17.4h[1] ++1: ++ cmp w5, #2-96 ++ blt 1f ++ st2 {v16.h, v17.h}[0], [x0], #4 ++ b 11b ++1: ++ st1 {v16.h}[0], [x0], #2 ++ b 11b ++ ++endfunc ++ ++// void ff_rpi_sand30_lines_to_planar_y8( ++// uint8_t * dest, : x0 ++// unsigned int dst_stride, : w1 ++// const uint8_t * src, : x2 ++// unsigned int src_stride1, : w3, always 128 ++// unsigned int src_stride2, : w4 ++// unsigned int _x, : w5 ++// unsigned int y, : w6 ++// unsigned int _w, : w7 ++// unsigned int h); : [sp, #0] ++// ++// Assumes that we are starting on a stripe boundary and that overreading ++// within the stripe is OK. However it does respect the dest size for wri ++ ++function ff_rpi_sand30_lines_to_planar_y8, export=1 ++ lsl w4, w4, #7 ++ sub w4, w4, #64 ++ sub w1, w1, w7 ++ uxtw x6, w6 ++ add x8, x2, x6, lsl #7 ++ ldr w6, [sp, #0] ++ ++10: ++ mov x2, x8 ++ mov w5, w7 ++1: ++ ld1 {v0.4s, v1.4s, v2.4s, v3.4s}, [x2], #64 ++ ld1 {v4.4s, v5.4s, v6.4s, v7.4s}, [x2], x4 ++ ++ subs w5, w5, #96 ++ ++ // v0, v1 ++ ++ shrn v18.4h, v0.4s, #16 ++ xtn v16.4h, v0.4s ++ shrn v17.4h, v0.4s, #12 ++ ++ shrn2 v18.8h, v1.4s, #16 ++ xtn2 v16.8h, v1.4s ++ shrn2 v17.8h, v1.4s, #12 ++ ++ shrn v18.8b, v18.8h, #6 ++ shrn v16.8b, v16.8h, #2 ++ xtn v17.8b, v17.8h ++ ++ // v2, v3 ++ ++ shrn v21.4h, v2.4s, #16 ++ xtn v19.4h, v2.4s ++ shrn v20.4h, v2.4s, #12 ++ ++ shrn2 v21.8h, v3.4s, #16 ++ xtn2 v19.8h, v3.4s ++ shrn2 v20.8h, v3.4s, #12 ++ ++ shrn2 v18.16b, v21.8h, #6 ++ shrn2 v16.16b, v19.8h, #2 ++ xtn2 v17.16b, v20.8h ++ ++ // v4, v5 ++ ++ shrn v24.4h, v4.4s, #16 ++ xtn v22.4h, v4.4s ++ shrn v23.4h, v4.4s, #12 ++ ++ shrn2 v24.8h, v5.4s, #16 ++ xtn2 v22.8h, v5.4s ++ shrn2 v23.8h, v5.4s, #12 ++ ++ shrn v21.8b, v24.8h, #6 ++ shrn v19.8b, v22.8h, #2 ++ xtn v20.8b, v23.8h ++ ++ // v6, v7 ++ ++ shrn v27.4h, v6.4s, #16 ++ xtn v25.4h, v6.4s ++ shrn v26.4h, v6.4s, #12 ++ ++ shrn2 v27.8h, v7.4s, #16 ++ xtn2 v25.8h, v7.4s ++ shrn2 v26.8h, v7.4s, #12 ++ ++ shrn2 v21.16b, v27.8h, #6 ++ shrn2 v19.16b, v25.8h, #2 ++ xtn2 v20.16b, v26.8h ++ ++ blt 2f ++ ++ st3 {v16.16b, v17.16b, v18.16b}, [x0], #48 ++ st3 {v19.16b, v20.16b, v21.16b}, [x0], #48 ++ ++ bne 1b ++ ++11: ++ subs w6, w6, #1 ++ add x0, x0, w1, uxtw ++ add x8, x8, #128 ++ bne 10b ++ ++ ret ++ ++// Partial final write ++2: ++ cmp w5, #48-96 ++ blt 1f ++ st3 {v16.16b, v17.16b, v18.16b}, [x0], #48 ++ beq 11b ++ mov v16.16b, v22.16b ++ mov v17.16b, v23.16b ++ sub w5, w5, #48 ++ mov v18.16b, v24.16b ++1: ++ cmp w5, #24-96 ++ blt 1f ++ st3 {v16.8b, v17.8b, v18.8b}, [x0], #24 ++ beq 11b ++ mov v16.2d[0], v16.2d[1] ++ sub w5, w5, #24 ++ mov v17.2d[0], v17.2d[1] ++ mov v18.2d[0], v18.2d[1] ++1: ++ cmp w5, #12-96 ++ blt 1f ++ st3 {v16.b, v17.b, v18.b}[0], [x0], #3 ++ st3 {v16.b, v17.b, v18.b}[1], [x0], #3 ++ st3 {v16.b, v17.b, v18.b}[2], [x0], #3 ++ st3 {v16.b, v17.b, v18.b}[3], [x0], #3 ++ beq 11b ++ mov v16.2s[0], v16.2s[1] ++ sub w5, w5, #12 ++ mov v17.2s[0], v17.2s[1] ++ mov v18.2s[0], v18.2s[1] ++1: ++ cmp w5, #6-96 ++ blt 1f ++ st3 {v16.b, v17.b, v18.b}[0], [x0], #3 ++ st3 {v16.b, v17.b, v18.b}[1], [x0], #3 ++ beq 11b ++ mov v16.4h[0], v16.4h[1] ++ sub w5, w5, #6 ++ mov v17.4h[0], v17.4h[1] ++ mov v18.4h[0], v18.4h[1] ++1: ++ cmp w5, #3-96 ++ blt 1f ++ st3 {v16.b, v17.b, v18.b}[0], [x0], #3 ++ beq 11b ++ mov v16.8b[0], v16.8b[1] ++ sub w5, w5, #3 ++ mov v17.8b[0], v17.8b[1] ++1: ++ cmp w5, #2-96 ++ blt 1f ++ st2 {v16.b, v17.b}[0], [x0], #2 ++ b 11b ++1: ++ st1 {v16.b}[0], [x0], #1 ++ b 11b ++ ++endfunc ++ diff --git a/libavutil/aarch64/rpi_sand_neon.h b/libavutil/aarch64/rpi_sand_neon.h new file mode 100644 -index 0000000000..b3aa481ea4 +index 0000000000..2a56135bc3 --- /dev/null +++ b/libavutil/aarch64/rpi_sand_neon.h -@@ -0,0 +1,55 @@ +@@ -0,0 +1,59 @@ +/* +Copyright (c) 2021 Michael Eiler + @@ -62578,6 +65324,10 @@ index 0000000000..b3aa481ea4 + uint8_t * dst_v, unsigned int dst_stride_v, const uint8_t * src, unsigned int stride1, + unsigned int stride2, unsigned int _x, unsigned int y, unsigned int _w, unsigned int h); + ++void ff_rpi_sand30_lines_to_planar_y8(uint8_t * dest, unsigned int dst_stride, ++ const uint8_t * src, unsigned int src_stride1, unsigned int src_stride2, ++ unsigned int _x, unsigned int y, unsigned int _w, unsigned int h); ++ +#ifdef __cplusplus +} +#endif @@ -62593,10 +65343,10 @@ index 5da44b0542..b74b7c4e2f 100644 + arm/rpi_sand_neon.o \ diff --git a/libavutil/arm/rpi_sand_neon.S b/libavutil/arm/rpi_sand_neon.S new file mode 100644 -index 0000000000..80890fe985 +index 0000000000..60e697f681 --- /dev/null +++ b/libavutil/arm/rpi_sand_neon.S -@@ -0,0 +1,768 @@ +@@ -0,0 +1,925 @@ +/* +Copyright (c) 2018 Raspberry Pi (Trading) Ltd. +All rights reserved. @@ -62959,7 +65709,6 @@ index 0000000000..80890fe985 + ldr r6, [sp, #36] + ldr r7, [sp, #32] @ y + mov r12, #48 -+ vmov.u16 q15, #0x3ff + sub r3, #1 + lsl r3, #7 + sub r1, r1, r6, lsl #1 @@ -62975,37 +65724,33 @@ index 0000000000..80890fe985 + vldm r2!, {q10-q13} + add lr, #64 + -+ vshr.u32 q14, q10, #20 @ Cannot vshrn.u32 #20! ++ vshrn.u32 d4 , q10, #14 @ Cannot vshrn.u32 #20! + ands lr, #127 + vshrn.u32 d2, q10, #10 + vmovn.u32 d0, q10 -+ vmovn.u32 d4, q14 + -+ vshr.u32 q14, q11, #20 ++ vshrn.u32 d5, q11, #14 + it eq + addeq r2, r3 + vshrn.u32 d3, q11, #10 + vmovn.u32 d1, q11 -+ vmovn.u32 d5, q14 + + subs r5, #48 -+ vand q0, q15 -+ vand q1, q15 -+ vand q2, q15 ++ vshr.u16 q2, #6 ++ vbic.u16 q0, #0xfc00 ++ vbic.u16 q1, #0xfc00 + -+ vshr.u32 q14, q12, #20 ++ vshrn.u32 d20, q12, #14 + vshrn.u32 d18, q12, #10 + vmovn.u32 d16, q12 -+ vmovn.u32 d20, q14 + -+ vshr.u32 q14, q13, #20 ++ vshrn.u32 d21, q13, #14 + vshrn.u32 d19, q13, #10 + vmovn.u32 d17, q13 -+ vmovn.u32 d21, q14 + -+ vand q8, q15 -+ vand q9, q15 -+ vand q10, q15 ++ vshr.u16 q10, #6 ++ vbic.u16 q8, #0xfc00 ++ vbic.u16 q9 , #0xfc00 + blt 2f + + vst3.16 {d0, d2, d4}, [r0], r12 @@ -63098,7 +65843,6 @@ index 0000000000..80890fe985 + ldr r7, [sp, #48] + ldr r9, [sp, #52] + mov r12, #48 -+ vmov.u16 q15, #0x3ff + sub r8, #1 + lsl r8, #7 + add r5, r5, r7, lsl #7 @@ -63114,48 +65858,44 @@ index 0000000000..80890fe985 + add lr, #64 + + @ N.B. unpack [0,1,2] -> (reg order) 1, 0, 2 -+ vshr.u32 q14, q0, #20 -+ vshrn.u32 d16, q0, #10 ++ vshrn.u32 d20, q0, #14 + vmovn.u32 d18, q0 ++ vshrn.u32 d0, q0, #10 + ands lr, #127 -+ vmovn.u32 d20, q14 + -+ vshr.u32 q14, q1, #20 -+ vshrn.u32 d17, q1, #10 ++ vshrn.u32 d21, q1, #14 + vmovn.u32 d19, q1 -+ vmovn.u32 d21, q14 ++ vshrn.u32 d1, q1, #10 + -+ vshr.u32 q14, q2, #20 + vshrn.u32 d22, q2, #10 -+ vmovn.u32 d24, q2 -+ vmovn.u32 d26, q14 ++ vmovn.u32 d2, q2 ++ vshrn.u32 d4, q2, #14 + -+ vshr.u32 q14, q3, #20 -+ vshrn.u32 d23, q3, #10 -+ vmovn.u32 d25, q3 + add r10, r0, #24 -+ vmovn.u32 d27, q14 ++ vshrn.u32 d23, q3, #10 ++ vmovn.u32 d3, q3 ++ vshrn.u32 d5, q3, #14 + + it eq + addeq r4, r8 -+ vuzp.16 q8, q11 -+ vuzp.16 q9, q12 -+ vuzp.16 q10, q13 ++ vuzp.16 q0, q11 ++ vuzp.16 q9, q1 ++ vuzp.16 q10, q2 + -+ @ q8 V0, V3,.. -> q0 ++ @ q0 V0, V3,.. + @ q9 U0, U3... + @ q10 U1, U4... + @ q11 U2, U5,.. -+ @ q12 V1, V4,.. -> q1 -+ @ q13 V2, V5,.. -> q2 ++ @ q1 V1, V4, ++ @ q2 V2, V5,.. + + subs r6, #24 -+ vand q11, q15 -+ vand q9, q15 -+ vand q10, q15 -+ vand q0, q8, q15 -+ vand q1, q12, q15 -+ vand q2, q13, q15 ++ vbic.u16 q11, #0xfc00 ++ vbic.u16 q9, #0xfc00 ++ vshr.u16 q10, #6 ++ vshr.u16 q2, #6 ++ vbic.u16 q0, #0xfc00 ++ vbic.u16 q1, #0xfc00 + + blt 2f + @@ -63364,13 +66104,180 @@ index 0000000000..80890fe985 +endfunc + + ++@ void ff_rpi_sand30_lines_to_planar_y8( ++@ uint8_t * dest, // [r0] ++@ unsigned int dst_stride, // [r1] ++@ const uint8_t * src, // [r2] ++@ unsigned int src_stride1, // [r3] Ignored - assumed 128 ++@ unsigned int src_stride2, // [sp, #0] -> r3 ++@ unsigned int _x, // [sp, #4] Ignored - 0 ++@ unsigned int y, // [sp, #8] (r7 in prefix) ++@ unsigned int _w, // [sp, #12] -> r6 (cur r5) ++@ unsigned int h); // [sp, #16] -> r7 ++@ ++@ Assumes that we are starting on a stripe boundary and that overreading ++@ within the stripe is OK. However it does respect the dest size for wri ++ ++function ff_rpi_sand30_lines_to_planar_y8, export=1 ++ push {r4-r8, lr} @ +24 ++ ldr r3, [sp, #24] ++ ldr r6, [sp, #36] ++ ldr r7, [sp, #32] @ y ++ mov r12, #48 ++ lsl r3, #7 ++ sub r1, r1, r6 ++ add r8, r2, r7, lsl #7 ++ ldr r7, [sp, #40] ++ ++10: ++ mov r2, r8 ++ add r4, r0, #24 ++ mov r5, r6 ++1: ++ vldm r2, {q8-q15} ++ ++ subs r5, #96 ++ ++ vmovn.u32 d0, q8 ++ vshrn.u32 d2, q8, #12 ++ vshrn.u32 d4, q8, #16 @ Cannot vshrn.u32 #20! ++ ++ add r2, r3 ++ ++ vmovn.u32 d1, q9 ++ vshrn.u32 d3, q9, #12 ++ vshrn.u32 d5, q9, #16 ++ ++ pld [r2, #0] ++ ++ vshrn.u16 d0, q0, #2 ++ vmovn.u16 d1, q1 ++ vshrn.u16 d2, q2, #6 ++ ++ vmovn.u32 d16, q10 ++ vshrn.u32 d18, q10, #12 ++ vshrn.u32 d20, q10, #16 ++ ++ vmovn.u32 d17, q11 ++ vshrn.u32 d19, q11, #12 ++ vshrn.u32 d21, q11, #16 ++ ++ pld [r2, #64] ++ ++ vshrn.u16 d4, q8, #2 ++ vmovn.u16 d5, q9 ++ vshrn.u16 d6, q10, #6 ++ ++ vmovn.u32 d16, q12 ++ vshrn.u32 d18, q12, #12 ++ vshrn.u32 d20, q12, #16 ++ ++ vmovn.u32 d17, q13 ++ vshrn.u32 d19, q13, #12 ++ vshrn.u32 d21, q13, #16 ++ ++ vshrn.u16 d16, q8, #2 ++ vmovn.u16 d17, q9 ++ vshrn.u16 d18, q10, #6 ++ ++ vmovn.u32 d20, q14 ++ vshrn.u32 d22, q14, #12 ++ vshrn.u32 d24, q14, #16 ++ ++ vmovn.u32 d21, q15 ++ vshrn.u32 d23, q15, #12 ++ vshrn.u32 d25, q15, #16 ++ ++ vshrn.u16 d20, q10, #2 ++ vmovn.u16 d21, q11 ++ vshrn.u16 d22, q12, #6 ++ ++ blt 2f ++ ++ vst3.8 {d0, d1, d2}, [r0], r12 ++ vst3.8 {d4, d5, d6}, [r4], r12 ++ vst3.8 {d16, d17, d18}, [r0], r12 ++ vst3.8 {d20, d21, d22}, [r4], r12 ++ ++ bne 1b ++ ++11: ++ subs r7, #1 ++ add r0, r1 ++ add r8, #128 ++ bne 10b ++ ++ pop {r4-r8, pc} ++ ++@ Partial final write ++2: ++ cmp r5, #48-96 ++ blt 1f ++ vst3.8 {d0, d1, d2}, [r0], r12 ++ vst3.8 {d4, d5, d6}, [r4], r12 ++ beq 11b ++ vmov q0, q8 ++ vmov q2, q10 ++ sub r5, #48 ++ vmov d2, d18 ++ vmov d6, d22 ++1: ++ cmp r5, #24-96 ++ blt 1f ++ vst3.8 {d0, d1, d2}, [r0]! ++ beq 11b ++ vmov q0, q2 ++ sub r5, #24 ++ vmov d2, d6 ++1: ++ cmp r5, #12-96 ++ blt 1f ++ vst3.8 {d0[0], d1[0], d2[0]}, [r0]! ++ vst3.8 {d0[1], d1[1], d2[1]}, [r0]! ++ vst3.8 {d0[2], d1[2], d2[2]}, [r0]! ++ vst3.8 {d0[3], d1[3], d2[3]}, [r0]! ++ beq 11b ++ vmov s0, s1 ++ sub r5, #12 ++ vmov s2, s3 ++ vmov s4, s5 ++1: ++ cmp r5, #6-96 ++ blt 1f ++ vst3.8 {d0[0], d1[0], d2[0]}, [r0]! ++ vst3.8 {d0[1], d1[1], d2[1]}, [r0]! ++ add r0, #12 ++ beq 11b ++ vshr.u32 d0, #16 ++ sub r5, #6 ++ vshr.u32 d1, #16 ++ vshr.u32 d2, #16 ++1: ++ cmp r5, #3-96 ++ blt 1f ++ vst3.8 {d0[0], d1[0], d2[0]}, [r0]! ++ beq 11b ++ sub r5, #3 ++ vshr.u32 d0, #8 ++ vshr.u32 d1, #8 ++1: ++ cmp r5, #2-96 ++ blt 1f ++ vst2.8 {d0[0], d1[0]}, [r0]! ++ b 11b ++1: ++ vst1.8 {d0[0]}, [r0]! ++ b 11b ++ ++endfunc ++ + diff --git a/libavutil/arm/rpi_sand_neon.h b/libavutil/arm/rpi_sand_neon.h new file mode 100644 -index 0000000000..447f367bea +index 0000000000..d457c10870 --- /dev/null +++ b/libavutil/arm/rpi_sand_neon.h -@@ -0,0 +1,99 @@ +@@ -0,0 +1,110 @@ +/* +Copyright (c) 2020 Raspberry Pi (Trading) Ltd. +All rights reserved. @@ -63468,6 +66375,17 @@ index 0000000000..447f367bea + unsigned int _w, // [sp, #12] -> r6 (cur r5) + unsigned int h); // [sp, #16] -> r7 + ++void ff_rpi_sand30_lines_to_planar_y8( ++ uint8_t * dest, // [r0] ++ unsigned int dst_stride, // [r1] ++ const uint8_t * src, // [r2] ++ unsigned int src_stride1, // [r3] Ignored - assumed 128 ++ unsigned int src_stride2, // [sp, #0] -> r3 ++ unsigned int _x, // [sp, #4] Ignored - 0 ++ unsigned int y, // [sp, #8] (r7 in prefix) ++ unsigned int _w, // [sp, #12] -> r6 (cur r5) ++ unsigned int h); // [sp, #16] -> r7 ++ +#endif // AVUTIL_ARM_SAND_NEON_H + diff --git a/libavutil/frame.c b/libavutil/frame.c @@ -63528,7 +66446,7 @@ index 7d1f8e2935..a4e7dc915d 100644 * @} */ diff --git a/libavutil/hwcontext_drm.c b/libavutil/hwcontext_drm.c -index 7a9fdbd263..2a498f9b50 100644 +index 7a9fdbd263..2f825b7e16 100644 --- a/libavutil/hwcontext_drm.c +++ b/libavutil/hwcontext_drm.c @@ -21,6 +21,7 @@ @@ -63603,13 +66521,23 @@ index 7a9fdbd263..2a498f9b50 100644 err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, &drm_unmap_frame, map); -@@ -212,7 +240,15 @@ static int drm_transfer_get_formats(AVHWFramesContext *ctx, - if (!pix_fmts) +@@ -206,16 +234,29 @@ static int drm_transfer_get_formats(AVHWFramesContext *ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats) + { +- enum AVPixelFormat *pix_fmts; ++ enum AVPixelFormat *p; + +- pix_fmts = av_malloc_array(2, sizeof(*pix_fmts)); +- if (!pix_fmts) ++ p = *formats = av_malloc_array(3, sizeof(*p)); ++ if (!p) return AVERROR(ENOMEM); - pix_fmts[0] = ctx->sw_format; +- pix_fmts[1] = AV_PIX_FMT_NONE; + // **** Offer native sand too ???? -+ pix_fmts[0] = ++ *p++ = +#if CONFIG_SAND + ctx->sw_format == AV_PIX_FMT_RPI4_8 || ctx->sw_format == AV_PIX_FMT_SAND128 ? + AV_PIX_FMT_YUV420P : @@ -63617,10 +66545,19 @@ index 7a9fdbd263..2a498f9b50 100644 + AV_PIX_FMT_YUV420P10LE : +#endif + ctx->sw_format; - pix_fmts[1] = AV_PIX_FMT_NONE; ++ ++#if CONFIG_SAND ++ if (ctx->sw_format == AV_PIX_FMT_RPI4_10 || ++ ctx->sw_format == AV_PIX_FMT_RPI4_8 || ctx->sw_format == AV_PIX_FMT_SAND128) ++ *p++ = AV_PIX_FMT_NV12; ++#endif - *formats = pix_fmts; -@@ -231,18 +267,80 @@ static int drm_transfer_data_from(AVHWFramesContext *hwfc, +- *formats = pix_fmts; ++ *p = AV_PIX_FMT_NONE; + return 0; + } + +@@ -231,18 +272,63 @@ static int drm_transfer_data_from(AVHWFramesContext *hwfc, map = av_frame_alloc(); if (!map) return AVERROR(ENOMEM); @@ -63655,29 +66592,12 @@ index 7a9fdbd263..2a498f9b50 100644 + const unsigned int w = FFMIN(dst->width, map->width); + const unsigned int h = FFMIN(dst->height, map->height); + -+ if (map->format == AV_PIX_FMT_RPI4_8 && dst->format == AV_PIX_FMT_YUV420P) { -+ av_rpi_sand_to_planar_y8(dst->data[0], dst->linesize[0], -+ map->data[0], -+ 128, stride2, -+ 0, 0, w, h); -+ av_rpi_sand_to_planar_c8(dst->data[1], dst->linesize[1], -+ dst->data[2], dst->linesize[2], -+ map->data[1], -+ 128, stride2, -+ 0, 0, w / 2, h / 2); -+ } -+ else if (map->format == AV_PIX_FMT_RPI4_10 && dst->format == AV_PIX_FMT_YUV420P10LE) { -+ av_rpi_sand30_to_planar_y16(dst->data[0], dst->linesize[0], -+ map->data[0], -+ 128, stride2, -+ 0, 0, w, h); -+ av_rpi_sand30_to_planar_c16(dst->data[1], dst->linesize[1], -+ dst->data[2], dst->linesize[2], -+ map->data[1], -+ 128, stride2, -+ 0, 0, w / 2, h / 2); -+ } -+ else ++ map->crop_top = 0; ++ map->crop_bottom = 0; ++ map->crop_left = 0; ++ map->crop_right = 0; ++ ++ if (av_rpi_sand_to_planar_frame(dst, map) != 0) + { + av_log(hwfc, AV_LOG_ERROR, "%s: Incompatible output pixfmt for sand\n", __func__); + err = AVERROR(EINVAL); @@ -63705,7 +66625,7 @@ index 7a9fdbd263..2a498f9b50 100644 err = 0; fail: -@@ -257,7 +355,10 @@ static int drm_transfer_data_to(AVHWFramesContext *hwfc, +@@ -257,7 +343,10 @@ static int drm_transfer_data_to(AVHWFramesContext *hwfc, int err; if (src->width > hwfc->width || src->height > hwfc->height) @@ -63717,10 +66637,10 @@ index 7a9fdbd263..2a498f9b50 100644 map = av_frame_alloc(); if (!map) diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c -index 18c7a0efc8..cada39e92f 100644 +index 18c7a0efc8..bab13a4d50 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c -@@ -2395,6 +2395,38 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { +@@ -2395,6 +2395,50 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { .name = "vulkan", .flags = AV_PIX_FMT_FLAG_HWACCEL, }, @@ -63748,12 +66668,24 @@ index 18c7a0efc8..cada39e92f 100644 + }, + .flags = 0, + }, ++ [AV_PIX_FMT_SAND64_16] = { ++ .name = "sand64_16", ++ .nb_components = 3, ++ .log2_chroma_w = 1, ++ .log2_chroma_h = 1, ++ .comp = { ++ { 0, 2, 0, 0, 16, 0, 15, 1 }, /* Y */ ++ { 1, 4, 0, 0, 16, 3, 15, 1 }, /* U */ ++ { 1, 4, 2, 0, 16, 3, 15, 3 }, /* V */ ++ }, ++ .flags = 0, ++ }, + [AV_PIX_FMT_RPI4_8] = { -+ .name = "rpi", ++ .name = "rpi4_8", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, + [AV_PIX_FMT_RPI4_10] = { -+ .name = "rpi", ++ .name = "rpi4_10", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, }; @@ -64011,10 +66943,10 @@ index 0000000000..0d5d203dc3 + diff --git a/libavutil/rpi_sand_fns.c b/libavutil/rpi_sand_fns.c new file mode 100644 -index 0000000000..1f543e9357 +index 0000000000..b6071e2928 --- /dev/null +++ b/libavutil/rpi_sand_fns.c -@@ -0,0 +1,356 @@ +@@ -0,0 +1,445 @@ +/* +Copyright (c) 2018 Raspberry Pi (Trading) Ltd. +All rights reserved. @@ -64246,6 +67178,75 @@ index 0000000000..1f543e9357 + } +} + ++// Fetches a single patch - offscreen fixup not done here ++// w <= stride1 ++// single lose bottom 2 bits truncation ++// _x & _w in pixels, strides in bytes ++void av_rpi_sand30_to_planar_y8(uint8_t * dst, const unsigned int dst_stride, ++ const uint8_t * src, ++ unsigned int stride1, unsigned int stride2, ++ unsigned int _x, unsigned int y, ++ unsigned int _w, unsigned int h) ++{ ++ const unsigned int x0 = (_x / 3) * 4; // Byte offset of the word ++ const unsigned int xskip0 = _x - (x0 >> 2) * 3; ++ const unsigned int x1 = ((_x + _w) / 3) * 4; ++ const unsigned int xrem1 = _x + _w - (x1 >> 2) * 3; ++ const unsigned int mask = stride1 - 1; ++ const uint8_t * p0 = src + (x0 & mask) + y * stride1 + (x0 & ~mask) * stride2; ++ const unsigned int slice_inc = ((stride2 - 1) * stride1) >> 2; // RHS of a stripe to LHS of next in words ++ ++#if HAVE_SAND_ASM ++ if (_x == 0) { ++ ff_rpi_sand30_lines_to_planar_y8(dst, dst_stride, src, stride1, stride2, _x, y, _w, h); ++ return; ++ } ++#endif ++ ++ if (x0 == x1) { ++ // ******************* ++ // Partial single word xfer ++ return; ++ } ++ ++ for (unsigned int i = 0; i != h; ++i, dst += dst_stride, p0 += stride1) ++ { ++ unsigned int x = x0; ++ const uint32_t * p = (const uint32_t *)p0; ++ uint8_t * d = dst; ++ ++ if (xskip0 != 0) { ++ const uint32_t p3 = *p++; ++ ++ if (xskip0 == 1) ++ *d++ = (p3 >> 12) & 0xff; ++ *d++ = (p3 >> 22) & 0xff; ++ ++ if (((x += 4) & mask) == 0) ++ p += slice_inc; ++ } ++ ++ while (x != x1) { ++ const uint32_t p3 = *p++; ++ *d++ = (p3 >> 2) & 0xff; ++ *d++ = (p3 >> 12) & 0xff; ++ *d++ = (p3 >> 22) & 0xff; ++ ++ if (((x += 4) & mask) == 0) ++ p += slice_inc; ++ } ++ ++ if (xrem1 != 0) { ++ const uint32_t p3 = *p; ++ ++ *d++ = (p3 >> 2) & 0xff; ++ if (xrem1 == 2) ++ *d++ = (p3 >> 12) & 0xff; ++ } ++ } ++} ++ ++ + +// w/h in pixels +void av_rpi_sand16_to_sand8(uint8_t * dst, const unsigned int dst_stride1, const unsigned int dst_stride2, @@ -64327,6 +67328,16 @@ index 0000000000..1f543e9357 + av_rpi_sand_frame_stride1(src), av_rpi_sand_frame_stride2(src), + x/2, y/2, w/2, h/2); + break; ++ case AV_PIX_FMT_NV12: ++ av_rpi_sand_to_planar_y8(dst->data[0], dst->linesize[0], ++ src->data[0], ++ av_rpi_sand_frame_stride1(src), av_rpi_sand_frame_stride2(src), ++ x, y, w, h); ++ av_rpi_sand_to_planar_y8(dst->data[1], dst->linesize[1], ++ src->data[1], ++ av_rpi_sand_frame_stride1(src), av_rpi_sand_frame_stride2(src), ++ x/2, y/2, w, h/2); ++ break; + default: + return -1; + } @@ -64361,6 +67372,16 @@ index 0000000000..1f543e9357 + av_rpi_sand_frame_stride1(src), av_rpi_sand_frame_stride2(src), + x/2, y/2, w/2, h/2); + break; ++ case AV_PIX_FMT_NV12: ++ av_rpi_sand30_to_planar_y8(dst->data[0], dst->linesize[0], ++ src->data[0], ++ av_rpi_sand_frame_stride1(src), av_rpi_sand_frame_stride2(src), ++ x, y, w, h); ++ av_rpi_sand30_to_planar_y8(dst->data[1], dst->linesize[1], ++ src->data[1], ++ av_rpi_sand_frame_stride1(src), av_rpi_sand_frame_stride2(src), ++ x/2, y/2, w, h/2); ++ break; + default: + return -1; + } @@ -64373,10 +67394,10 @@ index 0000000000..1f543e9357 +} diff --git a/libavutil/rpi_sand_fns.h b/libavutil/rpi_sand_fns.h new file mode 100644 -index 0000000000..634b55e800 +index 0000000000..462ccb8abd --- /dev/null +++ b/libavutil/rpi_sand_fns.h -@@ -0,0 +1,183 @@ +@@ -0,0 +1,188 @@ +/* +Copyright (c) 2018 Raspberry Pi (Trading) Ltd. +All rights reserved. @@ -64464,6 +67485,11 @@ index 0000000000..634b55e800 + unsigned int _x, unsigned int y, + unsigned int _w, unsigned int h); + ++void av_rpi_sand30_to_planar_y8(uint8_t * dst, const unsigned int dst_stride, ++ const uint8_t * src, ++ unsigned int stride1, unsigned int stride2, ++ unsigned int _x, unsigned int y, ++ unsigned int _w, unsigned int h); + +// w/h in pixels +void av_rpi_sand16_to_sand8(uint8_t * dst, const unsigned int dst_stride1, const unsigned int dst_stride2, @@ -66194,3 +69220,644 @@ index 0000000000..5935a11ca5 + + do_logparse(args.logfile) + +diff --git a/tests/checkasm/Makefile b/tests/checkasm/Makefile +index 1827a4e134..08da4166ef 100644 +--- a/tests/checkasm/Makefile ++++ b/tests/checkasm/Makefile +@@ -9,8 +9,10 @@ AVCODECOBJS-$(CONFIG_G722DSP) += g722dsp.o + AVCODECOBJS-$(CONFIG_H264DSP) += h264dsp.o + AVCODECOBJS-$(CONFIG_H264PRED) += h264pred.o + AVCODECOBJS-$(CONFIG_H264QPEL) += h264qpel.o ++AVCODECOBJS-$(CONFIG_IDCTDSP) += idctdsp.o + AVCODECOBJS-$(CONFIG_LLVIDDSP) += llviddsp.o + AVCODECOBJS-$(CONFIG_LLVIDENCDSP) += llviddspenc.o ++AVCODECOBJS-$(CONFIG_VC1DSP) += vc1dsp.o + AVCODECOBJS-$(CONFIG_VP8DSP) += vp8dsp.o + AVCODECOBJS-$(CONFIG_VIDEODSP) += videodsp.o + +diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c +index 8338e8ff58..81ef182f04 100644 +--- a/tests/checkasm/checkasm.c ++++ b/tests/checkasm/checkasm.c +@@ -131,6 +131,9 @@ static const struct { + #if CONFIG_HUFFYUV_DECODER + { "huffyuvdsp", checkasm_check_huffyuvdsp }, + #endif ++ #if CONFIG_IDCTDSP ++ { "idctdsp", checkasm_check_idctdsp }, ++ #endif + #if CONFIG_JPEG2000_DECODER + { "jpeg2000dsp", checkasm_check_jpeg2000dsp }, + #endif +@@ -155,6 +158,9 @@ static const struct { + #if CONFIG_V210_ENCODER + { "v210enc", checkasm_check_v210enc }, + #endif ++ #if CONFIG_VC1DSP ++ { "vc1dsp", checkasm_check_vc1dsp }, ++ #endif + #if CONFIG_VP8DSP + { "vp8dsp", checkasm_check_vp8dsp }, + #endif +diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h +index ef6645e3a2..1a1e17d835 100644 +--- a/tests/checkasm/checkasm.h ++++ b/tests/checkasm/checkasm.h +@@ -70,6 +70,7 @@ void checkasm_check_hevc_epel_bi(void); + void checkasm_check_hevc_epel_bi_w(void); + void checkasm_check_hevc_sao(void); + void checkasm_check_huffyuvdsp(void); ++void checkasm_check_idctdsp(void); + void checkasm_check_jpeg2000dsp(void); + void checkasm_check_llviddsp(void); + void checkasm_check_llviddspenc(void); +@@ -83,6 +84,7 @@ void checkasm_check_sw_scale(void); + void checkasm_check_utvideodsp(void); + void checkasm_check_v210dec(void); + void checkasm_check_v210enc(void); ++void checkasm_check_vc1dsp(void); + void checkasm_check_vf_eq(void); + void checkasm_check_vf_gblur(void); + void checkasm_check_vf_hflip(void); +diff --git a/tests/checkasm/idctdsp.c b/tests/checkasm/idctdsp.c +new file mode 100644 +index 0000000000..02724536a7 +--- /dev/null ++++ b/tests/checkasm/idctdsp.c +@@ -0,0 +1,98 @@ ++/* ++ * Copyright (c) 2022 Ben Avison ++ * ++ * This file is part of FFmpeg. ++ * ++ * FFmpeg is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * FFmpeg is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with FFmpeg; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#include ++ ++#include "checkasm.h" ++ ++#include "libavcodec/idctdsp.h" ++ ++#include "libavutil/common.h" ++#include "libavutil/internal.h" ++#include "libavutil/intreadwrite.h" ++#include "libavutil/mem_internal.h" ++ ++#define IDCTDSP_TEST(func) { #func, offsetof(IDCTDSPContext, func) }, ++ ++typedef struct { ++ const char *name; ++ size_t offset; ++} test; ++ ++#define RANDOMIZE_BUFFER16(name, size) \ ++ do { \ ++ int i; \ ++ for (i = 0; i < size; ++i) { \ ++ uint16_t r = rnd() % 0x201 - 0x100; \ ++ AV_WN16A(name##0 + i, r); \ ++ AV_WN16A(name##1 + i, r); \ ++ } \ ++ } while (0) ++ ++#define RANDOMIZE_BUFFER8(name, size) \ ++ do { \ ++ int i; \ ++ for (i = 0; i < size; ++i) { \ ++ uint8_t r = rnd(); \ ++ name##0[i] = r; \ ++ name##1[i] = r; \ ++ } \ ++ } while (0) ++ ++static void check_add_put_clamped(void) ++{ ++ /* Source buffers are only as big as needed, since any over-read won't affect results */ ++ LOCAL_ALIGNED_16(int16_t, src0, [64]); ++ LOCAL_ALIGNED_16(int16_t, src1, [64]); ++ /* Destination buffers have borders of one row above/below and 8 columns left/right to catch overflows */ ++ LOCAL_ALIGNED_8(uint8_t, dst0, [10 * 24]); ++ LOCAL_ALIGNED_8(uint8_t, dst1, [10 * 24]); ++ ++ AVCodecContext avctx = { 0 }; ++ IDCTDSPContext h; ++ ++ const test tests[] = { ++ IDCTDSP_TEST(add_pixels_clamped) ++ IDCTDSP_TEST(put_pixels_clamped) ++ IDCTDSP_TEST(put_signed_pixels_clamped) ++ }; ++ ++ ff_idctdsp_init(&h, &avctx); ++ ++ for (size_t t = 0; t < FF_ARRAY_ELEMS(tests); ++t) { ++ void (*func)(const int16_t *, uint8_t * ptrdiff_t) = *(void **)((intptr_t) &h + tests[t].offset); ++ if (check_func(func, "idctdsp.%s", tests[t].name)) { ++ declare_func_emms(AV_CPU_FLAG_MMX, void, const int16_t *, uint8_t *, ptrdiff_t); ++ RANDOMIZE_BUFFER16(src, 64); ++ RANDOMIZE_BUFFER8(dst, 10 * 24); ++ call_ref(src0, dst0 + 24 + 8, 24); ++ call_new(src1, dst1 + 24 + 8, 24); ++ if (memcmp(dst0, dst1, 10 * 24)) ++ fail(); ++ bench_new(src1, dst1 + 24 + 8, 24); ++ } ++ } ++} ++ ++void checkasm_check_idctdsp(void) ++{ ++ check_add_put_clamped(); ++ report("idctdsp"); ++} +diff --git a/tests/checkasm/vc1dsp.c b/tests/checkasm/vc1dsp.c +new file mode 100644 +index 0000000000..52628d15e4 +--- /dev/null ++++ b/tests/checkasm/vc1dsp.c +@@ -0,0 +1,452 @@ ++/* ++ * Copyright (c) 2022 Ben Avison ++ * ++ * This file is part of FFmpeg. ++ * ++ * FFmpeg is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * FFmpeg is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with FFmpeg; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#include ++ ++#include "checkasm.h" ++ ++#include "libavcodec/vc1dsp.h" ++ ++#include "libavutil/common.h" ++#include "libavutil/internal.h" ++#include "libavutil/intreadwrite.h" ++#include "libavutil/mem_internal.h" ++ ++#define VC1DSP_TEST(func) { #func, offsetof(VC1DSPContext, func) }, ++#define VC1DSP_SIZED_TEST(func, width, height) { #func, offsetof(VC1DSPContext, func), width, height }, ++ ++typedef struct { ++ const char *name; ++ size_t offset; ++ int width; ++ int height; ++} test; ++ ++typedef struct matrix { ++ size_t width; ++ size_t height; ++ float d[]; ++} matrix; ++ ++static const matrix T8 = { 8, 8, { ++ 12, 12, 12, 12, 12, 12, 12, 12, ++ 16, 15, 9, 4, -4, -9, -15, -16, ++ 16, 6, -6, -16, -16, -6, 6, 16, ++ 15, -4, -16, -9, 9, 16, 4, -15, ++ 12, -12, -12, 12, 12, -12, -12, 12, ++ 9, -16, 4, 15, -15, -4, 16, -9, ++ 6, -16, 16, -6, -6, 16, -16, 6, ++ 4, -9, 15, -16, 16, -15, 9, -4 ++} }; ++ ++static const matrix T4 = { 4, 4, { ++ 17, 17, 17, 17, ++ 22, 10, -10, -22, ++ 17, -17, -17, 17, ++ 10, -22, 22, -10 ++} }; ++ ++static const matrix T8t = { 8, 8, { ++ 12, 16, 16, 15, 12, 9, 6, 4, ++ 12, 15, 6, -4, -12, -16, -16, -9, ++ 12, 9, -6, -16, -12, 4, 16, 15, ++ 12, 4, -16, -9, 12, 15, -6, -16, ++ 12, -4, -16, 9, 12, -15, -6, 16, ++ 12, -9, -6, 16, -12, -4, 16, -15, ++ 12, -15, 6, 4, -12, 16, -16, 9, ++ 12, -16, 16, -15, 12, -9, 6, -4 ++} }; ++ ++static const matrix T4t = { 4, 4, { ++ 17, 22, 17, 10, ++ 17, 10, -17, -22, ++ 17, -10, -17, 22, ++ 17, -22, 17, -10 ++} }; ++ ++static matrix *new_matrix(size_t width, size_t height) ++{ ++ matrix *out = av_mallocz(sizeof (matrix) + height * width * sizeof (float)); ++ if (out == NULL) { ++ fprintf(stderr, "Memory allocation failure\n"); ++ exit(EXIT_FAILURE); ++ } ++ out->width = width; ++ out->height = height; ++ return out; ++} ++ ++static matrix *multiply(const matrix *a, const matrix *b) ++{ ++ matrix *out; ++ if (a->width != b->height) { ++ fprintf(stderr, "Incompatible multiplication\n"); ++ exit(EXIT_FAILURE); ++ } ++ out = new_matrix(b->width, a->height); ++ for (int j = 0; j < out->height; ++j) ++ for (int i = 0; i < out->width; ++i) { ++ float sum = 0; ++ for (int k = 0; k < a->width; ++k) ++ sum += a->d[j * a->width + k] * b->d[k * b->width + i]; ++ out->d[j * out->width + i] = sum; ++ } ++ return out; ++} ++ ++static void normalise(matrix *a) ++{ ++ for (int j = 0; j < a->height; ++j) ++ for (int i = 0; i < a->width; ++i) { ++ float *p = a->d + j * a->width + i; ++ *p *= 64; ++ if (a->height == 4) ++ *p /= (const unsigned[]) { 289, 292, 289, 292 } [j]; ++ else ++ *p /= (const unsigned[]) { 288, 289, 292, 289, 288, 289, 292, 289 } [j]; ++ if (a->width == 4) ++ *p /= (const unsigned[]) { 289, 292, 289, 292 } [i]; ++ else ++ *p /= (const unsigned[]) { 288, 289, 292, 289, 288, 289, 292, 289 } [i]; ++ } ++} ++ ++static void divide_and_round_nearest(matrix *a, float by) ++{ ++ for (int j = 0; j < a->height; ++j) ++ for (int i = 0; i < a->width; ++i) { ++ float *p = a->d + j * a->width + i; ++ *p = rintf(*p / by); ++ } ++} ++ ++static void tweak(matrix *a) ++{ ++ for (int j = 4; j < a->height; ++j) ++ for (int i = 0; i < a->width; ++i) { ++ float *p = a->d + j * a->width + i; ++ *p += 1; ++ } ++} ++ ++/* The VC-1 spec places restrictions on the values permitted at three ++ * different stages: ++ * - D: the input coefficients in frequency domain ++ * - E: the intermediate coefficients, inverse-transformed only horizontally ++ * - R: the fully inverse-transformed coefficients ++ * ++ * To fully cater for the ranges specified requires various intermediate ++ * values to be held to 17-bit precision; yet these conditions do not appear ++ * to be utilised in real-world streams. At least some assembly ++ * implementations have chosen to restrict these values to 16-bit precision, ++ * to accelerate the decoding of real-world streams at the cost of strict ++ * adherence to the spec. To avoid our test marking these as failures, ++ * reduce our random inputs. ++ */ ++#define ATTENUATION 4 ++ ++static matrix *generate_inverse_quantized_transform_coefficients(size_t width, size_t height) ++{ ++ matrix *raw, *tmp, *D, *E, *R; ++ raw = new_matrix(width, height); ++ for (int i = 0; i < width * height; ++i) ++ raw->d[i] = (int) (rnd() % (1024/ATTENUATION)) - 512/ATTENUATION; ++ tmp = multiply(height == 8 ? &T8 : &T4, raw); ++ D = multiply(tmp, width == 8 ? &T8t : &T4t); ++ normalise(D); ++ divide_and_round_nearest(D, 1); ++ for (int i = 0; i < width * height; ++i) { ++ if (D->d[i] < -2048/ATTENUATION || D->d[i] > 2048/ATTENUATION-1) { ++ /* Rare, so simply try again */ ++ av_free(raw); ++ av_free(tmp); ++ av_free(D); ++ return generate_inverse_quantized_transform_coefficients(width, height); ++ } ++ } ++ E = multiply(D, width == 8 ? &T8 : &T4); ++ divide_and_round_nearest(E, 8); ++ for (int i = 0; i < width * height; ++i) ++ if (E->d[i] < -4096/ATTENUATION || E->d[i] > 4096/ATTENUATION-1) { ++ /* Rare, so simply try again */ ++ av_free(raw); ++ av_free(tmp); ++ av_free(D); ++ av_free(E); ++ return generate_inverse_quantized_transform_coefficients(width, height); ++ } ++ R = multiply(height == 8 ? &T8t : &T4t, E); ++ tweak(R); ++ divide_and_round_nearest(R, 128); ++ for (int i = 0; i < width * height; ++i) ++ if (R->d[i] < -512/ATTENUATION || R->d[i] > 512/ATTENUATION-1) { ++ /* Rare, so simply try again */ ++ av_free(raw); ++ av_free(tmp); ++ av_free(D); ++ av_free(E); ++ av_free(R); ++ return generate_inverse_quantized_transform_coefficients(width, height); ++ } ++ av_free(raw); ++ av_free(tmp); ++ av_free(E); ++ av_free(R); ++ return D; ++} ++ ++#define RANDOMIZE_BUFFER16(name, size) \ ++ do { \ ++ int i; \ ++ for (i = 0; i < size; ++i) { \ ++ uint16_t r = rnd(); \ ++ AV_WN16A(name##0 + i, r); \ ++ AV_WN16A(name##1 + i, r); \ ++ } \ ++ } while (0) ++ ++#define RANDOMIZE_BUFFER8(name, size) \ ++ do { \ ++ int i; \ ++ for (i = 0; i < size; ++i) { \ ++ uint8_t r = rnd(); \ ++ name##0[i] = r; \ ++ name##1[i] = r; \ ++ } \ ++ } while (0) ++ ++#define RANDOMIZE_BUFFER8_MID_WEIGHTED(name, size) \ ++ do { \ ++ uint8_t *p##0 = name##0, *p##1 = name##1; \ ++ int i = (size); \ ++ while (i-- > 0) { \ ++ int x = 0x80 | (rnd() & 0x7F); \ ++ x >>= rnd() % 9; \ ++ if (rnd() & 1) \ ++ x = -x; \ ++ *p##1++ = *p##0++ = 0x80 + x; \ ++ } \ ++ } while (0) ++ ++static void check_inv_trans_inplace(void) ++{ ++ /* Inverse transform input coefficients are stored in a 16-bit buffer ++ * with row stride of 8 coefficients irrespective of transform size. ++ * vc1_inv_trans_8x8 differs from the others in two ways: coefficients ++ * are stored in column-major order, and the outputs are written back ++ * to the input buffer, so we oversize it slightly to catch overruns. */ ++ LOCAL_ALIGNED_16(int16_t, inv_trans_in0, [10 * 8]); ++ LOCAL_ALIGNED_16(int16_t, inv_trans_in1, [10 * 8]); ++ ++ VC1DSPContext h; ++ ++ ff_vc1dsp_init(&h); ++ ++ if (check_func(h.vc1_inv_trans_8x8, "vc1dsp.vc1_inv_trans_8x8")) { ++ matrix *coeffs; ++ declare_func_emms(AV_CPU_FLAG_MMX, void, int16_t *); ++ RANDOMIZE_BUFFER16(inv_trans_in, 10 * 8); ++ coeffs = generate_inverse_quantized_transform_coefficients(8, 8); ++ for (int j = 0; j < 8; ++j) ++ for (int i = 0; i < 8; ++i) { ++ int idx = 8 + i * 8 + j; ++ inv_trans_in1[idx] = inv_trans_in0[idx] = coeffs->d[j * 8 + i]; ++ } ++ call_ref(inv_trans_in0 + 8); ++ call_new(inv_trans_in1 + 8); ++ if (memcmp(inv_trans_in0, inv_trans_in1, 10 * 8 * sizeof (int16_t))) ++ fail(); ++ bench_new(inv_trans_in1 + 8); ++ av_free(coeffs); ++ } ++} ++ ++static void check_inv_trans_adding(void) ++{ ++ /* Inverse transform input coefficients are stored in a 16-bit buffer ++ * with row stride of 8 coefficients irrespective of transform size. */ ++ LOCAL_ALIGNED_16(int16_t, inv_trans_in0, [8 * 8]); ++ LOCAL_ALIGNED_16(int16_t, inv_trans_in1, [8 * 8]); ++ ++ /* For all but vc1_inv_trans_8x8, the inverse transform is narrowed and ++ * added with saturation to an array of unsigned 8-bit values. Oversize ++ * this by 8 samples left and right and one row above and below. */ ++ LOCAL_ALIGNED_8(uint8_t, inv_trans_out0, [10 * 24]); ++ LOCAL_ALIGNED_8(uint8_t, inv_trans_out1, [10 * 24]); ++ ++ VC1DSPContext h; ++ ++ const test tests[] = { ++ VC1DSP_SIZED_TEST(vc1_inv_trans_8x4, 8, 4) ++ VC1DSP_SIZED_TEST(vc1_inv_trans_4x8, 4, 8) ++ VC1DSP_SIZED_TEST(vc1_inv_trans_4x4, 4, 4) ++ VC1DSP_SIZED_TEST(vc1_inv_trans_8x8_dc, 8, 8) ++ VC1DSP_SIZED_TEST(vc1_inv_trans_8x4_dc, 8, 4) ++ VC1DSP_SIZED_TEST(vc1_inv_trans_4x8_dc, 4, 8) ++ VC1DSP_SIZED_TEST(vc1_inv_trans_4x4_dc, 4, 4) ++ }; ++ ++ ff_vc1dsp_init(&h); ++ ++ for (size_t t = 0; t < FF_ARRAY_ELEMS(tests); ++t) { ++ void (*func)(uint8_t *, ptrdiff_t, int16_t *) = *(void **)((intptr_t) &h + tests[t].offset); ++ if (check_func(func, "vc1dsp.%s", tests[t].name)) { ++ matrix *coeffs; ++ declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *, ptrdiff_t, int16_t *); ++ RANDOMIZE_BUFFER16(inv_trans_in, 8 * 8); ++ RANDOMIZE_BUFFER8(inv_trans_out, 10 * 24); ++ coeffs = generate_inverse_quantized_transform_coefficients(tests[t].width, tests[t].height); ++ for (int j = 0; j < tests[t].height; ++j) ++ for (int i = 0; i < tests[t].width; ++i) { ++ int idx = j * 8 + i; ++ inv_trans_in1[idx] = inv_trans_in0[idx] = coeffs->d[j * tests[t].width + i]; ++ } ++ call_ref(inv_trans_out0 + 24 + 8, 24, inv_trans_in0); ++ call_new(inv_trans_out1 + 24 + 8, 24, inv_trans_in1); ++ if (memcmp(inv_trans_out0, inv_trans_out1, 10 * 24)) ++ fail(); ++ bench_new(inv_trans_out1 + 24 + 8, 24, inv_trans_in1 + 8); ++ av_free(coeffs); ++ } ++ } ++} ++ ++static void check_loop_filter(void) ++{ ++ /* Deblocking filter buffers are big enough to hold a 16x16 block, ++ * plus 16 columns left and 4 rows above to hold filter inputs ++ * (depending on whether v or h neighbouring block edge, oversized ++ * horizontally to maintain 16-byte alignment) plus 16 columns and ++ * 4 rows below to catch write overflows */ ++ LOCAL_ALIGNED_16(uint8_t, filter_buf0, [24 * 48]); ++ LOCAL_ALIGNED_16(uint8_t, filter_buf1, [24 * 48]); ++ ++ VC1DSPContext h; ++ ++ const test tests[] = { ++ VC1DSP_TEST(vc1_v_loop_filter4) ++ VC1DSP_TEST(vc1_h_loop_filter4) ++ VC1DSP_TEST(vc1_v_loop_filter8) ++ VC1DSP_TEST(vc1_h_loop_filter8) ++ VC1DSP_TEST(vc1_v_loop_filter16) ++ VC1DSP_TEST(vc1_h_loop_filter16) ++ }; ++ ++ ff_vc1dsp_init(&h); ++ ++ for (size_t t = 0; t < FF_ARRAY_ELEMS(tests); ++t) { ++ void (*func)(uint8_t *, ptrdiff_t, int) = *(void **)((intptr_t) &h + tests[t].offset); ++ declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *, ptrdiff_t, int); ++ if (check_func(func, "vc1dsp.%s", tests[t].name)) { ++ for (int count = 1000; count > 0; --count) { ++ int pq = rnd() % 31 + 1; ++ RANDOMIZE_BUFFER8_MID_WEIGHTED(filter_buf, 24 * 48); ++ call_ref(filter_buf0 + 4 * 48 + 16, 48, pq); ++ call_new(filter_buf1 + 4 * 48 + 16, 48, pq); ++ if (memcmp(filter_buf0, filter_buf1, 24 * 48)) ++ fail(); ++ } ++ } ++ for (int j = 0; j < 24; ++j) ++ for (int i = 0; i < 48; ++i) ++ filter_buf1[j * 48 + i] = 0x60 + 0x40 * (i >= 16 && j >= 4); ++ if (check_func(func, "vc1dsp.%s_bestcase", tests[t].name)) ++ bench_new(filter_buf1 + 4 * 48 + 16, 48, 1); ++ if (check_func(func, "vc1dsp.%s_worstcase", tests[t].name)) ++ bench_new(filter_buf1 + 4 * 48 + 16, 48, 31); ++ } ++} ++ ++#define TEST_UNESCAPE \ ++ do { \ ++ for (int count = 100; count > 0; --count) { \ ++ escaped_offset = rnd() & 7; \ ++ unescaped_offset = rnd() & 7; \ ++ escaped_len = (1u << (rnd() % 8) + 3) - (rnd() & 7); \ ++ RANDOMIZE_BUFFER8(unescaped, UNESCAPE_BUF_SIZE); \ ++ len0 = call_ref(escaped0 + escaped_offset, escaped_len, unescaped0 + unescaped_offset); \ ++ len1 = call_new(escaped1 + escaped_offset, escaped_len, unescaped1 + unescaped_offset); \ ++ if (len0 != len1 || memcmp(unescaped0, unescaped1, UNESCAPE_BUF_SIZE)) \ ++ fail(); \ ++ } \ ++ } while (0) ++ ++static void check_unescape(void) ++{ ++ /* This appears to be a typical length of buffer in use */ ++#define LOG2_UNESCAPE_BUF_SIZE 17 ++#define UNESCAPE_BUF_SIZE (1u< Date: Tue, 24 Apr 2018 23:00:23 -0700 Subject: [PATCH 1/9] libavcodec: v4l2m2m: output AVDRMFrameDescriptor @@ -421,7 +421,7 @@ index ab07c0a24a..6bc7442702 100644 } -From 9a2a361c2c84c8da54cd3a74b0d0bb966df8fe69 Mon Sep 17 00:00:00 2001 +From deb0ba531401f069dc6e4dcf235dfc08bca6577c Mon Sep 17 00:00:00 2001 From: Lukas Rusak Date: Thu, 16 Aug 2018 21:09:40 -0700 Subject: [PATCH 2/9] libavcodec: v4l2m2m: depends on libdrm @@ -432,10 +432,10 @@ Subject: [PATCH 2/9] libavcodec: v4l2m2m: depends on libdrm 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/configure b/configure -index d7a3f507e8..d203f6f7da 100755 +index 4ba72bf84b..efb065905c 100755 --- a/configure +++ b/configure -@@ -3437,6 +3437,7 @@ sndio_indev_deps="sndio" +@@ -3438,6 +3438,7 @@ sndio_indev_deps="sndio" sndio_outdev_deps="sndio" v4l2_indev_deps_any="linux_videodev2_h sys_videoio_h" v4l2_indev_suggest="libv4l2" @@ -457,7 +457,7 @@ index cbd3e5680d..bebe2c1796 100644 #include #include -From 7b0fa2d859c12a8a129c884d16673ca731336c06 Mon Sep 17 00:00:00 2001 +From f89fad11f53110cd6968c83e89bafb0c449f34ec Mon Sep 17 00:00:00 2001 From: Lukas Rusak Date: Thu, 16 Aug 2018 21:10:13 -0700 Subject: [PATCH 3/9] libavcodec: v4l2m2m: set format_modifier to @@ -485,7 +485,7 @@ index bebe2c1796..12037d5d66 100644 } -From e1857456c8f24e40d5c898886f2f51014e59ee9d Mon Sep 17 00:00:00 2001 +From d5a37af1a8fe1ed70428e55286126d241986dd0c Mon Sep 17 00:00:00 2001 From: Lukas Rusak Date: Thu, 16 Aug 2018 21:10:53 -0700 Subject: [PATCH 4/9] libavcodec: v4l2m2m: only mmap the buffer when it is @@ -529,7 +529,7 @@ index 12037d5d66..1adf518ab9 100644 if (avbuf->plane_info[i].mm_addr == MAP_FAILED) -From c8fc3ea1b5777546f7ec72a54b053a2d4fa9fd59 Mon Sep 17 00:00:00 2001 +From d0be699166cdc413a5dc3e1c087433ac7cf142e7 Mon Sep 17 00:00:00 2001 From: Lukas Rusak Date: Thu, 16 Aug 2018 21:11:38 -0700 Subject: [PATCH 5/9] libavcodec: v4l2m2m: allow using software pixel formats @@ -569,7 +569,7 @@ index 6bc7442702..4b9baf833c 100644 .hw_configs = v4l2_m2m_hw_configs, \ .wrapper_name = "v4l2m2m", \ -From 13f02e940f083f19dbe8b9ac8fc7df45700dd36e Mon Sep 17 00:00:00 2001 +From c4736742883eb2a1965ac65a5c75d5409e3c85a0 Mon Sep 17 00:00:00 2001 From: Lukas Rusak Date: Mon, 24 Sep 2018 13:39:31 -0700 Subject: [PATCH 6/9] libavcodec: v4l2m2m: implement hwcontext @@ -677,7 +677,7 @@ index 4b9baf833c..6c23693137 100644 ret = ff_v4l2_m2m_codec_init(priv); if (ret) { -From 34be198b8039c9df434792f19f0985e45419407e Mon Sep 17 00:00:00 2001 +From 0b15c77718900bf60c91217ed1492390022ad6db Mon Sep 17 00:00:00 2001 From: Lukas Rusak Date: Mon, 4 May 2020 13:01:29 -0700 Subject: [PATCH 7/9] libavcodec: v4l2m2m: allow lower minimum buffer values @@ -718,7 +718,7 @@ index 6c23693137..e323c37052 100644 }; -From 2956fd1881d28abf6bf77bd9a57866c4ba81d199 Mon Sep 17 00:00:00 2001 +From acc86933e5fe3a13aae44cf84c48bab6c717e49b Mon Sep 17 00:00:00 2001 From: Lukas Rusak Date: Wed, 6 May 2020 11:12:58 -0700 Subject: [PATCH 8/9] libavcodec: v4l2m2m: add option to specify pixel format @@ -790,7 +790,7 @@ index e323c37052..363e998142 100644 }; -From 2bb6d0cb244590f0c70dd111ed978cd87fa3bee1 Mon Sep 17 00:00:00 2001 +From 909ca6380d9112cc0111266da02a4a8e1e5abc1e Mon Sep 17 00:00:00 2001 From: Lukas Rusak Date: Mon, 24 Sep 2018 13:39:56 -0700 Subject: [PATCH 9/9] libavcodec: v4l2m2m: implement flush diff --git a/packages/multimedia/ffmpeg/patches/v4l2-request/ffmpeg-001-v4l2-request.patch b/packages/multimedia/ffmpeg/patches/v4l2-request/ffmpeg-001-v4l2-request.patch index 1c2a5ce74..6afdb2d73 100644 --- a/packages/multimedia/ffmpeg/patches/v4l2-request/ffmpeg-001-v4l2-request.patch +++ b/packages/multimedia/ffmpeg/patches/v4l2-request/ffmpeg-001-v4l2-request.patch @@ -1,7 +1,7 @@ -From 904af26693095364851bbc6c6557fca9b3437b69 Mon Sep 17 00:00:00 2001 +From 46ce980905101822ca824243635d10d660172570 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 3 Dec 2018 23:48:04 +0100 -Subject: [PATCH 01/17] avutil: add av_buffer_pool_flush() +Subject: [PATCH 01/12] avutil: add av_buffer_pool_flush() Used by V4L2 request API hwaccel @@ -12,7 +12,7 @@ Signed-off-by: Jonas Karlman 2 files changed, 18 insertions(+) diff --git a/libavutil/buffer.c b/libavutil/buffer.c -index 858633e8c73..41555d99825 100644 +index 858633e8c7..41555d9982 100644 --- a/libavutil/buffer.c +++ b/libavutil/buffer.c @@ -305,6 +305,19 @@ static void buffer_pool_free(AVBufferPool *pool) @@ -36,7 +36,7 @@ index 858633e8c73..41555d99825 100644 { AVBufferPool *pool; diff --git a/libavutil/buffer.h b/libavutil/buffer.h -index 241a80ed670..f41363faf1d 100644 +index 241a80ed67..f41363faf1 100644 --- a/libavutil/buffer.h +++ b/libavutil/buffer.h @@ -315,6 +315,11 @@ AVBufferPool *av_buffer_pool_init2(size_t size, void *opaque, @@ -52,24 +52,25 @@ index 241a80ed670..f41363faf1d 100644 * Mark the pool as being available for freeing. It will actually be freed only * once all the allocated buffers associated with the pool are released. Thus it -From ec84dc22e99f544e4de7c43e7f8ef9ab7ee8e19b Mon Sep 17 00:00:00 2001 +From 6f3b6c4d442a9a3322305e5600ce7f84af5971cc Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sat, 15 Dec 2018 22:32:16 +0100 -Subject: [PATCH 02/17] Add common V4L2 request API code +Subject: [PATCH 02/12] Add common V4L2 request API code Signed-off-by: Jonas Karlman +Signed-off-by: Alex Bee --- - configure | 12 + - libavcodec/Makefile | 1 + - libavcodec/hwconfig.h | 2 + - libavcodec/v4l2_request.c | 984 ++++++++++++++++++++++++++++++++++++++ - libavcodec/v4l2_request.h | 77 +++ - 5 files changed, 1076 insertions(+) + configure | 12 + + libavcodec/Makefile | 1 + + libavcodec/hwconfig.h | 2 + + libavcodec/v4l2_request.c | 1027 +++++++++++++++++++++++++++++++++++++ + libavcodec/v4l2_request.h | 77 +++ + 5 files changed, 1119 insertions(+) create mode 100644 libavcodec/v4l2_request.c create mode 100644 libavcodec/v4l2_request.h diff --git a/configure b/configure -index d7a3f507e83..f2e203d1346 100755 +index 4ba72bf84b..4a3a5ae9e0 100755 --- a/configure +++ b/configure @@ -279,6 +279,7 @@ External library support: @@ -104,7 +105,7 @@ index d7a3f507e83..f2e203d1346 100755 vulkan " -@@ -2919,6 +2923,7 @@ d3d11va_deps="dxva_h ID3D11VideoDecoder ID3D11VideoContext" +@@ -2920,6 +2924,7 @@ d3d11va_deps="dxva_h ID3D11VideoDecoder ID3D11VideoContext" dxva2_deps="dxva2api_h DXVA2_ConfigPictureDecode ole32 user32" ffnvcodec_deps_any="libdl LoadLibrary" nvdec_deps="ffnvcodec" @@ -112,7 +113,7 @@ index d7a3f507e83..f2e203d1346 100755 vaapi_x11_deps="xlib" videotoolbox_hwaccel_deps="videotoolbox pthreads" videotoolbox_hwaccel_extralibs="-framework QuartzCore" -@@ -6438,6 +6443,7 @@ enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame +@@ -6439,6 +6444,7 @@ enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame { check_lib libtwolame twolame.h twolame_encode_buffer_float32_interleaved -ltwolame || die "ERROR: libtwolame must be installed and version must be >= 0.3.10"; } enabled libuavs3d && require_pkg_config libuavs3d "uavs3d >= 1.1.41" uavs3d.h uavs3d_decode @@ -120,7 +121,7 @@ index d7a3f507e83..f2e203d1346 100755 enabled libv4l2 && require_pkg_config libv4l2 libv4l2 libv4l2.h v4l2_ioctl enabled libvidstab && require_pkg_config libvidstab "vidstab >= 0.98" vid.stab/libvidstab.h vsMotionDetectInit enabled libvmaf && require_pkg_config libvmaf "libvmaf >= 1.5.2" libvmaf.h compute_vmaf -@@ -6536,6 +6542,10 @@ enabled rkmpp && { require_pkg_config rkmpp rockchip_mpp rockchip/r +@@ -6537,6 +6543,10 @@ enabled rkmpp && { require_pkg_config rkmpp rockchip_mpp rockchip/r { enabled libdrm || die "ERROR: rkmpp requires --enable-libdrm"; } } @@ -131,7 +132,7 @@ index d7a3f507e83..f2e203d1346 100755 enabled vapoursynth && require_pkg_config vapoursynth "vapoursynth-script >= 42" VSScript.h vsscript_init -@@ -6617,6 +6627,8 @@ if enabled v4l2_m2m; then +@@ -6618,6 +6628,8 @@ if enabled v4l2_m2m; then check_cc vp9_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VP9;" fi @@ -141,7 +142,7 @@ index d7a3f507e83..f2e203d1346 100755 test_code cc sys/videoio.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_sanitized struct_v4l2_frmivalenum_discrete diff --git a/libavcodec/Makefile b/libavcodec/Makefile -index 33a280cf695..90dfffcb200 100644 +index 33a280cf69..90dfffcb20 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -155,6 +155,7 @@ OBJS-$(CONFIG_VP3DSP) += vp3dsp.o @@ -153,7 +154,7 @@ index 33a280cf695..90dfffcb200 100644 OBJS-$(CONFIG_WMV2DSP) += wmv2dsp.o diff --git a/libavcodec/hwconfig.h b/libavcodec/hwconfig.h -index f421dc909f4..ee78d8ab8e8 100644 +index f421dc909f..ee78d8ab8e 100644 --- a/libavcodec/hwconfig.h +++ b/libavcodec/hwconfig.h @@ -80,6 +80,8 @@ typedef struct AVCodecHWConfigInternal { @@ -167,10 +168,10 @@ index f421dc909f4..ee78d8ab8e8 100644 &(const AVCodecHWConfigInternal) { \ diff --git a/libavcodec/v4l2_request.c b/libavcodec/v4l2_request.c new file mode 100644 -index 00000000000..5234b5049b0 +index 0000000000..b57bbf29bc --- /dev/null +++ b/libavcodec/v4l2_request.c -@@ -0,0 +1,984 @@ +@@ -0,0 +1,1027 @@ +/* + * This file is part of FFmpeg. + * @@ -518,6 +519,42 @@ index 00000000000..5234b5049b0 + return v4l2_request_queue_decode(avctx, frame, control, count, 1, 1); +} + ++static int v4l2_request_try_framesize(AVCodecContext *avctx, uint32_t pixelformat) ++{ ++ V4L2RequestContext *ctx = avctx->internal->hwaccel_priv_data; ++ struct v4l2_frmsizeenum frmsize = { ++ .index = 0, ++ .pixel_format = pixelformat, ++ }; ++ ++ if (ioctl(ctx->video_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) < 0) ++ return 0; ++ ++ /* ++ * We only validate min/max framesize for V4L2_FRMSIZE_TYPE_STEPWISE here, since the alignment ++ * which is eventually needed will be done driver-side later in VIDIOC_S_FMT and there is no need ++ * validate step_width/step_height here ++ */ ++ ++ do { ++ ++ if (frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE && frmsize.discrete.width == avctx->coded_width && ++ frmsize.discrete.height == avctx->coded_height) ++ return 0; ++ else if ((frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE || frmsize.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) && ++ avctx->coded_width >= frmsize.stepwise.min_width && avctx->coded_height >= frmsize.stepwise.min_height && ++ avctx->coded_width <= frmsize.stepwise.max_width && avctx->coded_height <= frmsize.stepwise.max_height) ++ return 0; ++ ++ frmsize.index++; ++ ++ } while (ioctl(ctx->video_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) >= 0); ++ ++ av_log(avctx, AV_LOG_INFO, "%s: pixelformat %u not supported for width %u height %u\n", __func__, pixelformat, avctx->coded_width, avctx->coded_height); ++ ++ return -1; ++} ++ +static int v4l2_request_try_format(AVCodecContext *avctx, enum v4l2_buf_type type, uint32_t pixelformat) +{ + V4L2RequestContext *ctx = avctx->internal->hwaccel_priv_data; @@ -685,6 +722,13 @@ index 00000000000..5234b5049b0 + goto fail; + } + ++ ret = v4l2_request_try_framesize(avctx, pixelformat); ++ if (ret < 0) { ++ av_log(avctx, AV_LOG_WARNING, "%s: try framesize failed\n", __func__); ++ ret = AVERROR(EINVAL); ++ goto fail; ++ } ++ + ret = v4l2_request_set_format(avctx, ctx->output_type, pixelformat, buffersize); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "%s: set output format failed, %s (%d)\n", __func__, strerror(errno), errno); @@ -1157,7 +1201,7 @@ index 00000000000..5234b5049b0 +} diff --git a/libavcodec/v4l2_request.h b/libavcodec/v4l2_request.h new file mode 100644 -index 00000000000..58d2aa70af8 +index 0000000000..58d2aa70af --- /dev/null +++ b/libavcodec/v4l2_request.h @@ -0,0 +1,77 @@ @@ -1239,10 +1283,10 @@ index 00000000000..58d2aa70af8 + +#endif /* AVCODEC_V4L2_REQUEST_H */ -From e432d3151f4c5507e40fb1fe8b3c3fb7c7a0a08c Mon Sep 17 00:00:00 2001 +From 3a8ac13e041cec840d3cd1e83e6294a1a47ac6df Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Wed, 20 Feb 2019 11:18:00 -0300 -Subject: [PATCH 03/17] h264dec: add idr_pic_id to slice context +Subject: [PATCH 03/12] h264dec: add idr_pic_id to slice context Used by V4L2 request API h264 hwaccel @@ -1254,7 +1298,7 @@ Signed-off-by: Jonas Karlman 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c -index 2d0605c7f4f..c3a7338a704 100644 +index 0b415ada6f..b3e3ef6183 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1830,7 +1830,7 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl, @@ -1264,10 +1308,10 @@ index 2d0605c7f4f..c3a7338a704 100644 - get_ue_golomb_long(&sl->gb); /* idr_pic_id */ + sl->idr_pic_id = get_ue_golomb_long(&sl->gb); - if (sps->poc_type == 0) { - sl->poc_lsb = get_bits(&sl->gb, sps->log2_max_poc_lsb); + sl->poc_lsb = 0; + sl->delta_poc_bottom = 0; diff --git a/libavcodec/h264dec.h b/libavcodec/h264dec.h -index b7b19ba4f16..0698ab95ba5 100644 +index b7b19ba4f1..0698ab95ba 100644 --- a/libavcodec/h264dec.h +++ b/libavcodec/h264dec.h @@ -336,6 +336,7 @@ typedef struct H264SliceContext { @@ -1279,10 +1323,10 @@ index b7b19ba4f16..0698ab95ba5 100644 /** -From 84564d13ec0ec40f408622ff6b0d900723bbab5b Mon Sep 17 00:00:00 2001 +From e7f515597ca5f0900f3bd08ef40bb517703433bc Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 22 May 2019 14:44:22 +0200 -Subject: [PATCH 04/17] h264dec: add ref_pic_marking and pic_order_cnt bit_size +Subject: [PATCH 04/12] h264dec: add ref_pic_marking and pic_order_cnt bit_size to slice context Used by V4L2 request API h264 hwaccel @@ -1295,7 +1339,7 @@ Signed-off-by: Jonas Karlman 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c -index c3a7338a704..c28b58cd5d9 100644 +index b3e3ef6183..bcb9f70c0e 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1748,7 +1748,7 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl, @@ -1307,15 +1351,15 @@ index c3a7338a704..c28b58cd5d9 100644 if (first_slice) av_assert0(!h->setup_finished); -@@ -1832,6 +1832,7 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl, - if (nal->type == H264_NAL_IDR_SLICE) - sl->idr_pic_id = get_ue_golomb_long(&sl->gb); +@@ -1834,6 +1834,7 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl, + sl->poc_lsb = 0; + sl->delta_poc_bottom = 0; + pos = sl->gb.index; if (sps->poc_type == 0) { sl->poc_lsb = get_bits(&sl->gb, sps->log2_max_poc_lsb); -@@ -1845,6 +1846,7 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl, +@@ -1848,6 +1849,7 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl, if (pps->pic_order_present == 1 && picture_structure == PICT_FRAME) sl->delta_poc[1] = get_se_golomb(&sl->gb); } @@ -1323,7 +1367,7 @@ index c3a7338a704..c28b58cd5d9 100644 sl->redundant_pic_count = 0; if (pps->redundant_pic_cnt_present) -@@ -1884,9 +1886,11 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl, +@@ -1887,9 +1889,11 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl, sl->explicit_ref_marking = 0; if (nal->ref_idc) { @@ -1336,7 +1380,7 @@ index c3a7338a704..c28b58cd5d9 100644 if (sl->slice_type_nos != AV_PICTURE_TYPE_I && pps->cabac) { diff --git a/libavcodec/h264dec.h b/libavcodec/h264dec.h -index 0698ab95ba5..2b39e82c3b0 100644 +index 0698ab95ba..2b39e82c3b 100644 --- a/libavcodec/h264dec.h +++ b/libavcodec/h264dec.h @@ -329,6 +329,7 @@ typedef struct H264SliceContext { @@ -1356,10 +1400,10 @@ index 0698ab95ba5..2b39e82c3b0 100644 /** -From 5a8628cf6368fe18457d02bf551d5935609efab5 Mon Sep 17 00:00:00 2001 +From 9f455a7adb8cabb575049204375cc3b8d97b2c86 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Sat, 15 Dec 2018 22:32:16 +0100 -Subject: [PATCH 05/17] Add V4L2 request API h264 hwaccel +Subject: [PATCH 05/12] Add V4L2 request API h264 hwaccel Signed-off-by: Jernej Skrabec Signed-off-by: Jonas Karlman @@ -1374,10 +1418,10 @@ Signed-off-by: Jonas Karlman create mode 100644 libavcodec/v4l2_request_h264.c diff --git a/configure b/configure -index f2e203d1346..b17e4108c1b 100755 +index 4a3a5ae9e0..efd12f1b52 100755 --- a/configure +++ b/configure -@@ -2951,6 +2951,8 @@ h264_dxva2_hwaccel_deps="dxva2" +@@ -2952,6 +2952,8 @@ h264_dxva2_hwaccel_deps="dxva2" h264_dxva2_hwaccel_select="h264_decoder" h264_nvdec_hwaccel_deps="nvdec" h264_nvdec_hwaccel_select="h264_decoder" @@ -1386,7 +1430,7 @@ index f2e203d1346..b17e4108c1b 100755 h264_vaapi_hwaccel_deps="vaapi" h264_vaapi_hwaccel_select="h264_decoder" h264_vdpau_hwaccel_deps="vdpau" -@@ -6628,6 +6630,7 @@ if enabled v4l2_m2m; then +@@ -6629,6 +6631,7 @@ if enabled v4l2_m2m; then fi check_func_headers "linux/media.h linux/videodev2.h" v4l2_timeval_to_ns @@ -1395,7 +1439,7 @@ index f2e203d1346..b17e4108c1b 100755 check_headers sys/videoio.h test_code cc sys/videoio.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_sanitized struct_v4l2_frmivalenum_discrete diff --git a/libavcodec/Makefile b/libavcodec/Makefile -index 90dfffcb200..426c7528e90 100644 +index 90dfffcb20..426c7528e9 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -935,6 +935,7 @@ OBJS-$(CONFIG_H264_D3D11VA_HWACCEL) += dxva2_h264.o @@ -1407,7 +1451,7 @@ index 90dfffcb200..426c7528e90 100644 OBJS-$(CONFIG_H264_VDPAU_HWACCEL) += vdpau_h264.o OBJS-$(CONFIG_H264_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c -index c28b58cd5d9..0a10d00aad9 100644 +index bcb9f70c0e..6b7f569da4 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -768,6 +768,7 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback) @@ -1429,7 +1473,7 @@ index c28b58cd5d9..0a10d00aad9 100644 if (h->avctx->codec->pix_fmts) choices = h->avctx->codec->pix_fmts; diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c -index 0a999bef43d..d78e3eaee3a 100644 +index 1705046e29..55046031b2 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -1076,6 +1076,9 @@ AVCodec ff_h264_decoder = { @@ -1443,7 +1487,7 @@ index 0a999bef43d..d78e3eaee3a 100644 NULL }, diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h -index 8e54cf73f90..969a1da0f4b 100644 +index 8e54cf73f9..969a1da0f4 100644 --- a/libavcodec/hwaccels.h +++ b/libavcodec/hwaccels.h @@ -32,6 +32,7 @@ extern const AVHWAccel ff_h264_d3d11va_hwaccel; @@ -1456,7 +1500,7 @@ index 8e54cf73f90..969a1da0f4b 100644 extern const AVHWAccel ff_h264_videotoolbox_hwaccel; diff --git a/libavcodec/v4l2_request_h264.c b/libavcodec/v4l2_request_h264.c new file mode 100644 -index 00000000000..88da8f0a2db +index 0000000000..394bae0550 --- /dev/null +++ b/libavcodec/v4l2_request_h264.c @@ -0,0 +1,456 @@ @@ -1528,7 +1572,7 @@ index 00000000000..88da8f0a2db +{ + entry->reference_ts = ff_v4l2_request_get_capture_timestamp(pic->f); + entry->pic_num = pic->pic_id; -+ entry->frame_num = pic->frame_num; ++ entry->frame_num = pic->long_ref ? pic->pic_id : pic->frame_num; + entry->fields = pic->reference & V4L2_H264_FRAME_REF; + entry->flags = V4L2_H264_DPB_ENTRY_FLAG_VALID; + if (entry->fields) @@ -1917,10 +1961,10 @@ index 00000000000..88da8f0a2db + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, +}; -From 02b8fb17c2a019463dcab4baa1cb0bec63353183 Mon Sep 17 00:00:00 2001 +From 1ffea498d7e1000acbaa456bb52e26757779622a Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sat, 15 Dec 2018 22:32:16 +0100 -Subject: [PATCH 06/17] Add V4L2 request API mpeg2 hwaccel +Subject: [PATCH 06/12] Add V4L2 request API mpeg2 hwaccel Signed-off-by: Jonas Karlman --- @@ -1933,10 +1977,10 @@ Signed-off-by: Jonas Karlman create mode 100644 libavcodec/v4l2_request_mpeg2.c diff --git a/configure b/configure -index b17e4108c1b..ec141fabbdc 100755 +index efd12f1b52..1b70ea65e4 100755 --- a/configure +++ b/configure -@@ -2995,6 +2995,8 @@ mpeg2_dxva2_hwaccel_deps="dxva2" +@@ -2996,6 +2996,8 @@ mpeg2_dxva2_hwaccel_deps="dxva2" mpeg2_dxva2_hwaccel_select="mpeg2video_decoder" mpeg2_nvdec_hwaccel_deps="nvdec" mpeg2_nvdec_hwaccel_select="mpeg2video_decoder" @@ -1945,7 +1989,7 @@ index b17e4108c1b..ec141fabbdc 100755 mpeg2_vaapi_hwaccel_deps="vaapi" mpeg2_vaapi_hwaccel_select="mpeg2video_decoder" mpeg2_vdpau_hwaccel_deps="vdpau" -@@ -6631,6 +6633,7 @@ fi +@@ -6632,6 +6634,7 @@ fi check_func_headers "linux/media.h linux/videodev2.h" v4l2_timeval_to_ns check_cc h264_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_H264_SLICE;" @@ -1954,7 +1998,7 @@ index b17e4108c1b..ec141fabbdc 100755 check_headers sys/videoio.h test_code cc sys/videoio.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_sanitized struct_v4l2_frmivalenum_discrete diff --git a/libavcodec/Makefile b/libavcodec/Makefile -index 426c7528e90..02c023a4477 100644 +index 426c7528e9..02c023a447 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -955,6 +955,7 @@ OBJS-$(CONFIG_MPEG2_D3D11VA_HWACCEL) += dxva2_mpeg2.o @@ -1966,7 +2010,7 @@ index 426c7528e90..02c023a4477 100644 OBJS-$(CONFIG_MPEG2_VDPAU_HWACCEL) += vdpau_mpeg12.o OBJS-$(CONFIG_MPEG2_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h -index 969a1da0f4b..a8ae1483d8e 100644 +index 969a1da0f4..a8ae1483d8 100644 --- a/libavcodec/hwaccels.h +++ b/libavcodec/hwaccels.h @@ -53,6 +53,7 @@ extern const AVHWAccel ff_mpeg2_d3d11va_hwaccel; @@ -1978,7 +2022,7 @@ index 969a1da0f4b..a8ae1483d8e 100644 extern const AVHWAccel ff_mpeg2_vdpau_hwaccel; extern const AVHWAccel ff_mpeg2_videotoolbox_hwaccel; diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c -index 94221da2c15..4b0176f6cb1 100644 +index 09bf01247d..bcdf26680a 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -1147,6 +1147,9 @@ static const enum AVPixelFormat mpeg2_hwaccel_pixfmt_list_420[] = { @@ -2003,7 +2047,7 @@ index 94221da2c15..4b0176f6cb1 100644 }, diff --git a/libavcodec/v4l2_request_mpeg2.c b/libavcodec/v4l2_request_mpeg2.c new file mode 100644 -index 00000000000..84d53209c79 +index 0000000000..84d53209c7 --- /dev/null +++ b/libavcodec/v4l2_request_mpeg2.c @@ -0,0 +1,159 @@ @@ -2167,10 +2211,10 @@ index 00000000000..84d53209c79 + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, +}; -From 1cd61e5730acc12c39c964bcf13c73a54203a390 Mon Sep 17 00:00:00 2001 +From 2190df619ea9d9cedf3d3c7442de0dc863c8b62e Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 22 May 2019 14:46:58 +0200 -Subject: [PATCH 07/17] Add V4L2 request API vp8 hwaccel +Subject: [PATCH 07/12] Add V4L2 request API vp8 hwaccel Signed-off-by: Boris Brezillon Signed-off-by: Ezequiel Garcia @@ -2185,10 +2229,10 @@ Signed-off-by: Jonas Karlman create mode 100644 libavcodec/v4l2_request_vp8.c diff --git a/configure b/configure -index ec141fabbdc..f16bed65a3a 100755 +index 1b70ea65e4..3f8f7b195a 100755 --- a/configure +++ b/configure -@@ -3027,6 +3027,8 @@ vc1_vdpau_hwaccel_deps="vdpau" +@@ -3028,6 +3028,8 @@ vc1_vdpau_hwaccel_deps="vdpau" vc1_vdpau_hwaccel_select="vc1_decoder" vp8_nvdec_hwaccel_deps="nvdec" vp8_nvdec_hwaccel_select="vp8_decoder" @@ -2197,7 +2241,7 @@ index ec141fabbdc..f16bed65a3a 100755 vp8_vaapi_hwaccel_deps="vaapi" vp8_vaapi_hwaccel_select="vp8_decoder" vp9_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_VP9" -@@ -6634,6 +6636,7 @@ fi +@@ -6635,6 +6637,7 @@ fi check_func_headers "linux/media.h linux/videodev2.h" v4l2_timeval_to_ns check_cc h264_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_H264_SLICE;" check_cc mpeg2_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG2_SLICE;" @@ -2206,7 +2250,7 @@ index ec141fabbdc..f16bed65a3a 100755 check_headers sys/videoio.h test_code cc sys/videoio.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_sanitized struct_v4l2_frmivalenum_discrete diff --git a/libavcodec/Makefile b/libavcodec/Makefile -index 02c023a4477..c79d678eb3e 100644 +index 02c023a447..c79d678eb3 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -971,6 +971,7 @@ OBJS-$(CONFIG_VC1_QSV_HWACCEL) += qsvdec.o @@ -2218,7 +2262,7 @@ index 02c023a4477..c79d678eb3e 100644 OBJS-$(CONFIG_VP9_D3D11VA_HWACCEL) += dxva2_vp9.o OBJS-$(CONFIG_VP9_DXVA2_HWACCEL) += dxva2_vp9.o diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h -index a8ae1483d8e..9f8d41e367e 100644 +index a8ae1483d8..9f8d41e367 100644 --- a/libavcodec/hwaccels.h +++ b/libavcodec/hwaccels.h @@ -69,6 +69,7 @@ extern const AVHWAccel ff_vc1_nvdec_hwaccel; @@ -2231,7 +2275,7 @@ index a8ae1483d8e..9f8d41e367e 100644 extern const AVHWAccel ff_vp9_d3d11va2_hwaccel; diff --git a/libavcodec/v4l2_request_vp8.c b/libavcodec/v4l2_request_vp8.c new file mode 100644 -index 00000000000..bc0fc400727 +index 0000000000..bc0fc40072 --- /dev/null +++ b/libavcodec/v4l2_request_vp8.c @@ -0,0 +1,180 @@ @@ -2416,7 +2460,7 @@ index 00000000000..bc0fc400727 + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, +}; diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c -index d16e7b6aa34..8ee768d875a 100644 +index d16e7b6aa3..8ee768d875 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -176,6 +176,9 @@ static enum AVPixelFormat get_pixel_format(VP8Context *s) @@ -2440,27 +2484,29 @@ index d16e7b6aa34..8ee768d875a 100644 NULL }, -From 41c38b001277f252c052ba0493546184760a0a8e Mon Sep 17 00:00:00 2001 +From 4886d1e8caeee49c6ca4d92bc1eaebcdb884924c Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Sat, 15 Dec 2018 22:32:16 +0100 -Subject: [PATCH 08/17] Add V4L2 request API hevc hwaccel +Subject: [PATCH 08/12] Add V4L2 request API hevc hwaccel Signed-off-by: Jernej Skrabec Signed-off-by: Jonas Karlman +Signed-off-by: Benjamin Gaignard +Signed-off-by: Alex Bee --- configure | 3 + libavcodec/Makefile | 1 + libavcodec/hevcdec.c | 10 + libavcodec/hwaccels.h | 1 + - libavcodec/v4l2_request_hevc.c | 580 +++++++++++++++++++++++++++++++++ - 5 files changed, 595 insertions(+) + libavcodec/v4l2_request_hevc.c | 681 +++++++++++++++++++++++++++++++++ + 5 files changed, 696 insertions(+) create mode 100644 libavcodec/v4l2_request_hevc.c diff --git a/configure b/configure -index f16bed65a3a..02a80cf27fd 100755 +index 3f8f7b195a..6192a6c144 100755 --- a/configure +++ b/configure -@@ -2967,6 +2967,8 @@ hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC" +@@ -2968,6 +2968,8 @@ hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC" hevc_dxva2_hwaccel_select="hevc_decoder" hevc_nvdec_hwaccel_deps="nvdec" hevc_nvdec_hwaccel_select="hevc_decoder" @@ -2469,7 +2515,7 @@ index f16bed65a3a..02a80cf27fd 100755 hevc_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferHEVC" hevc_vaapi_hwaccel_select="hevc_decoder" hevc_vdpau_hwaccel_deps="vdpau VdpPictureInfoHEVC" -@@ -6635,6 +6637,7 @@ fi +@@ -6636,6 +6638,7 @@ fi check_func_headers "linux/media.h linux/videodev2.h" v4l2_timeval_to_ns check_cc h264_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_H264_SLICE;" @@ -2478,7 +2524,7 @@ index f16bed65a3a..02a80cf27fd 100755 check_cc vp8_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_VP8_FRAME;" diff --git a/libavcodec/Makefile b/libavcodec/Makefile -index c79d678eb3e..0059074530c 100644 +index c79d678eb3..0059074530 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -943,6 +943,7 @@ OBJS-$(CONFIG_HEVC_D3D11VA_HWACCEL) += dxva2_hevc.o @@ -2490,7 +2536,7 @@ index c79d678eb3e..0059074530c 100644 OBJS-$(CONFIG_HEVC_VDPAU_HWACCEL) += vdpau_hevc.o h265_profile_level.o OBJS-$(CONFIG_MJPEG_NVDEC_HWACCEL) += nvdec_mjpeg.o diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c -index 2231aed2599..7507966d716 100644 +index 2231aed259..7507966d71 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -392,6 +392,7 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) @@ -2532,7 +2578,7 @@ index 2231aed2599..7507966d716 100644 NULL }, diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h -index 9f8d41e367e..ffb9fa5087d 100644 +index 9f8d41e367..ffb9fa5087 100644 --- a/libavcodec/hwaccels.h +++ b/libavcodec/hwaccels.h @@ -40,6 +40,7 @@ extern const AVHWAccel ff_hevc_d3d11va_hwaccel; @@ -2545,10 +2591,10 @@ index 9f8d41e367e..ffb9fa5087d 100644 extern const AVHWAccel ff_hevc_videotoolbox_hwaccel; diff --git a/libavcodec/v4l2_request_hevc.c b/libavcodec/v4l2_request_hevc.c new file mode 100644 -index 00000000000..fd253661086 +index 0000000000..c12748ed03 --- /dev/null +++ b/libavcodec/v4l2_request_hevc.c -@@ -0,0 +1,580 @@ +@@ -0,0 +1,681 @@ +/* + * This file is part of FFmpeg. + * @@ -2571,7 +2617,8 @@ index 00000000000..fd253661086 +#include "hwconfig.h" +#include "v4l2_request.h" + -+#define MAX_SLICES 16 ++#define MAX_SLICES 600 // as per HEVC spec ? ++#define V4L2_HEVC_CONTROLS_MAX 6 + +typedef struct V4L2RequestControlsHEVC { + struct v4l2_ctrl_hevc_sps sps; @@ -2579,15 +2626,20 @@ index 00000000000..fd253661086 + struct v4l2_ctrl_hevc_decode_params dec_params; + struct v4l2_ctrl_hevc_scaling_matrix scaling_matrix; + struct v4l2_ctrl_hevc_slice_params slice_params[MAX_SLICES]; ++ __u32 *entry_point_offsets; ++ unsigned int num_entry_point_offsets; + int first_slice; -+ int num_slices; //TODO: this should be in control ++ int num_slices; +} V4L2RequestControlsHEVC; + +typedef struct V4L2RequestContextHEVC { + V4L2RequestContext base; -+ int decode_mode; -+ int start_code; -+ int max_slices; ++ unsigned int decode_mode; ++ unsigned int start_code; ++ __u32 max_slices; ++ unsigned int supports_entry_point_offsets; ++ unsigned int supports_slices; ++ unsigned int supports_scaling_matrix; +} V4L2RequestContextHEVC; + +static uint8_t nalu_slice_start_code[] = { 0x00, 0x00, 0x01 }; @@ -2632,56 +2684,6 @@ index 00000000000..fd253661086 + } +} + -+static void fill_dec_params(struct v4l2_ctrl_hevc_decode_params *dec_params, const HEVCContext *h) -+{ -+ const HEVCFrame *pic = h->ref; -+ const SliceHeader *sh = &h->sh; -+ int i, entries = 0; -+ -+ *dec_params = (struct v4l2_ctrl_hevc_decode_params) { -+ .pic_order_cnt_val = pic->poc, /* FIXME: is this same as slice_params->slice_pic_order_cnt ? */ -+ .num_poc_st_curr_before = h->rps[ST_CURR_BEF].nb_refs, -+ .num_poc_st_curr_after = h->rps[ST_CURR_AFT].nb_refs, -+ .num_poc_lt_curr = h->rps[LT_CURR].nb_refs, -+ }; -+ -+ for (i = 0; i < FF_ARRAY_ELEMS(h->DPB); i++) { -+ const HEVCFrame *frame = &h->DPB[i]; -+ if (frame != pic && (frame->flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF))) { -+ struct v4l2_hevc_dpb_entry *entry = &dec_params->dpb[entries++]; -+ -+ entry->timestamp = ff_v4l2_request_get_capture_timestamp(frame->frame); -+ entry->field_pic = frame->frame->interlaced_frame; -+ entry->flags = 0; -+ if (frame->flags & HEVC_FRAME_FLAG_LONG_REF) -+ entry->flags |= V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE; -+ -+ /* TODO: Interleaved: Get the POC for each field. */ -+ entry->pic_order_cnt[0] = frame->poc; -+ entry->pic_order_cnt[1] = frame->poc; -+ } -+ } -+ -+ dec_params->num_active_dpb_entries = entries; -+ -+ if (IS_IRAP(h)) -+ dec_params->flags |= V4L2_HEVC_DECODE_PARAM_FLAG_IRAP_PIC; -+ -+ if (IS_IDR(h)) -+ dec_params->flags |= V4L2_HEVC_DECODE_PARAM_FLAG_IDR_PIC; -+ -+ /* FIXME: is this really frame property? */ -+ if (sh->no_output_of_prior_pics_flag) -+ dec_params->flags |= V4L2_HEVC_DECODE_PARAM_FLAG_NO_OUTPUT_OF_PRIOR; -+ -+ /* -+ * TODO: fill -+ * dec_params->poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; -+ * dec_params->poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; -+ * dec_params->poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; -+ */ -+} -+ +static uint8_t get_ref_pic_index(const HEVCContext *h, const HEVCFrame *frame, + struct v4l2_ctrl_hevc_decode_params *dec_params) +{ @@ -2701,21 +2703,69 @@ index 00000000000..fd253661086 + return 0; +} + -+static void v4l2_request_hevc_fill_slice_params(const HEVCContext *h, -+ struct v4l2_ctrl_hevc_decode_params *dec_params, -+ struct v4l2_ctrl_hevc_slice_params *slice_params) ++static void fill_dec_params(struct v4l2_ctrl_hevc_decode_params *dec_params, const HEVCContext *h) +{ + const HEVCFrame *pic = h->ref; + const SliceHeader *sh = &h->sh; ++ int i, entries = 0; ++ ++ *dec_params = (struct v4l2_ctrl_hevc_decode_params) { ++ .pic_order_cnt_val = pic->poc, /* FIXME: is this same as slice_params->slice_pic_order_cnt ? */ ++ .short_term_ref_pic_set_size = sh->short_term_ref_pic_set_size, ++ .long_term_ref_pic_set_size = sh->long_term_ref_pic_set_size, ++ .num_poc_st_curr_before = h->rps[ST_CURR_BEF].nb_refs, ++ .num_poc_st_curr_after = h->rps[ST_CURR_AFT].nb_refs, ++ .num_poc_lt_curr = h->rps[LT_CURR].nb_refs, ++ }; ++ ++ for (i = 0; i < FF_ARRAY_ELEMS(h->DPB); i++) { ++ const HEVCFrame *frame = &h->DPB[i]; ++ if (frame != pic && (frame->flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF))) { ++ struct v4l2_hevc_dpb_entry *entry = &dec_params->dpb[entries++]; ++ ++ entry->timestamp = ff_v4l2_request_get_capture_timestamp(frame->frame); ++ entry->field_pic = frame->frame->interlaced_frame; ++ entry->flags = 0; ++ if (frame->flags & HEVC_FRAME_FLAG_LONG_REF) ++ entry->flags |= V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE; ++ ++ entry->pic_order_cnt_val = frame->poc; ++ } ++ } ++ ++ dec_params->num_active_dpb_entries = entries; ++ ++ if (IS_IRAP(h)) ++ dec_params->flags |= V4L2_HEVC_DECODE_PARAM_FLAG_IRAP_PIC; ++ ++ if (IS_IDR(h)) ++ dec_params->flags |= V4L2_HEVC_DECODE_PARAM_FLAG_IDR_PIC; ++ ++ if (sh->no_output_of_prior_pics_flag) ++ dec_params->flags |= V4L2_HEVC_DECODE_PARAM_FLAG_NO_OUTPUT_OF_PRIOR; ++ ++ for (i = 0; i < V4L2_HEVC_DPB_ENTRIES_NUM_MAX; i++) { ++ dec_params->poc_st_curr_before[i] = get_ref_pic_index(h, h->rps[ST_CURR_BEF].ref[i], dec_params); ++ dec_params->poc_st_curr_after[i] = get_ref_pic_index(h, h->rps[ST_CURR_AFT].ref[i], dec_params); ++ dec_params->poc_lt_curr[i] = get_ref_pic_index(h, h->rps[LT_CURR].ref[i], dec_params); ++ } ++} ++ ++static int v4l2_request_hevc_fill_slice_params(const HEVCContext *h, ++ V4L2RequestControlsHEVC *controls, ++ int slice) ++{ ++ struct v4l2_ctrl_hevc_slice_params *slice_params = &controls->slice_params[slice]; ++ struct v4l2_ctrl_hevc_decode_params *dec_params = &controls->dec_params; ++ const HEVCFrame *pic = h->ref; ++ const SliceHeader *sh = &h->sh; + RefPicList *rpl; + int i; + + *slice_params = (struct v4l2_ctrl_hevc_slice_params) { + .bit_size = 0, -+ .data_bit_offset = get_bits_count(&h->HEVClc->gb), -+ -+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ -+ .slice_segment_addr = sh->slice_segment_addr, ++ .data_byte_offset = (get_bits_count(&h->HEVClc->gb) + 1 + 7) / 8, ++ .num_entry_point_offsets = sh->num_entry_point_offsets, + + /* ISO/IEC 23008-2, ITU-T Rec. H.265: NAL unit header */ + .nal_unit_type = h->nal_unit_type, @@ -2740,6 +2790,11 @@ index 00000000000..fd253661086 + + /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture timing SEI message */ + .pic_struct = h->sei.picture_timing.picture_struct, ++ ++ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ ++ .slice_segment_addr = sh->slice_segment_addr, ++ .short_term_ref_pic_set_size = sh->short_term_ref_pic_set_size, ++ .long_term_ref_pic_set_size = sh->long_term_ref_pic_set_size, + }; + + if (sh->slice_sample_adaptive_offset_flag[0]) @@ -2760,6 +2815,8 @@ index 00000000000..fd253661086 + if (sh->collocated_list == L0) + slice_params->flags |= V4L2_HEVC_SLICE_PARAMS_FLAG_COLLOCATED_FROM_L0; + ++ /* TODO: V4L2_HEVC_SLICE_PARAMS_FLAG_USE_INTEGER_MV */ ++ + if (sh->disable_deblocking_filter_flag) + slice_params->flags |= V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED; + @@ -2782,18 +2839,34 @@ index 00000000000..fd253661086 + } + + v4l2_request_hevc_fill_pred_table(h, &slice_params->pred_weight_table); ++ ++ if (controls->num_entry_point_offsets < sh->num_entry_point_offsets) { ++ av_freep(&controls->entry_point_offsets); ++ controls->entry_point_offsets = av_mallocz(sizeof(*controls->entry_point_offsets) * sh->num_entry_point_offsets); ++ if (!controls->entry_point_offsets) ++ return AVERROR(ENOMEM); ++ controls->num_entry_point_offsets = sh->num_entry_point_offsets; ++ } ++ ++ for (i = 0; i < sh->num_entry_point_offsets; i++) ++ controls->entry_point_offsets[i] = sh->entry_point_offset[i]; ++ ++ return 0; +} + +static void fill_sps(struct v4l2_ctrl_hevc_sps *ctrl, const HEVCContext *h) +{ + const HEVCSPS *sps = h->ps.sps; ++ const HEVCPPS *pps = h->ps.pps; + + /* ISO/IEC 23008-2, ITU-T Rec. H.265: Sequence parameter set */ + *ctrl = (struct v4l2_ctrl_hevc_sps) { ++ .video_parameter_set_id = sps->vps_id, ++ .seq_parameter_set_id = pps->sps_id, + .pic_width_in_luma_samples = sps->width, + .pic_height_in_luma_samples = sps->height, + .bit_depth_luma_minus8 = sps->bit_depth - 8, -+ .bit_depth_chroma_minus8 = sps->bit_depth - 8, ++ .bit_depth_chroma_minus8 = sps->bit_depth_chroma - 8, + .log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_poc_lsb - 4, + .sps_max_dec_pic_buffering_minus1 = sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering - 1, + .sps_max_num_reorder_pics = sps->temporal_layer[sps->max_sub_layers - 1].num_reorder_pics, @@ -2854,6 +2927,7 @@ index 00000000000..fd253661086 + sps->scaling_list_enable_flag ? + &sps->scaling_list : NULL; + V4L2RequestControlsHEVC *controls = h->ref->hwaccel_picture_private; ++ const SliceHeader *sh = &h->sh; + + fill_sps(&controls->sps, h); + fill_dec_params(&controls->dec_params, h); @@ -2876,6 +2950,7 @@ index 00000000000..fd253661086 + + /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture parameter set */ + controls->pps = (struct v4l2_ctrl_hevc_pps) { ++ .pic_parameter_set_id = sh->pps_id, + .num_extra_slice_header_bits = pps->num_extra_slice_header_bits, + .num_ref_idx_l0_default_active_minus1 = pps->num_ref_idx_l0_default_active - 1, + .num_ref_idx_l1_default_active_minus1 = pps->num_ref_idx_l1_default_active - 1, @@ -2964,6 +3039,7 @@ index 00000000000..fd253661086 + + controls->first_slice = 1; + controls->num_slices = 0; ++ controls->num_entry_point_offsets = 0; + + return ff_v4l2_request_reset_frame(avctx, h->ref->frame); +} @@ -2972,40 +3048,58 @@ index 00000000000..fd253661086 +{ + const HEVCContext *h = avctx->priv_data; + V4L2RequestControlsHEVC *controls = h->ref->hwaccel_picture_private; ++ struct v4l2_ctrl_hevc_slice_params *first_slice_params = &controls->slice_params[0]; + V4L2RequestContextHEVC *ctx = avctx->internal->hwaccel_priv_data; ++ int num_controls = 0; + -+ struct v4l2_ext_control control[] = { -+ { -+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SPS, ++ struct v4l2_ext_control control[V4L2_HEVC_CONTROLS_MAX] = {}; ++ ++ control[num_controls++] = (struct v4l2_ext_control) { ++ .id = V4L2_CID_STATELESS_HEVC_SPS, + .ptr = &controls->sps, + .size = sizeof(controls->sps), -+ }, -+ { -+ .id = V4L2_CID_MPEG_VIDEO_HEVC_PPS, -+ .ptr = &controls->pps, -+ .size = sizeof(controls->pps), -+ }, -+ { -+ .id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS, -+ .ptr = &controls->dec_params, -+ .size = sizeof(controls->dec_params), -+ }, -+ { -+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX, -+ .ptr = &controls->scaling_matrix, -+ .size = sizeof(controls->scaling_matrix), -+ }, -+ { -+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS, -+ .ptr = &controls->slice_params, -+ .size = sizeof(controls->slice_params[0]) * FFMAX(FFMIN(controls->num_slices, MAX_SLICES), ctx->max_slices), -+ }, + }; + -+ if (ctx->decode_mode == V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED) -+ return ff_v4l2_request_decode_slice(avctx, h->ref->frame, control, FF_ARRAY_ELEMS(control), controls->first_slice, last_slice); ++ control[num_controls++] = (struct v4l2_ext_control) { ++ .id = V4L2_CID_STATELESS_HEVC_PPS, ++ .ptr = &controls->pps, ++ .size = sizeof(controls->pps), ++ }; + -+ return ff_v4l2_request_decode_frame(avctx, h->ref->frame, control, FF_ARRAY_ELEMS(control)); ++ control[num_controls++] = (struct v4l2_ext_control) { ++ .id = V4L2_CID_STATELESS_HEVC_DECODE_PARAMS, ++ .ptr = &controls->dec_params, ++ .size = sizeof(controls->dec_params), ++ }; ++ ++ if (ctx->supports_scaling_matrix) { ++ control[num_controls++] = (struct v4l2_ext_control) { ++ .id = V4L2_CID_STATELESS_HEVC_SCALING_MATRIX, ++ .ptr = &controls->scaling_matrix, ++ .size = sizeof(controls->scaling_matrix), ++ }; ++ } ++ ++ if (ctx->supports_slices) { ++ control[num_controls++] = (struct v4l2_ext_control) { ++ .id = V4L2_CID_STATELESS_HEVC_SLICE_PARAMS, ++ .ptr = &controls->slice_params, ++ .size = sizeof(*first_slice_params) * controls->num_slices, ++ }; ++ } ++ //this assumes that decoders supporting entry_point_offsets submit a single slice per request ++ if (ctx->supports_entry_point_offsets && first_slice_params->num_entry_point_offsets > 0) { ++ control[num_controls++] = (struct v4l2_ext_control) { ++ .id = V4L2_CID_STATELESS_HEVC_ENTRY_POINT_OFFSETS, ++ .ptr = controls->entry_point_offsets, ++ .size = sizeof(*controls->entry_point_offsets) * first_slice_params->num_entry_point_offsets, ++ }; ++ } ++ ++ if (ctx->decode_mode == V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED) ++ return ff_v4l2_request_decode_slice(avctx, h->ref->frame, control, num_controls, controls->first_slice, last_slice); ++ ++ return ff_v4l2_request_decode_frame(avctx, h->ref->frame, control, num_controls); +} + +static int v4l2_request_hevc_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) @@ -3016,7 +3110,7 @@ index 00000000000..fd253661086 + V4L2RequestDescriptor *req = (V4L2RequestDescriptor*)h->ref->frame->data[0]; + int ret, slice = FFMIN(controls->num_slices, MAX_SLICES - 1); + -+ if (ctx->decode_mode == V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED && slice) { ++ if (ctx->decode_mode == V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED && slice) { + ret = v4l2_request_hevc_queue_decode(avctx, 0); + if (ret) + return ret; @@ -3026,9 +3120,11 @@ index 00000000000..fd253661086 + controls->first_slice = 0; + } + -+ v4l2_request_hevc_fill_slice_params(h, &controls->dec_params, &controls->slice_params[slice]); ++ ret = v4l2_request_hevc_fill_slice_params(h, controls, slice); ++ if (ret) ++ return ret; + -+ if (ctx->start_code == V4L2_MPEG_VIDEO_HEVC_START_CODE_ANNEX_B) { ++ if (ctx->start_code == V4L2_STATELESS_HEVC_START_CODE_ANNEX_B) { + ret = ff_v4l2_request_append_output_buffer(avctx, h->ref->frame, nalu_slice_start_code, 3); + if (ret) + return ret; @@ -3045,7 +3141,15 @@ index 00000000000..fd253661086 + +static int v4l2_request_hevc_end_frame(AVCodecContext *avctx) +{ -+ return v4l2_request_hevc_queue_decode(avctx, 1); ++ const HEVCContext *h = avctx->priv_data; ++ V4L2RequestControlsHEVC *controls = h->ref->hwaccel_picture_private; ++ int ret; ++ ++ ret = v4l2_request_hevc_queue_decode(avctx, 1); ++ ++ av_freep(&controls->entry_point_offsets); ++ ++ return ret; +} + +static int v4l2_request_hevc_set_controls(AVCodecContext *avctx) @@ -3054,37 +3158,80 @@ index 00000000000..fd253661086 + int ret; + + struct v4l2_ext_control control[] = { -+ { .id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE, }, -+ { .id = V4L2_CID_MPEG_VIDEO_HEVC_START_CODE, }, ++ { .id = V4L2_CID_STATELESS_HEVC_DECODE_MODE, }, ++ { .id = V4L2_CID_STATELESS_HEVC_START_CODE, }, ++ }; ++ struct v4l2_query_ext_ctrl entry_point_offsets = { ++ .id = V4L2_CID_STATELESS_HEVC_ENTRY_POINT_OFFSETS, + }; + struct v4l2_query_ext_ctrl slice_params = { -+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS, ++ .id = V4L2_CID_STATELESS_HEVC_SLICE_PARAMS, ++ }; ++ struct v4l2_query_ext_ctrl scaling_matrix = { ++ .id = V4L2_CID_STATELESS_HEVC_SCALING_MATRIX, + }; + -+ ctx->decode_mode = ff_v4l2_request_query_control_default_value(avctx, V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE); -+ if (ctx->decode_mode != V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED && -+ ctx->decode_mode != V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_FRAME_BASED) { ++ ctx->decode_mode = ff_v4l2_request_query_control_default_value(avctx, V4L2_CID_STATELESS_HEVC_DECODE_MODE); ++ if (ctx->decode_mode != V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED && ++ ctx->decode_mode != V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED) { + av_log(avctx, AV_LOG_ERROR, "%s: unsupported decode mode, %d\n", __func__, ctx->decode_mode); + return AVERROR(EINVAL); + } + -+ ctx->start_code = ff_v4l2_request_query_control_default_value(avctx, V4L2_CID_MPEG_VIDEO_HEVC_START_CODE); -+ if (ctx->start_code != V4L2_MPEG_VIDEO_HEVC_START_CODE_NONE && -+ ctx->start_code != V4L2_MPEG_VIDEO_HEVC_START_CODE_ANNEX_B) { ++ ctx->start_code = ff_v4l2_request_query_control_default_value(avctx, V4L2_CID_STATELESS_HEVC_START_CODE); ++ if (ctx->start_code != V4L2_STATELESS_HEVC_START_CODE_NONE && ++ ctx->start_code != V4L2_STATELESS_HEVC_START_CODE_ANNEX_B) { + av_log(avctx, AV_LOG_ERROR, "%s: unsupported start code, %d\n", __func__, ctx->start_code); + return AVERROR(EINVAL); + } + -+ ret = ff_v4l2_request_query_control(avctx, &slice_params); -+ if (ret) -+ return ret; -+ -+ ctx->max_slices = slice_params.elems; -+ if (ctx->max_slices > MAX_SLICES) { -+ av_log(avctx, AV_LOG_ERROR, "%s: unsupported max slices, %d\n", __func__, ctx->max_slices); -+ return AVERROR(EINVAL); ++ ret = ff_v4l2_request_query_control(avctx, &entry_point_offsets); ++ if (ret) { ++ ctx->supports_entry_point_offsets = 0; ++ } else { ++ ctx->supports_entry_point_offsets = 1; + } + ++ ret = ff_v4l2_request_query_control(avctx, &slice_params); ++ if (ret) { ++ ctx->supports_slices = 0; ++ ctx->max_slices = 0; ++ if (ctx->decode_mode == V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED) { ++ av_log(avctx, AV_LOG_ERROR, "%s: decoder is slice-based, \ ++ but doesn't support V4L2_CID_STATELESS_HEVC_SLICE_PARAMS control \n", __func__); ++ return AVERROR(EINVAL); ++ } ++ ++ if (ctx->supports_entry_point_offsets) { ++ av_log(avctx, AV_LOG_ERROR, "%s: decoder supports entry_point_offsets, \ ++ but doesn't support V4L2_CID_STATELESS_HEVC_SLICE_PARAMS control \n", __func__); ++ return AVERROR(EINVAL); ++ } ++ } else { ++ ctx->supports_slices = 1; ++ ctx->max_slices = slice_params.dims[0]; ++ if (ctx->max_slices > MAX_SLICES) { ++ av_log(avctx, AV_LOG_ERROR, "%s: unsupported max slices, %u\n", __func__, ctx->max_slices); ++ return AVERROR(EINVAL); ++ } ++ } ++ ++ ret = ff_v4l2_request_query_control(avctx, &scaling_matrix); ++ if (ret) { ++ ctx->supports_scaling_matrix = 0; ++ } else { ++ ctx->supports_scaling_matrix = 1; ++ } ++ ++ av_log(avctx, AV_LOG_DEBUG, "%s: decoder is %s and supports slices %d, supports entry_point_offsets: %d supports scaling_matrix: %d max slices: %u\n", ++ __func__, ++ ctx->decode_mode == V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED ? "slice based" : "frame based", ++ ctx->supports_slices, ++ ctx->supports_entry_point_offsets, ++ ctx->supports_scaling_matrix, ++ ctx->max_slices ++ ); ++ + control[0].value = ctx->decode_mode; + control[1].value = ctx->start_code; + @@ -3099,7 +3246,7 @@ index 00000000000..fd253661086 + + struct v4l2_ext_control control[] = { + { -+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SPS, ++ .id = V4L2_CID_STATELESS_HEVC_SPS, + .ptr = &sps, + .size = sizeof(sps), + }, @@ -3130,10 +3277,10 @@ index 00000000000..fd253661086 + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, +}; -From 3c9c4c99eccdda102064ea67a04c8cbf8083ad1a Mon Sep 17 00:00:00 2001 +From 44f20a53f2ef6ad0ecfb413ebcc95f92fc17377f Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 12 Dec 2019 16:13:55 +0100 -Subject: [PATCH 09/17] Add V4L2 request API VP9 hwaccel +Subject: [PATCH 09/12] Add V4L2 request API VP9 hwaccel Signed-off-by: Boris Brezillon Signed-off-by: Jernej Skrabec @@ -3141,18 +3288,18 @@ Signed-off-by: Jernej Skrabec configure | 3 + libavcodec/Makefile | 1 + libavcodec/hwaccels.h | 1 + - libavcodec/v4l2_request_vp9.c | 268 ++++++++++++++++++++++++++++++++++ - libavcodec/vp9.c | 192 +++++++++++++++++------- + libavcodec/v4l2_request_vp9.c | 282 ++++++++++++++++++++++++++++++++++ + libavcodec/vp9.c | 192 ++++++++++++++++------- libavcodec/vp9dec.h | 4 + libavcodec/vp9shared.h | 1 + - 7 files changed, 415 insertions(+), 55 deletions(-) + 7 files changed, 429 insertions(+), 55 deletions(-) create mode 100644 libavcodec/v4l2_request_vp9.c diff --git a/configure b/configure -index 02a80cf27fd..0b238c051df 100755 +index 6192a6c144..36a1271a6c 100755 --- a/configure +++ b/configure -@@ -3041,6 +3041,8 @@ vp9_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_VP9" +@@ -3042,6 +3042,8 @@ vp9_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_VP9" vp9_dxva2_hwaccel_select="vp9_decoder" vp9_nvdec_hwaccel_deps="nvdec" vp9_nvdec_hwaccel_select="vp9_decoder" @@ -3161,7 +3308,7 @@ index 02a80cf27fd..0b238c051df 100755 vp9_vaapi_hwaccel_deps="vaapi VADecPictureParameterBufferVP9_bit_depth" vp9_vaapi_hwaccel_select="vp9_decoder" vp9_vdpau_hwaccel_deps="vdpau VdpPictureInfoVP9" -@@ -6640,6 +6642,7 @@ check_cc h264_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_H264_SLICE;" +@@ -6641,6 +6643,7 @@ check_cc h264_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_H264_SLICE;" check_cc hevc_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_HEVC_SLICE;" check_cc mpeg2_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG2_SLICE;" check_cc vp8_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_VP8_FRAME;" @@ -3170,7 +3317,7 @@ index 02a80cf27fd..0b238c051df 100755 check_headers sys/videoio.h test_code cc sys/videoio.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_sanitized struct_v4l2_frmivalenum_discrete diff --git a/libavcodec/Makefile b/libavcodec/Makefile -index 0059074530c..38edf1cfe5e 100644 +index 0059074530..38edf1cfe5 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -977,6 +977,7 @@ OBJS-$(CONFIG_VP8_VAAPI_HWACCEL) += vaapi_vp8.o @@ -3182,7 +3329,7 @@ index 0059074530c..38edf1cfe5e 100644 OBJS-$(CONFIG_VP9_VDPAU_HWACCEL) += vdpau_vp9.o OBJS-$(CONFIG_VP8_QSV_HWACCEL) += qsvdec.o diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h -index ffb9fa5087d..fc5d0b0479b 100644 +index ffb9fa5087..fc5d0b0479 100644 --- a/libavcodec/hwaccels.h +++ b/libavcodec/hwaccels.h @@ -76,6 +76,7 @@ extern const AVHWAccel ff_vp9_d3d11va_hwaccel; @@ -3195,10 +3342,10 @@ index ffb9fa5087d..fc5d0b0479b 100644 extern const AVHWAccel ff_wmv3_d3d11va_hwaccel; diff --git a/libavcodec/v4l2_request_vp9.c b/libavcodec/v4l2_request_vp9.c new file mode 100644 -index 00000000000..9b95c76cdb8 +index 0000000000..ec0300f66d --- /dev/null +++ b/libavcodec/v4l2_request_vp9.c -@@ -0,0 +1,268 @@ +@@ -0,0 +1,282 @@ +/* + * This file is part of FFmpeg. + * @@ -3223,78 +3370,62 @@ index 00000000000..9b95c76cdb8 + +typedef struct V4L2RequestControlsVP9 { + struct v4l2_ctrl_vp9_frame decode_params; ++ struct v4l2_ctrl_vp9_compressed_hdr chp; +} V4L2RequestControlsVP9; + -+static int v4l2_request_vp9_set_frame_ctx(AVCodecContext *avctx) ++static void v4l2_request_vp9_set_frame_ctx(AVCodecContext *avctx) +{ + VP9Context *s = avctx->priv_data; -+ struct v4l2_ctrl_vp9_compressed_hdr chp; -+ struct v4l2_ext_control control[] = { -+ { -+ .id = V4L2_CID_STATELESS_VP9_COMPRESSED_HDR, -+ .ptr = &chp, -+ .size = sizeof(chp), -+ }, -+ }; ++ const VP9Frame *f = &s->s.frames[CUR_FRAME]; ++ V4L2RequestControlsVP9 *controls = f->hwaccel_picture_private; ++ struct v4l2_ctrl_vp9_compressed_hdr *chp = &controls->chp; + -+ memset(&chp, 0, sizeof(chp)); ++ memset(chp, 0, sizeof(&chp)); + -+ chp.tx_mode = s->s.h.txfmmode; -+ memcpy(chp.tx8, s->prob_raw.p.tx8p, sizeof(s->prob_raw.p.tx8p)); -+ memcpy(chp.tx16, s->prob_raw.p.tx16p, sizeof(s->prob_raw.p.tx16p)); -+ memcpy(chp.tx32, s->prob_raw.p.tx32p, sizeof(s->prob_raw.p.tx32p)); ++ chp->tx_mode = s->s.h.txfmmode; ++ memcpy(chp->tx8, s->prob_raw.p.tx8p, sizeof(s->prob_raw.p.tx8p)); ++ memcpy(chp->tx16, s->prob_raw.p.tx16p, sizeof(s->prob_raw.p.tx16p)); ++ memcpy(chp->tx32, s->prob_raw.p.tx32p, sizeof(s->prob_raw.p.tx32p)); + for (unsigned i = 0; i < 4; i++) { + for (unsigned j = 0; j < 2; j++) { + for (unsigned k = 0; k < 2; k++) { + for (unsigned l = 0; l < 6; l++) { + for (unsigned m = 0; m < 6; m++) { -+ memcpy(chp.coef[i][j][k][l][m], s->prob_raw.coef[i][j][k][l][m], sizeof(chp.coef[0][0][0][0][0])); ++ memcpy(chp->coef[i][j][k][l][m], s->prob_raw.coef[i][j][k][l][m], sizeof(chp->coef[0][0][0][0][0])); + } + } + } + } + } -+ memcpy(chp.skip, s->prob_raw.p.skip, sizeof(s->prob_raw.p.skip)); -+ memcpy(chp.inter_mode, s->prob_raw.p.mv_mode, sizeof(s->prob_raw.p.mv_mode)); -+ memcpy(chp.interp_filter, s->prob_raw.p.filter, sizeof(s->prob_raw.p.filter)); -+ memcpy(chp.is_inter, s->prob_raw.p.intra, sizeof(s->prob_raw.p.intra)); -+ memcpy(chp.comp_mode, s->prob_raw.p.comp, sizeof(s->prob_raw.p.comp)); -+ memcpy(chp.single_ref, s->prob_raw.p.single_ref, sizeof(s->prob_raw.p.single_ref)); -+ memcpy(chp.comp_ref, s->prob_raw.p.comp_ref, sizeof(s->prob_raw.p.comp_ref)); -+ memcpy(chp.y_mode, s->prob_raw.p.y_mode, sizeof(s->prob_raw.p.y_mode)); ++ memcpy(chp->skip, s->prob_raw.p.skip, sizeof(s->prob_raw.p.skip)); ++ memcpy(chp->inter_mode, s->prob_raw.p.mv_mode, sizeof(s->prob_raw.p.mv_mode)); ++ memcpy(chp->interp_filter, s->prob_raw.p.filter, sizeof(s->prob_raw.p.filter)); ++ memcpy(chp->is_inter, s->prob_raw.p.intra, sizeof(s->prob_raw.p.intra)); ++ memcpy(chp->comp_mode, s->prob_raw.p.comp, sizeof(s->prob_raw.p.comp)); ++ memcpy(chp->single_ref, s->prob_raw.p.single_ref, sizeof(s->prob_raw.p.single_ref)); ++ memcpy(chp->comp_ref, s->prob_raw.p.comp_ref, sizeof(s->prob_raw.p.comp_ref)); ++ memcpy(chp->y_mode, s->prob_raw.p.y_mode, sizeof(s->prob_raw.p.y_mode)); + for (unsigned i = 0; i < 10; i++) -+ memcpy(chp.uv_mode[i], s->prob.p.uv_mode[i], sizeof(s->prob.p.uv_mode[0])); ++ memcpy(chp->uv_mode[i], s->prob.p.uv_mode[i], sizeof(s->prob.p.uv_mode[0])); + for (unsigned i = 0; i < 4; i++) -+ memcpy(chp.partition[i * 4], s->prob_raw.p.partition[i], sizeof(s->prob_raw.p.partition[0])); -+ memcpy(chp.mv.joint, s->prob_raw.p.mv_joint, sizeof(s->prob_raw.p.mv_joint)); ++ memcpy(chp->partition[i * 4], s->prob_raw.p.partition[i], sizeof(s->prob_raw.p.partition[0])); ++ memcpy(chp->mv.joint, s->prob_raw.p.mv_joint, sizeof(s->prob_raw.p.mv_joint)); + for (unsigned i = 0; i < 2; i++) { -+ chp.mv.sign[i] = s->prob_raw.p.mv_comp[i].sign; -+ memcpy(chp.mv.classes[i], s->prob_raw.p.mv_comp[i].classes, sizeof(s->prob_raw.p.mv_comp[0].classes)); -+ chp.mv.class0_bit[i] = s->prob_raw.p.mv_comp[i].class0; -+ memcpy(chp.mv.bits[i], s->prob_raw.p.mv_comp[i].bits, sizeof(s->prob_raw.p.mv_comp[0].bits)); -+ memcpy(chp.mv.class0_fr[i], s->prob_raw.p.mv_comp[i].class0_fp, sizeof(s->prob_raw.p.mv_comp[0].class0_fp)); -+ memcpy(chp.mv.fr[i], s->prob_raw.p.mv_comp[i].fp, sizeof(s->prob_raw.p.mv_comp[0].fp)); -+ chp.mv.class0_hp[i] = s->prob_raw.p.mv_comp[i].class0_hp; -+ chp.mv.hp[i] = s->prob_raw.p.mv_comp[i].hp; ++ chp->mv.sign[i] = s->prob_raw.p.mv_comp[i].sign; ++ memcpy(chp->mv.classes[i], s->prob_raw.p.mv_comp[i].classes, sizeof(s->prob_raw.p.mv_comp[0].classes)); ++ chp->mv.class0_bit[i] = s->prob_raw.p.mv_comp[i].class0; ++ memcpy(chp->mv.bits[i], s->prob_raw.p.mv_comp[i].bits, sizeof(s->prob_raw.p.mv_comp[0].bits)); ++ memcpy(chp->mv.class0_fr[i], s->prob_raw.p.mv_comp[i].class0_fp, sizeof(s->prob_raw.p.mv_comp[0].class0_fp)); ++ memcpy(chp->mv.fr[i], s->prob_raw.p.mv_comp[i].fp, sizeof(s->prob_raw.p.mv_comp[0].fp)); ++ chp->mv.class0_hp[i] = s->prob_raw.p.mv_comp[i].class0_hp; ++ chp->mv.hp[i] = s->prob_raw.p.mv_comp[i].hp; + } -+ -+ return ff_v4l2_request_set_controls(avctx, control, FF_ARRAY_ELEMS(control)); +} + -+static int v4l2_request_vp9_start_frame(AVCodecContext *avctx, -+ av_unused const uint8_t *buffer, -+ av_unused uint32_t size) ++static void fill_frame(struct v4l2_ctrl_vp9_frame *dec_params, AVCodecContext *avctx) +{ + const VP9Context *s = avctx->priv_data; -+ const VP9Frame *f = &s->s.frames[CUR_FRAME]; -+ V4L2RequestControlsVP9 *controls = f->hwaccel_picture_private; -+ struct v4l2_ctrl_vp9_frame *dec_params = &controls->decode_params; + const ThreadFrame *ref; -+ int ret; -+ -+ ret = v4l2_request_vp9_set_frame_ctx(avctx); -+ if (ret) -+ return ret; + + memset(dec_params, 0, sizeof(*dec_params)); + @@ -3409,6 +3540,19 @@ index 00000000000..9b95c76cdb8 + if (s->s.h.segmentation.feat[i].skip_enabled) + dec_params->seg.feature_enabled[i] |= 1 << V4L2_VP9_SEG_LVL_SKIP; + } ++} ++ ++static int v4l2_request_vp9_start_frame(AVCodecContext *avctx, ++ av_unused const uint8_t *buffer, ++ av_unused uint32_t size) ++{ ++ const VP9Context *s = avctx->priv_data; ++ const VP9Frame *f = &s->s.frames[CUR_FRAME]; ++ V4L2RequestControlsVP9 *controls = f->hwaccel_picture_private; ++ ++ v4l2_request_vp9_set_frame_ctx(avctx); ++ ++ fill_frame(&controls->decode_params, avctx); + + return ff_v4l2_request_reset_frame(avctx, f->tf.f); +} @@ -3434,6 +3578,11 @@ index 00000000000..9b95c76cdb8 + .ptr = &controls->decode_params, + .size = sizeof(controls->decode_params), + }, ++ { ++ .id = V4L2_CID_STATELESS_VP9_COMPRESSED_HDR, ++ .ptr = &controls->chp, ++ .size = sizeof(controls->chp), ++ }, + }; + + ret = ff_v4l2_request_decode_frame(avctx, f->tf.f, control, FF_ARRAY_ELEMS(control)); @@ -3448,8 +3597,20 @@ index 00000000000..9b95c76cdb8 + +static int v4l2_request_vp9_init(AVCodecContext *avctx) +{ ++ struct v4l2_ctrl_vp9_frame frame; ++ ++ struct v4l2_ext_control control[] = { ++ { ++ .id = V4L2_CID_STATELESS_VP9_FRAME, ++ .ptr = &frame, ++ .size = sizeof(frame), ++ }, ++ }; ++ ++ fill_frame(&frame, avctx); ++ + // TODO: check V4L2_CID_MPEG_VIDEO_VP9_PROFILE -+ return ff_v4l2_request_init(avctx, V4L2_PIX_FMT_VP9_FRAME, 3 * 1024 * 1024, NULL, 0); ++ return ff_v4l2_request_init(avctx, V4L2_PIX_FMT_VP9_FRAME, 3 * 1024 * 1024, control, FF_ARRAY_ELEMS(control)); +} + +const AVHWAccel ff_vp9_v4l2request_hwaccel = { @@ -3468,7 +3629,7 @@ index 00000000000..9b95c76cdb8 + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, +}; diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c -index 4659f94ee8b..1b2f1eeaf69 100644 +index 4659f94ee8..1b2f1eeaf6 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -191,6 +191,7 @@ static int update_size(AVCodecContext *avctx, int w, int h) @@ -3831,7 +3992,7 @@ index 4659f94ee8b..1b2f1eeaf69 100644 NULL }, diff --git a/libavcodec/vp9dec.h b/libavcodec/vp9dec.h -index d82b258a3d8..8d2c341e0b9 100644 +index d82b258a3d..8d2c341e0b 100644 --- a/libavcodec/vp9dec.h +++ b/libavcodec/vp9dec.h @@ -131,6 +131,10 @@ typedef struct VP9Context { @@ -3846,7 +4007,7 @@ index d82b258a3d8..8d2c341e0b9 100644 // contextual (above) cache uint8_t *above_partition_ctx; diff --git a/libavcodec/vp9shared.h b/libavcodec/vp9shared.h -index 54726df742f..fee3568736f 100644 +index 54726df742..fee3568736 100644 --- a/libavcodec/vp9shared.h +++ b/libavcodec/vp9shared.h @@ -131,6 +131,7 @@ typedef struct VP9BitstreamHeader { @@ -3858,307 +4019,10 @@ index 54726df742f..fee3568736f 100644 uint8_t pred_prob[3]; struct { -From 3d23a6cb94067e5c2529955551d6a8fcc8e48acd Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Thu, 14 Feb 2019 23:20:05 +0100 -Subject: [PATCH 10/17] Add and use private linux v5.18 headers for V4L2 - request API ctrls - -Signed-off-by: Jernej Skrabec -Signed-off-by: Jonas Karlman ---- - configure | 2 +- - libavcodec/hevc-ctrls.h | 250 +++++++++++++++++++++++++++++++++ - libavcodec/v4l2_request_hevc.c | 1 + - 3 files changed, 252 insertions(+), 1 deletion(-) - create mode 100644 libavcodec/hevc-ctrls.h - -diff --git a/configure b/configure -index 0b238c051df..1c1929d2c28 100755 ---- a/configure -+++ b/configure -@@ -2967,7 +2967,7 @@ hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC" - hevc_dxva2_hwaccel_select="hevc_decoder" - hevc_nvdec_hwaccel_deps="nvdec" - hevc_nvdec_hwaccel_select="hevc_decoder" --hevc_v4l2request_hwaccel_deps="v4l2_request hevc_v4l2_request" -+hevc_v4l2request_hwaccel_deps="v4l2_request" - hevc_v4l2request_hwaccel_select="hevc_decoder" - hevc_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferHEVC" - hevc_vaapi_hwaccel_select="hevc_decoder" -diff --git a/libavcodec/hevc-ctrls.h b/libavcodec/hevc-ctrls.h -new file mode 100644 -index 00000000000..01ccda48d8c ---- /dev/null -+++ b/libavcodec/hevc-ctrls.h -@@ -0,0 +1,250 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * These are the HEVC state controls for use with stateless HEVC -+ * codec drivers. -+ * -+ * It turns out that these structs are not stable yet and will undergo -+ * more changes. So keep them private until they are stable and ready to -+ * become part of the official public API. -+ */ -+ -+#ifndef _HEVC_CTRLS_H_ -+#define _HEVC_CTRLS_H_ -+ -+#include -+ -+/* The pixel format isn't stable at the moment and will likely be renamed. */ -+#define V4L2_PIX_FMT_HEVC_SLICE v4l2_fourcc('S', '2', '6', '5') /* HEVC parsed slices */ -+ -+#define V4L2_CID_MPEG_VIDEO_HEVC_SPS (V4L2_CID_CODEC_BASE + 1008) -+#define V4L2_CID_MPEG_VIDEO_HEVC_PPS (V4L2_CID_CODEC_BASE + 1009) -+#define V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS (V4L2_CID_CODEC_BASE + 1010) -+#define V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX (V4L2_CID_CODEC_BASE + 1011) -+#define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS (V4L2_CID_CODEC_BASE + 1012) -+#define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE (V4L2_CID_CODEC_BASE + 1015) -+#define V4L2_CID_MPEG_VIDEO_HEVC_START_CODE (V4L2_CID_CODEC_BASE + 1016) -+ -+/* enum v4l2_ctrl_type type values */ -+#define V4L2_CTRL_TYPE_HEVC_SPS 0x0120 -+#define V4L2_CTRL_TYPE_HEVC_PPS 0x0121 -+#define V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS 0x0122 -+#define V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX 0x0123 -+#define V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS 0x0124 -+ -+enum v4l2_mpeg_video_hevc_decode_mode { -+ V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED, -+ V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_FRAME_BASED, -+}; -+ -+enum v4l2_mpeg_video_hevc_start_code { -+ V4L2_MPEG_VIDEO_HEVC_START_CODE_NONE, -+ V4L2_MPEG_VIDEO_HEVC_START_CODE_ANNEX_B, -+}; -+ -+#define V4L2_HEVC_SLICE_TYPE_B 0 -+#define V4L2_HEVC_SLICE_TYPE_P 1 -+#define V4L2_HEVC_SLICE_TYPE_I 2 -+ -+#define V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE (1ULL << 0) -+#define V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED (1ULL << 1) -+#define V4L2_HEVC_SPS_FLAG_AMP_ENABLED (1ULL << 2) -+#define V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET (1ULL << 3) -+#define V4L2_HEVC_SPS_FLAG_PCM_ENABLED (1ULL << 4) -+#define V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED (1ULL << 5) -+#define V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT (1ULL << 6) -+#define V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED (1ULL << 7) -+#define V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED (1ULL << 8) -+ -+/* The controls are not stable at the moment and will likely be reworked. */ -+struct v4l2_ctrl_hevc_sps { -+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Sequence parameter set */ -+ __u16 pic_width_in_luma_samples; -+ __u16 pic_height_in_luma_samples; -+ __u8 bit_depth_luma_minus8; -+ __u8 bit_depth_chroma_minus8; -+ __u8 log2_max_pic_order_cnt_lsb_minus4; -+ __u8 sps_max_dec_pic_buffering_minus1; -+ __u8 sps_max_num_reorder_pics; -+ __u8 sps_max_latency_increase_plus1; -+ __u8 log2_min_luma_coding_block_size_minus3; -+ __u8 log2_diff_max_min_luma_coding_block_size; -+ __u8 log2_min_luma_transform_block_size_minus2; -+ __u8 log2_diff_max_min_luma_transform_block_size; -+ __u8 max_transform_hierarchy_depth_inter; -+ __u8 max_transform_hierarchy_depth_intra; -+ __u8 pcm_sample_bit_depth_luma_minus1; -+ __u8 pcm_sample_bit_depth_chroma_minus1; -+ __u8 log2_min_pcm_luma_coding_block_size_minus3; -+ __u8 log2_diff_max_min_pcm_luma_coding_block_size; -+ __u8 num_short_term_ref_pic_sets; -+ __u8 num_long_term_ref_pics_sps; -+ __u8 chroma_format_idc; -+ __u8 sps_max_sub_layers_minus1; -+ -+ __u64 flags; -+}; -+ -+#define V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT_ENABLED (1ULL << 0) -+#define V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT (1ULL << 1) -+#define V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED (1ULL << 2) -+#define V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT (1ULL << 3) -+#define V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED (1ULL << 4) -+#define V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED (1ULL << 5) -+#define V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED (1ULL << 6) -+#define V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT (1ULL << 7) -+#define V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED (1ULL << 8) -+#define V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED (1ULL << 9) -+#define V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED (1ULL << 10) -+#define V4L2_HEVC_PPS_FLAG_TILES_ENABLED (1ULL << 11) -+#define V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED (1ULL << 12) -+#define V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED (1ULL << 13) -+#define V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED (1ULL << 14) -+#define V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_OVERRIDE_ENABLED (1ULL << 15) -+#define V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER (1ULL << 16) -+#define V4L2_HEVC_PPS_FLAG_LISTS_MODIFICATION_PRESENT (1ULL << 17) -+#define V4L2_HEVC_PPS_FLAG_SLICE_SEGMENT_HEADER_EXTENSION_PRESENT (1ULL << 18) -+#define V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT (1ULL << 19) -+#define V4L2_HEVC_PPS_FLAG_UNIFORM_SPACING (1ULL << 20) -+ -+struct v4l2_ctrl_hevc_pps { -+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture parameter set */ -+ __u8 num_extra_slice_header_bits; -+ __u8 num_ref_idx_l0_default_active_minus1; -+ __u8 num_ref_idx_l1_default_active_minus1; -+ __s8 init_qp_minus26; -+ __u8 diff_cu_qp_delta_depth; -+ __s8 pps_cb_qp_offset; -+ __s8 pps_cr_qp_offset; -+ __u8 num_tile_columns_minus1; -+ __u8 num_tile_rows_minus1; -+ __u8 column_width_minus1[20]; -+ __u8 row_height_minus1[22]; -+ __s8 pps_beta_offset_div2; -+ __s8 pps_tc_offset_div2; -+ __u8 log2_parallel_merge_level_minus2; -+ -+ __u8 padding[4]; -+ __u64 flags; -+}; -+ -+#define V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE 0x01 -+ -+#define V4L2_HEVC_DPB_ENTRIES_NUM_MAX 16 -+ -+struct v4l2_hevc_dpb_entry { -+ __u64 timestamp; -+ __u8 flags; -+ __u8 field_pic; -+ __u16 pic_order_cnt[2]; -+ __u8 padding[2]; -+}; -+ -+struct v4l2_hevc_pred_weight_table { -+ __s8 delta_luma_weight_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; -+ __s8 luma_offset_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; -+ __s8 delta_chroma_weight_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]; -+ __s8 chroma_offset_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]; -+ -+ __s8 delta_luma_weight_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; -+ __s8 luma_offset_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; -+ __s8 delta_chroma_weight_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]; -+ __s8 chroma_offset_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]; -+ -+ __u8 padding[6]; -+ -+ __u8 luma_log2_weight_denom; -+ __s8 delta_chroma_log2_weight_denom; -+}; -+ -+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_LUMA (1ULL << 0) -+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_CHROMA (1ULL << 1) -+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_TEMPORAL_MVP_ENABLED (1ULL << 2) -+#define V4L2_HEVC_SLICE_PARAMS_FLAG_MVD_L1_ZERO (1ULL << 3) -+#define V4L2_HEVC_SLICE_PARAMS_FLAG_CABAC_INIT (1ULL << 4) -+#define V4L2_HEVC_SLICE_PARAMS_FLAG_COLLOCATED_FROM_L0 (1ULL << 5) -+#define V4L2_HEVC_SLICE_PARAMS_FLAG_USE_INTEGER_MV (1ULL << 6) -+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED (1ULL << 7) -+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED (1ULL << 8) -+#define V4L2_HEVC_SLICE_PARAMS_FLAG_DEPENDENT_SLICE_SEGMENT (1ULL << 9) -+ -+struct v4l2_ctrl_hevc_slice_params { -+ __u32 bit_size; -+ __u32 data_bit_offset; -+ -+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: NAL unit header */ -+ __u8 nal_unit_type; -+ __u8 nuh_temporal_id_plus1; -+ -+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ -+ __u8 slice_type; -+ __u8 colour_plane_id; -+ __u16 slice_pic_order_cnt; -+ __u8 num_ref_idx_l0_active_minus1; -+ __u8 num_ref_idx_l1_active_minus1; -+ __u8 collocated_ref_idx; -+ __u8 five_minus_max_num_merge_cand; -+ __s8 slice_qp_delta; -+ __s8 slice_cb_qp_offset; -+ __s8 slice_cr_qp_offset; -+ __s8 slice_act_y_qp_offset; -+ __s8 slice_act_cb_qp_offset; -+ __s8 slice_act_cr_qp_offset; -+ __s8 slice_beta_offset_div2; -+ __s8 slice_tc_offset_div2; -+ -+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture timing SEI message */ -+ __u8 pic_struct; -+ -+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ -+ __u32 slice_segment_addr; -+ __u8 ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; -+ __u8 ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; -+ -+ __u8 padding; -+ -+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Weighted prediction parameter */ -+ struct v4l2_hevc_pred_weight_table pred_weight_table; -+ -+ __u64 flags; -+}; -+ -+#define V4L2_HEVC_DECODE_PARAM_FLAG_IRAP_PIC 0x1 -+#define V4L2_HEVC_DECODE_PARAM_FLAG_IDR_PIC 0x2 -+#define V4L2_HEVC_DECODE_PARAM_FLAG_NO_OUTPUT_OF_PRIOR 0x4 -+ -+struct v4l2_ctrl_hevc_decode_params { -+ __s32 pic_order_cnt_val; -+ __u8 num_active_dpb_entries; -+ struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; -+ __u8 num_poc_st_curr_before; -+ __u8 num_poc_st_curr_after; -+ __u8 num_poc_lt_curr; -+ __u8 poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; -+ __u8 poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; -+ __u8 poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; -+ __u64 flags; -+}; -+ -+struct v4l2_ctrl_hevc_scaling_matrix { -+ __u8 scaling_list_4x4[6][16]; -+ __u8 scaling_list_8x8[6][64]; -+ __u8 scaling_list_16x16[6][64]; -+ __u8 scaling_list_32x32[2][64]; -+ __u8 scaling_list_dc_coef_16x16[6]; -+ __u8 scaling_list_dc_coef_32x32[2]; -+}; -+ -+/* MPEG-class control IDs specific to the Hantro driver as defined by V4L2 */ -+#define V4L2_CID_CODEC_HANTRO_BASE (V4L2_CTRL_CLASS_CODEC | 0x1200) -+/* -+ * V4L2_CID_HANTRO_HEVC_SLICE_HEADER_SKIP - -+ * the number of data (in bits) to skip in the -+ * slice segment header. -+ * If non-IDR, the bits to be skipped go from syntax element "pic_output_flag" -+ * to before syntax element "slice_temporal_mvp_enabled_flag". -+ * If IDR, the skipped bits are just "pic_output_flag" -+ * (separate_colour_plane_flag is not supported). -+ */ -+#define V4L2_CID_HANTRO_HEVC_SLICE_HEADER_SKIP (V4L2_CID_CODEC_HANTRO_BASE + 0) -+ -+#endif -diff --git a/libavcodec/v4l2_request_hevc.c b/libavcodec/v4l2_request_hevc.c -index fd253661086..949df3811ac 100644 ---- a/libavcodec/v4l2_request_hevc.c -+++ b/libavcodec/v4l2_request_hevc.c -@@ -19,6 +19,7 @@ - #include "hevcdec.h" - #include "hwconfig.h" - #include "v4l2_request.h" -+#include "hevc-ctrls.h" - - #define MAX_SLICES 16 - - -From bb3cf90c0533a0096dff74b416f55832814293e0 Mon Sep 17 00:00:00 2001 +From 0a7d6808383a5c88a690b7ba6c634970dcd33548 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 29 Apr 2019 22:08:59 +0000 -Subject: [PATCH 11/17] HACK: hwcontext_drm: do not require drm device +Subject: [PATCH 10/12] HACK: hwcontext_drm: do not require drm device Signed-off-by: Jonas Karlman --- @@ -4166,7 +4030,7 @@ Signed-off-by: Jonas Karlman 1 file changed, 5 insertions(+) diff --git a/libavutil/hwcontext_drm.c b/libavutil/hwcontext_drm.c -index 7a9fdbd263d..6297d1f9b61 100644 +index 7a9fdbd263..6297d1f9b6 100644 --- a/libavutil/hwcontext_drm.c +++ b/libavutil/hwcontext_drm.c @@ -53,6 +53,11 @@ static int drm_device_create(AVHWDeviceContext *hwdev, const char *device, @@ -4182,57 +4046,10 @@ index 7a9fdbd263d..6297d1f9b61 100644 if (hwctx->fd < 0) return AVERROR(errno); -From 0a9c478c1e826eb1ecff27da1206542614449de5 Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Sat, 15 Dec 2018 22:32:16 +0100 -Subject: [PATCH 12/17] WIP: hevc entry point offsets - -Signed-off-by: Jernej Skrabec ---- - libavcodec/hevc-ctrls.h | 4 +++- - libavcodec/v4l2_request_hevc.c | 9 +++++++++ - 2 files changed, 12 insertions(+), 1 deletion(-) - -diff --git a/libavcodec/hevc-ctrls.h b/libavcodec/hevc-ctrls.h -index 01ccda48d8c..00bae349d34 100644 ---- a/libavcodec/hevc-ctrls.h -+++ b/libavcodec/hevc-ctrls.h -@@ -200,7 +200,9 @@ struct v4l2_ctrl_hevc_slice_params { - __u8 ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; - __u8 ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; - -- __u8 padding; -+ __u32 num_entry_point_offsets; -+ __u32 entry_point_offset_minus1[256]; -+ __u8 padding[8]; - - /* ISO/IEC 23008-2, ITU-T Rec. H.265: Weighted prediction parameter */ - struct v4l2_hevc_pred_weight_table pred_weight_table; -diff --git a/libavcodec/v4l2_request_hevc.c b/libavcodec/v4l2_request_hevc.c -index 949df3811ac..b74244f3be6 100644 ---- a/libavcodec/v4l2_request_hevc.c -+++ b/libavcodec/v4l2_request_hevc.c -@@ -232,6 +232,15 @@ static void v4l2_request_hevc_fill_slice_params(const HEVCContext *h, - } - - v4l2_request_hevc_fill_pred_table(h, &slice_params->pred_weight_table); -+ -+ slice_params->num_entry_point_offsets = sh->num_entry_point_offsets; -+ if (slice_params->num_entry_point_offsets > 256) { -+ slice_params->num_entry_point_offsets = 256; -+ av_log(NULL, AV_LOG_ERROR, "%s: Currently only 256 entry points are supported, but slice has %d entry points.\n", __func__, sh->num_entry_point_offsets); -+ } -+ -+ for (i = 0; i < slice_params->num_entry_point_offsets; i++) -+ slice_params->entry_point_offset_minus1[i] = sh->entry_point_offset[i] - 1; - } - - static void fill_sps(struct v4l2_ctrl_hevc_sps *ctrl, const HEVCContext *h) - -From 154405d2d8987c741e722f59430fda9326c8cdef Mon Sep 17 00:00:00 2001 +From d82c704c262fea62250c5989d8e97cdd769d8359 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Fri, 15 May 2020 16:54:05 +0000 -Subject: [PATCH 13/17] WIP: add NV15 and NV20 support +Subject: [PATCH 11/12] WIP: add NV15 and NV20 support Signed-off-by: Jonas Karlman --- @@ -4241,7 +4058,7 @@ Signed-off-by: Jonas Karlman 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c -index 0a10d00aad9..45057fd049b 100644 +index 6b7f569da4..ee4c76cf41 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -794,10 +794,17 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback) @@ -4275,7 +4092,7 @@ index 0a10d00aad9..45057fd049b 100644 *fmt++ = AV_PIX_FMT_YUVJ422P; else diff --git a/libavcodec/v4l2_request.c b/libavcodec/v4l2_request.c -index 5234b5049b0..0b294feff2e 100644 +index b57bbf29bc..349ed67cb2 100644 --- a/libavcodec/v4l2_request.c +++ b/libavcodec/v4l2_request.c @@ -188,6 +188,13 @@ const uint32_t v4l2_request_capture_pixelformats[] = { @@ -4316,17 +4133,17 @@ index 5234b5049b0..0b294feff2e 100644 default: return -1; -From d7933e19a712a59af418f6b029c0984d5b29afe9 Mon Sep 17 00:00:00 2001 +From 0b8eff40d910669ea03417f76468fcf2518d293e Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 27 Jul 2020 23:15:45 +0000 -Subject: [PATCH 14/17] HACK: define drm NV15 and NV20 format +Subject: [PATCH 12/12] HACK: define drm NV15 and NV20 format --- libavcodec/v4l2_request.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libavcodec/v4l2_request.c b/libavcodec/v4l2_request.c -index 0b294feff2e..a8f0ee79eee 100644 +index 349ed67cb2..824dcaa8e9 100644 --- a/libavcodec/v4l2_request.c +++ b/libavcodec/v4l2_request.c @@ -30,6 +30,14 @@ @@ -4344,364 +4161,3 @@ index 0b294feff2e..a8f0ee79eee 100644 uint64_t ff_v4l2_request_get_capture_timestamp(AVFrame *frame) { V4L2RequestDescriptor *req = (V4L2RequestDescriptor*)frame->data[0]; - -From 7ebf970204f1aaabc3d0ca0c81d8d4dd99916c56 Mon Sep 17 00:00:00 2001 -From: Jonas Karlman -Date: Wed, 13 May 2020 22:51:21 +0000 -Subject: [PATCH 15/17] WIP: hevc rkvdec fields - -Signed-off-by: Jonas Karlman ---- - libavcodec/hevc-ctrls.h | 11 ++++++++++- - libavcodec/v4l2_request_hevc.c | 12 ++++++++++++ - 2 files changed, 22 insertions(+), 1 deletion(-) - -diff --git a/libavcodec/hevc-ctrls.h b/libavcodec/hevc-ctrls.h -index 00bae349d34..2ecec618669 100644 ---- a/libavcodec/hevc-ctrls.h -+++ b/libavcodec/hevc-ctrls.h -@@ -58,6 +58,8 @@ enum v4l2_mpeg_video_hevc_start_code { - /* The controls are not stable at the moment and will likely be reworked. */ - struct v4l2_ctrl_hevc_sps { - /* ISO/IEC 23008-2, ITU-T Rec. H.265: Sequence parameter set */ -+ __u8 video_parameter_set_id; -+ __u8 seq_parameter_set_id; - __u16 pic_width_in_luma_samples; - __u16 pic_height_in_luma_samples; - __u8 bit_depth_luma_minus8; -@@ -81,6 +83,9 @@ struct v4l2_ctrl_hevc_sps { - __u8 chroma_format_idc; - __u8 sps_max_sub_layers_minus1; - -+ __u8 num_slices; -+ __u8 padding[5]; -+ - __u64 flags; - }; - -@@ -108,6 +113,7 @@ struct v4l2_ctrl_hevc_sps { - - struct v4l2_ctrl_hevc_pps { - /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture parameter set */ -+ __u8 pic_parameter_set_id; - __u8 num_extra_slice_header_bits; - __u8 num_ref_idx_l0_default_active_minus1; - __u8 num_ref_idx_l1_default_active_minus1; -@@ -123,7 +129,7 @@ struct v4l2_ctrl_hevc_pps { - __s8 pps_tc_offset_div2; - __u8 log2_parallel_merge_level_minus2; - -- __u8 padding[4]; -+ __u8 padding; - __u64 flags; - }; - -@@ -200,6 +206,9 @@ struct v4l2_ctrl_hevc_slice_params { - __u8 ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; - __u8 ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; - -+ __u16 short_term_ref_pic_set_size; -+ __u16 long_term_ref_pic_set_size; -+ - __u32 num_entry_point_offsets; - __u32 entry_point_offset_minus1[256]; - __u8 padding[8]; -diff --git a/libavcodec/v4l2_request_hevc.c b/libavcodec/v4l2_request_hevc.c -index b74244f3be6..093700c4063 100644 ---- a/libavcodec/v4l2_request_hevc.c -+++ b/libavcodec/v4l2_request_hevc.c -@@ -190,6 +190,9 @@ static void v4l2_request_hevc_fill_slice_params(const HEVCContext *h, - - /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture timing SEI message */ - .pic_struct = h->sei.picture_timing.picture_struct, -+ -+ .short_term_ref_pic_set_size = sh->short_term_ref_pic_set_size, -+ .long_term_ref_pic_set_size = sh->long_term_ref_pic_set_size, - }; - - if (sh->slice_sample_adaptive_offset_flag[0]) -@@ -246,9 +249,12 @@ static void v4l2_request_hevc_fill_slice_params(const HEVCContext *h, - static void fill_sps(struct v4l2_ctrl_hevc_sps *ctrl, const HEVCContext *h) - { - const HEVCSPS *sps = h->ps.sps; -+ const HEVCPPS *pps = h->ps.pps; - - /* ISO/IEC 23008-2, ITU-T Rec. H.265: Sequence parameter set */ - *ctrl = (struct v4l2_ctrl_hevc_sps) { -+ .video_parameter_set_id = sps->vps_id, -+ .seq_parameter_set_id = pps->sps_id, - .pic_width_in_luma_samples = sps->width, - .pic_height_in_luma_samples = sps->height, - .bit_depth_luma_minus8 = sps->bit_depth - 8, -@@ -312,6 +318,7 @@ static int v4l2_request_hevc_start_frame(AVCodecContext *avctx, - &pps->scaling_list : - sps->scaling_list_enable_flag ? - &sps->scaling_list : NULL; -+ const SliceHeader *sh = &h->sh; - V4L2RequestControlsHEVC *controls = h->ref->hwaccel_picture_private; - - fill_sps(&controls->sps, h); -@@ -335,6 +342,9 @@ static int v4l2_request_hevc_start_frame(AVCodecContext *avctx, - - /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture parameter set */ - controls->pps = (struct v4l2_ctrl_hevc_pps) { -+ .pic_parameter_set_id = sh->pps_id, -+ .num_ref_idx_l0_default_active_minus1 = pps->num_ref_idx_l0_default_active - 1, -+ .num_ref_idx_l1_default_active_minus1 = pps->num_ref_idx_l1_default_active - 1, - .num_extra_slice_header_bits = pps->num_extra_slice_header_bits, - .num_ref_idx_l0_default_active_minus1 = pps->num_ref_idx_l0_default_active - 1, - .num_ref_idx_l1_default_active_minus1 = pps->num_ref_idx_l1_default_active - 1, -@@ -464,6 +474,8 @@ static int v4l2_request_hevc_queue_decode(AVCodecContext *avctx, int last_slice) - if (ctx->decode_mode == V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED) - return ff_v4l2_request_decode_slice(avctx, h->ref->frame, control, FF_ARRAY_ELEMS(control), controls->first_slice, last_slice); - -+ controls->sps.num_slices = controls->num_slices; -+ - return ff_v4l2_request_decode_frame(avctx, h->ref->frame, control, FF_ARRAY_ELEMS(control)); - } - - -From c9ae9a29ef84096bb2e4d37fbdea6c3b3d20fff7 Mon Sep 17 00:00:00 2001 -From: Alex Bee -Date: Sun, 19 Sep 2021 13:10:55 +0200 -Subject: [PATCH 16/17] v4l2_request: validate supported framesizes - -Signed-off-by: Alex Bee ---- - libavcodec/v4l2_request.c | 38 +++++++++++++++++++++++++++++++++++++- - 1 file changed, 37 insertions(+), 1 deletion(-) - -diff --git a/libavcodec/v4l2_request.c b/libavcodec/v4l2_request.c -index a8f0ee79eee..2fbe1663416 100644 ---- a/libavcodec/v4l2_request.c -+++ b/libavcodec/v4l2_request.c -@@ -376,6 +376,42 @@ int ff_v4l2_request_decode_frame(AVCodecContext *avctx, AVFrame *frame, struct v - return v4l2_request_queue_decode(avctx, frame, control, count, 1, 1); - } - -+static int v4l2_request_try_framesize(AVCodecContext *avctx, uint32_t pixelformat) -+{ -+ V4L2RequestContext *ctx = avctx->internal->hwaccel_priv_data; -+ struct v4l2_frmsizeenum frmsize = { -+ .index = 0, -+ .pixel_format = pixelformat, -+ }; -+ -+ if (ioctl(ctx->video_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) < 0) -+ return 0; -+ -+ /* -+ * We only validate min/max framesize for V4L2_FRMSIZE_TYPE_STEPWISE here, since the alignment -+ * which is eventually needed will be done driver-side later in VIDIOC_S_FMT and there is no need -+ * validate step_width/step_height here -+ */ -+ -+ do { -+ -+ if (frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE && frmsize.discrete.width == avctx->coded_width && -+ frmsize.discrete.height == avctx->coded_height) -+ return 0; -+ else if ((frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE || frmsize.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) && -+ avctx->coded_width >= frmsize.stepwise.min_width && avctx->coded_height >= frmsize.stepwise.min_height && -+ avctx->coded_width <= frmsize.stepwise.max_width && avctx->coded_height <= frmsize.stepwise.max_height) -+ return 0; -+ -+ frmsize.index++; -+ -+ } while (ioctl(ctx->video_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) >= 0); -+ -+ av_log(avctx, AV_LOG_INFO, "%s: pixelformat %u not supported for width %u height %u\n", __func__, pixelformat, avctx->coded_width, avctx->coded_height); -+ -+ return -1; -+} -+ - static int v4l2_request_try_format(AVCodecContext *avctx, enum v4l2_buf_type type, uint32_t pixelformat) - { - V4L2RequestContext *ctx = avctx->internal->hwaccel_priv_data; -@@ -404,7 +440,7 @@ static int v4l2_request_try_format(AVCodecContext *avctx, enum v4l2_buf_type typ - - while (ioctl(ctx->video_fd, VIDIOC_ENUM_FMT, &fmtdesc) >= 0) { - if (fmtdesc.pixelformat == pixelformat) -- return 0; -+ return v4l2_request_try_framesize(avctx, pixelformat); - - fmtdesc.index++; - } - -From c415926540fe04141bb1e8cabd24049b61752d4f Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Sun, 27 Feb 2022 18:54:21 +0100 -Subject: [PATCH 17/17] Improve VP9 decoding - ---- - libavcodec/v4l2_request_vp9.c | 110 +++++++++++++++++++--------------- - 1 file changed, 62 insertions(+), 48 deletions(-) - -diff --git a/libavcodec/v4l2_request_vp9.c b/libavcodec/v4l2_request_vp9.c -index 9b95c76cdb8..ec0300f66db 100644 ---- a/libavcodec/v4l2_request_vp9.c -+++ b/libavcodec/v4l2_request_vp9.c -@@ -22,78 +22,62 @@ - - typedef struct V4L2RequestControlsVP9 { - struct v4l2_ctrl_vp9_frame decode_params; -+ struct v4l2_ctrl_vp9_compressed_hdr chp; - } V4L2RequestControlsVP9; - --static int v4l2_request_vp9_set_frame_ctx(AVCodecContext *avctx) -+static void v4l2_request_vp9_set_frame_ctx(AVCodecContext *avctx) - { - VP9Context *s = avctx->priv_data; -- struct v4l2_ctrl_vp9_compressed_hdr chp; -- struct v4l2_ext_control control[] = { -- { -- .id = V4L2_CID_STATELESS_VP9_COMPRESSED_HDR, -- .ptr = &chp, -- .size = sizeof(chp), -- }, -- }; -+ const VP9Frame *f = &s->s.frames[CUR_FRAME]; -+ V4L2RequestControlsVP9 *controls = f->hwaccel_picture_private; -+ struct v4l2_ctrl_vp9_compressed_hdr *chp = &controls->chp; - -- memset(&chp, 0, sizeof(chp)); -+ memset(chp, 0, sizeof(&chp)); - -- chp.tx_mode = s->s.h.txfmmode; -- memcpy(chp.tx8, s->prob_raw.p.tx8p, sizeof(s->prob_raw.p.tx8p)); -- memcpy(chp.tx16, s->prob_raw.p.tx16p, sizeof(s->prob_raw.p.tx16p)); -- memcpy(chp.tx32, s->prob_raw.p.tx32p, sizeof(s->prob_raw.p.tx32p)); -+ chp->tx_mode = s->s.h.txfmmode; -+ memcpy(chp->tx8, s->prob_raw.p.tx8p, sizeof(s->prob_raw.p.tx8p)); -+ memcpy(chp->tx16, s->prob_raw.p.tx16p, sizeof(s->prob_raw.p.tx16p)); -+ memcpy(chp->tx32, s->prob_raw.p.tx32p, sizeof(s->prob_raw.p.tx32p)); - for (unsigned i = 0; i < 4; i++) { - for (unsigned j = 0; j < 2; j++) { - for (unsigned k = 0; k < 2; k++) { - for (unsigned l = 0; l < 6; l++) { - for (unsigned m = 0; m < 6; m++) { -- memcpy(chp.coef[i][j][k][l][m], s->prob_raw.coef[i][j][k][l][m], sizeof(chp.coef[0][0][0][0][0])); -+ memcpy(chp->coef[i][j][k][l][m], s->prob_raw.coef[i][j][k][l][m], sizeof(chp->coef[0][0][0][0][0])); - } - } - } - } - } -- memcpy(chp.skip, s->prob_raw.p.skip, sizeof(s->prob_raw.p.skip)); -- memcpy(chp.inter_mode, s->prob_raw.p.mv_mode, sizeof(s->prob_raw.p.mv_mode)); -- memcpy(chp.interp_filter, s->prob_raw.p.filter, sizeof(s->prob_raw.p.filter)); -- memcpy(chp.is_inter, s->prob_raw.p.intra, sizeof(s->prob_raw.p.intra)); -- memcpy(chp.comp_mode, s->prob_raw.p.comp, sizeof(s->prob_raw.p.comp)); -- memcpy(chp.single_ref, s->prob_raw.p.single_ref, sizeof(s->prob_raw.p.single_ref)); -- memcpy(chp.comp_ref, s->prob_raw.p.comp_ref, sizeof(s->prob_raw.p.comp_ref)); -- memcpy(chp.y_mode, s->prob_raw.p.y_mode, sizeof(s->prob_raw.p.y_mode)); -+ memcpy(chp->skip, s->prob_raw.p.skip, sizeof(s->prob_raw.p.skip)); -+ memcpy(chp->inter_mode, s->prob_raw.p.mv_mode, sizeof(s->prob_raw.p.mv_mode)); -+ memcpy(chp->interp_filter, s->prob_raw.p.filter, sizeof(s->prob_raw.p.filter)); -+ memcpy(chp->is_inter, s->prob_raw.p.intra, sizeof(s->prob_raw.p.intra)); -+ memcpy(chp->comp_mode, s->prob_raw.p.comp, sizeof(s->prob_raw.p.comp)); -+ memcpy(chp->single_ref, s->prob_raw.p.single_ref, sizeof(s->prob_raw.p.single_ref)); -+ memcpy(chp->comp_ref, s->prob_raw.p.comp_ref, sizeof(s->prob_raw.p.comp_ref)); -+ memcpy(chp->y_mode, s->prob_raw.p.y_mode, sizeof(s->prob_raw.p.y_mode)); - for (unsigned i = 0; i < 10; i++) -- memcpy(chp.uv_mode[i], s->prob.p.uv_mode[i], sizeof(s->prob.p.uv_mode[0])); -+ memcpy(chp->uv_mode[i], s->prob.p.uv_mode[i], sizeof(s->prob.p.uv_mode[0])); - for (unsigned i = 0; i < 4; i++) -- memcpy(chp.partition[i * 4], s->prob_raw.p.partition[i], sizeof(s->prob_raw.p.partition[0])); -- memcpy(chp.mv.joint, s->prob_raw.p.mv_joint, sizeof(s->prob_raw.p.mv_joint)); -+ memcpy(chp->partition[i * 4], s->prob_raw.p.partition[i], sizeof(s->prob_raw.p.partition[0])); -+ memcpy(chp->mv.joint, s->prob_raw.p.mv_joint, sizeof(s->prob_raw.p.mv_joint)); - for (unsigned i = 0; i < 2; i++) { -- chp.mv.sign[i] = s->prob_raw.p.mv_comp[i].sign; -- memcpy(chp.mv.classes[i], s->prob_raw.p.mv_comp[i].classes, sizeof(s->prob_raw.p.mv_comp[0].classes)); -- chp.mv.class0_bit[i] = s->prob_raw.p.mv_comp[i].class0; -- memcpy(chp.mv.bits[i], s->prob_raw.p.mv_comp[i].bits, sizeof(s->prob_raw.p.mv_comp[0].bits)); -- memcpy(chp.mv.class0_fr[i], s->prob_raw.p.mv_comp[i].class0_fp, sizeof(s->prob_raw.p.mv_comp[0].class0_fp)); -- memcpy(chp.mv.fr[i], s->prob_raw.p.mv_comp[i].fp, sizeof(s->prob_raw.p.mv_comp[0].fp)); -- chp.mv.class0_hp[i] = s->prob_raw.p.mv_comp[i].class0_hp; -- chp.mv.hp[i] = s->prob_raw.p.mv_comp[i].hp; -+ chp->mv.sign[i] = s->prob_raw.p.mv_comp[i].sign; -+ memcpy(chp->mv.classes[i], s->prob_raw.p.mv_comp[i].classes, sizeof(s->prob_raw.p.mv_comp[0].classes)); -+ chp->mv.class0_bit[i] = s->prob_raw.p.mv_comp[i].class0; -+ memcpy(chp->mv.bits[i], s->prob_raw.p.mv_comp[i].bits, sizeof(s->prob_raw.p.mv_comp[0].bits)); -+ memcpy(chp->mv.class0_fr[i], s->prob_raw.p.mv_comp[i].class0_fp, sizeof(s->prob_raw.p.mv_comp[0].class0_fp)); -+ memcpy(chp->mv.fr[i], s->prob_raw.p.mv_comp[i].fp, sizeof(s->prob_raw.p.mv_comp[0].fp)); -+ chp->mv.class0_hp[i] = s->prob_raw.p.mv_comp[i].class0_hp; -+ chp->mv.hp[i] = s->prob_raw.p.mv_comp[i].hp; - } -- -- return ff_v4l2_request_set_controls(avctx, control, FF_ARRAY_ELEMS(control)); - } - --static int v4l2_request_vp9_start_frame(AVCodecContext *avctx, -- av_unused const uint8_t *buffer, -- av_unused uint32_t size) -+static void fill_frame(struct v4l2_ctrl_vp9_frame *dec_params, AVCodecContext *avctx) - { - const VP9Context *s = avctx->priv_data; -- const VP9Frame *f = &s->s.frames[CUR_FRAME]; -- V4L2RequestControlsVP9 *controls = f->hwaccel_picture_private; -- struct v4l2_ctrl_vp9_frame *dec_params = &controls->decode_params; - const ThreadFrame *ref; -- int ret; -- -- ret = v4l2_request_vp9_set_frame_ctx(avctx); -- if (ret) -- return ret; - - memset(dec_params, 0, sizeof(*dec_params)); - -@@ -208,6 +192,19 @@ static int v4l2_request_vp9_start_frame(AVCodecContext *avctx, - if (s->s.h.segmentation.feat[i].skip_enabled) - dec_params->seg.feature_enabled[i] |= 1 << V4L2_VP9_SEG_LVL_SKIP; - } -+} -+ -+static int v4l2_request_vp9_start_frame(AVCodecContext *avctx, -+ av_unused const uint8_t *buffer, -+ av_unused uint32_t size) -+{ -+ const VP9Context *s = avctx->priv_data; -+ const VP9Frame *f = &s->s.frames[CUR_FRAME]; -+ V4L2RequestControlsVP9 *controls = f->hwaccel_picture_private; -+ -+ v4l2_request_vp9_set_frame_ctx(avctx); -+ -+ fill_frame(&controls->decode_params, avctx); - - return ff_v4l2_request_reset_frame(avctx, f->tf.f); - } -@@ -233,6 +230,11 @@ static int v4l2_request_vp9_end_frame(AVCodecContext *avctx) - .ptr = &controls->decode_params, - .size = sizeof(controls->decode_params), - }, -+ { -+ .id = V4L2_CID_STATELESS_VP9_COMPRESSED_HDR, -+ .ptr = &controls->chp, -+ .size = sizeof(controls->chp), -+ }, - }; - - ret = ff_v4l2_request_decode_frame(avctx, f->tf.f, control, FF_ARRAY_ELEMS(control)); -@@ -247,8 +249,20 @@ static int v4l2_request_vp9_end_frame(AVCodecContext *avctx) - - static int v4l2_request_vp9_init(AVCodecContext *avctx) - { -+ struct v4l2_ctrl_vp9_frame frame; -+ -+ struct v4l2_ext_control control[] = { -+ { -+ .id = V4L2_CID_STATELESS_VP9_FRAME, -+ .ptr = &frame, -+ .size = sizeof(frame), -+ }, -+ }; -+ -+ fill_frame(&frame, avctx); -+ - // TODO: check V4L2_CID_MPEG_VIDEO_VP9_PROFILE -- return ff_v4l2_request_init(avctx, V4L2_PIX_FMT_VP9_FRAME, 3 * 1024 * 1024, NULL, 0); -+ return ff_v4l2_request_init(avctx, V4L2_PIX_FMT_VP9_FRAME, 3 * 1024 * 1024, control, FF_ARRAY_ELEMS(control)); - } - - const AVHWAccel ff_vp9_v4l2request_hwaccel = { diff --git a/packages/network/iptables/package.mk b/packages/network/iptables/package.mk index 532480de1..3c76f8f71 100644 --- a/packages/network/iptables/package.mk +++ b/packages/network/iptables/package.mk @@ -10,17 +10,19 @@ PKG_DEPENDS_TARGET="toolchain linux libmnl libnftnl" PKG_LONGDESC="IP packet filter administration." PKG_TOOLCHAIN="autotools" -## Workaround until I can fix this correctly, or we get to mainline. -if [[ "$(kernel_version)" =~ ^5. ]] -then - PKG_VERSION="1.8.8" - PKG_PATCH_DIRS+="5.x" -else - PKG_VERSION="1.8.3" - PKG_PATCH_DIRS+="4.x" - PKG_CONFIGURE_OPTS_TARGET="--with-kernel=$(kernel_path) - CPPFLAGS=-I${SYSROOT_PREFIX}/usr/include" -fi + +case ${DEVICE} in + RG503|RG353P|RG351P|RG351V|RG351MP) + PKG_VERSION="1.8.3" + PKG_PATCH_DIRS+="4.x" + PKG_CONFIGURE_OPTS_TARGET="--with-kernel=$(kernel_path) + CPPFLAGS=-I${SYSROOT_PREFIX}/usr/include" + ;; + *) + PKG_VERSION="1.8.8" + PKG_PATCH_DIRS+="5.x" + ;; +esac PKG_URL="https://www.netfilter.org/projects/iptables/files/${PKG_NAME}-${PKG_VERSION}.tar.bz2" diff --git a/packages/network/iptables/patches/01-libiptc.patch b/packages/network/iptables/patches/4.x/01-libiptc.patch similarity index 100% rename from packages/network/iptables/patches/01-libiptc.patch rename to packages/network/iptables/patches/4.x/01-libiptc.patch diff --git a/packages/network/iptables/patches/5.x/iptables-0001-xshared-fix-build-for--werror-format-security.patch b/packages/network/iptables/patches/5.x/iptables-0001-xshared-fix-build-for--werror-format-security.patch new file mode 100644 index 000000000..7c05b009c --- /dev/null +++ b/packages/network/iptables/patches/5.x/iptables-0001-xshared-fix-build-for--werror-format-security.patch @@ -0,0 +1,28 @@ +From b72eb12ea5a61df0655ad99d5048994e916be83a Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 13 May 2022 16:51:58 +0200 +Subject: xshared: Fix build for -Werror=format-security + +Gcc complains about the omitted format string. + +Signed-off-by: Phil Sutter +--- + iptables/xshared.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/iptables/xshared.c b/iptables/xshared.c +index fae5ddd5..a8512d38 100644 +--- a/iptables/xshared.c ++++ b/iptables/xshared.c +@@ -1307,7 +1307,7 @@ static void check_empty_interface(struct xtables_args *args, const char *arg) + return; + + if (args->family != NFPROTO_ARP) +- xtables_error(PARAMETER_PROBLEM, msg); ++ xtables_error(PARAMETER_PROBLEM, "%s", msg); + + fprintf(stderr, "%s", msg); + } +-- +cgit v1.2.3 + diff --git a/packages/network/iptables/patches/5.x/iptables-0002-xshared-fix-for-build-in-sub-directory.patch b/packages/network/iptables/patches/5.x/iptables-0002-xshared-fix-for-build-in-sub-directory.patch new file mode 100644 index 000000000..d00828544 --- /dev/null +++ b/packages/network/iptables/patches/5.x/iptables-0002-xshared-fix-for-build-in-sub-directory.patch @@ -0,0 +1,11 @@ +--- a/libxtables/xtables.c 2022-05-13 13:26:26.000000000 +0000 ++++ b/libxtables/xtables.c 2022-05-14 09:53:20.593250503 +0000 +@@ -49,7 +49,7 @@ + #include + #include + #include +-#include ++#include "../libiptc/linux_list.h" + + #ifndef NO_SHARED_LIBS + #include diff --git a/packages/python/devel/pygobject/package.mk b/packages/python/devel/pygobject/package.mk index ee941cce9..8accfa18e 100644 --- a/packages/python/devel/pygobject/package.mk +++ b/packages/python/devel/pygobject/package.mk @@ -4,8 +4,8 @@ # Copyright (C) 2022-present Team CoreELEC (https://coreelec.org) PKG_NAME="pygobject" -PKG_VERSION="3.42.1" -PKG_SHA256="1f34b5f7624de35e44eb5a7eb428353285bd03004d55131a5f7f7fa9b90f3cc9" +PKG_VERSION="3.42.2" +PKG_SHA256="ade8695e2a7073849dd0316d31d8728e15e1e0bc71d9ff6d1c09e86be52bc957" PKG_ARCH="any" PKG_LICENSE="LGPL" PKG_SITE="http://www.pygtk.org/" @@ -24,8 +24,6 @@ pre_configure_target() { } post_makeinstall_target() { - python_remove_source - rm -rf ${INSTALL}/usr/bin rm -rf ${INSTALL}/usr/share/pygobject } diff --git a/packages/sysutils/busybox/scripts/fs-resize b/packages/sysutils/busybox/scripts/fs-resize index 435f5f5ea..70b203846 100755 --- a/packages/sysutils/busybox/scripts/fs-resize +++ b/packages/sysutils/busybox/scripts/fs-resize @@ -46,7 +46,7 @@ if [ -e /storage/.please_resize_me ] ; then # identify the partition scheme, and if gpt fix minor issues such as gpt header not at end of disk SCHEME=$(blkid -s PTTYPE -o value ${DISK}) if [ "$SCHEME" = "gpt" ]; then - StartProgress spinner "Checking layout... " "sgdisk -e ${DISK} &>/dev/null" + StartProgress spinner "Checking layout... " "parted -fs ${DISK} print &>/dev/null" fi StartProgress spinner "Resizing storage partition... " "parted -s -a optimal -m ${DISK} resizepart ${PARTNUM} 100% &>/dev/null" diff --git a/packages/sysutils/gptfdisk/package.mk b/packages/sysutils/gptfdisk/package.mk index c23b89d6a..18171c3fd 100644 --- a/packages/sysutils/gptfdisk/package.mk +++ b/packages/sysutils/gptfdisk/package.mk @@ -2,8 +2,7 @@ # Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv) PKG_NAME="gptfdisk" -PKG_VERSION="1.0.4" -PKG_SHA256="b663391a6876f19a3cd901d862423a16e2b5ceaa2f4a3b9bb681e64b9c7ba78d" +PKG_VERSION="1.0.9" PKG_LICENSE="GPL" PKG_SITE="http://www.rodsbooks.com/gdisk/" PKG_URL="https://downloads.sourceforge.net/project/$PKG_NAME/$PKG_NAME/$PKG_VERSION/$PKG_NAME-$PKG_VERSION.tar.gz" diff --git a/packages/sysutils/rclone/package.mk b/packages/sysutils/rclone/package.mk index d93731278..720d15248 100644 --- a/packages/sysutils/rclone/package.mk +++ b/packages/sysutils/rclone/package.mk @@ -3,27 +3,41 @@ # Copyright (C) 2022-present Fewtarius PKG_NAME="rclone" -PKG_VERSION="1.58.0" -PKG_URL="https://downloads.rclone.org/v${PKG_VERSION}/rclone-v${PKG_VERSION}-linux-arm64.zip" +PKG_VERSION="1.60.0" PKG_DEPENDS_TARGET="toolchain fuse rsync" PKG_SECTION="tools" PKG_SHORTDESC="rsync for cloud storage" PKG_TOOLCHAIN="manual" -pre_unpack() { - unzip sources/rclone/rclone-${PKG_VERSION}.zip -d ${PKG_BUILD}/ +case ${ARCH} in + aarch64) + RCLONE_ARCH="arm64" + ;; + *) + RCLONE_ARCH="amd64" + ;; +esac + +PKG_URL="https://downloads.rclone.org/v${PKG_VERSION}/rclone-v${PKG_VERSION}-linux-${RCLONE_ARCH}.zip" +PKG_RCLONE="rclone-v${PKG_VERSION}-linux-${RCLONE_ARCH}/rclone" + +unpack() { + mkdir -p ${PKG_BUILD} + mv ${SOURCES}/rclone/rclone-${PKG_VERSION}.zip ${SOURCES}/rclone/rclone-${PKG_VERSION}-${RCLONE_ARCH}.zip + unzip ${SOURCES}/rclone/rclone-${PKG_VERSION}-${RCLONE_ARCH}.zip -d ${PKG_BUILD}/ + rm -f ${SOURCES}/rclone/rclone-${PKG_VERSION}* } makeinstall_target() { mkdir -p ${INSTALL}/usr/bin/ mkdir -p ${INSTALL}/usr/config/ - cp ${PKG_DIR}/sources/rclonectl ${INSTALL}/usr/bin/ - cp ${PKG_DIR}/sources/cloud_backup ${INSTALL}/usr/bin/ - cp ${PKG_DIR}/sources/cloud_restore ${INSTALL}/usr/bin/ - cp ${PKG_BUILD}/rclone-v${PKG_VERSION}-linux-arm64/rclone ${INSTALL}/usr/bin/ + cp rclonectl ${INSTALL}/usr/bin/ + cp cloud_backup ${INSTALL}/usr/bin/ + cp cloud_restore ${INSTALL}/usr/bin/ + cp ${PKG_BUILD}/${PKG_RCLONE} ${INSTALL}/usr/bin/ chmod 0755 ${INSTALL}/usr/bin/* - cp ${PKG_DIR}/sources/rsync-rules.conf ${INSTALL}/usr/config/ - cp ${PKG_DIR}/sources/rsync.conf ${INSTALL}/usr/config/ + cp rsync-rules.conf ${INSTALL}/usr/config/ + cp rsync.conf ${INSTALL}/usr/config/ chmod 755 ${INSTALL}/usr/bin/rclone mkdir -p ${INSTALL}/usr/config/modules ln -sf /usr/bin/cloud_backup ${INSTALL}/usr/config/modules/cloud_backup.sh diff --git a/packages/sysutils/sleep/sources/sleep.sh b/packages/sysutils/sleep/sources/sleep.sh index 8fdeeb329..1e73218e5 100755 --- a/packages/sysutils/sleep/sources/sleep.sh +++ b/packages/sysutils/sleep/sources/sleep.sh @@ -25,6 +25,8 @@ case $1 in nohup alsactl store -f /storage/.config/asound.state >/dev/null 2>&1 + nohup systemctl stop bluetooth & >/dev/null 2>&1 + wait touch /run/.last_sleep_time @@ -48,9 +50,14 @@ case $1 in fi if [ "$(get_setting wifi.enabled)" == "1" ] - then - nohup wifictl reconnect & >/dev/null 2>&1 - fi + then + nohup wifictl reconnect & >/dev/null 2>&1 + fi + + if [ "$(get_setting bluetooth.enabled)" == "1" ] + then + nohup systemctl start bluetooth & >/dev/null 2>&1 + fi DEVICE_VOLUME=$(get_setting "audio.volume" 2>/dev/null) nohup amixer -M set "${DEVICE_AUDIO_MIXER}" ${DEVICE_VOLUME}% & >/dev/null 2>&1 diff --git a/packages/sysutils/system-utils/sources/devices/handheld/overclock b/packages/sysutils/system-utils/sources/devices/handheld/overclock index 8347358f5..c8cfb788a 100755 --- a/packages/sysutils/system-utils/sources/devices/handheld/overclock +++ b/packages/sysutils/system-utils/sources/devices/handheld/overclock @@ -42,6 +42,15 @@ case ${PROFILE} in 18w) WATTS="18000" ;; + 20w) + WATTS="18000" + ;; + 22w) + WATTS="18000" + ;; + 24w) + WATTS="18000" + ;; esac ryzenadj --tctl-temp=97 --stapm-limit=${WATTS} --fast-limit=${WATTS} --stapm-time=500 --slow-limit=${WATTS} --slow-time=30 --vrmmax-current=70000 diff --git a/packages/sysutils/system-utils/sources/scripts/volume_sense b/packages/sysutils/system-utils/sources/scripts/volume_sense index 350c39db3..eb45ea0ba 100755 --- a/packages/sysutils/system-utils/sources/scripts/volume_sense +++ b/packages/sysutils/system-utils/sources/scripts/volume_sense @@ -91,7 +91,7 @@ get_devices # If the input devices change, it may be a new controller # so handle it here. -mkcontroller +mkcontroller 2>/dev/null ||: # Logic: # - Listen to both: diff --git a/packages/sysutils/systemd/package.mk b/packages/sysutils/systemd/package.mk index 9b6bdef03..cd49ec6b6 100644 --- a/packages/sysutils/systemd/package.mk +++ b/packages/sysutils/systemd/package.mk @@ -3,8 +3,7 @@ # Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) PKG_NAME="systemd" -PKG_VERSION="251.2" -PKG_SHA256="5b371e824fe3e3128f2338b8db8cd37171f8e249eea88077eea468f73d833545" +PKG_VERSION="251.7" PKG_LICENSE="LGPL2.1+" PKG_SITE="http://www.freedesktop.org/wiki/Software/systemd" PKG_URL="https://github.com/systemd/systemd-stable/archive/v${PKG_VERSION}.tar.gz" diff --git a/packages/sysutils/systemd/patches/systemd-0700=no-format-overflow-error.patch b/packages/sysutils/systemd/patches/systemd-0700=no-format-overflow-error.patch new file mode 100644 index 000000000..56935d265 --- /dev/null +++ b/packages/sysutils/systemd/patches/systemd-0700=no-format-overflow-error.patch @@ -0,0 +1,11 @@ +diff -rupN systemd.orig/meson.build systemd/meson.build +--- systemd.orig/meson.build 2022-11-01 14:19:46.286920312 +0000 ++++ systemd/meson.build 2022-11-01 15:20:34.490729536 +0000 +@@ -370,6 +370,7 @@ possible_common_cc_flags = [ + '-Wsuggest-attribute=noreturn', + '-Wunused-function', + '-Wwrite-strings', ++ '-Wno-error=format-overflow', + + # negative arguments are correctly detected starting with meson 0.46. + '-Wno-error=#warnings', # clang diff --git a/packages/tools/hdparm/package.mk b/packages/tools/hdparm/package.mk index a41ae9c75..36d2a0b3f 100644 --- a/packages/tools/hdparm/package.mk +++ b/packages/tools/hdparm/package.mk @@ -3,15 +3,15 @@ # Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) PKG_NAME="hdparm" -PKG_VERSION="9.58" -PKG_SHA256="9ae78e883f3ce071d32ee0f1b9a2845a634fc4dd94a434e653fdbef551c5e10f" +PKG_VERSION="9.65" +PKG_SHA256="d14929f910d060932e717e9382425d47c2e7144235a53713d55a94f7de535a4b" PKG_LICENSE="BSD" PKG_SITE="http://sourceforge.net/projects/hdparm/" -PKG_URL="$SOURCEFORGE_SRC/$PKG_NAME/$PKG_NAME/$PKG_NAME-$PKG_VERSION.tar.gz" +PKG_URL="${SOURCEFORGE_SRC}/${PKG_NAME}/${PKG_NAME}/${PKG_NAME}-${PKG_VERSION}.tar.gz" PKG_DEPENDS_TARGET="toolchain" PKG_LONGDESC="Shell utility to access/tune ioctl features of the Linux IDE driver and IDE drives." makeinstall_target() { - mkdir -p $INSTALL/usr/sbin - cp -a $PKG_BUILD/hdparm $INSTALL/usr/sbin + mkdir -p ${INSTALL}/usr/sbin + cp -a ${PKG_BUILD}/hdparm ${INSTALL}/usr/sbin } diff --git a/packages/tools/syslinux/patches/syslinux-0002-fix-build-with-glibc_2.36.patch b/packages/tools/syslinux/patches/syslinux-0002-fix-build-with-glibc_2.36.patch new file mode 100644 index 000000000..5bab31044 --- /dev/null +++ b/packages/tools/syslinux/patches/syslinux-0002-fix-build-with-glibc_2.36.patch @@ -0,0 +1,17 @@ +--- a/libinstaller/linuxioctl.h 2022-07-17 12:45:43.459729359 +0000 ++++ b/libinstaller/linuxioctl.h 2022-07-17 12:58:50.204815753 +0000 +@@ -16,7 +16,13 @@ + #include /* Floppy geometry */ + #include /* Hard disk geometry */ + +-#include /* FIGETBSZ, FIBMAP, FS_IOC_* */ ++#define FIBMAP _IO(0x00,1) /* bmap access */ ++#define FIGETBSZ _IO(0x00,2) /* get the block size used for bmap */ ++ ++#define FS_IOC_GETFLAGS _IOR('f', 1, long) ++#define FS_IOC_SETFLAGS _IOW('f', 2, long) ++ ++#define FS_IMMUTABLE_FL 0x00000010 /* Immutable file */ + + #undef SECTOR_SIZE /* Defined in msdos_fs.h for no good reason */ + #undef SECTOR_BITS diff --git a/packages/ui/emulationstation/bluez/bluezutils.py b/packages/ui/emulationstation/bluez/bluezutils.py index de08cbdcb..cd8964082 100644 --- a/packages/ui/emulationstation/bluez/bluezutils.py +++ b/packages/ui/emulationstation/bluez/bluezutils.py @@ -15,7 +15,7 @@ def find_adapter(pattern=None): def find_adapter_in_objects(objects, pattern=None): bus = dbus.SystemBus() - for path, ifaces in objects.iteritems(): + for path, ifaces in objects.items(): adapter = ifaces.get(ADAPTER_INTERFACE) if adapter is None: continue @@ -35,7 +35,7 @@ def find_device_in_objects(objects, device_address, adapter_pattern=None): if adapter_pattern: adapter = find_adapter_in_objects(objects, adapter_pattern) path_prefix = adapter.object_path - for path, ifaces in objects.iteritems(): + for path, ifaces in objects.items(): device = ifaces.get(DEVICE_INTERFACE) if device is None: continue diff --git a/packages/ui/emulationstation/config/common/es_features.cfg b/packages/ui/emulationstation/config/common/es_features.cfg index a3e5ca095..01037f67f 100644 --- a/packages/ui/emulationstation/config/common/es_features.cfg +++ b/packages/ui/emulationstation/config/common/es_features.cfg @@ -21,6 +21,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/ui/emulationstation/config/common/es_systems.cfg b/packages/ui/emulationstation/config/common/es_systems.cfg index 849f54de4..b8009b8ae 100644 --- a/packages/ui/emulationstation/config/common/es_systems.cfg +++ b/packages/ui/emulationstation/config/common/es_systems.cfg @@ -779,14 +779,38 @@ 2001 console /storage/roms/gamecube - .gcm .GCM .iso .ISO .gcz .GCZ .ciso .CISO .wbfs .WBFS .rvz .RVZ + .gcm .GCM .iso .ISO .gcz .GCZ .ciso .CISO .wbfs .WBFS .rvz .RVZ .dol .DOL /usr/bin/runemu.sh %ROM% -P%SYSTEM% --core=%CORE% --emulator=%EMULATOR% --controllers="%CONTROLLERSCONFIG%" gc gc - + - dolphinsa + dolphinsa-gc + + + + + dolphin + + + + + + Nintendo Wii + wii + Nintendo + 2006 + console + /storage/roms/wii + .gcm .GCM .iso .ISO .gcz .GCZ .ciso .CISO .wbfs .WBFS .rvz .RVZ .dol .DOL + /usr/bin/runemu.sh %ROM% -P%SYSTEM% --core=%CORE% --emulator=%EMULATOR% --controllers="%CONTROLLERSCONFIG%" + wii + wii + + + + dolphinsa-wii @@ -1430,7 +1454,6 @@ pcsx_rearmed32 pcsx_rearmed swanstation - duckstation diff --git a/packages/ui/emulationstation/config/device/X86_64/es_input.cfg b/packages/ui/emulationstation/config/device/X86_64/es_input.cfg index 754ff3917..41ab5cd5e 100644 --- a/packages/ui/emulationstation/config/device/X86_64/es_input.cfg +++ b/packages/ui/emulationstation/config/device/X86_64/es_input.cfg @@ -976,4 +976,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/ui/emulationstation/config/device/X86_64/es_systems.cfg b/packages/ui/emulationstation/config/device/X86_64/es_systems.cfg index a96bd8470..b559ede7b 100644 --- a/packages/ui/emulationstation/config/device/X86_64/es_systems.cfg +++ b/packages/ui/emulationstation/config/device/X86_64/es_systems.cfg @@ -796,19 +796,19 @@ 2001 console /storage/roms/gamecube - .gcm .GCM .iso .ISO .gcz .GCZ .ciso .CISO .wbfs .WBFS .rvz .RVZ + .gcm .GCM .iso .ISO .gcz .GCZ .ciso .CISO .wbfs .WBFS .rvz .RVZ .dol .DOL /usr/bin/runemu.sh %ROM% -P%SYSTEM% --core=%CORE% --emulator=%EMULATOR% --controllers="%CONTROLLERSCONFIG%" gc gc - + - dolphinsa + dolphinsa-gc - dolphin + dolphin @@ -820,14 +820,14 @@ 2006 console /storage/roms/wii - .gcm .GCM .iso .ISO .gcz .GCZ .ciso .CISO .wbfs .WBFS .rvz .RVZ + .gcm .GCM .iso .ISO .gcz .GCZ .ciso .CISO .wbfs .WBFS .rvz .RVZ .dol .DOL /usr/bin/runemu.sh %ROM% -P%SYSTEM% --core=%CORE% --emulator=%EMULATOR% --controllers="%CONTROLLERSCONFIG%" wii wii - + - dolphinsa + dolphinsa-wii @@ -1465,7 +1465,6 @@ swanstation - duckstation diff --git a/packages/ui/emulationstation/package.mk b/packages/ui/emulationstation/package.mk index 0f10410a6..b24e51b83 100644 --- a/packages/ui/emulationstation/package.mk +++ b/packages/ui/emulationstation/package.mk @@ -3,7 +3,7 @@ # Copyright (C) 2020-present Fewtarius PKG_NAME="emulationstation" -PKG_VERSION="a179a4e" +PKG_VERSION="0b5c0e3" PKG_GIT_CLONE_BRANCH="main" PKG_REV="1" PKG_ARCH="any" diff --git a/packages/virtual/arm32/package.mk b/packages/virtual/arm32/package.mk index fc56a71e8..d34f1aced 100644 --- a/packages/virtual/arm32/package.mk +++ b/packages/virtual/arm32/package.mk @@ -4,6 +4,6 @@ PKG_NAME="arm32" PKG_LICENSE="Apache-2.0" PKG_SITE="www.jelos.org" -PKG_DEPENDS_TARGET="toolchain squashfs-tools:host dosfstools:host fakeroot:host kmod:host mtools:host populatefs:host libc gcc linux linux-drivers linux-firmware libusb unzip socat p7zip file ${OPENGLES} SDL2 SDL2_gfx SDL2_image SDL2_mixer SDL2_net SDL2_ttf libgo2 retroarch pcsx_rearmed parallel-n64_rice parallel-n64_gln64 parallel-n64_glide64 gpsp flycast" +PKG_DEPENDS_TARGET="toolchain squashfs-tools:host dosfstools:host fakeroot:host kmod:host mtools:host populatefs:host libc gcc linux linux-drivers linux-firmware libusb unzip socat p7zip file ${OPENGLES} SDL2 SDL2_gfx SDL2_image SDL2_mixer SDL2_net SDL2_ttf retroarch pcsx_rearmed parallel-n64_rice parallel-n64_gln64 parallel-n64_glide64 gpsp flycast" PKG_SECTION="virtual" PKG_LONGDESC="Root package used to build and create 32-bit userland" diff --git a/packages/virtual/emulators/package.mk b/packages/virtual/emulators/package.mk index 857f5daf8..85897d344 100644 --- a/packages/virtual/emulators/package.mk +++ b/packages/virtual/emulators/package.mk @@ -17,7 +17,7 @@ PKG_RETROARCH="retroarch retroarch-overlays retroarch-joypads retroarch-assets l LIBRETRO_CORES="2048 81 a5200 atari800 beetle-gba beetle-lynx beetle-ngp beetle-pce beetle-pce-fast beetle-pcfx \ beetle-supafaust beetle-supergrafx beetle-vb beetle-wswan bluemsx cannonball cap32 \ - crocods daphne dinothawr dosbox-svn dosbox-pure duckstation easyrpg fbalpha2012 \ + crocods daphne dinothawr dosbox-svn dosbox-pure easyrpg fbalpha2012 \ fbalpha2019 fbneo fceumm fmsx flycast flycast_libretro freechaf freeintv \ freej2me fuse-libretro gambatte gearboy gearcoleco gearsystem genesis-plus-gx \ genesis-plus-gx-wide gme gpsp gw-libretro handy hatari mame2000 mame2003-plus \ @@ -41,7 +41,7 @@ case "${DEVICE}" in PKG_DEPENDS_TARGET+=" duckstationsa dolphinsa dolphin slang-shaders" ;; RG503|RG353P) - PKG_DEPENDS_TARGET+=" duckstationsa dolphinsa common-shaders glsl-shaders" + PKG_DEPENDS_TARGET+=" duckstationsa common-shaders glsl-shaders" ;; handheld) PKG_DEPENDS_TARGET+=" duckstationsa dolphinsa dolphin pcsx2sa pcsx2 desmume bsnes citra slang-shaders" diff --git a/packages/wayland/weston/config/kiosk.ini b/packages/wayland/weston/config/kiosk.ini index ca9ce11ab..30fbd1c19 100644 --- a/packages/wayland/weston/config/kiosk.ini +++ b/packages/wayland/weston/config/kiosk.ini @@ -17,6 +17,5 @@ clock-format=minutes-24h locking=false [autolaunch] -path=/usr/bin/start_es.sh -icon=/usr/config/emulationstation/resources/window_icon_24.png +path=@STARTUP@ watch=true diff --git a/projects/Rockchip/devices/RG351MP/options b/projects/Rockchip/devices/RG351MP/options index f09b7ce87..28be5aea0 100644 --- a/projects/Rockchip/devices/RG351MP/options +++ b/projects/Rockchip/devices/RG351MP/options @@ -66,7 +66,7 @@ HW_CPU="Rockchip RK3326" # kernel serial console - EXTRA_CMDLINE="quiet console=tty0 ssh consoleblank=0 systemd.show_status=0 loglevel=0 panic=20" + EXTRA_CMDLINE="quiet rootwait console=tty0 ssh consoleblank=0 systemd.show_status=0 loglevel=0 panic=20" # additional packages to install ADDITIONAL_PACKAGES=" emulators gamesupport 351files" diff --git a/projects/Rockchip/devices/RG351P/options b/projects/Rockchip/devices/RG351P/options index 355b636d1..e5b159dff 100644 --- a/projects/Rockchip/devices/RG351P/options +++ b/projects/Rockchip/devices/RG351P/options @@ -66,7 +66,7 @@ HW_CPU="Rockchip RK3326" # kernel serial console - EXTRA_CMDLINE="quiet console=tty0 fbcon=rotate:3 ssh consoleblank=0 systemd.show_status=0 loglevel=0 panic=20" + EXTRA_CMDLINE="quiet rootwait console=tty0 fbcon=rotate:3 ssh consoleblank=0 systemd.show_status=0 loglevel=0 panic=20" # additional packages to install ADDITIONAL_PACKAGES=" emulators gamesupport 351files" diff --git a/projects/Rockchip/devices/RG351V/options b/projects/Rockchip/devices/RG351V/options index 7499fca9d..542a792d0 100644 --- a/projects/Rockchip/devices/RG351V/options +++ b/projects/Rockchip/devices/RG351V/options @@ -66,7 +66,7 @@ HW_CPU="Rockchip RK3326" # kernel serial console - EXTRA_CMDLINE="quiet console=tty0 ssh consoleblank=0 systemd.show_status=0 loglevel=0 panic=20" + EXTRA_CMDLINE="quiet rootwait console=tty0 ssh consoleblank=0 systemd.show_status=0 loglevel=0 panic=20" # additional packages to install # ADDITIONAL_PACKAGES="" diff --git a/projects/Rockchip/devices/RG353P/linux/linux.aarch64.conf b/projects/Rockchip/devices/RG353P/linux/linux.aarch64.conf index a4fb78a44..c071d41bc 100644 --- a/projects/Rockchip/devices/RG353P/linux/linux.aarch64.conf +++ b/projects/Rockchip/devices/RG353P/linux/linux.aarch64.conf @@ -1345,7 +1345,7 @@ CONFIG_BT_HCIUART_H4=y # CONFIG_BT_HCIUART_BCSP is not set CONFIG_BT_HCIUART_ATH3K=y # CONFIG_BT_HCIUART_LL is not set -# CONFIG_BT_HCIUART_3WIRE is not set +CONFIG_BT_HCIUART_3WIRE=y # CONFIG_BT_HCIUART_INTEL is not set CONFIG_BT_HCIUART_BCM=y # CONFIG_BT_HCIUART_QCA is not set diff --git a/projects/Rockchip/devices/RG353P/options b/projects/Rockchip/devices/RG353P/options index 1feaf4631..9e896c790 100644 --- a/projects/Rockchip/devices/RG353P/options +++ b/projects/Rockchip/devices/RG353P/options @@ -67,7 +67,7 @@ WINDOWMANAGER="no" # kernel serial console - EXTRA_CMDLINE="quiet console=ttyS2,1500000 console=tty0 ssh consoleblank=0 systemd.show_status=0 loglevel=0 panic=20 video=HDMI-A-1:1280x720@60" + EXTRA_CMDLINE="quiet rootwait console=ttyS2,1500000 console=tty0 ssh consoleblank=0 systemd.show_status=0 loglevel=0 panic=20 video=HDMI-A-1:1280x720@60" # additional packages to install ADDITIONAL_PACKAGES=" emulators gamesupport 351files device-switch" @@ -75,7 +75,7 @@ # additional Firmware to use (dvb-firmware, misc-firmware, wlan-firmware) # Space separated list is supported, # e.g. FIRMWARE="dvb-firmware misc-firmware wlan-firmware" - FIRMWARE="misc-firmware wlan-firmware" + FIRMWARE="misc-firmware wlan-firmware RTL8821CS-prebuilt-firmware" # additional drivers to install: # for a list of additional drivers see packages/linux-drivers diff --git a/projects/Rockchip/devices/RG353P/packages/device-switch/sources/scripts/device-switch b/projects/Rockchip/devices/RG353P/packages/device-switch/sources/scripts/device-switch index cb48374dc..509d25e93 100755 --- a/projects/Rockchip/devices/RG353P/packages/device-switch/sources/scripts/device-switch +++ b/projects/Rockchip/devices/RG353P/packages/device-switch/sources/scripts/device-switch @@ -8,12 +8,12 @@ mount -o remount,rw /flash case $1 in RG353P) sed -i "s#rk3566-rg353v-linux.dtb#rk3566-rg353p-linux.dtb#g" /flash/extlinux/extlinux.conf - cp /usr/config/asound.conf /storage/.config + set-audio set "DEFAULT (SYSTEM PROVIDED)" rm -f /storage/.config/profile.d/001-fake-jacksense ;; RG353V) sed -i "s#rk3566-rg353p-linux.dtb#rk3566-rg353v-linux.dtb#g" /flash/extlinux/extlinux.conf - cp /usr/config/asound.conf.RG353V /storage/.config/asound.conf + set-audio set "DEFAULT (SYSTEM PROVIDED)" echo "DEVICE_FAKE_JACKSENSE=true" >/storage/.config/profile.d/001-fake-jacksense chmod 0755 /storage/.config/profile.d/001-fake-jacksense ;; diff --git a/projects/Rockchip/devices/RG503/options b/projects/Rockchip/devices/RG503/options index cb2a73d04..ea32b4129 100644 --- a/projects/Rockchip/devices/RG503/options +++ b/projects/Rockchip/devices/RG503/options @@ -66,7 +66,7 @@ WINDOWMANAGER="no" # kernel serial console - EXTRA_CMDLINE="quiet console=ttyS2,1500000 console=tty0 ssh consoleblank=0 systemd.show_status=0 loglevel=0 panic=20 video=HDMI-A-1:1280x720@60" + EXTRA_CMDLINE="quiet rootwait console=ttyS2,1500000 console=tty0 ssh consoleblank=0 systemd.show_status=0 loglevel=0 panic=20 video=HDMI-A-1:1280x720@60" # additional packages to install ADDITIONAL_PACKAGES=" emulators gamesupport 351files" diff --git a/projects/Rockchip/devices/RG552/options b/projects/Rockchip/devices/RG552/options index 6e7ded1b1..c2fca4cfa 100644 --- a/projects/Rockchip/devices/RG552/options +++ b/projects/Rockchip/devices/RG552/options @@ -66,7 +66,7 @@ WINDOWMANAGER="weston" # kernel serial console - EXTRA_CMDLINE="quiet console=tty0 video=DSI-1:1152x1920p60 fbcon=rotate:3 ssh consoleblank=0 systemd.show_status=0 loglevel=0 panic=20" + EXTRA_CMDLINE="quiet rootwait console=tty0 video=DSI-1:1152x1920p60 fbcon=rotate:3 ssh consoleblank=0 systemd.show_status=0 loglevel=0 panic=20" # additional packages to install ADDITIONAL_PACKAGES=" emulators gamesupport 351files" diff --git a/projects/Rockchip/packages/linux/package.mk b/projects/Rockchip/packages/linux/package.mk index 59f25f5d7..aee2623a4 100644 --- a/projects/Rockchip/packages/linux/package.mk +++ b/projects/Rockchip/packages/linux/package.mk @@ -16,30 +16,31 @@ PKG_LONGDESC="This package builds the kernel for Rockchip devices" PKG_IS_KERNEL_PKG="yes" PKG_STAMP="${KERNEL_TARGET} ${KERNEL_MAKE_EXTRACMD}" PKG_PATCH_DIRS+="${DEVICE}" -PKG_GIT_CLONE_BRANCH="main" -GET_HANDLER_SUPPORT="git" case ${DEVICE} in RG351P|RG351V|RG351MP) PKG_URL="${PKG_SITE}/rk3326-kernel.git" - PKG_VERSION="a19b4df7c" + PKG_VERSION="0b4eef36a" + GET_HANDLER_SUPPORT="git" + PKG_GIT_CLONE_BRANCH="main" ;; RG552) - PKG_URL="https://github.com/brooksytech/rk3399-kernel-5.19.git" - PKG_VERSION="f1c01bbdb7d4539eac2221f2650a14201860d928" - PKG_GIT_CLONE_BRANCH="dev" + PKG_VERSION="6.0.6" + PKG_URL="https://www.kernel.org/pub/linux/kernel/v6.x/${PKG_NAME}-${PKG_VERSION}.tar.xz" ;; RG353P|RG503) PKG_URL="${PKG_SITE}/rk356x-kernel.git" - PKG_VERSION="7e1b435e1" + PKG_VERSION="178e6ca92" + GET_HANDLER_SUPPORT="git" + PKG_GIT_CLONE_BRANCH="main" ;; esac PKG_KERNEL_CFG_FILE=$(kernel_config_path) || die if [ -n "${KERNEL_TOOLCHAIN}" ]; then - PKG_DEPENDS_HOST="${PKG_DEPENDS_HOST} gcc-arm-${KERNEL_TOOLCHAIN}:host" - PKG_DEPENDS_TARGET="${PKG_DEPENDS_TARGET} gcc-arm-${KERNEL_TOOLCHAIN}:host" + PKG_DEPENDS_HOST="${PKG_DEPENDS_HOST} gcc-${KERNEL_TOOLCHAIN}:host" + PKG_DEPENDS_TARGET="${PKG_DEPENDS_TARGET} gcc-${KERNEL_TOOLCHAIN}:host" HEADERS_ARCH=${TARGET_ARCH} fi @@ -130,7 +131,7 @@ pre_make_target() { sed -i "s|CONFIG_EXTRA_FIRMWARE=.*|CONFIG_EXTRA_FIRMWARE=\"${FW_LIST}\"|" ${PKG_BUILD}/.config fi - kernel_make oldconfig + yes "" | kernel_make oldconfig # regdb (backward compatability with pre-4.15 kernels) if grep -q ^CONFIG_CFG80211_INTERNAL_REGDB= ${PKG_BUILD}/.config ; then diff --git a/projects/Rockchip/packages/linux/patches/RG552/RG552-6.0.6.patch b/projects/Rockchip/packages/linux/patches/RG552/RG552-6.0.6.patch new file mode 100644 index 000000000..8d2988494 --- /dev/null +++ b/projects/Rockchip/packages/linux/patches/RG552/RG552-6.0.6.patch @@ -0,0 +1,12408 @@ +diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/Makefile linux/arch/arm64/boot/dts/rockchip/Makefile +--- linux.orig/arch/arm64/boot/dts/rockchip/Makefile 2022-11-01 17:55:23.658604366 -0400 ++++ linux/arch/arm64/boot/dts/rockchip/Makefile 2022-11-01 17:56:17.128793891 -0400 +@@ -43,6 +43,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-na + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-orangepi.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-pinebook-pro.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-puma-haikou.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rg552-linux.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc-mezzanine.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc-plus.dtb +diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi linux/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi +--- linux.orig/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi 2022-11-01 17:55:23.662604223 -0400 ++++ linux/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi 2022-11-01 17:56:17.128793891 -0400 +@@ -101,6 +101,10 @@ + opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <1100000 1100000 1150000>; + }; ++ opp06 { ++ opp-hz = /bits/ 64 <900000000>; ++ opp-microvolt = <1100000 1100000 1150000>; ++ }; + }; + }; + +diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3399-rg552-linux.dts linux/arch/arm64/boot/dts/rockchip/rk3399-rg552-linux.dts +--- linux.orig/arch/arm64/boot/dts/rockchip/rk3399-rg552-linux.dts 1969-12-31 19:00:00.000000000 -0500 ++++ linux/arch/arm64/boot/dts/rockchip/rk3399-rg552-linux.dts 2022-11-01 17:56:17.132793763 -0400 +@@ -0,0 +1,1407 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd. ++ * Copyright (c) 2018 Akash Gajjar ++ * Copyright (c) 2022 Maya Matuszczyk ++ */ ++ ++ ++/dts-v1/; ++#include ++#include ++#include ++#include "rk3399.dtsi" ++#include "rk3399-opp.dtsi" ++ ++/ { ++ model = "Anbernic RG552"; ++ compatible = "anbernic,rg552", "rockchip,rk3399"; ++ ++ aliases { ++ mmc0 = &sdio0; ++ mmc1 = &sdmmc; ++ mmc2 = &sdhci; ++ }; ++ ++ chosen { ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ memory { ++ device_type = "memory"; ++ reg = <0x0 0x00200000 0x0 0xf7e00000>; ++ }; ++ ++ volume-keys { ++ compatible = "gpio-keys"; ++ autorepeat; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vol_pwr_btn>; ++ ++ sw1 { ++ debounce-interval = <100>; ++ gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>; ++ label = "BTN PWR"; ++ linux,code = ; ++ wakeup-source; ++ }; ++ sw2 { ++ label = "BTN VOL+"; ++ linux,code = ; ++ gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>; ++ }; ++ sw3 { ++ label = "BTN VOL-"; ++ linux,code = ; ++ gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ adc-keys { ++ compatible = "adc-keys"; ++ io-channels = <&saradc 1>; ++ io-channel-names = "buttons"; ++ keyup-threshold-microvolt = <1800000>; ++ poll-interval = <100>; ++ ++ home-key { ++ linux,code = ; ++ label = "F Button"; ++ press-threshold-microvolt = <1750>; ++ }; ++ }; ++ ++ joypad: singleadc-joypad { ++ compatible = "singleadc-joypad"; ++ ++ pwms = <&pwm3 0 200000000 0>; ++ pwm-names = "enable"; ++ rumble-boost-weak = <0x0000>; ++ rumble-boost-strong = <0x0000>; ++ ++ joypad-name = "retrogame_joypad"; ++ joypad-product = <0x1101>; ++ joypad-revision = <0x0100>; ++ ++ status = "okay"; ++ ++ /* gpio pincontrol setup */ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&btn_pins>; ++ ++ /* Analog mux define */ ++ io-channel-names = "amux_adc"; ++ io-channels = <&saradc 4>; ++ ++ /* adc mux channel count */ ++ amux-count = <4>; ++ /* adc mux select(a,b) gpio */ ++ amux-a-gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_LOW>; ++ amux-b-gpios = <&gpio1 RK_PA0 GPIO_ACTIVE_LOW>; ++ /* adc mux enable gpio */ ++ amux-en-gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_LOW>; ++ ++ /* adc calculate scale */ ++ button-adc-scale = <2>; ++ ++ /* adc deadzone range */ ++ button-adc-deadzone = <64>; ++ ++ /* ++ specifies fuzz value that is used to filter noise from ++ the event stream. ++ */ ++ button-adc-fuzz = <32>; ++ button-adc-flat = <32>; ++ ++ /* ++ Analog Stick data tuning value(precent) ++ p = positive direction, n = negative direction ++ report value = (real_adc_data * tuning_value) / 100 ++ */ ++ abs_x-p-tuning = <300>; ++ abs_x-n-tuning = <300>; ++ ++ abs_y-p-tuning = <300>; ++ abs_y-n-tuning = <300>; ++ ++ abs_rx-p-tuning = <300>; ++ abs_rx-n-tuning = <300>; ++ ++ abs_ry-p-tuning = <300>; ++ abs_ry-n-tuning = <300>; ++ ++ /* poll device interval (ms), adc read interval */ ++ poll-interval = <10>; ++ ++ /* required for RG552(invert) */ ++ invert-absx; ++ invert-absy; ++ ++ /* gpio button auto repeat set value : default disable */ ++ /* ++ autorepeat; ++ */ ++ sw1 { ++ gpios = <&gpio3 RK_PA0 GPIO_ACTIVE_LOW>; ++ label = "GPIO DPAD-UP"; ++ linux,code = ; ++ }; ++ sw2 { ++ gpios = <&gpio3 RK_PA1 GPIO_ACTIVE_LOW>; ++ label = "GPIO DPAD-DOWN"; ++ linux,code = ; ++ }; ++ sw3 { ++ gpios = <&gpio3 RK_PA3 GPIO_ACTIVE_LOW>; ++ label = "GPIO DPAD-LEFT"; ++ linux,code = ; ++ }; ++ sw4 { ++ gpios = <&gpio3 RK_PA2 GPIO_ACTIVE_LOW>; ++ label = "GPIO DPAD-RIGHT"; ++ linux,code = ; ++ }; ++ sw5 { ++ gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_LOW>; ++ label = "GPIO KEY BTN-A"; ++ linux,code = ; ++ }; ++ sw6 { ++ gpios = <&gpio3 RK_PA7 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN-B"; ++ linux,code = ; ++ }; ++ sw7 { ++ gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN-X"; ++ linux,code = ; ++ }; ++ sw8 { ++ gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN-Y"; ++ linux,code = ; ++ }; ++ sw9 { ++ gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN_SELECT"; ++ linux,code = ; ++ }; ++ sw10 { ++ gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN_START"; ++ linux,code = ; ++ }; ++ sw11 { ++ gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN_F"; ++ linux,code = ; ++ }; ++ sw12 { ++ gpios = <&gpio3 RK_PD0 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN_TL"; ++ linux,code = ; ++ }; ++ sw13 { ++ gpios = <&gpio3 RK_PD2 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN_TR"; ++ linux,code = ; ++ }; ++ sw14 { ++ gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN_TL2"; ++ linux,code = ; ++ }; ++ sw15 { ++ gpios = <&gpio3 RK_PD3 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN_TR2"; ++ linux,code = ; ++ }; ++ sw16 { ++ gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN_THUMBL"; ++ linux,code = ; ++ }; ++ sw17 { ++ gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN_THUMBR"; ++ linux,code = ; ++ }; ++ }; ++ ++ leds: gpio-leds { ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 =<&leds_gpio>; ++ ++ led@1 { ++ gpios = <&gpio1 RK_PC4 GPIO_ACTIVE_HIGH>; ++ label = "battery_green"; ++ default-state= "on"; ++ // retain-state-suspended; ++ }; ++ ++ led@2 { ++ gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>; ++ label = "battery_red"; ++ // retain-state-suspended; ++ }; ++ ++ }; ++ ++ es8316-sound { ++ compatible = "simple-audio-card"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hp_det_pin>; ++ simple-audio-card,name = "rockchip,es8316-codec"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <256>; ++ ++ simple-audio-card,widgets = ++ "Headphone", "Headphones", ++ "Speaker", "Speaker"; ++ simple-audio-card,routing = ++ "Headphones", "HPOL", ++ "Headphones", "HPOR", ++ "Speaker Amplifier INL", "HPOL", ++ "Speaker Amplifier INR", "HPOR", ++ "Speaker", "Speaker Amplifier OUTL", ++ "Speaker", "Speaker Amplifier OUTR"; ++ ++ simple-audio-card,hp-det-gpio = <&gpio0 RK_PB0 GPIO_ACTIVE_HIGH>; ++ simple-audio-card,aux-devs = <&speaker_amp>; ++ simple-audio-card,pin-switches = "Speaker"; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&i2s1>; ++ }; ++ ++ simple-audio-card,codec { ++ sound-dai = <&es8316>; ++ }; ++ }; ++ ++ speaker_amp: speaker-amplifier { ++ compatible = "simple-audio-amplifier"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spk_en_pin>; ++ enable-gpios = <&gpio1 RK_PC5 GPIO_ACTIVE_HIGH>; ++ sound-name-prefix = "Speaker Amplifier"; ++ VCC-supply = <&vcc5v0_sys>; ++ }; ++ ++ fan: pwm-fan { ++ compatible = "pwm-fan"; ++ pwms = <&pwm1 0 10000 1>; ++ #cooling-cells = <2>; ++ cooling-levels = <80 140 200 255>; ++ fan-supply = <&vcc5v0_sys>; ++ }; ++ ++ backlight: backlight { ++ status = "okay"; ++ compatible = "pwm-backlight"; ++ pwms = <&pwm0 0 25000 0>; ++ //power-supply = <&vcc12v_dcin>; ++ brightness-levels = < ++ 0 1 2 3 4 5 6 7 ++ 8 9 10 11 12 13 14 15 ++ 16 17 18 19 20 21 22 23 ++ 24 25 26 27 28 29 30 31 ++ 32 33 34 35 36 37 38 39 ++ 40 41 42 43 44 45 46 47 ++ 48 49 50 51 52 53 54 55 ++ 56 57 58 59 60 61 62 63 ++ 64 65 66 67 68 69 70 71 ++ 72 73 74 75 76 77 78 79 ++ 80 81 82 83 84 85 86 87 ++ 88 89 90 91 92 93 94 95 ++ 96 97 98 99 100 101 102 103 ++ 104 105 106 107 108 109 110 111 ++ 112 113 114 115 116 117 118 119 ++ 120 121 122 123 124 125 126 127 ++ 128 129 130 131 132 133 134 135 ++ 136 137 138 139 140 141 142 143 ++ 144 145 146 147 148 149 150 151 ++ 152 153 154 155 156 157 158 159 ++ 160 161 162 163 164 165 166 167 ++ 168 169 170 171 172 173 174 175 ++ 176 177 178 179 180 181 182 183 ++ 184 185 186 187 188 189 190 191 ++ 192 193 194 195 196 197 198 199 ++ 200 201 202 203 204 205 206 207 ++ 208 209 210 211 212 213 214 215 ++ 216 217 218 219 220 221 222 223 ++ 224 225 226 227 228 229 230 231 ++ 232 233 234 235 236 237 238 239 ++ 240 241 242 243 244 245 246 247 ++ 248 249 250 251 252 253 254 255>; ++ default-brightness-level = <200>; ++ }; ++ bat: battery { ++ compatible = "simple-battery"; ++ charge-full-design-microamp-hours = <6400000>; ++ voltage-max-design-microvolt = <4350000>; ++ voltage-min-design-microvolt = <3400000>; ++ constant-charge-current-max-microamp = <1500000>; ++ constant-charge-voltage-max-microvolt = <4350000>; ++ factory-internal-resistance-micro-ohms = <150000>; ++ resistance-temp-table = <20 150>; ++ ++ ocv-capacity-celsius = <20>; ++ ocv-capacity-table-0 = <4308000 100>,<4217000 95>, ++ <4161000 90>,<4110000 85>, ++ <4066000 80>,<4007000 75>, ++ <3974000 70>,<3937000 65>, ++ <3896000 60>,<3853000 55>, ++ <3827000 50>,<3807000 45>, ++ <3793000 40>,<3780000 35>, ++ <3768000 30>,<3756000 25>, ++ <3740000 20>,<3716000 15>, ++ <3689000 10>,<3675000 5>, ++ <3400000 0>; ++ }; ++ ++ mains_charger: dc-charger { ++ compatible = "gpio-charger"; ++ charger-type = "mains"; ++ gpios = <&gpio4 RK_PD0 GPIO_ACTIVE_LOW>; ++ ++ /* Also triggered by USB charger */ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&dc_det_pin>; ++ monitored-battery = <&bat>; ++ }; ++ ++ xin32k: xin32k { ++ compatible = "fixed-clock"; ++ clock-frequency = <32768>; ++ clock-output-names = "xin32k"; ++ #clock-cells = <0>; ++ }; ++ ++ clkin_gmac: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "clkin_gmac"; ++ #clock-cells = <0>; ++ }; ++ ++ /* TODO: shouldn't be here */ ++ vcc12v_dcin: vcc12v-dcin { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc12v_dcin"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ }; ++ ++ vcc_sys: vcc-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_sys"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-always-on; ++ vin-supply = <&vcc12v_dcin>; ++ }; ++ ++ vcc3v3_sys: vcc3v3-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ vcc3v0_sd: vcc3v0-sd { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_pwr_h>; ++ regulator-name = "vcc3v0_sd"; ++ regulator-always-on; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ vin-supply = <&vcc3v3_sys>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc5v0_host: vcc5v0-host-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio4 RK_PD2 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc5v0_host_en>; ++ regulator-name = "vcc5v0_host"; ++ regulator-always-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc5v0_usb>; ++ }; ++ ++ vcc5v0_typec: vcc5v0-typec-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc5v0_typec_en>; ++ regulator-name = "vcc5v0_typec"; ++ regulator-always-on; ++ vin-supply = <&vcc5v0_usb>; ++ }; ++ ++ vcc5v0_sys: vcc5v0-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc12v_dcin>; ++ }; ++ ++ vcc5v0_usb: vcc5v0-usb { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_usb"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc12v_dcin>; ++ }; ++ ++ vdd_log: vdd-log { ++ compatible = "pwm-regulator"; ++ pwms = <&pwm2 0 25000 1>; ++ regulator-name = "vdd_log"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <1700000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ vcc5v5_lcd: vcc5v5-lcd { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio4 RK_PD3 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc5v5_lcd_en>; ++ regulator-name = "vcc5v5_lcd"; ++ regulator-min-microvolt = <5500000>; ++ regulator-max-microvolt = <5500000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ vcc5v5_neg_lcd: vcc5v5-neg-lcd { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio4 RK_PD1 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc5v5_neg_lcd_en>; ++ regulator-name = "vcc5v5_neg_lcd"; ++ /* ++ * technically negative ++ */ ++ regulator-min-microvolt = <5500000>; ++ regulator-max-microvolt = <5500000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ vcc_wifi: vcc-wifi-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio3 RK_PC1 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_pwr>; ++ regulator-name = "wifi_enable"; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ dmc_opp_table: dmc_opp_table { ++ compatible = "operating-points-v2"; ++ ++ opp-300000000 { ++ opp-hz = /bits/ 64 <300000000>; ++ opp-microvolt = <900000>; ++ }; ++ opp-666000000 { ++ opp-hz = /bits/ 64 <666000000>; ++ opp-microvolt = <900000>; ++ }; ++ opp-800000000 { ++ opp-hz = /bits/ 64 <800000000>; ++ opp-microvolt = <900000>; ++ }; ++ opp-856000000 { ++ opp-hz = /bits/ 64 <856000000>; ++ opp-microvolt = <900000>; ++ }; ++ opp-928000000 { ++ opp-hz = /bits/ 64 <928000000>; ++ opp-microvolt = <900000>; ++ }; ++ opp-933000000 { ++ opp-hz = /bits/ 64 <933000000>; ++ opp-microvolt = <900000>; ++ }; ++ }; ++}; ++ ++&cluster0_opp { ++ opp-1512000000 { ++ opp-hz = /bits/ 64 <1512000000>; ++ opp-microvolt = <1200000>; ++ }; ++ opp-1608000000 { ++ opp-hz = /bits/ 64 <1608000000>; ++ opp-microvolt = <1200000>; ++ }; ++ opp-1704000000 { ++ opp-hz = /bits/ 64 <1704000000>; ++ opp-microvolt = <1225000>; ++ }; ++}; ++ ++&cluster1_opp { ++ opp-1992000000 { ++ opp-hz = /bits/ 64 <1992000000>; ++ opp-microvolt = <1250000>; ++ }; ++ opp-2016000000 { ++ opp-hz = /bits/ 64 <2016000000>; ++ opp-microvolt = <1250000>; ++ }; ++ opp-2040000000 { ++ opp-hz = /bits/ 64 <2040000000>; ++ opp-microvolt = <1250000>; ++ }; ++ opp-2088000000 { ++ opp-hz = /bits/ 64 <2088000000>; ++ opp-microvolt = <1250000>; ++ }; ++ opp-2184000000 { ++ opp-hz = /bits/ 64 <2184000000>; ++ opp-microvolt = <1350000>; ++ }; ++}; ++ ++&cpu_thermal { ++ trips { ++ cpu_warm: cpu_warm { ++ temperature = <50000>; ++ hysteresis = <2000>; ++ type = "active"; ++ }; ++ ++ cpu_hot: cpu_hot { ++ temperature = <55000>; ++ hysteresis = <2000>; ++ type = "active"; ++ }; ++ ++ cpu_scalding: cpu_scalding { ++ temperature = <65000>; ++ hysteresis = <5000>; ++ type = "active"; ++ }; ++ }; ++ ++ cooling-maps { ++ map1 { ++ trip = <&cpu_warm>; ++ cooling-device = <&fan THERMAL_NO_LIMIT 1>; ++ }; ++ ++ map2 { ++ trip = <&cpu_hot>; ++ cooling-device = <&fan THERMAL_NO_LIMIT 1>; ++ }; ++ ++ map3 { ++ trip = <&cpu_scalding>; ++ cooling-device = <&fan 2 THERMAL_NO_LIMIT>; ++ }; ++ }; ++}; ++ ++&cpu_l0 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l1 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l2 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l3 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_b0 { ++ cpu-supply = <&vdd_cpu_b>; ++}; ++ ++&cpu_b1 { ++ cpu-supply = <&vdd_cpu_b>; ++}; ++ ++&saradc { ++ status = "okay"; ++}; ++ ++&sdio0 { ++ clock-frequency = <150000000>; ++ clock-freq-min-max = <100000 150000000>; ++ supports-sd; ++ no-sdio; ++ bus-width = <4>; ++ disable-wp; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ keep-power-in-suspend; ++ card-detect-delay = <800>; ++ cd-gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_LOW>; /*[> CD GPIO <]*/ ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdio0_clk &sdio0_cmd &sdio0_cd &sdio0_bus4>; ++ sd-uhs-sdr104; ++ vqmmc-supply = <&vcc3v0_touch>; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cd-gpios = <&gpio0 7 GPIO_ACTIVE_LOW>; ++ disable-wp; ++ max-frequency = <150000000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4>; ++ vmmc-supply = <&vcc3v0_sd>; ++ vqmmc-supply = <&vcc_sdio>; ++ status = "okay"; ++}; ++ ++&emmc_phy { ++ status = "okay"; ++}; ++ ++&gpu { ++ mali-supply = <&vdd_gpu>; ++ status = "okay"; ++}; ++ ++&pwm0 { ++ status = "okay"; ++}; ++ ++&pwm1 { ++ status = "okay"; ++}; ++ ++&pwm2 { ++ status = "okay"; ++ pinctrl-names = "active"; ++ pinctrl-0 = <&pwm2_pin_pull_down>; ++}; ++ ++&pwm3 { ++ status = "okay"; ++ label = "rumble-pwm"; ++}; ++ ++&saradc { ++ vref-supply = <&vcc_1v8>; ++ status = "okay"; ++}; ++ ++&sdhci { ++ assigned-clock-rates = <150000000>; ++ ++ bus-width = <8>; ++ mmc-hs400-1_8v; ++ mmc-hs400-enhanced-strobe; ++ non-removable; ++ ++ status = "okay"; ++}; ++ ++&hdmi { ++ ddc-i2c-bus = <&i2c3>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdmi_cec>; ++ status = "okay"; ++}; ++ ++&mipi_dsi { ++ status = "okay"; ++ clock-master; ++ ++ ports { ++ mipi_out: port@1 { ++ #address-cells = <0>; ++ #size-cells = <0>; ++ reg = <1>; ++ ++ mipi_out_panel: endpoint { ++ remote-endpoint = <&mipi_in_panel>; ++ }; ++ }; ++ }; ++ ++ panel@0 { ++ reg = <0>; ++ compatible = "sharp,ls054b3sx01"; ++ backlight = <&backlight>; ++ rotation = <270>; ++ ++ iovcc-supply = <&vcc1v8_dvp>; ++ vsp-supply = <&vcc5v5_lcd>; ++ vsn-supply = <&vcc5v5_neg_lcd>; ++ ++ reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_HIGH>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&lcd_reset_gpio>; ++ ++ port { ++ mipi_in_panel: endpoint { ++ remote-endpoint = <&mipi_out_panel>; ++ }; ++ }; ++ }; ++}; ++ ++&i2c0 { ++ clock-frequency = <400000>; ++ i2c-scl-rising-time-ns = <168>; ++ i2c-scl-falling-time-ns = <4>; ++ status = "okay"; ++ ++ rk808: pmic@1b { ++ compatible = "rockchip,rk808"; ++ reg = <0x1b>; ++ interrupt-parent = <&gpio3>; ++ interrupts = <10 IRQ_TYPE_LEVEL_LOW>; ++ #clock-cells = <1>; ++ clock-output-names = "xin32k", "rk808-clkout2"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ ++ vcc1-supply = <&vcc5v0_sys>; ++ vcc2-supply = <&vcc5v0_sys>; ++ vcc3-supply = <&vcc5v0_sys>; ++ vcc4-supply = <&vcc5v0_sys>; ++ vcc6-supply = <&vcc5v0_sys>; ++ vcc7-supply = <&vcc5v0_sys>; ++ vcc8-supply = <&vcc3v3_sys>; ++ vcc9-supply = <&vcc5v0_sys>; ++ vcc10-supply = <&vcc5v0_sys>; ++ vcc11-supply = <&vcc5v0_sys>; ++ vcc12-supply = <&vcc3v3_sys>; ++ vddio-supply = <&vcca_1v8>; ++ ++ rtc { ++ status = "okay"; ++ }; ++ ++ regulators { // are all those regulator-on-in-suspend really needed?/ ++ vdd_center: DCDC_REG1 { ++ regulator-name = "vdd_center"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_cpu_l: DCDC_REG2 { ++ regulator-name = "vdd_cpu_l"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_ddr: DCDC_REG3 { ++ regulator-name = "vcc_ddr"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_1v8: DCDC_REG4 { ++ regulator-name = "vcc_1v8"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc1v8_dvp: LDO_REG1 { ++ regulator-name = "vcc1v8_dvp"; ++ //regulator-always-on; ++ //regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc3v0_touch: LDO_REG2 { ++ regulator-name = "vcc3v0_touch"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcca_1v8: LDO_REG3 { ++ regulator-name = "vcca_1v8"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc_sdio: LDO_REG4 { ++ regulator-name = "vcc_sdio"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ ++ vcca3v0_codec: LDO_REG5 { ++ regulator-name = "vcca3v0_codec"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_1v5: LDO_REG6 { ++ regulator-name = "vcc_1v5"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1500000>; ++ regulator-max-microvolt = <1500000>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1500000>; ++ }; ++ }; ++ ++ vcca1v8_codec: LDO_REG7 { ++ regulator-name = "vcca1v8_codec"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_3v0: LDO_REG8 { ++ regulator-name = "vcc_3v0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ ++ vcc3v3_s3: vcc_lan: SWITCH_REG1 { ++ regulator-name = "vcc3v3_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc3v3_s0: SWITCH_REG2 { ++ regulator-name = "vcc3v3_s0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ }; ++ }; ++ ++ vdd_cpu_b: regulator@40 { ++ compatible = "silergy,syr827"; ++ reg = <0x40>; ++ fcs,suspend-voltage-selector = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vsel1_pin>; ++ regulator-name = "vdd_cpu_b"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1500000>; ++ regulator-ramp-delay = <1000>; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc5v0_sys>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_gpu: regulator@41 { ++ compatible = "silergy,syr828"; ++ reg = <0x41>; ++ fcs,suspend-voltage-selector = <1>; ++ vsel-gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vsel2_pin>; ++ regulator-name = "vdd_gpu"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1500000>; ++ regulator-ramp-delay = <1000>; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc5v0_sys>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ cw2015@62 { ++ compatible = "cellwise,cw2015"; ++ reg = <0x62>; ++ cellwise,battery-profile = /bits/ 8 < ++ 0x15 0x7E 0x66 0x5B 0x58 0x55 0x51 0x4D ++ 0x4A 0x47 0x44 0x47 0x4D 0x46 0x32 0x27 ++ 0x1F 0x1A 0x15 0x16 0x21 0x30 0x3F 0x4A ++ 0x46 0x5C 0x0C 0x29 0x19 0x31 0x59 0x74 ++ 0x7B 0x7D 0x81 0x82 0x3F 0x1A 0x58 0x22 ++ 0x06 0x42 0x2B 0x63 0x89 0x93 0x94 0x3C ++ 0x57 0x7D 0x93 0xAE 0x80 0xC2 0xD2 0xCB ++ 0x2F 0x00 0x64 0xA5 0xB5 0x1F 0xB0 0x11 ++ >; ++ cellwise,monitor-interval-ms = <5000>; ++ power-supplies = <&mains_charger>; ++ monitored-battery = <&bat>; ++ }; ++}; ++ ++&i2c1 { ++ clock-frequency = <100000>; ++ i2c-scl-rising-time-ns = <300>; ++ i2c-scl-falling-time-ns = <15>; ++ status = "okay"; ++ ++ es8316: es8316@11 { ++ compatible = "everest,es8316"; ++ reg = <0x11>; ++ clocks = <&cru SCLK_I2S_8CH_OUT>; ++ clock-names = "mclk"; ++ #sound-dai-cells = <0>; ++ }; ++}; ++ ++&i2c3 { ++ i2c-scl-rising-time-ns = <450>; ++ i2c-scl-falling-time-ns = <15>; ++ status = "okay"; ++}; ++ ++&i2c4 { ++ i2c-scl-rising-time-ns = <600>; ++ i2c-scl-falling-time-ns = <20>; ++ status = "okay"; ++ ++ gt9xx: gt9xx@14 { ++ compatible = "goodix,gt927"; ++ goodix,config-name = "rg552_goodix_927_cfg.bin"; ++ reg = <0x14>; ++ irq-gpios = <&gpio3 RK_PD7 GPIO_ACTIVE_HIGH>; ++ reset-gpios = <&gpio3 RK_PD6 GPIO_ACTIVE_HIGH>; ++ touchscreen-size-x = <1152>; ++ touchscreen-size-y = <1920>; ++ touchscreen-inverted-x; ++ touchscreen-inverted-y; ++ interrupt-parent = <&gpio3>; ++ interrupts = ; ++ }; ++ ++ fusb0: typec-portc@22 { ++ compatible = "fcs,fusb302"; ++ status = "okay"; ++ reg = <0x22>; ++ interrupt-parent = <&gpio1>; ++ interrupts = ; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&fusb0_int>; ++ vbus-supply = <&vcc5v0_typec>; ++ ++ connector { ++ compatible = "usb-c-connector"; ++ data-role = "dual"; ++ label = "USB-C"; ++ op-sink-microwatt = <1000000>; ++ power-role = "dual"; ++ sink-pdos = ++ ; ++ source-pdos = ++ ; ++ try-power-role = "sink"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ ++ usbc_hs: endpoint { ++ remote-endpoint = <&u2phy0_typec_hs>; ++ }; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ ++ usbc_ss: endpoint { ++ remote-endpoint = <&tcphy0_typec_ss>; ++ }; ++ }; ++ // displayport maybe? ++ }; ++ }; ++ }; ++}; ++ ++&i2s1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_8ch_mclk_pin>, <&i2s1_2ch_bus>; ++ rockchip,i2s-broken-burst-len; ++ rockchip,playback-channels = <8>; ++ rockchip,capture-channels = <8>; ++ status = "okay"; ++}; ++ ++&i2s2 { ++ status = "okay"; ++}; ++ ++&io_domains { ++ status = "okay"; ++ ++ bt656-supply = <&vcc1v8_dvp>; ++ audio-supply = <&vcca3v0_codec>; ++ sdmmc-supply = <&vcc_sdio>; ++ gpio1830-supply = <&vcc_3v0>; ++}; ++ ++&pmu_io_domains { ++ pmu1830-supply = <&vcc_3v0>; ++ status = "okay"; ++}; ++ ++&pinctrl { ++ dc-charger { ++ dc_det_pin: dc-det-pin { ++ rockchip,pins = <4 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ es8316 { ++ hp_det_pin: hp-det-pin { ++ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ spk_en_pin: spk-en-pin { ++ rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++ i2s1 { ++ i2s_8ch_mclk_pin: i2s-8ch-mclk-pin { ++ rockchip,pins = <4 RK_PA0 1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ fusb302x { ++ fusb0_int: fusb0-int { ++ rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ vsel1_pin: vsel1-pin { ++ rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ vsel2_pin: vsel2-pin { ++ rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++ sdcard { ++ sdmmc0_pwr_h: sdmmc0-pwr-h { ++ rockchip,pins = <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ }; ++ ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = <2 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb-typec { ++ vcc5v0_typec_en: vcc5v0_typec_en { ++ rockchip,pins = <1 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ usb2 { ++ vcc5v0_host_en: vcc5v0-host-en { ++ rockchip,pins = <4 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ gpio-leds { ++ leds_gpio: leds-gpio { ++ rockchip,pins = ++ <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ lcd-panel { ++ lcd_reset_gpio: lcd-reset-gpio { ++ rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ vcc5v5_lcd_en: vcc5v5-lcd-en { ++ rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ vcc5v5_neg_lcd_en: vcc5v5-neg-lcd-en { ++ rockchip,pins = <0 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ wifi { ++ wifi_pwr: wifi-pwr-en { ++ rockchip,pins = <3 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ btns { ++ btn_pins: btn-pins { ++ rockchip,pins = ++ <3 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PB3 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ vol_pwr_btn: vol-pwr-btn { ++ rockchip,pins = ++ <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>, ++ <3 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++}; ++ ++&tcphy0 { ++ status = "okay"; ++}; ++ ++&tcphy0_usb3 { ++ port { ++ tcphy0_typec_ss: endpoint { ++ remote-endpoint = <&usbc_ss>; ++ }; ++ }; ++}; ++ ++&tcphy1 { ++ status = "okay"; ++}; ++ ++&tsadc { ++ /* tshut mode 0:CRU 1:GPIO */ ++ rockchip,hw-tshut-mode = <1>; ++ /* tshut polarity 0:LOW 1:HIGH */ ++ rockchip,hw-tshut-polarity = <1>; ++ status = "okay"; ++}; ++ ++&u2phy0 { ++ status = "okay"; ++ ++ u2phy0_otg: otg-port { ++ status = "okay"; ++ }; ++ ++ u2phy0_host: host-port { ++ phy-supply = <&vcc5v0_host>; ++ status = "okay"; ++ }; ++ ++ port { ++ u2phy0_typec_hs: endpoint { ++ remote-endpoint = <&usbc_hs>; ++ }; ++ }; ++}; ++ ++&u2phy1 { ++ status = "okay"; ++ ++ u2phy1_otg: otg-port { ++ status = "okay"; ++ }; ++ ++ u2phy1_host: host-port { ++ phy-supply = <&vcc5v0_host>; ++ status = "okay"; ++ }; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usb_host1_ehci { ++ status = "okay"; ++}; ++ ++&usb_host1_ohci { ++ status = "okay"; ++}; ++ ++&usbdrd3_0 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3_0 { ++ status = "okay"; ++ dr_mode = "host"; ++}; ++ ++&usbdrd3_1 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3_1 { ++ status = "okay"; ++ dr_mode = "host"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ wifi_card: device@1 { ++ compatible = "usbbda,f179"; ++ reg = <1>; ++ #size-cells = <0>; ++ #address-cells = <2>; ++ ++ interface@0 { ++ compatible = "usbifbda,f179.config1.0"; ++ reg = <0 1>; ++ }; ++ }; ++}; ++ ++&vopb { ++ status = "okay"; ++}; ++ ++&vopb_mmu { ++ status = "okay"; ++}; ++ ++&vopl { ++ status = "okay"; ++}; ++ ++&vopl_mmu { ++ status = "okay"; ++}; +diff -rupN linux.orig/arch/arm64/configs/rg552_defconfig linux/arch/arm64/configs/rg552_defconfig +--- linux.orig/arch/arm64/configs/rg552_defconfig 1969-12-31 19:00:00.000000000 -0500 ++++ linux/arch/arm64/configs/rg552_defconfig 2022-11-01 17:56:17.136793634 -0400 +@@ -0,0 +1,7577 @@ ++# ++# Automatically generated file; DO NOT EDIT. ++# Linux/arm64 5.18.0-rc3 Kernel Configuration ++# ++CONFIG_CC_VERSION_TEXT="aarch64-libreelec-linux-gnueabi-gcc-10.3.0 (GCC) 10.3.0" ++CONFIG_CC_IS_GCC=y ++CONFIG_GCC_VERSION=100300 ++CONFIG_CLANG_VERSION=0 ++CONFIG_AS_IS_GNU=y ++CONFIG_AS_VERSION=23800 ++CONFIG_LD_IS_BFD=y ++CONFIG_LD_VERSION=23800 ++CONFIG_LLD_VERSION=0 ++CONFIG_CC_CAN_LINK=y ++CONFIG_CC_CAN_LINK_STATIC=y ++CONFIG_CC_HAS_ASM_GOTO=y ++CONFIG_CC_HAS_ASM_INLINE=y ++CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y ++CONFIG_PAHOLE_VERSION=0 ++CONFIG_IRQ_WORK=y ++CONFIG_BUILDTIME_TABLE_SORT=y ++CONFIG_THREAD_INFO_IN_TASK=y ++ ++# ++# General setup ++# ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++# CONFIG_COMPILE_TEST is not set ++# CONFIG_WERROR is not set ++CONFIG_LOCALVERSION="" ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_BUILD_SALT="-ragnarok" ++CONFIG_DEFAULT_INIT="" ++CONFIG_DEFAULT_HOSTNAME="RG552" ++# CONFIG_SWAP is not set ++CONFIG_SYSVIPC=y ++CONFIG_SYSVIPC_SYSCTL=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_POSIX_MQUEUE_SYSCTL=y ++CONFIG_WATCH_QUEUE=y ++# CONFIG_CROSS_MEMORY_ATTACH is not set ++CONFIG_USELIB=y ++# CONFIG_AUDIT is not set ++CONFIG_HAVE_ARCH_AUDITSYSCALL=y ++ ++# ++# IRQ subsystem ++# ++CONFIG_GENERIC_IRQ_PROBE=y ++CONFIG_GENERIC_IRQ_SHOW=y ++CONFIG_GENERIC_IRQ_SHOW_LEVEL=y ++CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y ++CONFIG_GENERIC_IRQ_MIGRATION=y ++CONFIG_HARDIRQS_SW_RESEND=y ++CONFIG_GENERIC_IRQ_CHIP=y ++CONFIG_IRQ_DOMAIN=y ++CONFIG_IRQ_DOMAIN_HIERARCHY=y ++CONFIG_GENERIC_IRQ_IPI=y ++CONFIG_GENERIC_MSI_IRQ=y ++CONFIG_GENERIC_MSI_IRQ_DOMAIN=y ++CONFIG_IRQ_MSI_IOMMU=y ++CONFIG_IRQ_FORCED_THREADING=y ++CONFIG_SPARSE_IRQ=y ++# CONFIG_GENERIC_IRQ_DEBUGFS is not set ++# end of IRQ subsystem ++ ++CONFIG_GENERIC_TIME_VSYSCALL=y ++CONFIG_GENERIC_CLOCKEVENTS=y ++CONFIG_ARCH_HAS_TICK_BROADCAST=y ++CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y ++CONFIG_HAVE_POSIX_CPU_TIMERS_TASK_WORK=y ++CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y ++ ++# ++# Timers subsystem ++# ++CONFIG_TICK_ONESHOT=y ++CONFIG_NO_HZ_COMMON=y ++# CONFIG_HZ_PERIODIC is not set ++# CONFIG_NO_HZ_IDLE is not set ++CONFIG_NO_HZ_FULL=y ++CONFIG_CONTEXT_TRACKING=y ++# CONFIG_CONTEXT_TRACKING_FORCE is not set ++CONFIG_NO_HZ=y ++CONFIG_HIGH_RES_TIMERS=y ++# end of Timers subsystem ++ ++CONFIG_BPF=y ++CONFIG_HAVE_EBPF_JIT=y ++CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y ++ ++# ++# BPF subsystem ++# ++CONFIG_BPF_SYSCALL=y ++CONFIG_BPF_JIT=y ++# CONFIG_BPF_JIT_ALWAYS_ON is not set ++CONFIG_BPF_JIT_DEFAULT_ON=y ++# CONFIG_BPF_UNPRIV_DEFAULT_OFF is not set ++# CONFIG_BPF_PRELOAD is not set ++# end of BPF subsystem ++ ++CONFIG_PREEMPT_BUILD=y ++# CONFIG_PREEMPT_NONE is not set ++# CONFIG_PREEMPT_VOLUNTARY is not set ++CONFIG_PREEMPT=y ++CONFIG_PREEMPT_COUNT=y ++CONFIG_PREEMPTION=y ++# CONFIG_PREEMPT_DYNAMIC is not set ++ ++# ++# CPU/Task time and stats accounting ++# ++CONFIG_VIRT_CPU_ACCOUNTING=y ++CONFIG_VIRT_CPU_ACCOUNTING_GEN=y ++# CONFIG_IRQ_TIME_ACCOUNTING is not set ++CONFIG_SCHED_THERMAL_PRESSURE=y ++# CONFIG_BSD_PROCESS_ACCT is not set ++# CONFIG_TASKSTATS is not set ++# CONFIG_PSI is not set ++# end of CPU/Task time and stats accounting ++ ++CONFIG_CPU_ISOLATION=y ++ ++# ++# RCU Subsystem ++# ++CONFIG_TREE_RCU=y ++CONFIG_PREEMPT_RCU=y ++# CONFIG_RCU_EXPERT is not set ++CONFIG_SRCU=y ++CONFIG_TREE_SRCU=y ++CONFIG_TASKS_RCU_GENERIC=y ++CONFIG_TASKS_RCU=y ++CONFIG_RCU_STALL_COMMON=y ++CONFIG_RCU_NEED_SEGCBLIST=y ++CONFIG_RCU_NOCB_CPU=y ++# end of RCU Subsystem ++ ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++# CONFIG_IKHEADERS is not set ++CONFIG_LOG_BUF_SHIFT=18 ++CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 ++CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 ++# CONFIG_PRINTK_INDEX is not set ++CONFIG_GENERIC_SCHED_CLOCK=y ++ ++# ++# Scheduler features ++# ++# CONFIG_UCLAMP_TASK is not set ++# end of Scheduler features ++ ++CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y ++CONFIG_CC_HAS_INT128=y ++CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" ++CONFIG_ARCH_SUPPORTS_INT128=y ++CONFIG_CGROUPS=y ++CONFIG_PAGE_COUNTER=y ++CONFIG_MEMCG=y ++CONFIG_MEMCG_KMEM=y ++CONFIG_BLK_CGROUP=y ++CONFIG_CGROUP_WRITEBACK=y ++CONFIG_CGROUP_SCHED=y ++CONFIG_FAIR_GROUP_SCHED=y ++CONFIG_CFS_BANDWIDTH=y ++# CONFIG_RT_GROUP_SCHED is not set ++CONFIG_CGROUP_PIDS=y ++CONFIG_CGROUP_RDMA=y ++CONFIG_CGROUP_FREEZER=y ++CONFIG_CPUSETS=y ++# CONFIG_PROC_PID_CPUSET is not set ++CONFIG_CGROUP_DEVICE=y ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_CGROUP_MISC=y ++CONFIG_CGROUP_DEBUG=y ++CONFIG_SOCK_CGROUP_DATA=y ++CONFIG_NAMESPACES=y ++CONFIG_UTS_NS=y ++CONFIG_TIME_NS=y ++CONFIG_IPC_NS=y ++CONFIG_USER_NS=y ++CONFIG_PID_NS=y ++CONFIG_NET_NS=y ++# CONFIG_CHECKPOINT_RESTORE is not set ++# CONFIG_SCHED_AUTOGROUP is not set ++# CONFIG_SYSFS_DEPRECATED is not set ++CONFIG_RELAY=y ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_INITRAMFS_SOURCE="/media/git/JELOS/build.JELOS-RG552.aarch64/image/initramfs.cpio" ++CONFIG_INITRAMFS_ROOT_UID=0 ++CONFIG_INITRAMFS_ROOT_GID=0 ++CONFIG_RD_GZIP=y ++CONFIG_RD_BZIP2=y ++CONFIG_RD_LZMA=y ++CONFIG_RD_XZ=y ++CONFIG_RD_LZO=y ++CONFIG_RD_LZ4=y ++CONFIG_RD_ZSTD=y ++CONFIG_INITRAMFS_COMPRESSION_GZIP=y ++# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set ++# CONFIG_INITRAMFS_COMPRESSION_LZMA is not set ++# CONFIG_INITRAMFS_COMPRESSION_XZ is not set ++# CONFIG_INITRAMFS_COMPRESSION_LZO is not set ++# CONFIG_INITRAMFS_COMPRESSION_LZ4 is not set ++# CONFIG_INITRAMFS_COMPRESSION_ZSTD is not set ++# CONFIG_INITRAMFS_COMPRESSION_NONE is not set ++# CONFIG_BOOT_CONFIG is not set ++# CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE is not set ++CONFIG_CC_OPTIMIZE_FOR_SIZE=y ++CONFIG_LD_ORPHAN_WARN=y ++CONFIG_SYSCTL=y ++CONFIG_HAVE_UID16=y ++CONFIG_SYSCTL_EXCEPTION_TRACE=y ++CONFIG_EXPERT=y ++CONFIG_UID16=y ++CONFIG_MULTIUSER=y ++CONFIG_SGETMASK_SYSCALL=y ++CONFIG_SYSFS_SYSCALL=y ++CONFIG_FHANDLE=y ++CONFIG_POSIX_TIMERS=y ++CONFIG_PRINTK=y ++# CONFIG_BUG is not set ++CONFIG_BASE_FULL=y ++CONFIG_FUTEX=y ++CONFIG_FUTEX_PI=y ++CONFIG_EPOLL=y ++CONFIG_SIGNALFD=y ++CONFIG_TIMERFD=y ++CONFIG_EVENTFD=y ++CONFIG_SHMEM=y ++CONFIG_AIO=y ++CONFIG_IO_URING=y ++CONFIG_ADVISE_SYSCALLS=y ++CONFIG_MEMBARRIER=y ++# CONFIG_KALLSYMS is not set ++# CONFIG_USERFAULTFD is not set ++CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y ++CONFIG_KCMP=y ++CONFIG_RSEQ=y ++# CONFIG_DEBUG_RSEQ is not set ++CONFIG_EMBEDDED=y ++CONFIG_HAVE_PERF_EVENTS=y ++# CONFIG_PC104 is not set ++ ++# ++# Kernel Performance Events And Counters ++# ++# CONFIG_PERF_EVENTS is not set ++# end of Kernel Performance Events And Counters ++ ++# CONFIG_VM_EVENT_COUNTERS is not set ++# CONFIG_SLUB_DEBUG is not set ++# CONFIG_COMPAT_BRK is not set ++# CONFIG_SLAB is not set ++CONFIG_SLUB=y ++# CONFIG_SLOB is not set ++# CONFIG_SLAB_MERGE_DEFAULT is not set ++# CONFIG_SLAB_FREELIST_RANDOM is not set ++# CONFIG_SLAB_FREELIST_HARDENED is not set ++# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set ++# CONFIG_SLUB_CPU_PARTIAL is not set ++CONFIG_SYSTEM_DATA_VERIFICATION=y ++CONFIG_PROFILING=y ++# end of General setup ++ ++CONFIG_ARM64=y ++CONFIG_64BIT=y ++CONFIG_MMU=y ++CONFIG_ARM64_PAGE_SHIFT=12 ++CONFIG_ARM64_CONT_PTE_SHIFT=4 ++CONFIG_ARM64_CONT_PMD_SHIFT=4 ++CONFIG_ARCH_MMAP_RND_BITS_MIN=18 ++CONFIG_ARCH_MMAP_RND_BITS_MAX=33 ++CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 ++CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 ++CONFIG_STACKTRACE_SUPPORT=y ++CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 ++CONFIG_LOCKDEP_SUPPORT=y ++CONFIG_GENERIC_HWEIGHT=y ++CONFIG_GENERIC_CSUM=y ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y ++CONFIG_SMP=y ++CONFIG_KERNEL_MODE_NEON=y ++CONFIG_FIX_EARLYCON_MEM=y ++CONFIG_PGTABLE_LEVELS=4 ++CONFIG_ARCH_SUPPORTS_UPROBES=y ++CONFIG_ARCH_PROC_KCORE_TEXT=y ++ ++# ++# Platform selection ++# ++# CONFIG_ARCH_ACTIONS is not set ++# CONFIG_ARCH_SUNXI is not set ++# CONFIG_ARCH_ALPINE is not set ++# CONFIG_ARCH_APPLE is not set ++# CONFIG_ARCH_BCM2835 is not set ++# CONFIG_ARCH_BCM4908 is not set ++# CONFIG_ARCH_BCM_IPROC is not set ++# CONFIG_ARCH_BERLIN is not set ++# CONFIG_ARCH_BITMAIN is not set ++# CONFIG_ARCH_BRCMSTB is not set ++# CONFIG_ARCH_EXYNOS is not set ++# CONFIG_ARCH_SPARX5 is not set ++# CONFIG_ARCH_K3 is not set ++# CONFIG_ARCH_LAYERSCAPE is not set ++# CONFIG_ARCH_LG1K is not set ++# CONFIG_ARCH_HISI is not set ++# CONFIG_ARCH_KEEMBAY is not set ++# CONFIG_ARCH_MEDIATEK is not set ++# CONFIG_ARCH_MESON is not set ++# CONFIG_ARCH_MVEBU is not set ++# CONFIG_ARCH_MXC is not set ++# CONFIG_ARCH_QCOM is not set ++# CONFIG_ARCH_REALTEK is not set ++# CONFIG_ARCH_RENESAS is not set ++CONFIG_ARCH_ROCKCHIP=y ++# CONFIG_ARCH_S32 is not set ++# CONFIG_ARCH_SEATTLE is not set ++# CONFIG_ARCH_INTEL_SOCFPGA is not set ++# CONFIG_ARCH_SYNQUACER is not set ++# CONFIG_ARCH_TEGRA is not set ++# CONFIG_ARCH_SPRD is not set ++# CONFIG_ARCH_THUNDER is not set ++# CONFIG_ARCH_THUNDER2 is not set ++# CONFIG_ARCH_UNIPHIER is not set ++# CONFIG_ARCH_VEXPRESS is not set ++# CONFIG_ARCH_VISCONTI is not set ++# CONFIG_ARCH_XGENE is not set ++# CONFIG_ARCH_ZYNQMP is not set ++# end of Platform selection ++ ++# ++# Kernel Features ++# ++ ++# ++# ARM errata workarounds via the alternatives framework ++# ++# CONFIG_ARM64_ERRATUM_826319 is not set ++# CONFIG_ARM64_ERRATUM_827319 is not set ++# CONFIG_ARM64_ERRATUM_824069 is not set ++# CONFIG_ARM64_ERRATUM_819472 is not set ++# CONFIG_ARM64_ERRATUM_832075 is not set ++CONFIG_ARM64_ERRATUM_834220=y ++# CONFIG_ARM64_ERRATUM_845719 is not set ++# CONFIG_ARM64_ERRATUM_843419 is not set ++CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y ++# CONFIG_ARM64_ERRATUM_1024718 is not set ++# CONFIG_ARM64_ERRATUM_1418040 is not set ++# CONFIG_ARM64_ERRATUM_1165522 is not set ++# CONFIG_ARM64_ERRATUM_1319367 is not set ++# CONFIG_ARM64_ERRATUM_1530923 is not set ++# CONFIG_ARM64_ERRATUM_1286807 is not set ++# CONFIG_ARM64_ERRATUM_1463225 is not set ++# CONFIG_ARM64_ERRATUM_1542419 is not set ++# CONFIG_ARM64_ERRATUM_1508412 is not set ++# CONFIG_ARM64_ERRATUM_2051678 is not set ++CONFIG_ARM64_ERRATUM_2077057=y ++# CONFIG_ARM64_ERRATUM_2054223 is not set ++# CONFIG_ARM64_ERRATUM_2067961 is not set ++# CONFIG_CAVIUM_ERRATUM_22375 is not set ++# CONFIG_CAVIUM_ERRATUM_23154 is not set ++# CONFIG_CAVIUM_ERRATUM_27456 is not set ++# CONFIG_CAVIUM_ERRATUM_30115 is not set ++# CONFIG_CAVIUM_TX2_ERRATUM_219 is not set ++# CONFIG_FUJITSU_ERRATUM_010001 is not set ++# CONFIG_HISILICON_ERRATUM_161600802 is not set ++# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set ++# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set ++# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set ++# CONFIG_QCOM_FALKOR_ERRATUM_E1041 is not set ++# CONFIG_NVIDIA_CARMEL_CNP_ERRATUM is not set ++# CONFIG_SOCIONEXT_SYNQUACER_PREITS is not set ++# end of ARM errata workarounds via the alternatives framework ++ ++CONFIG_ARM64_4K_PAGES=y ++# CONFIG_ARM64_16K_PAGES is not set ++# CONFIG_ARM64_64K_PAGES is not set ++# CONFIG_ARM64_VA_BITS_39 is not set ++CONFIG_ARM64_VA_BITS_48=y ++CONFIG_ARM64_VA_BITS=48 ++CONFIG_ARM64_PA_BITS_48=y ++CONFIG_ARM64_PA_BITS=48 ++# CONFIG_CPU_BIG_ENDIAN is not set ++CONFIG_CPU_LITTLE_ENDIAN=y ++CONFIG_SCHED_MC=y ++CONFIG_SCHED_CLUSTER=y ++# CONFIG_SCHED_SMT is not set ++CONFIG_NR_CPUS=8 ++CONFIG_HOTPLUG_CPU=y ++# CONFIG_NUMA is not set ++# CONFIG_HZ_100 is not set ++# CONFIG_HZ_250 is not set ++# CONFIG_HZ_300 is not set ++CONFIG_HZ_1000=y ++CONFIG_HZ=1000 ++CONFIG_SCHED_HRTICK=y ++CONFIG_ARCH_SPARSEMEM_ENABLE=y ++# CONFIG_PARAVIRT is not set ++# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set ++# CONFIG_KEXEC is not set ++# CONFIG_KEXEC_FILE is not set ++# CONFIG_CRASH_DUMP is not set ++# CONFIG_XEN is not set ++CONFIG_FORCE_MAX_ZONEORDER=11 ++# CONFIG_UNMAP_KERNEL_AT_EL0 is not set ++# CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY is not set ++# CONFIG_RODATA_FULL_DEFAULT_ENABLED is not set ++# CONFIG_ARM64_SW_TTBR0_PAN is not set ++CONFIG_ARM64_TAGGED_ADDR_ABI=y ++CONFIG_COMPAT=y ++CONFIG_KUSER_HELPERS=y ++CONFIG_ARMV8_DEPRECATED=y ++CONFIG_SWP_EMULATION=y ++CONFIG_CP15_BARRIER_EMULATION=y ++CONFIG_SETEND_EMULATION=y ++ ++# ++# ARMv8.1 architectural features ++# ++# CONFIG_ARM64_HW_AFDBM is not set ++# CONFIG_ARM64_PAN is not set ++CONFIG_AS_HAS_LDAPR=y ++CONFIG_AS_HAS_LSE_ATOMICS=y ++# end of ARMv8.1 architectural features ++ ++# ++# ARMv8.2 architectural features ++# ++CONFIG_AS_HAS_ARMV8_2=y ++CONFIG_AS_HAS_SHA3=y ++# CONFIG_ARM64_PMEM is not set ++# CONFIG_ARM64_RAS_EXTN is not set ++# CONFIG_ARM64_CNP is not set ++# end of ARMv8.2 architectural features ++ ++# ++# ARMv8.3 architectural features ++# ++# CONFIG_ARM64_PTR_AUTH is not set ++CONFIG_CC_HAS_BRANCH_PROT_PAC_RET=y ++CONFIG_CC_HAS_SIGN_RETURN_ADDRESS=y ++CONFIG_AS_HAS_PAC=y ++CONFIG_AS_HAS_CFI_NEGATE_RA_STATE=y ++# end of ARMv8.3 architectural features ++ ++# ++# ARMv8.4 architectural features ++# ++# CONFIG_ARM64_AMU_EXTN is not set ++CONFIG_AS_HAS_ARMV8_4=y ++CONFIG_ARM64_TLB_RANGE=y ++# end of ARMv8.4 architectural features ++ ++# ++# ARMv8.5 architectural features ++# ++CONFIG_AS_HAS_ARMV8_5=y ++# CONFIG_ARM64_BTI is not set ++CONFIG_CC_HAS_BRANCH_PROT_PAC_RET_BTI=y ++# CONFIG_ARM64_E0PD is not set ++# CONFIG_ARCH_RANDOM is not set ++CONFIG_ARM64_AS_HAS_MTE=y ++# end of ARMv8.5 architectural features ++ ++# ++# ARMv8.7 architectural features ++# ++# end of ARMv8.7 architectural features ++ ++CONFIG_ARM64_SVE=y ++CONFIG_ARM64_MODULE_PLTS=y ++# CONFIG_ARM64_PSEUDO_NMI is not set ++CONFIG_RELOCATABLE=y ++CONFIG_RANDOMIZE_BASE=y ++CONFIG_RANDOMIZE_MODULE_REGION_FULL=y ++CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y ++CONFIG_STACKPROTECTOR_PER_TASK=y ++# end of Kernel Features ++ ++# ++# Boot options ++# ++CONFIG_CMDLINE="console=ttyS2,1500000" ++CONFIG_CMDLINE_FROM_BOOTLOADER=y ++# CONFIG_CMDLINE_FORCE is not set ++# CONFIG_EFI is not set ++# end of Boot options ++ ++CONFIG_SYSVIPC_COMPAT=y ++ ++# ++# Power management options ++# ++CONFIG_SUSPEND=y ++CONFIG_SUSPEND_FREEZER=y ++CONFIG_SUSPEND_SKIP_SYNC=y ++CONFIG_PM_SLEEP=y ++CONFIG_PM_SLEEP_SMP=y ++CONFIG_PM_AUTOSLEEP=y ++# CONFIG_PM_WAKELOCKS is not set ++CONFIG_PM=y ++# CONFIG_PM_DEBUG is not set ++CONFIG_PM_CLK=y ++CONFIG_PM_GENERIC_DOMAINS=y ++CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y ++CONFIG_PM_GENERIC_DOMAINS_SLEEP=y ++CONFIG_PM_GENERIC_DOMAINS_OF=y ++CONFIG_CPU_PM=y ++CONFIG_ENERGY_MODEL=y ++CONFIG_ARCH_HIBERNATION_POSSIBLE=y ++CONFIG_ARCH_SUSPEND_POSSIBLE=y ++# end of Power management options ++ ++# ++# CPU Power Management ++# ++ ++# ++# CPU Idle ++# ++CONFIG_CPU_IDLE=y ++CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y ++CONFIG_CPU_IDLE_GOV_LADDER=y ++CONFIG_CPU_IDLE_GOV_MENU=y ++# CONFIG_CPU_IDLE_GOV_TEO is not set ++CONFIG_DT_IDLE_STATES=y ++CONFIG_DT_IDLE_GENPD=y ++ ++# ++# ARM CPU Idle Drivers ++# ++CONFIG_ARM_CPUIDLE=y ++CONFIG_ARM_PSCI_CPUIDLE=y ++CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y ++# end of ARM CPU Idle Drivers ++# end of CPU Idle ++ ++# ++# CPU Frequency scaling ++# ++CONFIG_CPU_FREQ=y ++CONFIG_CPU_FREQ_GOV_ATTR_SET=y ++CONFIG_CPU_FREQ_GOV_COMMON=y ++CONFIG_CPU_FREQ_STAT=y ++CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y ++# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set ++# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set ++# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set ++# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set ++# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set ++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y ++CONFIG_CPU_FREQ_GOV_POWERSAVE=y ++CONFIG_CPU_FREQ_GOV_USERSPACE=y ++CONFIG_CPU_FREQ_GOV_ONDEMAND=y ++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y ++CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y ++ ++# ++# CPU frequency scaling drivers ++# ++CONFIG_CPUFREQ_DT=y ++CONFIG_CPUFREQ_DT_PLATDEV=y ++# CONFIG_ARM_SCMI_CPUFREQ is not set ++# end of CPU Frequency scaling ++# end of CPU Power Management ++ ++CONFIG_IRQ_BYPASS_MANAGER=y ++CONFIG_HAVE_KVM=y ++CONFIG_HAVE_KVM_IRQCHIP=y ++CONFIG_HAVE_KVM_IRQFD=y ++CONFIG_HAVE_KVM_IRQ_ROUTING=y ++CONFIG_HAVE_KVM_EVENTFD=y ++CONFIG_KVM_MMIO=y ++CONFIG_HAVE_KVM_MSI=y ++CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y ++CONFIG_KVM_VFIO=y ++CONFIG_HAVE_KVM_ARCH_TLB_FLUSH_ALL=y ++CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y ++CONFIG_HAVE_KVM_IRQ_BYPASS=y ++CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE=y ++CONFIG_KVM_XFER_TO_GUEST_WORK=y ++CONFIG_VIRTUALIZATION=y ++CONFIG_KVM=y ++# CONFIG_NVHE_EL2_DEBUG is not set ++CONFIG_ARM64_CRYPTO=y ++CONFIG_CRYPTO_SHA256_ARM64=y ++# CONFIG_CRYPTO_SHA512_ARM64 is not set ++CONFIG_CRYPTO_SHA1_ARM64_CE=y ++CONFIG_CRYPTO_SHA2_ARM64_CE=y ++# CONFIG_CRYPTO_SHA512_ARM64_CE is not set ++# CONFIG_CRYPTO_SHA3_ARM64 is not set ++# CONFIG_CRYPTO_SM3_ARM64_CE is not set ++# CONFIG_CRYPTO_SM4_ARM64_CE is not set ++CONFIG_CRYPTO_GHASH_ARM64_CE=y ++# CONFIG_CRYPTO_CRCT10DIF_ARM64_CE is not set ++# CONFIG_CRYPTO_AES_ARM64 is not set ++CONFIG_CRYPTO_AES_ARM64_CE=y ++CONFIG_CRYPTO_AES_ARM64_CE_CCM=y ++CONFIG_CRYPTO_AES_ARM64_CE_BLK=y ++# CONFIG_CRYPTO_AES_ARM64_NEON_BLK is not set ++# CONFIG_CRYPTO_CHACHA20_NEON is not set ++# CONFIG_CRYPTO_POLY1305_NEON is not set ++# CONFIG_CRYPTO_NHPOLY1305_NEON is not set ++# CONFIG_CRYPTO_AES_ARM64_BS is not set ++ ++# ++# General architecture-dependent options ++# ++# CONFIG_KPROBES is not set ++# CONFIG_JUMP_LABEL is not set ++CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y ++CONFIG_HAVE_KPROBES=y ++CONFIG_HAVE_KRETPROBES=y ++CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y ++CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y ++CONFIG_HAVE_NMI=y ++CONFIG_TRACE_IRQFLAGS_SUPPORT=y ++CONFIG_HAVE_ARCH_TRACEHOOK=y ++CONFIG_HAVE_DMA_CONTIGUOUS=y ++CONFIG_GENERIC_SMP_IDLE_THREAD=y ++CONFIG_GENERIC_IDLE_POLL_SETUP=y ++CONFIG_ARCH_HAS_FORTIFY_SOURCE=y ++CONFIG_ARCH_HAS_KEEPINITRD=y ++CONFIG_ARCH_HAS_SET_MEMORY=y ++CONFIG_ARCH_HAS_SET_DIRECT_MAP=y ++CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y ++CONFIG_ARCH_WANTS_NO_INSTR=y ++CONFIG_HAVE_ASM_MODVERSIONS=y ++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y ++CONFIG_HAVE_RSEQ=y ++CONFIG_HAVE_FUNCTION_ARG_ACCESS_API=y ++CONFIG_HAVE_PERF_REGS=y ++CONFIG_HAVE_PERF_USER_STACK_DUMP=y ++CONFIG_HAVE_ARCH_JUMP_LABEL=y ++CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE=y ++CONFIG_MMU_GATHER_TABLE_FREE=y ++CONFIG_MMU_GATHER_RCU_TABLE_FREE=y ++CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y ++CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y ++CONFIG_HAVE_CMPXCHG_LOCAL=y ++CONFIG_HAVE_CMPXCHG_DOUBLE=y ++CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y ++CONFIG_HAVE_ARCH_SECCOMP=y ++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y ++# CONFIG_SECCOMP is not set ++CONFIG_HAVE_ARCH_STACKLEAK=y ++CONFIG_HAVE_STACKPROTECTOR=y ++CONFIG_STACKPROTECTOR=y ++# CONFIG_STACKPROTECTOR_STRONG is not set ++CONFIG_ARCH_SUPPORTS_LTO_CLANG=y ++CONFIG_ARCH_SUPPORTS_LTO_CLANG_THIN=y ++CONFIG_LTO_NONE=y ++CONFIG_ARCH_SUPPORTS_CFI_CLANG=y ++CONFIG_HAVE_CONTEXT_TRACKING=y ++CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y ++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y ++CONFIG_HAVE_MOVE_PUD=y ++CONFIG_HAVE_MOVE_PMD=y ++CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y ++CONFIG_HAVE_ARCH_HUGE_VMAP=y ++CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y ++CONFIG_HAVE_MOD_ARCH_SPECIFIC=y ++CONFIG_MODULES_USE_ELF_RELA=y ++CONFIG_ARCH_HAS_ELF_RANDOMIZE=y ++CONFIG_HAVE_ARCH_MMAP_RND_BITS=y ++CONFIG_ARCH_MMAP_RND_BITS=18 ++CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS=y ++CONFIG_ARCH_MMAP_RND_COMPAT_BITS=11 ++CONFIG_PAGE_SIZE_LESS_THAN_64KB=y ++CONFIG_PAGE_SIZE_LESS_THAN_256KB=y ++CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y ++CONFIG_CLONE_BACKWARDS=y ++CONFIG_OLD_SIGSUSPEND3=y ++CONFIG_COMPAT_OLD_SIGACTION=y ++CONFIG_COMPAT_32BIT_TIME=y ++CONFIG_HAVE_ARCH_VMAP_STACK=y ++CONFIG_VMAP_STACK=y ++CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET=y ++CONFIG_RANDOMIZE_KSTACK_OFFSET=y ++# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set ++CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y ++CONFIG_STRICT_KERNEL_RWX=y ++CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y ++CONFIG_STRICT_MODULE_RWX=y ++CONFIG_HAVE_ARCH_COMPILER_H=y ++CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y ++# CONFIG_LOCK_EVENT_COUNTS is not set ++CONFIG_ARCH_HAS_RELR=y ++CONFIG_HAVE_PREEMPT_DYNAMIC=y ++CONFIG_HAVE_PREEMPT_DYNAMIC_KEY=y ++CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y ++CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y ++ ++# ++# GCOV-based kernel profiling ++# ++# CONFIG_GCOV_KERNEL is not set ++CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y ++# end of GCOV-based kernel profiling ++ ++CONFIG_HAVE_GCC_PLUGINS=y ++CONFIG_GCC_PLUGINS=y ++# CONFIG_GCC_PLUGIN_LATENT_ENTROPY is not set ++# CONFIG_GCC_PLUGIN_RANDSTRUCT is not set ++# end of General architecture-dependent options ++ ++CONFIG_RT_MUTEXES=y ++CONFIG_BASE_SMALL=0 ++CONFIG_MODULES=y ++CONFIG_MODULE_FORCE_LOAD=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODULE_FORCE_UNLOAD=y ++# CONFIG_MODVERSIONS is not set ++# CONFIG_MODULE_SRCVERSION_ALL is not set ++# CONFIG_MODULE_SIG is not set ++CONFIG_MODULE_COMPRESS_NONE=y ++# CONFIG_MODULE_COMPRESS_GZIP is not set ++# CONFIG_MODULE_COMPRESS_XZ is not set ++# CONFIG_MODULE_COMPRESS_ZSTD is not set ++# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set ++CONFIG_MODPROBE_PATH="/sbin/modprobe" ++# CONFIG_TRIM_UNUSED_KSYMS is not set ++CONFIG_BLOCK=y ++CONFIG_BLOCK_LEGACY_AUTOLOAD=y ++CONFIG_BLK_DEV_BSG_COMMON=y ++CONFIG_BLK_DEV_BSGLIB=y ++# CONFIG_BLK_DEV_INTEGRITY is not set ++# CONFIG_BLK_DEV_ZONED is not set ++# CONFIG_BLK_DEV_THROTTLING is not set ++# CONFIG_BLK_WBT is not set ++# CONFIG_BLK_CGROUP_IOLATENCY is not set ++# CONFIG_BLK_CGROUP_IOCOST is not set ++# CONFIG_BLK_CGROUP_IOPRIO is not set ++# CONFIG_BLK_DEBUG_FS is not set ++# CONFIG_BLK_SED_OPAL is not set ++# CONFIG_BLK_INLINE_ENCRYPTION is not set ++ ++# ++# Partition Types ++# ++CONFIG_PARTITION_ADVANCED=y ++# CONFIG_ACORN_PARTITION is not set ++# CONFIG_AIX_PARTITION is not set ++# CONFIG_OSF_PARTITION is not set ++# CONFIG_AMIGA_PARTITION is not set ++# CONFIG_ATARI_PARTITION is not set ++CONFIG_MAC_PARTITION=y ++CONFIG_MSDOS_PARTITION=y ++# CONFIG_BSD_DISKLABEL is not set ++# CONFIG_MINIX_SUBPARTITION is not set ++# CONFIG_SOLARIS_X86_PARTITION is not set ++# CONFIG_UNIXWARE_DISKLABEL is not set ++# CONFIG_LDM_PARTITION is not set ++# CONFIG_SGI_PARTITION is not set ++# CONFIG_ULTRIX_PARTITION is not set ++# CONFIG_SUN_PARTITION is not set ++# CONFIG_KARMA_PARTITION is not set ++CONFIG_EFI_PARTITION=y ++# CONFIG_SYSV68_PARTITION is not set ++# CONFIG_CMDLINE_PARTITION is not set ++# end of Partition Types ++ ++CONFIG_BLOCK_COMPAT=y ++CONFIG_BLK_MQ_PCI=y ++CONFIG_BLK_PM=y ++CONFIG_BLOCK_HOLDER_DEPRECATED=y ++CONFIG_BLK_MQ_STACKING=y ++ ++# ++# IO Schedulers ++# ++CONFIG_MQ_IOSCHED_DEADLINE=y ++# CONFIG_MQ_IOSCHED_KYBER is not set ++# CONFIG_IOSCHED_BFQ is not set ++# end of IO Schedulers ++ ++CONFIG_PREEMPT_NOTIFIERS=y ++CONFIG_ASN1=y ++CONFIG_UNINLINE_SPIN_UNLOCK=y ++CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y ++CONFIG_MUTEX_SPIN_ON_OWNER=y ++CONFIG_RWSEM_SPIN_ON_OWNER=y ++CONFIG_LOCK_SPIN_ON_OWNER=y ++CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y ++CONFIG_QUEUED_SPINLOCKS=y ++CONFIG_ARCH_USE_QUEUED_RWLOCKS=y ++CONFIG_QUEUED_RWLOCKS=y ++CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y ++CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y ++CONFIG_FREEZER=y ++ ++# ++# Executable file formats ++# ++CONFIG_BINFMT_ELF=y ++CONFIG_COMPAT_BINFMT_ELF=y ++CONFIG_ARCH_BINFMT_ELF_STATE=y ++CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y ++CONFIG_ARCH_HAVE_ELF_PROT=y ++CONFIG_ARCH_USE_GNU_PROPERTY=y ++CONFIG_ELFCORE=y ++CONFIG_BINFMT_SCRIPT=y ++CONFIG_BINFMT_MISC=y ++# CONFIG_COREDUMP is not set ++# end of Executable file formats ++ ++# ++# Memory Management options ++# ++CONFIG_SPARSEMEM=y ++CONFIG_SPARSEMEM_EXTREME=y ++CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y ++CONFIG_SPARSEMEM_VMEMMAP=y ++CONFIG_HAVE_FAST_GUP=y ++CONFIG_ARCH_KEEP_MEMBLOCK=y ++CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y ++# CONFIG_MEMORY_HOTPLUG is not set ++CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y ++CONFIG_SPLIT_PTLOCK_CPUS=4 ++CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y ++# CONFIG_COMPACTION is not set ++# CONFIG_PAGE_REPORTING is not set ++CONFIG_MIGRATION=y ++CONFIG_PHYS_ADDR_T_64BIT=y ++CONFIG_MMU_NOTIFIER=y ++# CONFIG_KSM is not set ++CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 ++CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y ++# CONFIG_MEMORY_FAILURE is not set ++# CONFIG_TRANSPARENT_HUGEPAGE is not set ++# CONFIG_CMA is not set ++CONFIG_ZPOOL=y ++CONFIG_ZBUD=y ++# CONFIG_Z3FOLD is not set ++CONFIG_ZSMALLOC=y ++# CONFIG_ZSMALLOC_STAT is not set ++CONFIG_GENERIC_EARLY_IOREMAP=y ++# CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set ++# CONFIG_IDLE_PAGE_TRACKING is not set ++CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y ++CONFIG_ARCH_HAS_CURRENT_STACK_POINTER=y ++CONFIG_ARCH_HAS_PTE_DEVMAP=y ++CONFIG_ARCH_HAS_ZONE_DMA_SET=y ++CONFIG_ZONE_DMA=y ++CONFIG_ZONE_DMA32=y ++# CONFIG_PERCPU_STATS is not set ++# CONFIG_GUP_TEST is not set ++CONFIG_ARCH_HAS_PTE_SPECIAL=y ++# CONFIG_ANON_VMA_NAME is not set ++ ++# ++# Data Access Monitoring ++# ++# CONFIG_DAMON is not set ++# end of Data Access Monitoring ++# end of Memory Management options ++ ++CONFIG_NET=y ++CONFIG_COMPAT_NETLINK_MESSAGES=y ++CONFIG_NET_INGRESS=y ++CONFIG_NET_EGRESS=y ++CONFIG_SKB_EXTENSIONS=y ++ ++# ++# Networking options ++# ++CONFIG_PACKET=y ++# CONFIG_PACKET_DIAG is not set ++CONFIG_UNIX=y ++CONFIG_UNIX_SCM=y ++CONFIG_AF_UNIX_OOB=y ++CONFIG_UNIX_DIAG=m ++# CONFIG_TLS is not set ++CONFIG_XFRM=y ++CONFIG_XFRM_ALGO=y ++CONFIG_XFRM_USER=y ++# CONFIG_XFRM_SUB_POLICY is not set ++# CONFIG_XFRM_MIGRATE is not set ++# CONFIG_XFRM_STATISTICS is not set ++CONFIG_XFRM_AH=y ++CONFIG_XFRM_ESP=y ++CONFIG_XFRM_IPCOMP=y ++CONFIG_NET_KEY=y ++# CONFIG_NET_KEY_MIGRATE is not set ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++# CONFIG_IP_FIB_TRIE_STATS is not set ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_ROUTE_MULTIPATH=y ++CONFIG_IP_ROUTE_VERBOSE=y ++CONFIG_IP_ROUTE_CLASSID=y ++# CONFIG_IP_PNP is not set ++CONFIG_NET_IPIP=m ++CONFIG_NET_IPGRE_DEMUX=m ++CONFIG_NET_IP_TUNNEL=m ++CONFIG_NET_IPGRE=m ++# CONFIG_NET_IPGRE_BROADCAST is not set ++CONFIG_IP_MROUTE_COMMON=y ++CONFIG_IP_MROUTE=y ++CONFIG_IP_MROUTE_MULTIPLE_TABLES=y ++CONFIG_IP_PIMSM_V1=y ++CONFIG_IP_PIMSM_V2=y ++CONFIG_SYN_COOKIES=y ++# CONFIG_NET_IPVTI is not set ++CONFIG_NET_UDP_TUNNEL=m ++# CONFIG_NET_FOU is not set ++# CONFIG_NET_FOU_IP_TUNNELS is not set ++CONFIG_INET_AH=y ++CONFIG_INET_ESP=y ++# CONFIG_INET_ESP_OFFLOAD is not set ++# CONFIG_INET_ESPINTCP is not set ++CONFIG_INET_IPCOMP=y ++CONFIG_INET_XFRM_TUNNEL=y ++CONFIG_INET_TUNNEL=y ++# CONFIG_INET_DIAG is not set ++CONFIG_TCP_CONG_ADVANCED=y ++CONFIG_TCP_CONG_BIC=m ++CONFIG_TCP_CONG_CUBIC=m ++CONFIG_TCP_CONG_WESTWOOD=m ++CONFIG_TCP_CONG_HTCP=m ++CONFIG_TCP_CONG_HSTCP=m ++CONFIG_TCP_CONG_HYBLA=m ++CONFIG_TCP_CONG_VEGAS=m ++# CONFIG_TCP_CONG_NV is not set ++CONFIG_TCP_CONG_SCALABLE=m ++CONFIG_TCP_CONG_LP=m ++CONFIG_TCP_CONG_VENO=m ++CONFIG_TCP_CONG_YEAH=m ++CONFIG_TCP_CONG_ILLINOIS=m ++CONFIG_TCP_CONG_DCTCP=m ++CONFIG_TCP_CONG_CDG=m ++# CONFIG_TCP_CONG_BBR is not set ++CONFIG_DEFAULT_RENO=y ++CONFIG_DEFAULT_TCP_CONG="reno" ++CONFIG_TCP_MD5SIG=y ++# CONFIG_IPV6 is not set ++# CONFIG_MPTCP is not set ++# CONFIG_NETWORK_SECMARK is not set ++CONFIG_NET_PTP_CLASSIFY=y ++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set ++CONFIG_NETFILTER=y ++CONFIG_NETFILTER_ADVANCED=y ++CONFIG_BRIDGE_NETFILTER=y ++ ++# ++# Core Netfilter Configuration ++# ++CONFIG_NETFILTER_INGRESS=y ++CONFIG_NETFILTER_EGRESS=y ++CONFIG_NETFILTER_NETLINK=y ++CONFIG_NETFILTER_FAMILY_BRIDGE=y ++CONFIG_NETFILTER_FAMILY_ARP=y ++# CONFIG_NETFILTER_NETLINK_HOOK is not set ++CONFIG_NETFILTER_NETLINK_ACCT=m ++CONFIG_NETFILTER_NETLINK_QUEUE=y ++CONFIG_NETFILTER_NETLINK_LOG=y ++CONFIG_NETFILTER_NETLINK_OSF=m ++CONFIG_NF_CONNTRACK=m ++CONFIG_NF_LOG_SYSLOG=m ++CONFIG_NETFILTER_CONNCOUNT=m ++CONFIG_NF_CONNTRACK_MARK=y ++# CONFIG_NF_CONNTRACK_ZONES is not set ++CONFIG_NF_CONNTRACK_PROCFS=y ++CONFIG_NF_CONNTRACK_EVENTS=y ++CONFIG_NF_CONNTRACK_TIMEOUT=y ++CONFIG_NF_CONNTRACK_TIMESTAMP=y ++CONFIG_NF_CONNTRACK_LABELS=y ++CONFIG_NF_CT_PROTO_DCCP=y ++CONFIG_NF_CT_PROTO_GRE=y ++CONFIG_NF_CT_PROTO_SCTP=y ++CONFIG_NF_CT_PROTO_UDPLITE=y ++CONFIG_NF_CONNTRACK_AMANDA=m ++CONFIG_NF_CONNTRACK_FTP=m ++CONFIG_NF_CONNTRACK_H323=m ++CONFIG_NF_CONNTRACK_IRC=m ++CONFIG_NF_CONNTRACK_BROADCAST=m ++CONFIG_NF_CONNTRACK_NETBIOS_NS=m ++CONFIG_NF_CONNTRACK_SNMP=m ++CONFIG_NF_CONNTRACK_PPTP=m ++CONFIG_NF_CONNTRACK_SANE=m ++CONFIG_NF_CONNTRACK_SIP=m ++CONFIG_NF_CONNTRACK_TFTP=m ++CONFIG_NF_CT_NETLINK=m ++CONFIG_NF_CT_NETLINK_TIMEOUT=m ++# CONFIG_NETFILTER_NETLINK_GLUE_CT is not set ++CONFIG_NF_NAT=m ++CONFIG_NF_NAT_AMANDA=m ++CONFIG_NF_NAT_FTP=m ++CONFIG_NF_NAT_IRC=m ++CONFIG_NF_NAT_SIP=m ++CONFIG_NF_NAT_TFTP=m ++CONFIG_NF_NAT_REDIRECT=y ++CONFIG_NF_NAT_MASQUERADE=y ++CONFIG_NETFILTER_SYNPROXY=m ++CONFIG_NF_TABLES=m ++# CONFIG_NF_TABLES_NETDEV is not set ++# CONFIG_NFT_NUMGEN is not set ++CONFIG_NFT_CT=m ++# CONFIG_NFT_CONNLIMIT is not set ++CONFIG_NFT_LOG=m ++CONFIG_NFT_LIMIT=m ++CONFIG_NFT_MASQ=m ++CONFIG_NFT_REDIR=m ++# CONFIG_NFT_TUNNEL is not set ++# CONFIG_NFT_OBJREF is not set ++CONFIG_NFT_QUEUE=m ++# CONFIG_NFT_QUOTA is not set ++CONFIG_NFT_REJECT=m ++CONFIG_NFT_COMPAT=m ++CONFIG_NFT_HASH=m ++# CONFIG_NFT_XFRM is not set ++# CONFIG_NFT_SOCKET is not set ++# CONFIG_NFT_OSF is not set ++# CONFIG_NFT_TPROXY is not set ++# CONFIG_NFT_SYNPROXY is not set ++# CONFIG_NF_FLOW_TABLE is not set ++CONFIG_NETFILTER_XTABLES=y ++CONFIG_NETFILTER_XTABLES_COMPAT=y ++ ++# ++# Xtables combined modules ++# ++CONFIG_NETFILTER_XT_MARK=m ++CONFIG_NETFILTER_XT_CONNMARK=m ++CONFIG_NETFILTER_XT_SET=m ++ ++# ++# Xtables targets ++# ++CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m ++CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m ++CONFIG_NETFILTER_XT_TARGET_CONNMARK=m ++CONFIG_NETFILTER_XT_TARGET_CT=m ++CONFIG_NETFILTER_XT_TARGET_DSCP=m ++CONFIG_NETFILTER_XT_TARGET_HL=m ++CONFIG_NETFILTER_XT_TARGET_HMARK=m ++CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m ++CONFIG_NETFILTER_XT_TARGET_LED=m ++CONFIG_NETFILTER_XT_TARGET_LOG=m ++CONFIG_NETFILTER_XT_TARGET_MARK=m ++CONFIG_NETFILTER_XT_NAT=m ++CONFIG_NETFILTER_XT_TARGET_NETMAP=m ++CONFIG_NETFILTER_XT_TARGET_NFLOG=m ++CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m ++CONFIG_NETFILTER_XT_TARGET_NOTRACK=m ++CONFIG_NETFILTER_XT_TARGET_RATEEST=m ++CONFIG_NETFILTER_XT_TARGET_REDIRECT=m ++CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m ++CONFIG_NETFILTER_XT_TARGET_TEE=m ++CONFIG_NETFILTER_XT_TARGET_TPROXY=m ++CONFIG_NETFILTER_XT_TARGET_TRACE=m ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=m ++CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m ++ ++# ++# Xtables matches ++# ++CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m ++CONFIG_NETFILTER_XT_MATCH_BPF=m ++CONFIG_NETFILTER_XT_MATCH_CGROUP=m ++CONFIG_NETFILTER_XT_MATCH_CLUSTER=m ++CONFIG_NETFILTER_XT_MATCH_COMMENT=m ++CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m ++CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m ++CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=m ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m ++CONFIG_NETFILTER_XT_MATCH_CPU=m ++CONFIG_NETFILTER_XT_MATCH_DCCP=m ++CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m ++CONFIG_NETFILTER_XT_MATCH_DSCP=m ++CONFIG_NETFILTER_XT_MATCH_ECN=m ++CONFIG_NETFILTER_XT_MATCH_ESP=m ++CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m ++CONFIG_NETFILTER_XT_MATCH_HELPER=m ++CONFIG_NETFILTER_XT_MATCH_HL=m ++CONFIG_NETFILTER_XT_MATCH_IPCOMP=m ++CONFIG_NETFILTER_XT_MATCH_IPRANGE=m ++CONFIG_NETFILTER_XT_MATCH_IPVS=m ++CONFIG_NETFILTER_XT_MATCH_L2TP=m ++CONFIG_NETFILTER_XT_MATCH_LENGTH=m ++CONFIG_NETFILTER_XT_MATCH_LIMIT=m ++CONFIG_NETFILTER_XT_MATCH_MAC=m ++CONFIG_NETFILTER_XT_MATCH_MARK=m ++CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m ++CONFIG_NETFILTER_XT_MATCH_NFACCT=m ++CONFIG_NETFILTER_XT_MATCH_OSF=m ++CONFIG_NETFILTER_XT_MATCH_OWNER=m ++CONFIG_NETFILTER_XT_MATCH_POLICY=m ++CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m ++CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m ++CONFIG_NETFILTER_XT_MATCH_QUOTA=m ++CONFIG_NETFILTER_XT_MATCH_RATEEST=m ++CONFIG_NETFILTER_XT_MATCH_REALM=m ++CONFIG_NETFILTER_XT_MATCH_RECENT=m ++CONFIG_NETFILTER_XT_MATCH_SCTP=m ++CONFIG_NETFILTER_XT_MATCH_SOCKET=m ++CONFIG_NETFILTER_XT_MATCH_STATE=m ++CONFIG_NETFILTER_XT_MATCH_STATISTIC=m ++CONFIG_NETFILTER_XT_MATCH_STRING=m ++CONFIG_NETFILTER_XT_MATCH_TCPMSS=m ++CONFIG_NETFILTER_XT_MATCH_TIME=m ++CONFIG_NETFILTER_XT_MATCH_U32=m ++# end of Core Netfilter Configuration ++ ++CONFIG_IP_SET=y ++CONFIG_IP_SET_MAX=256 ++CONFIG_IP_SET_BITMAP_IP=m ++CONFIG_IP_SET_BITMAP_IPMAC=m ++CONFIG_IP_SET_BITMAP_PORT=m ++CONFIG_IP_SET_HASH_IP=m ++CONFIG_IP_SET_HASH_IPMARK=m ++CONFIG_IP_SET_HASH_IPPORT=m ++CONFIG_IP_SET_HASH_IPPORTIP=m ++CONFIG_IP_SET_HASH_IPPORTNET=m ++# CONFIG_IP_SET_HASH_IPMAC is not set ++CONFIG_IP_SET_HASH_MAC=m ++CONFIG_IP_SET_HASH_NETPORTNET=m ++CONFIG_IP_SET_HASH_NET=m ++CONFIG_IP_SET_HASH_NETNET=m ++CONFIG_IP_SET_HASH_NETPORT=m ++CONFIG_IP_SET_HASH_NETIFACE=m ++CONFIG_IP_SET_LIST_SET=m ++CONFIG_IP_VS=m ++# CONFIG_IP_VS_DEBUG is not set ++CONFIG_IP_VS_TAB_BITS=12 ++ ++# ++# IPVS transport protocol load balancing support ++# ++CONFIG_IP_VS_PROTO_TCP=y ++CONFIG_IP_VS_PROTO_UDP=y ++CONFIG_IP_VS_PROTO_AH_ESP=y ++CONFIG_IP_VS_PROTO_ESP=y ++CONFIG_IP_VS_PROTO_AH=y ++CONFIG_IP_VS_PROTO_SCTP=y ++ ++# ++# IPVS scheduler ++# ++CONFIG_IP_VS_RR=m ++CONFIG_IP_VS_WRR=m ++CONFIG_IP_VS_LC=m ++CONFIG_IP_VS_WLC=m ++CONFIG_IP_VS_FO=m ++CONFIG_IP_VS_OVF=m ++CONFIG_IP_VS_LBLC=m ++CONFIG_IP_VS_LBLCR=m ++CONFIG_IP_VS_DH=m ++CONFIG_IP_VS_SH=m ++# CONFIG_IP_VS_MH is not set ++CONFIG_IP_VS_SED=m ++CONFIG_IP_VS_NQ=m ++# CONFIG_IP_VS_TWOS is not set ++ ++# ++# IPVS SH scheduler ++# ++CONFIG_IP_VS_SH_TAB_BITS=8 ++ ++# ++# IPVS MH scheduler ++# ++CONFIG_IP_VS_MH_TAB_INDEX=12 ++ ++# ++# IPVS application helper ++# ++# CONFIG_IP_VS_FTP is not set ++CONFIG_IP_VS_NFCT=y ++# CONFIG_IP_VS_PE_SIP is not set ++ ++# ++# IP: Netfilter Configuration ++# ++CONFIG_NF_DEFRAG_IPV4=m ++CONFIG_NF_SOCKET_IPV4=m ++CONFIG_NF_TPROXY_IPV4=m ++# CONFIG_NF_TABLES_IPV4 is not set ++# CONFIG_NF_TABLES_ARP is not set ++CONFIG_NF_DUP_IPV4=m ++CONFIG_NF_LOG_ARP=m ++CONFIG_NF_LOG_IPV4=m ++CONFIG_NF_REJECT_IPV4=m ++CONFIG_NF_NAT_SNMP_BASIC=m ++CONFIG_NF_NAT_PPTP=m ++CONFIG_NF_NAT_H323=m ++CONFIG_IP_NF_IPTABLES=y ++CONFIG_IP_NF_MATCH_AH=m ++CONFIG_IP_NF_MATCH_ECN=m ++CONFIG_IP_NF_MATCH_RPFILTER=m ++CONFIG_IP_NF_MATCH_TTL=m ++CONFIG_IP_NF_FILTER=y ++CONFIG_IP_NF_TARGET_REJECT=m ++CONFIG_IP_NF_TARGET_SYNPROXY=m ++CONFIG_IP_NF_NAT=m ++CONFIG_IP_NF_TARGET_MASQUERADE=m ++CONFIG_IP_NF_TARGET_NETMAP=m ++CONFIG_IP_NF_TARGET_REDIRECT=m ++CONFIG_IP_NF_MANGLE=m ++CONFIG_IP_NF_TARGET_CLUSTERIP=m ++CONFIG_IP_NF_TARGET_ECN=m ++CONFIG_IP_NF_TARGET_TTL=m ++CONFIG_IP_NF_RAW=m ++CONFIG_IP_NF_ARPTABLES=m ++CONFIG_IP_NF_ARPFILTER=m ++CONFIG_IP_NF_ARP_MANGLE=m ++# end of IP: Netfilter Configuration ++ ++CONFIG_NF_TABLES_BRIDGE=m ++CONFIG_NFT_BRIDGE_META=m ++# CONFIG_NF_CONNTRACK_BRIDGE is not set ++CONFIG_BRIDGE_NF_EBTABLES=m ++CONFIG_BRIDGE_EBT_BROUTE=m ++CONFIG_BRIDGE_EBT_T_FILTER=m ++CONFIG_BRIDGE_EBT_T_NAT=m ++CONFIG_BRIDGE_EBT_802_3=m ++CONFIG_BRIDGE_EBT_AMONG=m ++CONFIG_BRIDGE_EBT_ARP=m ++CONFIG_BRIDGE_EBT_IP=m ++CONFIG_BRIDGE_EBT_LIMIT=m ++CONFIG_BRIDGE_EBT_MARK=m ++CONFIG_BRIDGE_EBT_PKTTYPE=m ++CONFIG_BRIDGE_EBT_STP=m ++CONFIG_BRIDGE_EBT_VLAN=m ++CONFIG_BRIDGE_EBT_ARPREPLY=m ++CONFIG_BRIDGE_EBT_DNAT=m ++CONFIG_BRIDGE_EBT_MARK_T=m ++CONFIG_BRIDGE_EBT_REDIRECT=m ++CONFIG_BRIDGE_EBT_SNAT=m ++CONFIG_BRIDGE_EBT_LOG=m ++CONFIG_BRIDGE_EBT_NFLOG=m ++# CONFIG_BPFILTER is not set ++# CONFIG_IP_DCCP is not set ++# CONFIG_IP_SCTP is not set ++# CONFIG_RDS is not set ++# CONFIG_TIPC is not set ++# CONFIG_ATM is not set ++# CONFIG_L2TP is not set ++CONFIG_STP=y ++CONFIG_BRIDGE=y ++CONFIG_BRIDGE_IGMP_SNOOPING=y ++# CONFIG_BRIDGE_VLAN_FILTERING is not set ++# CONFIG_BRIDGE_MRP is not set ++# CONFIG_BRIDGE_CFM is not set ++# CONFIG_NET_DSA is not set ++CONFIG_VLAN_8021Q=y ++# CONFIG_VLAN_8021Q_GVRP is not set ++# CONFIG_VLAN_8021Q_MVRP is not set ++# CONFIG_DECNET is not set ++CONFIG_LLC=y ++# CONFIG_LLC2 is not set ++# CONFIG_ATALK is not set ++# CONFIG_X25 is not set ++# CONFIG_LAPB is not set ++# CONFIG_PHONET is not set ++# CONFIG_IEEE802154 is not set ++CONFIG_NET_SCHED=y ++ ++# ++# Queueing/Scheduling ++# ++# CONFIG_NET_SCH_CBQ is not set ++CONFIG_NET_SCH_HTB=y ++# CONFIG_NET_SCH_HFSC is not set ++# CONFIG_NET_SCH_PRIO is not set ++# CONFIG_NET_SCH_MULTIQ is not set ++# CONFIG_NET_SCH_RED is not set ++# CONFIG_NET_SCH_SFB is not set ++# CONFIG_NET_SCH_SFQ is not set ++# CONFIG_NET_SCH_TEQL is not set ++# CONFIG_NET_SCH_TBF is not set ++# CONFIG_NET_SCH_CBS is not set ++# CONFIG_NET_SCH_ETF is not set ++# CONFIG_NET_SCH_TAPRIO is not set ++# CONFIG_NET_SCH_GRED is not set ++# CONFIG_NET_SCH_DSMARK is not set ++# CONFIG_NET_SCH_NETEM is not set ++# CONFIG_NET_SCH_DRR is not set ++# CONFIG_NET_SCH_MQPRIO is not set ++# CONFIG_NET_SCH_SKBPRIO is not set ++# CONFIG_NET_SCH_CHOKE is not set ++# CONFIG_NET_SCH_QFQ is not set ++CONFIG_NET_SCH_CODEL=y ++CONFIG_NET_SCH_FQ_CODEL=y ++# CONFIG_NET_SCH_CAKE is not set ++# CONFIG_NET_SCH_FQ is not set ++# CONFIG_NET_SCH_HHF is not set ++# CONFIG_NET_SCH_PIE is not set ++# CONFIG_NET_SCH_PLUG is not set ++# CONFIG_NET_SCH_ETS is not set ++# CONFIG_NET_SCH_DEFAULT is not set ++ ++# ++# Classification ++# ++CONFIG_NET_CLS=y ++# CONFIG_NET_CLS_BASIC is not set ++# CONFIG_NET_CLS_TCINDEX is not set ++# CONFIG_NET_CLS_ROUTE4 is not set ++# CONFIG_NET_CLS_FW is not set ++CONFIG_NET_CLS_U32=y ++# CONFIG_CLS_U32_PERF is not set ++CONFIG_CLS_U32_MARK=y ++# CONFIG_NET_CLS_RSVP is not set ++# CONFIG_NET_CLS_RSVP6 is not set ++# CONFIG_NET_CLS_FLOW is not set ++CONFIG_NET_CLS_CGROUP=y ++# CONFIG_NET_CLS_BPF is not set ++# CONFIG_NET_CLS_FLOWER is not set ++# CONFIG_NET_CLS_MATCHALL is not set ++# CONFIG_NET_EMATCH is not set ++# CONFIG_NET_CLS_ACT is not set ++CONFIG_NET_SCH_FIFO=y ++# CONFIG_DCB is not set ++CONFIG_DNS_RESOLVER=y ++# CONFIG_BATMAN_ADV is not set ++CONFIG_OPENVSWITCH=m ++CONFIG_OPENVSWITCH_GRE=m ++CONFIG_OPENVSWITCH_VXLAN=m ++# CONFIG_VSOCKETS is not set ++# CONFIG_NETLINK_DIAG is not set ++CONFIG_MPLS=y ++CONFIG_NET_MPLS_GSO=m ++# CONFIG_MPLS_ROUTING is not set ++CONFIG_NET_NSH=m ++# CONFIG_HSR is not set ++# CONFIG_NET_SWITCHDEV is not set ++CONFIG_NET_L3_MASTER_DEV=y ++# CONFIG_QRTR is not set ++# CONFIG_NET_NCSI is not set ++CONFIG_PCPU_DEV_REFCNT=y ++CONFIG_RPS=y ++CONFIG_RFS_ACCEL=y ++CONFIG_SOCK_RX_QUEUE_MAPPING=y ++CONFIG_XPS=y ++CONFIG_CGROUP_NET_PRIO=y ++CONFIG_CGROUP_NET_CLASSID=y ++CONFIG_NET_RX_BUSY_POLL=y ++CONFIG_BQL=y ++CONFIG_NET_FLOW_LIMIT=y ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++# end of Network testing ++# end of Networking options ++ ++# CONFIG_HAMRADIO is not set ++CONFIG_CAN=y ++CONFIG_CAN_RAW=y ++CONFIG_CAN_BCM=y ++CONFIG_CAN_GW=y ++# CONFIG_CAN_J1939 is not set ++# CONFIG_CAN_ISOTP is not set ++ ++# ++# CAN Device Drivers ++# ++# CONFIG_CAN_VCAN is not set ++# CONFIG_CAN_VXCAN is not set ++# CONFIG_CAN_SLCAN is not set ++CONFIG_CAN_DEV=y ++CONFIG_CAN_CALC_BITTIMING=y ++# CONFIG_CAN_FLEXCAN is not set ++# CONFIG_CAN_GRCAN is not set ++# CONFIG_CAN_KVASER_PCIEFD is not set ++# CONFIG_CAN_XILINXCAN is not set ++# CONFIG_CAN_C_CAN is not set ++# CONFIG_CAN_CC770 is not set ++# CONFIG_CAN_IFI_CANFD is not set ++# CONFIG_CAN_M_CAN is not set ++# CONFIG_CAN_PEAK_PCIEFD is not set ++CONFIG_CAN_SJA1000=y ++# CONFIG_CAN_EMS_PCI is not set ++# CONFIG_CAN_EMS_PCMCIA is not set ++# CONFIG_CAN_F81601 is not set ++# CONFIG_CAN_KVASER_PCI is not set ++# CONFIG_CAN_PEAK_PCI is not set ++# CONFIG_CAN_PEAK_PCMCIA is not set ++CONFIG_CAN_PLX_PCI=y ++# CONFIG_CAN_SJA1000_ISA is not set ++# CONFIG_CAN_SJA1000_PLATFORM is not set ++# CONFIG_CAN_SOFTING is not set ++ ++# ++# CAN SPI interfaces ++# ++# CONFIG_CAN_HI311X is not set ++# CONFIG_CAN_MCP251X is not set ++# CONFIG_CAN_MCP251XFD is not set ++# end of CAN SPI interfaces ++ ++# ++# CAN USB interfaces ++# ++# CONFIG_CAN_8DEV_USB is not set ++# CONFIG_CAN_EMS_USB is not set ++# CONFIG_CAN_ESD_USB2 is not set ++# CONFIG_CAN_ETAS_ES58X is not set ++# CONFIG_CAN_GS_USB is not set ++# CONFIG_CAN_KVASER_USB is not set ++# CONFIG_CAN_MCBA_USB is not set ++# CONFIG_CAN_PEAK_USB is not set ++# CONFIG_CAN_UCAN is not set ++# end of CAN USB interfaces ++ ++# CONFIG_CAN_DEBUG_DEVICES is not set ++# end of CAN Device Drivers ++ ++CONFIG_BT=y ++CONFIG_BT_BREDR=y ++CONFIG_BT_RFCOMM=y ++# CONFIG_BT_RFCOMM_TTY is not set ++# CONFIG_BT_BNEP is not set ++# CONFIG_BT_CMTP is not set ++CONFIG_BT_HIDP=y ++CONFIG_BT_HS=y ++CONFIG_BT_LE=y ++# CONFIG_BT_LEDS is not set ++# CONFIG_BT_MSFTEXT is not set ++# CONFIG_BT_AOSPEXT is not set ++CONFIG_BT_DEBUGFS=y ++# CONFIG_BT_SELFTEST is not set ++ ++# ++# Bluetooth device drivers ++# ++CONFIG_BT_INTEL=y ++CONFIG_BT_BCM=y ++CONFIG_BT_RTL=y ++CONFIG_BT_HCIBTUSB=y ++# CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set ++CONFIG_BT_HCIBTUSB_BCM=y ++# CONFIG_BT_HCIBTUSB_MTK is not set ++CONFIG_BT_HCIBTUSB_RTL=y ++# CONFIG_BT_HCIBTSDIO is not set ++CONFIG_BT_HCIUART=y ++CONFIG_BT_HCIUART_SERDEV=y ++CONFIG_BT_HCIUART_H4=y ++# CONFIG_BT_HCIUART_NOKIA is not set ++# CONFIG_BT_HCIUART_BCSP is not set ++CONFIG_BT_HCIUART_ATH3K=y ++# CONFIG_BT_HCIUART_LL is not set ++# CONFIG_BT_HCIUART_3WIRE is not set ++# CONFIG_BT_HCIUART_INTEL is not set ++# CONFIG_BT_HCIUART_BCM is not set ++# CONFIG_BT_HCIUART_RTL is not set ++# CONFIG_BT_HCIUART_QCA is not set ++# CONFIG_BT_HCIUART_AG6XX is not set ++# CONFIG_BT_HCIUART_MRVL is not set ++# CONFIG_BT_HCIBCM203X is not set ++# CONFIG_BT_HCIBPA10X is not set ++CONFIG_BT_HCIBFUSB=y ++# CONFIG_BT_HCIDTL1 is not set ++# CONFIG_BT_HCIBT3C is not set ++# CONFIG_BT_HCIBLUECARD is not set ++CONFIG_BT_HCIVHCI=y ++CONFIG_BT_MRVL=y ++CONFIG_BT_MRVL_SDIO=y ++# CONFIG_BT_ATH3K is not set ++# CONFIG_BT_MTKSDIO is not set ++# CONFIG_BT_MTKUART is not set ++# end of Bluetooth device drivers ++ ++# CONFIG_AF_RXRPC is not set ++# CONFIG_AF_KCM is not set ++# CONFIG_MCTP is not set ++CONFIG_FIB_RULES=y ++CONFIG_WIRELESS=y ++CONFIG_WIRELESS_EXT=y ++CONFIG_WEXT_CORE=y ++CONFIG_WEXT_PROC=y ++CONFIG_WEXT_SPY=y ++CONFIG_CFG80211=y ++CONFIG_NL80211_TESTMODE=y ++# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set ++# CONFIG_CFG80211_CERTIFICATION_ONUS is not set ++CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y ++CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y ++CONFIG_CFG80211_DEFAULT_PS=y ++CONFIG_CFG80211_DEBUGFS=y ++CONFIG_CFG80211_CRDA_SUPPORT=y ++CONFIG_CFG80211_WEXT=y ++CONFIG_LIB80211=y ++# CONFIG_LIB80211_DEBUG is not set ++CONFIG_MAC80211=y ++CONFIG_MAC80211_HAS_RC=y ++CONFIG_MAC80211_RC_MINSTREL=y ++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y ++CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" ++# CONFIG_MAC80211_MESH is not set ++CONFIG_MAC80211_LEDS=y ++CONFIG_MAC80211_DEBUGFS=y ++# CONFIG_MAC80211_MESSAGE_TRACING is not set ++CONFIG_MAC80211_DEBUG_MENU=y ++# CONFIG_MAC80211_NOINLINE is not set ++CONFIG_MAC80211_VERBOSE_DEBUG=y ++# CONFIG_MAC80211_MLME_DEBUG is not set ++# CONFIG_MAC80211_STA_DEBUG is not set ++# CONFIG_MAC80211_HT_DEBUG is not set ++# CONFIG_MAC80211_OCB_DEBUG is not set ++# CONFIG_MAC80211_IBSS_DEBUG is not set ++# CONFIG_MAC80211_PS_DEBUG is not set ++# CONFIG_MAC80211_TDLS_DEBUG is not set ++# CONFIG_MAC80211_DEBUG_COUNTERS is not set ++CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 ++CONFIG_RFKILL=y ++CONFIG_RFKILL_LEDS=y ++# CONFIG_RFKILL_INPUT is not set ++# CONFIG_RFKILL_GPIO is not set ++# CONFIG_NET_9P is not set ++# CONFIG_CAIF is not set ++CONFIG_CEPH_LIB=m ++# CONFIG_CEPH_LIB_PRETTYDEBUG is not set ++# CONFIG_CEPH_LIB_USE_DNS_RESOLVER is not set ++# CONFIG_NFC is not set ++# CONFIG_PSAMPLE is not set ++# CONFIG_NET_IFE is not set ++CONFIG_LWTUNNEL=y ++CONFIG_LWTUNNEL_BPF=y ++CONFIG_DST_CACHE=y ++CONFIG_GRO_CELLS=y ++CONFIG_NET_SELFTESTS=y ++CONFIG_PAGE_POOL=y ++# CONFIG_PAGE_POOL_STATS is not set ++# CONFIG_FAILOVER is not set ++# CONFIG_ETHTOOL_NETLINK is not set ++ ++# ++# Device Drivers ++# ++CONFIG_ARM_AMBA=y ++CONFIG_HAVE_PCI=y ++CONFIG_PCI=y ++CONFIG_PCI_DOMAINS=y ++CONFIG_PCI_DOMAINS_GENERIC=y ++CONFIG_PCI_SYSCALL=y ++CONFIG_PCIEPORTBUS=y ++CONFIG_PCIEAER=y ++# CONFIG_PCIEAER_INJECT is not set ++# CONFIG_PCIE_ECRC is not set ++CONFIG_PCIEASPM=y ++# CONFIG_PCIEASPM_DEFAULT is not set ++CONFIG_PCIEASPM_POWERSAVE=y ++# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set ++# CONFIG_PCIEASPM_PERFORMANCE is not set ++CONFIG_PCIE_PME=y ++# CONFIG_PCIE_DPC is not set ++# CONFIG_PCIE_PTM is not set ++CONFIG_PCI_MSI=y ++CONFIG_PCI_MSI_IRQ_DOMAIN=y ++CONFIG_PCI_QUIRKS=y ++CONFIG_PCI_DEBUG=y ++# CONFIG_PCI_STUB is not set ++# CONFIG_PCI_IOV is not set ++# CONFIG_PCI_PRI is not set ++# CONFIG_PCI_PASID is not set ++# CONFIG_PCIE_BUS_TUNE_OFF is not set ++CONFIG_PCIE_BUS_DEFAULT=y ++# CONFIG_PCIE_BUS_SAFE is not set ++# CONFIG_PCIE_BUS_PERFORMANCE is not set ++# CONFIG_PCIE_BUS_PEER2PEER is not set ++# CONFIG_VGA_ARB is not set ++# CONFIG_HOTPLUG_PCI is not set ++ ++# ++# PCI controller drivers ++# ++# CONFIG_PCI_FTPCI100 is not set ++# CONFIG_PCI_HOST_GENERIC is not set ++# CONFIG_PCIE_XILINX is not set ++# CONFIG_PCI_XGENE is not set ++# CONFIG_PCIE_ALTERA is not set ++# CONFIG_PCI_HOST_THUNDER_PEM is not set ++# CONFIG_PCI_HOST_THUNDER_ECAM is not set ++# CONFIG_PCIE_ROCKCHIP_HOST is not set ++# CONFIG_PCIE_MICROCHIP_HOST is not set ++ ++# ++# DesignWare PCI Core Support ++# ++# CONFIG_PCIE_DW_PLAT_HOST is not set ++# CONFIG_PCI_HISI is not set ++# CONFIG_PCIE_ROCKCHIP_DW_HOST is not set ++# CONFIG_PCIE_KIRIN is not set ++# CONFIG_PCI_MESON is not set ++# CONFIG_PCIE_AL is not set ++# end of DesignWare PCI Core Support ++ ++# ++# Mobiveil PCIe Core Support ++# ++# end of Mobiveil PCIe Core Support ++ ++# ++# Cadence PCIe controllers support ++# ++# CONFIG_PCIE_CADENCE_PLAT_HOST is not set ++# CONFIG_PCI_J721E_HOST is not set ++# end of Cadence PCIe controllers support ++# end of PCI controller drivers ++ ++# ++# PCI Endpoint ++# ++# CONFIG_PCI_ENDPOINT is not set ++# end of PCI Endpoint ++ ++# ++# PCI switch controller drivers ++# ++# CONFIG_PCI_SW_SWITCHTEC is not set ++# end of PCI switch controller drivers ++ ++# CONFIG_CXL_BUS is not set ++CONFIG_PCCARD=y ++CONFIG_PCMCIA=y ++CONFIG_PCMCIA_LOAD_CIS=y ++CONFIG_CARDBUS=y ++ ++# ++# PC-card bridges ++# ++# CONFIG_YENTA is not set ++# CONFIG_PD6729 is not set ++# CONFIG_I82092 is not set ++# CONFIG_RAPIDIO is not set ++ ++# ++# Generic Driver Options ++# ++CONFIG_UEVENT_HELPER=y ++CONFIG_UEVENT_HELPER_PATH="" ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_DEVTMPFS_SAFE=y ++CONFIG_STANDALONE=y ++CONFIG_PREVENT_FIRMWARE_BUILD=y ++ ++# ++# Firmware loader ++# ++CONFIG_FW_LOADER=y ++CONFIG_FW_LOADER_PAGED_BUF=y ++CONFIG_EXTRA_FIRMWARE="" ++CONFIG_FW_LOADER_USER_HELPER=y ++CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y ++# CONFIG_FW_LOADER_COMPRESS is not set ++CONFIG_FW_CACHE=y ++# end of Firmware loader ++ ++CONFIG_WANT_DEV_COREDUMP=y ++# CONFIG_ALLOW_DEV_COREDUMP is not set ++# CONFIG_DEBUG_DRIVER is not set ++CONFIG_DEBUG_DEVRES=y ++# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set ++# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set ++CONFIG_GENERIC_CPU_AUTOPROBE=y ++CONFIG_GENERIC_CPU_VULNERABILITIES=y ++CONFIG_REGMAP=y ++CONFIG_REGMAP_I2C=y ++CONFIG_REGMAP_SPI=y ++CONFIG_REGMAP_MMIO=y ++CONFIG_REGMAP_IRQ=y ++CONFIG_DMA_SHARED_BUFFER=y ++# CONFIG_DMA_FENCE_TRACE is not set ++CONFIG_GENERIC_ARCH_TOPOLOGY=y ++# end of Generic Driver Options ++ ++# ++# Bus devices ++# ++# CONFIG_BRCMSTB_GISB_ARB is not set ++# CONFIG_MOXTET is not set ++# CONFIG_VEXPRESS_CONFIG is not set ++# CONFIG_MHI_BUS is not set ++# end of Bus devices ++ ++CONFIG_CONNECTOR=y ++CONFIG_PROC_EVENTS=y ++ ++# ++# Firmware Drivers ++# ++ ++# ++# ARM System Control and Management Interface Protocol ++# ++CONFIG_ARM_SCMI_PROTOCOL=y ++CONFIG_ARM_SCMI_HAVE_TRANSPORT=y ++CONFIG_ARM_SCMI_HAVE_SHMEM=y ++CONFIG_ARM_SCMI_TRANSPORT_MAILBOX=y ++CONFIG_ARM_SCMI_TRANSPORT_SMC=y ++# CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE is not set ++CONFIG_ARM_SCMI_POWER_DOMAIN=y ++# end of ARM System Control and Management Interface Protocol ++ ++CONFIG_ARM_SCPI_PROTOCOL=y ++CONFIG_ARM_SCPI_POWER_DOMAIN=y ++# CONFIG_FIRMWARE_MEMMAP is not set ++# CONFIG_FW_CFG_SYSFS is not set ++# CONFIG_ARM_FFA_TRANSPORT is not set ++# CONFIG_GOOGLE_FIRMWARE is not set ++CONFIG_ARM_PSCI_FW=y ++# CONFIG_ARM_PSCI_CHECKER is not set ++CONFIG_HAVE_ARM_SMCCC=y ++CONFIG_HAVE_ARM_SMCCC_DISCOVERY=y ++# CONFIG_ARM_SMCCC_SOC_ID is not set ++ ++# ++# Tegra firmware driver ++# ++# end of Tegra firmware driver ++# end of Firmware Drivers ++ ++# CONFIG_GNSS is not set ++# CONFIG_MTD is not set ++CONFIG_DTC=y ++CONFIG_OF=y ++# CONFIG_OF_UNITTEST is not set ++CONFIG_OF_FLATTREE=y ++CONFIG_OF_EARLY_FLATTREE=y ++CONFIG_OF_KOBJ=y ++CONFIG_OF_DYNAMIC=y ++CONFIG_OF_ADDRESS=y ++CONFIG_OF_IRQ=y ++CONFIG_OF_RESERVED_MEM=y ++CONFIG_OF_RESOLVE=y ++CONFIG_OF_OVERLAY=y ++# CONFIG_PARPORT is not set ++CONFIG_BLK_DEV=y ++# CONFIG_BLK_DEV_NULL_BLK is not set ++CONFIG_CDROM=y ++# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set ++CONFIG_ZRAM=y ++CONFIG_ZRAM_DEF_COMP_LZORLE=y ++# CONFIG_ZRAM_DEF_COMP_LZ4 is not set ++# CONFIG_ZRAM_DEF_COMP_LZO is not set ++CONFIG_ZRAM_DEF_COMP="lzo-rle" ++# CONFIG_ZRAM_WRITEBACK is not set ++# CONFIG_ZRAM_MEMORY_TRACKING is not set ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 ++CONFIG_BLK_DEV_DRBD=m ++# CONFIG_DRBD_FAULT_INJECTION is not set ++CONFIG_BLK_DEV_NBD=m ++# CONFIG_BLK_DEV_SX8 is not set ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_COUNT=1 ++CONFIG_BLK_DEV_RAM_SIZE=4096 ++# CONFIG_CDROM_PKTCDVD is not set ++CONFIG_ATA_OVER_ETH=m ++CONFIG_BLK_DEV_RBD=m ++ ++# ++# NVME Support ++# ++CONFIG_NVME_CORE=m ++CONFIG_BLK_DEV_NVME=m ++# CONFIG_NVME_MULTIPATH is not set ++# CONFIG_NVME_VERBOSE_ERRORS is not set ++# CONFIG_NVME_HWMON is not set ++# CONFIG_NVME_FC is not set ++# CONFIG_NVME_TCP is not set ++# CONFIG_NVME_TARGET is not set ++# end of NVME Support ++ ++# ++# Misc devices ++# ++# CONFIG_AD525X_DPOT is not set ++# CONFIG_DUMMY_IRQ is not set ++# CONFIG_PHANTOM is not set ++# CONFIG_TIFM_CORE is not set ++# CONFIG_ICS932S401 is not set ++# CONFIG_ENCLOSURE_SERVICES is not set ++# CONFIG_HP_ILO is not set ++# CONFIG_APDS9802ALS is not set ++# CONFIG_ISL29003 is not set ++# CONFIG_ISL29020 is not set ++# CONFIG_SENSORS_TSL2550 is not set ++# CONFIG_SENSORS_BH1770 is not set ++# CONFIG_SENSORS_APDS990X is not set ++# CONFIG_HMC6352 is not set ++# CONFIG_DS1682 is not set ++# CONFIG_LATTICE_ECP3_CONFIG is not set ++CONFIG_SRAM=y ++# CONFIG_DW_XDATA_PCIE is not set ++# CONFIG_PCI_ENDPOINT_TEST is not set ++# CONFIG_XILINX_SDFEC is not set ++# CONFIG_HISI_HIKEY_USB is not set ++# CONFIG_OPEN_DICE is not set ++# CONFIG_C2PORT is not set ++ ++# ++# EEPROM support ++# ++# CONFIG_EEPROM_AT24 is not set ++# CONFIG_EEPROM_AT25 is not set ++# CONFIG_EEPROM_LEGACY is not set ++# CONFIG_EEPROM_MAX6875 is not set ++CONFIG_EEPROM_93CX6=y ++# CONFIG_EEPROM_93XX46 is not set ++# CONFIG_EEPROM_IDT_89HPESX is not set ++# CONFIG_EEPROM_EE1004 is not set ++# end of EEPROM support ++ ++# CONFIG_CB710_CORE is not set ++ ++# ++# Texas Instruments shared transport line discipline ++# ++# CONFIG_TI_ST is not set ++# end of Texas Instruments shared transport line discipline ++ ++# CONFIG_SENSORS_LIS3_SPI is not set ++# CONFIG_SENSORS_LIS3_I2C is not set ++# CONFIG_ALTERA_STAPL is not set ++# CONFIG_GENWQE is not set ++# CONFIG_ECHO is not set ++# CONFIG_BCM_VK is not set ++# CONFIG_MISC_ALCOR_PCI is not set ++# CONFIG_MISC_RTSX_PCI is not set ++# CONFIG_MISC_RTSX_USB is not set ++# CONFIG_HABANA_AI is not set ++# CONFIG_UACCE is not set ++# CONFIG_PVPANIC is not set ++# end of Misc devices ++ ++# ++# SCSI device support ++# ++CONFIG_SCSI_MOD=y ++CONFIG_RAID_ATTRS=m ++CONFIG_SCSI_COMMON=y ++CONFIG_SCSI=y ++CONFIG_SCSI_DMA=y ++CONFIG_SCSI_PROC_FS=y ++ ++# ++# SCSI support type (disk, tape, CD-ROM) ++# ++CONFIG_BLK_DEV_SD=y ++# CONFIG_CHR_DEV_ST is not set ++CONFIG_BLK_DEV_SR=y ++# CONFIG_CHR_DEV_SG is not set ++CONFIG_BLK_DEV_BSG=y ++# CONFIG_CHR_DEV_SCH is not set ++# CONFIG_SCSI_CONSTANTS is not set ++# CONFIG_SCSI_LOGGING is not set ++CONFIG_SCSI_SCAN_ASYNC=y ++ ++# ++# SCSI Transports ++# ++CONFIG_SCSI_SPI_ATTRS=y ++# CONFIG_SCSI_FC_ATTRS is not set ++# CONFIG_SCSI_ISCSI_ATTRS is not set ++CONFIG_SCSI_SAS_ATTRS=m ++# CONFIG_SCSI_SAS_LIBSAS is not set ++# CONFIG_SCSI_SRP_ATTRS is not set ++# end of SCSI Transports ++ ++CONFIG_SCSI_LOWLEVEL=y ++# CONFIG_ISCSI_TCP is not set ++# CONFIG_ISCSI_BOOT_SYSFS is not set ++# CONFIG_SCSI_CXGB3_ISCSI is not set ++# CONFIG_SCSI_CXGB4_ISCSI is not set ++# CONFIG_SCSI_BNX2_ISCSI is not set ++# CONFIG_BE2ISCSI is not set ++# CONFIG_BLK_DEV_3W_XXXX_RAID is not set ++# CONFIG_SCSI_HPSA is not set ++# CONFIG_SCSI_3W_9XXX is not set ++# CONFIG_SCSI_3W_SAS is not set ++# CONFIG_SCSI_ACARD is not set ++# CONFIG_SCSI_AACRAID is not set ++# CONFIG_SCSI_AIC7XXX is not set ++# CONFIG_SCSI_AIC79XX is not set ++# CONFIG_SCSI_AIC94XX is not set ++# CONFIG_SCSI_HISI_SAS is not set ++# CONFIG_SCSI_MVSAS is not set ++# CONFIG_SCSI_MVUMI is not set ++# CONFIG_SCSI_ADVANSYS is not set ++# CONFIG_SCSI_ARCMSR is not set ++# CONFIG_SCSI_ESAS2R is not set ++# CONFIG_MEGARAID_NEWGEN is not set ++# CONFIG_MEGARAID_LEGACY is not set ++CONFIG_MEGARAID_SAS=m ++CONFIG_SCSI_MPT3SAS=m ++CONFIG_SCSI_MPT2SAS_MAX_SGE=128 ++CONFIG_SCSI_MPT3SAS_MAX_SGE=128 ++CONFIG_SCSI_MPT2SAS=m ++# CONFIG_SCSI_MPI3MR is not set ++# CONFIG_SCSI_SMARTPQI is not set ++# CONFIG_SCSI_UFSHCD is not set ++# CONFIG_SCSI_HPTIOP is not set ++# CONFIG_SCSI_MYRB is not set ++# CONFIG_SCSI_MYRS is not set ++# CONFIG_SCSI_SNIC is not set ++# CONFIG_SCSI_DMX3191D is not set ++# CONFIG_SCSI_FDOMAIN_PCI is not set ++# CONFIG_SCSI_IPS is not set ++# CONFIG_SCSI_INITIO is not set ++# CONFIG_SCSI_INIA100 is not set ++# CONFIG_SCSI_STEX is not set ++# CONFIG_SCSI_SYM53C8XX_2 is not set ++# CONFIG_SCSI_IPR is not set ++# CONFIG_SCSI_QLOGIC_1280 is not set ++# CONFIG_SCSI_QLA_ISCSI is not set ++# CONFIG_SCSI_DC395x is not set ++# CONFIG_SCSI_AM53C974 is not set ++# CONFIG_SCSI_WD719X is not set ++# CONFIG_SCSI_DEBUG is not set ++# CONFIG_SCSI_PMCRAID is not set ++# CONFIG_SCSI_PM8001 is not set ++# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set ++# CONFIG_SCSI_DH is not set ++# end of SCSI device support ++ ++CONFIG_HAVE_PATA_PLATFORM=y ++CONFIG_ATA=y ++CONFIG_SATA_HOST=y ++CONFIG_ATA_VERBOSE_ERROR=y ++CONFIG_ATA_FORCE=y ++CONFIG_SATA_PMP=y ++ ++# ++# Controllers with non-SFF native interface ++# ++CONFIG_SATA_AHCI=y ++CONFIG_SATA_MOBILE_LPM_POLICY=0 ++CONFIG_SATA_AHCI_PLATFORM=y ++# CONFIG_AHCI_CEVA is not set ++# CONFIG_AHCI_QORIQ is not set ++# CONFIG_SATA_INIC162X is not set ++# CONFIG_SATA_ACARD_AHCI is not set ++# CONFIG_SATA_SIL24 is not set ++CONFIG_ATA_SFF=y ++ ++# ++# SFF controllers with custom DMA interface ++# ++# CONFIG_PDC_ADMA is not set ++# CONFIG_SATA_QSTOR is not set ++# CONFIG_SATA_SX4 is not set ++CONFIG_ATA_BMDMA=y ++ ++# ++# SATA SFF controllers with BMDMA ++# ++# CONFIG_ATA_PIIX is not set ++# CONFIG_SATA_DWC is not set ++CONFIG_SATA_MV=m ++CONFIG_SATA_NV=m ++CONFIG_SATA_PROMISE=m ++CONFIG_SATA_SIL=m ++# CONFIG_SATA_SIS is not set ++# CONFIG_SATA_SVW is not set ++# CONFIG_SATA_ULI is not set ++# CONFIG_SATA_VIA is not set ++# CONFIG_SATA_VITESSE is not set ++ ++# ++# PATA SFF controllers with BMDMA ++# ++# CONFIG_PATA_ALI is not set ++# CONFIG_PATA_AMD is not set ++# CONFIG_PATA_ARTOP is not set ++# CONFIG_PATA_ATIIXP is not set ++# CONFIG_PATA_ATP867X is not set ++# CONFIG_PATA_CMD64X is not set ++# CONFIG_PATA_CYPRESS is not set ++# CONFIG_PATA_EFAR is not set ++# CONFIG_PATA_HPT366 is not set ++# CONFIG_PATA_HPT37X is not set ++# CONFIG_PATA_HPT3X2N is not set ++# CONFIG_PATA_HPT3X3 is not set ++# CONFIG_PATA_IT8213 is not set ++# CONFIG_PATA_IT821X is not set ++# CONFIG_PATA_JMICRON is not set ++# CONFIG_PATA_MARVELL is not set ++# CONFIG_PATA_NETCELL is not set ++# CONFIG_PATA_NINJA32 is not set ++# CONFIG_PATA_NS87415 is not set ++# CONFIG_PATA_OLDPIIX is not set ++# CONFIG_PATA_OPTIDMA is not set ++# CONFIG_PATA_PDC2027X is not set ++# CONFIG_PATA_PDC_OLD is not set ++# CONFIG_PATA_RADISYS is not set ++# CONFIG_PATA_RDC is not set ++# CONFIG_PATA_SCH is not set ++# CONFIG_PATA_SERVERWORKS is not set ++# CONFIG_PATA_SIL680 is not set ++# CONFIG_PATA_SIS is not set ++# CONFIG_PATA_TOSHIBA is not set ++# CONFIG_PATA_TRIFLEX is not set ++# CONFIG_PATA_VIA is not set ++# CONFIG_PATA_WINBOND is not set ++ ++# ++# PIO-only SFF controllers ++# ++# CONFIG_PATA_CMD640_PCI is not set ++# CONFIG_PATA_MPIIX is not set ++# CONFIG_PATA_NS87410 is not set ++# CONFIG_PATA_OPTI is not set ++# CONFIG_PATA_PCMCIA is not set ++# CONFIG_PATA_PLATFORM is not set ++# CONFIG_PATA_RZ1000 is not set ++ ++# ++# Generic fallback / legacy drivers ++# ++# CONFIG_ATA_GENERIC is not set ++# CONFIG_PATA_LEGACY is not set ++CONFIG_MD=y ++CONFIG_BLK_DEV_MD=y ++CONFIG_MD_AUTODETECT=y ++CONFIG_MD_LINEAR=m ++CONFIG_MD_RAID0=y ++CONFIG_MD_RAID1=y ++CONFIG_MD_RAID10=y ++CONFIG_MD_RAID456=y ++# CONFIG_MD_MULTIPATH is not set ++# CONFIG_MD_FAULTY is not set ++CONFIG_BCACHE=m ++# CONFIG_BCACHE_DEBUG is not set ++# CONFIG_BCACHE_CLOSURES_DEBUG is not set ++# CONFIG_BCACHE_ASYNC_REGISTRATION is not set ++CONFIG_BLK_DEV_DM_BUILTIN=y ++CONFIG_BLK_DEV_DM=y ++# CONFIG_DM_DEBUG is not set ++# CONFIG_DM_UNSTRIPED is not set ++CONFIG_DM_CRYPT=m ++# CONFIG_DM_SNAPSHOT is not set ++# CONFIG_DM_THIN_PROVISIONING is not set ++# CONFIG_DM_CACHE is not set ++# CONFIG_DM_WRITECACHE is not set ++# CONFIG_DM_EBS is not set ++# CONFIG_DM_ERA is not set ++# CONFIG_DM_CLONE is not set ++# CONFIG_DM_MIRROR is not set ++CONFIG_DM_RAID=y ++# CONFIG_DM_ZERO is not set ++# CONFIG_DM_MULTIPATH is not set ++# CONFIG_DM_DELAY is not set ++# CONFIG_DM_DUST is not set ++# CONFIG_DM_INIT is not set ++# CONFIG_DM_UEVENT is not set ++# CONFIG_DM_FLAKEY is not set ++# CONFIG_DM_VERITY is not set ++# CONFIG_DM_SWITCH is not set ++# CONFIG_DM_LOG_WRITES is not set ++# CONFIG_DM_INTEGRITY is not set ++# CONFIG_TARGET_CORE is not set ++# CONFIG_FUSION is not set ++ ++# ++# IEEE 1394 (FireWire) support ++# ++# CONFIG_FIREWIRE is not set ++# CONFIG_FIREWIRE_NOSY is not set ++# end of IEEE 1394 (FireWire) support ++ ++CONFIG_NETDEVICES=y ++CONFIG_MII=y ++CONFIG_NET_CORE=y ++# CONFIG_BONDING is not set ++# CONFIG_DUMMY is not set ++# CONFIG_WIREGUARD is not set ++# CONFIG_EQUALIZER is not set ++# CONFIG_NET_FC is not set ++# CONFIG_NET_TEAM is not set ++CONFIG_MACVLAN=y ++# CONFIG_MACVTAP is not set ++CONFIG_IPVLAN_L3S=y ++CONFIG_IPVLAN=y ++# CONFIG_IPVTAP is not set ++CONFIG_VXLAN=m ++# CONFIG_GENEVE is not set ++# CONFIG_BAREUDP is not set ++# CONFIG_GTP is not set ++# CONFIG_AMT is not set ++# CONFIG_MACSEC is not set ++# CONFIG_NETCONSOLE is not set ++CONFIG_TUN=m ++# CONFIG_TUN_VNET_CROSS_LE is not set ++CONFIG_VETH=y ++# CONFIG_NLMON is not set ++# CONFIG_NET_VRF is not set ++# CONFIG_ARCNET is not set ++CONFIG_ETHERNET=y ++CONFIG_MDIO=y ++# CONFIG_NET_VENDOR_3COM is not set ++# CONFIG_NET_VENDOR_ADAPTEC is not set ++# CONFIG_NET_VENDOR_AGERE is not set ++CONFIG_NET_VENDOR_ALACRITECH=y ++# CONFIG_SLICOSS is not set ++# CONFIG_NET_VENDOR_ALTEON is not set ++# CONFIG_ALTERA_TSE is not set ++CONFIG_NET_VENDOR_AMAZON=y ++# CONFIG_ENA_ETHERNET is not set ++# CONFIG_NET_VENDOR_AMD is not set ++CONFIG_NET_VENDOR_AQUANTIA=y ++# CONFIG_AQTION is not set ++# CONFIG_NET_VENDOR_ARC is not set ++CONFIG_NET_VENDOR_ASIX=y ++# CONFIG_SPI_AX88796C is not set ++# CONFIG_NET_VENDOR_ATHEROS is not set ++# CONFIG_NET_VENDOR_BROADCOM is not set ++# CONFIG_NET_VENDOR_BROCADE is not set ++CONFIG_NET_VENDOR_CADENCE=y ++# CONFIG_MACB is not set ++# CONFIG_NET_VENDOR_CAVIUM is not set ++# CONFIG_NET_VENDOR_CHELSIO is not set ++# CONFIG_NET_VENDOR_CISCO is not set ++CONFIG_NET_VENDOR_CORTINA=y ++# CONFIG_GEMINI_ETHERNET is not set ++CONFIG_NET_VENDOR_DAVICOM=y ++# CONFIG_DM9051 is not set ++# CONFIG_DNET is not set ++# CONFIG_NET_VENDOR_DEC is not set ++# CONFIG_NET_VENDOR_DLINK is not set ++# CONFIG_NET_VENDOR_EMULEX is not set ++CONFIG_NET_VENDOR_ENGLEDER=y ++# CONFIG_TSNEP is not set ++# CONFIG_NET_VENDOR_EZCHIP is not set ++CONFIG_NET_VENDOR_FUJITSU=y ++# CONFIG_PCMCIA_FMVJ18X is not set ++CONFIG_NET_VENDOR_FUNGIBLE=y ++# CONFIG_FUN_ETH is not set ++CONFIG_NET_VENDOR_GOOGLE=y ++# CONFIG_GVE is not set ++# CONFIG_NET_VENDOR_HISILICON is not set ++CONFIG_NET_VENDOR_HUAWEI=y ++# CONFIG_HINIC is not set ++CONFIG_NET_VENDOR_I825XX=y ++CONFIG_NET_VENDOR_INTEL=y ++CONFIG_E100=y ++CONFIG_E1000=y ++CONFIG_E1000E=y ++CONFIG_IGB=y ++CONFIG_IGB_HWMON=y ++# CONFIG_IGBVF is not set ++# CONFIG_IXGB is not set ++CONFIG_IXGBE=y ++CONFIG_IXGBE_HWMON=y ++# CONFIG_IXGBEVF is not set ++# CONFIG_I40E is not set ++# CONFIG_I40EVF is not set ++# CONFIG_ICE is not set ++# CONFIG_FM10K is not set ++# CONFIG_IGC is not set ++CONFIG_NET_VENDOR_MICROSOFT=y ++# CONFIG_JME is not set ++CONFIG_NET_VENDOR_LITEX=y ++# CONFIG_LITEX_LITEETH is not set ++# CONFIG_NET_VENDOR_MARVELL is not set ++# CONFIG_NET_VENDOR_MELLANOX is not set ++# CONFIG_NET_VENDOR_MICREL is not set ++# CONFIG_NET_VENDOR_MICROCHIP is not set ++CONFIG_NET_VENDOR_MICROSEMI=y ++# CONFIG_NET_VENDOR_MYRI is not set ++# CONFIG_FEALNX is not set ++# CONFIG_NET_VENDOR_NATSEMI is not set ++CONFIG_NET_VENDOR_NETERION=y ++# CONFIG_S2IO is not set ++# CONFIG_VXGE is not set ++CONFIG_NET_VENDOR_NETRONOME=y ++# CONFIG_NFP is not set ++CONFIG_NET_VENDOR_NI=y ++# CONFIG_NI_XGE_MANAGEMENT_ENET is not set ++# CONFIG_NET_VENDOR_NVIDIA is not set ++# CONFIG_NET_VENDOR_OKI is not set ++# CONFIG_ETHOC is not set ++CONFIG_NET_VENDOR_PACKET_ENGINES=y ++# CONFIG_HAMACHI is not set ++# CONFIG_YELLOWFIN is not set ++CONFIG_NET_VENDOR_PENSANDO=y ++# CONFIG_IONIC is not set ++# CONFIG_NET_VENDOR_QLOGIC is not set ++# CONFIG_NET_VENDOR_QUALCOMM is not set ++# CONFIG_NET_VENDOR_RDC is not set ++# CONFIG_NET_VENDOR_REALTEK is not set ++# CONFIG_NET_VENDOR_RENESAS is not set ++# CONFIG_NET_VENDOR_ROCKER is not set ++# CONFIG_NET_VENDOR_SAMSUNG is not set ++# CONFIG_NET_VENDOR_SEEQ is not set ++CONFIG_NET_VENDOR_SOLARFLARE=y ++# CONFIG_SFC is not set ++# CONFIG_SFC_FALCON is not set ++# CONFIG_NET_VENDOR_SILAN is not set ++# CONFIG_NET_VENDOR_SIS is not set ++# CONFIG_NET_VENDOR_SMSC is not set ++CONFIG_NET_VENDOR_SOCIONEXT=y ++CONFIG_NET_VENDOR_STMICRO=y ++CONFIG_STMMAC_ETH=y ++# CONFIG_STMMAC_SELFTESTS is not set ++CONFIG_STMMAC_PLATFORM=y ++# CONFIG_DWMAC_DWC_QOS_ETH is not set ++CONFIG_DWMAC_GENERIC=y ++CONFIG_DWMAC_ROCKCHIP=y ++# CONFIG_DWMAC_INTEL_PLAT is not set ++# CONFIG_DWMAC_LOONGSON is not set ++# CONFIG_STMMAC_PCI is not set ++# CONFIG_NET_VENDOR_SUN is not set ++# CONFIG_NET_VENDOR_SYNOPSYS is not set ++# CONFIG_NET_VENDOR_TEHUTI is not set ++# CONFIG_NET_VENDOR_TI is not set ++CONFIG_NET_VENDOR_VERTEXCOM=y ++# CONFIG_MSE102X is not set ++# CONFIG_NET_VENDOR_VIA is not set ++# CONFIG_NET_VENDOR_WIZNET is not set ++CONFIG_NET_VENDOR_XILINX=y ++# CONFIG_XILINX_EMACLITE is not set ++# CONFIG_XILINX_AXI_EMAC is not set ++# CONFIG_XILINX_LL_TEMAC is not set ++CONFIG_NET_VENDOR_XIRCOM=y ++# CONFIG_PCMCIA_XIRC2PS is not set ++# CONFIG_FDDI is not set ++# CONFIG_HIPPI is not set ++CONFIG_PHYLINK=y ++CONFIG_PHYLIB=y ++CONFIG_SWPHY=y ++# CONFIG_LED_TRIGGER_PHY is not set ++CONFIG_FIXED_PHY=y ++# CONFIG_SFP is not set ++ ++# ++# MII PHY device drivers ++# ++# CONFIG_AMD_PHY is not set ++# CONFIG_ADIN_PHY is not set ++# CONFIG_AQUANTIA_PHY is not set ++CONFIG_AX88796B_PHY=y ++# CONFIG_BROADCOM_PHY is not set ++# CONFIG_BCM54140_PHY is not set ++# CONFIG_BCM7XXX_PHY is not set ++# CONFIG_BCM84881_PHY is not set ++# CONFIG_BCM87XX_PHY is not set ++# CONFIG_CICADA_PHY is not set ++# CONFIG_CORTINA_PHY is not set ++# CONFIG_DAVICOM_PHY is not set ++# CONFIG_ICPLUS_PHY is not set ++# CONFIG_LXT_PHY is not set ++# CONFIG_INTEL_XWAY_PHY is not set ++# CONFIG_LSI_ET1011C_PHY is not set ++# CONFIG_MARVELL_PHY is not set ++# CONFIG_MARVELL_10G_PHY is not set ++# CONFIG_MARVELL_88X2222_PHY is not set ++# CONFIG_MAXLINEAR_GPHY is not set ++# CONFIG_MEDIATEK_GE_PHY is not set ++# CONFIG_MICREL_PHY is not set ++# CONFIG_MICROCHIP_PHY is not set ++# CONFIG_MICROCHIP_T1_PHY is not set ++# CONFIG_MICROSEMI_PHY is not set ++# CONFIG_MOTORCOMM_PHY is not set ++# CONFIG_NATIONAL_PHY is not set ++# CONFIG_NXP_C45_TJA11XX_PHY is not set ++# CONFIG_NXP_TJA11XX_PHY is not set ++# CONFIG_AT803X_PHY is not set ++# CONFIG_QSEMI_PHY is not set ++# CONFIG_REALTEK_PHY is not set ++# CONFIG_RENESAS_PHY is not set ++CONFIG_ROCKCHIP_PHY=y ++# CONFIG_SMSC_PHY is not set ++# CONFIG_STE10XP is not set ++# CONFIG_TERANETICS_PHY is not set ++# CONFIG_DP83822_PHY is not set ++# CONFIG_DP83TC811_PHY is not set ++# CONFIG_DP83848_PHY is not set ++# CONFIG_DP83867_PHY is not set ++# CONFIG_DP83869_PHY is not set ++# CONFIG_VITESSE_PHY is not set ++# CONFIG_XILINX_GMII2RGMII is not set ++# CONFIG_MICREL_KS8995MA is not set ++CONFIG_MDIO_DEVICE=y ++CONFIG_MDIO_BUS=y ++CONFIG_FWNODE_MDIO=y ++CONFIG_OF_MDIO=y ++CONFIG_MDIO_DEVRES=y ++# CONFIG_MDIO_BITBANG is not set ++# CONFIG_MDIO_BCM_UNIMAC is not set ++# CONFIG_MDIO_HISI_FEMAC is not set ++# CONFIG_MDIO_MVUSB is not set ++# CONFIG_MDIO_MSCC_MIIM is not set ++# CONFIG_MDIO_OCTEON is not set ++# CONFIG_MDIO_IPQ4019 is not set ++# CONFIG_MDIO_IPQ8064 is not set ++# CONFIG_MDIO_THUNDER is not set ++ ++# ++# MDIO Multiplexers ++# ++# CONFIG_MDIO_BUS_MUX_GPIO is not set ++# CONFIG_MDIO_BUS_MUX_MULTIPLEXER is not set ++# CONFIG_MDIO_BUS_MUX_MMIOREG is not set ++ ++# ++# PCS device drivers ++# ++CONFIG_PCS_XPCS=y ++# end of PCS device drivers ++ ++CONFIG_PPP=m ++CONFIG_PPP_BSDCOMP=m ++CONFIG_PPP_DEFLATE=m ++# CONFIG_PPP_FILTER is not set ++# CONFIG_PPP_MPPE is not set ++# CONFIG_PPP_MULTILINK is not set ++CONFIG_PPPOE=m ++# CONFIG_PPTP is not set ++CONFIG_PPP_ASYNC=m ++CONFIG_PPP_SYNC_TTY=m ++# CONFIG_SLIP is not set ++CONFIG_SLHC=m ++CONFIG_USB_NET_DRIVERS=y ++# CONFIG_USB_CATC is not set ++# CONFIG_USB_KAWETH is not set ++# CONFIG_USB_PEGASUS is not set ++CONFIG_USB_RTL8150=y ++CONFIG_USB_RTL8152=y ++# CONFIG_USB_LAN78XX is not set ++CONFIG_USB_USBNET=y ++CONFIG_USB_NET_AX8817X=y ++CONFIG_USB_NET_AX88179_178A=y ++CONFIG_USB_NET_CDCETHER=y ++# CONFIG_USB_NET_CDC_EEM is not set ++CONFIG_USB_NET_CDC_NCM=y ++# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set ++CONFIG_USB_NET_CDC_MBIM=y ++# CONFIG_USB_NET_DM9601 is not set ++# CONFIG_USB_NET_SR9700 is not set ++# CONFIG_USB_NET_SR9800 is not set ++# CONFIG_USB_NET_SMSC75XX is not set ++# CONFIG_USB_NET_SMSC95XX is not set ++# CONFIG_USB_NET_GL620A is not set ++# CONFIG_USB_NET_NET1080 is not set ++# CONFIG_USB_NET_PLUSB is not set ++# CONFIG_USB_NET_MCS7830 is not set ++CONFIG_USB_NET_RNDIS_HOST=y ++# CONFIG_USB_NET_CDC_SUBSET is not set ++# CONFIG_USB_NET_ZAURUS is not set ++# CONFIG_USB_NET_CX82310_ETH is not set ++# CONFIG_USB_NET_KALMIA is not set ++# CONFIG_USB_NET_QMI_WWAN is not set ++# CONFIG_USB_HSO is not set ++# CONFIG_USB_NET_INT51X1 is not set ++# CONFIG_USB_IPHETH is not set ++# CONFIG_USB_SIERRA_NET is not set ++# CONFIG_USB_VL600 is not set ++# CONFIG_USB_NET_CH9200 is not set ++# CONFIG_USB_NET_AQC111 is not set ++# CONFIG_USB_RTL8153_ECM is not set ++CONFIG_WLAN=y ++CONFIG_WLAN_VENDOR_ADMTEK=y ++# CONFIG_ADM8211 is not set ++CONFIG_ATH_COMMON=y ++CONFIG_WLAN_VENDOR_ATH=y ++# CONFIG_ATH_DEBUG is not set ++CONFIG_ATH5K=y ++# CONFIG_ATH5K_DEBUG is not set ++CONFIG_ATH5K_PCI=y ++CONFIG_ATH9K_HW=y ++CONFIG_ATH9K_COMMON=y ++CONFIG_ATH9K_BTCOEX_SUPPORT=y ++CONFIG_ATH9K=y ++CONFIG_ATH9K_PCI=y ++# CONFIG_ATH9K_AHB is not set ++# CONFIG_ATH9K_DEBUGFS is not set ++# CONFIG_ATH9K_DYNACK is not set ++# CONFIG_ATH9K_WOW is not set ++CONFIG_ATH9K_RFKILL=y ++# CONFIG_ATH9K_CHANNEL_CONTEXT is not set ++CONFIG_ATH9K_PCOEM=y ++# CONFIG_ATH9K_PCI_NO_EEPROM is not set ++# CONFIG_ATH9K_HTC is not set ++# CONFIG_ATH9K_HWRNG is not set ++# CONFIG_CARL9170 is not set ++CONFIG_ATH6KL=y ++# CONFIG_ATH6KL_SDIO is not set ++CONFIG_ATH6KL_USB=y ++# CONFIG_ATH6KL_DEBUG is not set ++CONFIG_AR5523=y ++# CONFIG_WIL6210 is not set ++CONFIG_ATH10K=y ++CONFIG_ATH10K_CE=y ++# CONFIG_ATH10K_PCI is not set ++# CONFIG_ATH10K_SDIO is not set ++# CONFIG_ATH10K_USB is not set ++# CONFIG_ATH10K_DEBUG is not set ++# CONFIG_ATH10K_DEBUGFS is not set ++CONFIG_WCN36XX=y ++# CONFIG_WCN36XX_DEBUGFS is not set ++CONFIG_WLAN_VENDOR_ATMEL=y ++# CONFIG_ATMEL is not set ++CONFIG_AT76C50X_USB=y ++CONFIG_WLAN_VENDOR_BROADCOM=y ++CONFIG_B43=y ++CONFIG_B43_BCMA=y ++CONFIG_B43_SSB=y ++CONFIG_B43_BUSES_BCMA_AND_SSB=y ++# CONFIG_B43_BUSES_BCMA is not set ++# CONFIG_B43_BUSES_SSB is not set ++CONFIG_B43_PCI_AUTOSELECT=y ++CONFIG_B43_PCICORE_AUTOSELECT=y ++# CONFIG_B43_SDIO is not set ++CONFIG_B43_BCMA_PIO=y ++CONFIG_B43_PIO=y ++CONFIG_B43_PHY_G=y ++CONFIG_B43_PHY_N=y ++CONFIG_B43_PHY_LP=y ++CONFIG_B43_PHY_HT=y ++CONFIG_B43_LEDS=y ++CONFIG_B43_HWRNG=y ++# CONFIG_B43_DEBUG is not set ++# CONFIG_B43LEGACY is not set ++CONFIG_BRCMUTIL=y ++# CONFIG_BRCMSMAC is not set ++CONFIG_BRCMFMAC=y ++CONFIG_BRCMFMAC_PROTO_BCDC=y ++CONFIG_BRCMFMAC_PROTO_MSGBUF=y ++# CONFIG_BRCMFMAC_SDIO is not set ++CONFIG_BRCMFMAC_USB=y ++CONFIG_BRCMFMAC_PCIE=y ++# CONFIG_BRCM_TRACING is not set ++# CONFIG_BRCMDBG is not set ++CONFIG_WLAN_VENDOR_CISCO=y ++# CONFIG_AIRO_CS is not set ++CONFIG_WLAN_VENDOR_INTEL=y ++# CONFIG_IPW2100 is not set ++# CONFIG_IPW2200 is not set ++# CONFIG_IWL4965 is not set ++# CONFIG_IWL3945 is not set ++# CONFIG_IWLWIFI is not set ++CONFIG_WLAN_VENDOR_INTERSIL=y ++# CONFIG_HOSTAP is not set ++# CONFIG_HERMES is not set ++# CONFIG_P54_COMMON is not set ++CONFIG_WLAN_VENDOR_MARVELL=y ++CONFIG_LIBERTAS=y ++CONFIG_LIBERTAS_USB=y ++# CONFIG_LIBERTAS_CS is not set ++# CONFIG_LIBERTAS_SDIO is not set ++# CONFIG_LIBERTAS_SPI is not set ++# CONFIG_LIBERTAS_DEBUG is not set ++# CONFIG_LIBERTAS_MESH is not set ++CONFIG_LIBERTAS_THINFIRM=y ++# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set ++# CONFIG_LIBERTAS_THINFIRM_USB is not set ++CONFIG_MWIFIEX=y ++CONFIG_MWIFIEX_SDIO=y ++# CONFIG_MWIFIEX_PCIE is not set ++CONFIG_MWIFIEX_USB=y ++# CONFIG_MWL8K is not set ++CONFIG_WLAN_VENDOR_MEDIATEK=y ++CONFIG_MT7601U=y ++# CONFIG_MT76x0U is not set ++# CONFIG_MT76x0E is not set ++# CONFIG_MT76x2E is not set ++# CONFIG_MT76x2U is not set ++# CONFIG_MT7603E is not set ++# CONFIG_MT7615E is not set ++# CONFIG_MT7663U is not set ++# CONFIG_MT7663S is not set ++# CONFIG_MT7915E is not set ++# CONFIG_MT7921E is not set ++# CONFIG_MT7921S is not set ++# CONFIG_MT7921U is not set ++CONFIG_WLAN_VENDOR_MICROCHIP=y ++# CONFIG_WILC1000_SDIO is not set ++# CONFIG_WILC1000_SPI is not set ++CONFIG_WLAN_VENDOR_RALINK=y ++CONFIG_RT2X00=y ++# CONFIG_RT2400PCI is not set ++# CONFIG_RT2500PCI is not set ++# CONFIG_RT61PCI is not set ++# CONFIG_RT2800PCI is not set ++CONFIG_RT2500USB=y ++CONFIG_RT73USB=y ++CONFIG_RT2800USB=y ++CONFIG_RT2800USB_RT33XX=y ++CONFIG_RT2800USB_RT35XX=y ++CONFIG_RT2800USB_RT3573=y ++CONFIG_RT2800USB_RT53XX=y ++CONFIG_RT2800USB_RT55XX=y ++CONFIG_RT2800USB_UNKNOWN=y ++CONFIG_RT2800_LIB=y ++CONFIG_RT2X00_LIB_USB=y ++CONFIG_RT2X00_LIB=y ++CONFIG_RT2X00_LIB_FIRMWARE=y ++CONFIG_RT2X00_LIB_CRYPTO=y ++CONFIG_RT2X00_LIB_LEDS=y ++# CONFIG_RT2X00_LIB_DEBUGFS is not set ++# CONFIG_RT2X00_DEBUG is not set ++CONFIG_WLAN_VENDOR_REALTEK=y ++CONFIG_RTL8180=m ++CONFIG_RTL8187=y ++CONFIG_RTL8187_LEDS=y ++CONFIG_RTL_CARDS=y ++CONFIG_RTL8192CE=m ++CONFIG_RTL8192SE=m ++CONFIG_RTL8192DE=m ++CONFIG_RTL8723AE=m ++CONFIG_RTL8723BE=m ++CONFIG_RTL8188EE=m ++CONFIG_RTL8192EE=m ++CONFIG_RTL8821AE=m ++CONFIG_RTL8192CU=m ++CONFIG_RTLWIFI=m ++CONFIG_RTLWIFI_PCI=m ++CONFIG_RTLWIFI_USB=m ++CONFIG_RTLWIFI_DEBUG=y ++CONFIG_RTL8192C_COMMON=m ++CONFIG_RTL8723_COMMON=m ++CONFIG_RTLBTCOEXIST=m ++CONFIG_RTL8XXXU=y ++CONFIG_RTL8XXXU_UNTESTED=y ++# CONFIG_RTW88 is not set ++# CONFIG_RTW89 is not set ++CONFIG_WLAN_VENDOR_RSI=y ++# CONFIG_RSI_91X is not set ++CONFIG_WLAN_VENDOR_ST=y ++# CONFIG_CW1200 is not set ++CONFIG_WLAN_VENDOR_TI=y ++# CONFIG_WL1251 is not set ++# CONFIG_WL12XX is not set ++# CONFIG_WL18XX is not set ++# CONFIG_WLCORE is not set ++CONFIG_WLAN_VENDOR_ZYDAS=y ++# CONFIG_USB_ZD1201 is not set ++CONFIG_ZD1211RW=y ++# CONFIG_ZD1211RW_DEBUG is not set ++CONFIG_WLAN_VENDOR_QUANTENNA=y ++# CONFIG_QTNFMAC_PCIE is not set ++# CONFIG_PCMCIA_RAYCS is not set ++# CONFIG_PCMCIA_WL3501 is not set ++# CONFIG_MAC80211_HWSIM is not set ++CONFIG_USB_NET_RNDIS_WLAN=y ++# CONFIG_VIRT_WIFI is not set ++# CONFIG_WAN is not set ++ ++# ++# Wireless WAN ++# ++# CONFIG_WWAN is not set ++# end of Wireless WAN ++ ++# CONFIG_VMXNET3 is not set ++# CONFIG_NETDEVSIM is not set ++# CONFIG_NET_FAILOVER is not set ++CONFIG_ISDN=y ++CONFIG_ISDN_CAPI=y ++# CONFIG_MISDN is not set ++ ++# ++# Input device support ++# ++CONFIG_INPUT=y ++CONFIG_INPUT_LEDS=y ++CONFIG_INPUT_FF_MEMLESS=y ++CONFIG_INPUT_POLLDEV=y ++# CONFIG_INPUT_SPARSEKMAP is not set ++CONFIG_INPUT_MATRIXKMAP=y ++ ++# ++# Userland interfaces ++# ++# CONFIG_INPUT_MOUSEDEV is not set ++CONFIG_INPUT_JOYDEV=y ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_EVBUG is not set ++ ++# ++# Input Device Drivers ++# ++CONFIG_INPUT_KEYBOARD=y ++CONFIG_KEYBOARD_ADC=y ++# CONFIG_KEYBOARD_ADP5588 is not set ++# CONFIG_KEYBOARD_ADP5589 is not set ++# CONFIG_KEYBOARD_ATKBD is not set ++# CONFIG_KEYBOARD_QT1050 is not set ++# CONFIG_KEYBOARD_QT1070 is not set ++# CONFIG_KEYBOARD_QT2160 is not set ++# CONFIG_KEYBOARD_DLINK_DIR685 is not set ++# CONFIG_KEYBOARD_LKKBD is not set ++CONFIG_KEYBOARD_GPIO=y ++CONFIG_KEYBOARD_GPIO_POLLED=y ++# CONFIG_KEYBOARD_TCA6416 is not set ++# CONFIG_KEYBOARD_TCA8418 is not set ++# CONFIG_KEYBOARD_MATRIX is not set ++# CONFIG_KEYBOARD_LM8323 is not set ++# CONFIG_KEYBOARD_LM8333 is not set ++# CONFIG_KEYBOARD_MAX7359 is not set ++# CONFIG_KEYBOARD_MCS is not set ++# CONFIG_KEYBOARD_MPR121 is not set ++# CONFIG_KEYBOARD_NEWTON is not set ++# CONFIG_KEYBOARD_OPENCORES is not set ++# CONFIG_KEYBOARD_SAMSUNG is not set ++# CONFIG_KEYBOARD_STOWAWAY is not set ++# CONFIG_KEYBOARD_SUNKBD is not set ++# CONFIG_KEYBOARD_OMAP4 is not set ++# CONFIG_KEYBOARD_TM2_TOUCHKEY is not set ++# CONFIG_KEYBOARD_XTKBD is not set ++# CONFIG_KEYBOARD_CAP11XX is not set ++# CONFIG_KEYBOARD_BCM is not set ++# CONFIG_KEYBOARD_CYPRESS_SF is not set ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_INPUT_JOYSTICK=y ++CONFIG_JOYSTICK_ANALOG=y ++CONFIG_JOYSTICK_A3D=y ++CONFIG_JOYSTICK_ADC=y ++CONFIG_JOYSTICK_ADI=y ++CONFIG_JOYSTICK_COBRA=y ++CONFIG_JOYSTICK_GF2K=y ++CONFIG_JOYSTICK_GRIP=y ++CONFIG_JOYSTICK_GRIP_MP=y ++CONFIG_JOYSTICK_GUILLEMOT=y ++CONFIG_JOYSTICK_INTERACT=y ++CONFIG_JOYSTICK_SIDEWINDER=y ++CONFIG_JOYSTICK_TMDC=y ++CONFIG_JOYSTICK_IFORCE=y ++CONFIG_JOYSTICK_IFORCE_USB=y ++# CONFIG_JOYSTICK_IFORCE_232 is not set ++CONFIG_JOYSTICK_WARRIOR=y ++CONFIG_JOYSTICK_MAGELLAN=y ++CONFIG_JOYSTICK_SPACEORB=y ++CONFIG_JOYSTICK_SPACEBALL=y ++CONFIG_JOYSTICK_STINGER=y ++CONFIG_JOYSTICK_TWIDJOY=y ++CONFIG_JOYSTICK_ZHENHUA=y ++CONFIG_JOYSTICK_AS5011=y ++CONFIG_JOYSTICK_JOYDUMP=y ++CONFIG_JOYSTICK_XPAD=y ++CONFIG_JOYSTICK_XPAD_FF=y ++# CONFIG_JOYSTICK_XPAD_LEDS is not set ++# CONFIG_JOYSTICK_PSXPAD_SPI is not set ++# CONFIG_JOYSTICK_PXRC is not set ++# CONFIG_JOYSTICK_QWIIC is not set ++# CONFIG_JOYSTICK_FSIA6B is not set ++CONFIG_JOYSTICK_SINGLEADCJOY=y ++CONFIG_INPUT_TABLET=y ++# CONFIG_TABLET_USB_ACECAD is not set ++# CONFIG_TABLET_USB_AIPTEK is not set ++# CONFIG_TABLET_USB_HANWANG is not set ++# CONFIG_TABLET_USB_KBTAB is not set ++# CONFIG_TABLET_USB_PEGASUS is not set ++# CONFIG_TABLET_SERIAL_WACOM4 is not set ++CONFIG_INPUT_TOUCHSCREEN=y ++# CONFIG_TOUCHSCREEN_ADS7846 is not set ++# CONFIG_TOUCHSCREEN_AD7877 is not set ++# CONFIG_TOUCHSCREEN_AD7879 is not set ++# CONFIG_TOUCHSCREEN_ADC is not set ++# CONFIG_TOUCHSCREEN_AR1021_I2C is not set ++CONFIG_TOUCHSCREEN_ATMEL_MXT=y ++# CONFIG_TOUCHSCREEN_ATMEL_MXT_T37 is not set ++# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set ++# CONFIG_TOUCHSCREEN_BU21013 is not set ++# CONFIG_TOUCHSCREEN_BU21029 is not set ++# CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set ++# CONFIG_TOUCHSCREEN_CY8CTMA140 is not set ++# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set ++# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set ++# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set ++# CONFIG_TOUCHSCREEN_DYNAPRO is not set ++# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set ++# CONFIG_TOUCHSCREEN_EETI is not set ++# CONFIG_TOUCHSCREEN_EGALAX is not set ++# CONFIG_TOUCHSCREEN_EGALAX_SERIAL is not set ++# CONFIG_TOUCHSCREEN_EXC3000 is not set ++# CONFIG_TOUCHSCREEN_FUJITSU is not set ++CONFIG_TOUCHSCREEN_GOODIX=y ++# CONFIG_TOUCHSCREEN_HIDEEP is not set ++# CONFIG_TOUCHSCREEN_HYCON_HY46XX is not set ++# CONFIG_TOUCHSCREEN_ILI210X is not set ++# CONFIG_TOUCHSCREEN_ILITEK is not set ++# CONFIG_TOUCHSCREEN_S6SY761 is not set ++# CONFIG_TOUCHSCREEN_GUNZE is not set ++# CONFIG_TOUCHSCREEN_EKTF2127 is not set ++# CONFIG_TOUCHSCREEN_ELAN is not set ++# CONFIG_TOUCHSCREEN_ELO is not set ++# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set ++# CONFIG_TOUCHSCREEN_WACOM_I2C is not set ++# CONFIG_TOUCHSCREEN_MAX11801 is not set ++# CONFIG_TOUCHSCREEN_MCS5000 is not set ++# CONFIG_TOUCHSCREEN_MMS114 is not set ++# CONFIG_TOUCHSCREEN_MELFAS_MIP4 is not set ++# CONFIG_TOUCHSCREEN_MSG2638 is not set ++# CONFIG_TOUCHSCREEN_MTOUCH is not set ++# CONFIG_TOUCHSCREEN_IMAGIS is not set ++# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set ++# CONFIG_TOUCHSCREEN_INEXIO is not set ++# CONFIG_TOUCHSCREEN_MK712 is not set ++# CONFIG_TOUCHSCREEN_PENMOUNT is not set ++# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set ++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set ++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set ++# CONFIG_TOUCHSCREEN_PIXCIR is not set ++# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set ++CONFIG_TOUCHSCREEN_USB_COMPOSITE=y ++CONFIG_TOUCHSCREEN_USB_EGALAX=y ++CONFIG_TOUCHSCREEN_USB_PANJIT=y ++CONFIG_TOUCHSCREEN_USB_3M=y ++CONFIG_TOUCHSCREEN_USB_ITM=y ++CONFIG_TOUCHSCREEN_USB_ETURBO=y ++CONFIG_TOUCHSCREEN_USB_GUNZE=y ++CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y ++CONFIG_TOUCHSCREEN_USB_IRTOUCH=y ++CONFIG_TOUCHSCREEN_USB_IDEALTEK=y ++CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y ++CONFIG_TOUCHSCREEN_USB_GOTOP=y ++CONFIG_TOUCHSCREEN_USB_JASTEC=y ++CONFIG_TOUCHSCREEN_USB_ELO=y ++CONFIG_TOUCHSCREEN_USB_E2I=y ++CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y ++CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y ++CONFIG_TOUCHSCREEN_USB_NEXIO=y ++CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y ++# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set ++# CONFIG_TOUCHSCREEN_TSC_SERIO is not set ++# CONFIG_TOUCHSCREEN_TSC2004 is not set ++# CONFIG_TOUCHSCREEN_TSC2005 is not set ++# CONFIG_TOUCHSCREEN_TSC2007 is not set ++# CONFIG_TOUCHSCREEN_RM_TS is not set ++# CONFIG_TOUCHSCREEN_SILEAD is not set ++# CONFIG_TOUCHSCREEN_SIS_I2C is not set ++# CONFIG_TOUCHSCREEN_ST1232 is not set ++# CONFIG_TOUCHSCREEN_STMFTS is not set ++# CONFIG_TOUCHSCREEN_SUR40 is not set ++# CONFIG_TOUCHSCREEN_SURFACE3_SPI is not set ++# CONFIG_TOUCHSCREEN_SX8654 is not set ++# CONFIG_TOUCHSCREEN_TPS6507X is not set ++# CONFIG_TOUCHSCREEN_ZET6223 is not set ++# CONFIG_TOUCHSCREEN_ZFORCE is not set ++# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set ++# CONFIG_TOUCHSCREEN_IQS5XX is not set ++# CONFIG_TOUCHSCREEN_ZINITIX is not set ++CONFIG_INPUT_MISC=y ++# CONFIG_INPUT_AD714X is not set ++# CONFIG_INPUT_ATMEL_CAPTOUCH is not set ++# CONFIG_INPUT_BMA150 is not set ++# CONFIG_INPUT_E3X0_BUTTON is not set ++# CONFIG_INPUT_MMA8450 is not set ++# CONFIG_INPUT_GPIO_BEEPER is not set ++# CONFIG_INPUT_GPIO_DECODER is not set ++# CONFIG_INPUT_GPIO_VIBRA is not set ++# CONFIG_INPUT_ATI_REMOTE2 is not set ++# CONFIG_INPUT_KEYSPAN_REMOTE is not set ++# CONFIG_INPUT_KXTJ9 is not set ++# CONFIG_INPUT_POWERMATE is not set ++# CONFIG_INPUT_YEALINK is not set ++# CONFIG_INPUT_CM109 is not set ++# CONFIG_INPUT_REGULATOR_HAPTIC is not set ++CONFIG_INPUT_UINPUT=y ++# CONFIG_INPUT_PCF8574 is not set ++# CONFIG_INPUT_PWM_BEEPER is not set ++CONFIG_INPUT_PWM_VIBRA=y ++CONFIG_INPUT_RK805_PWRKEY=y ++# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set ++# CONFIG_INPUT_DA7280_HAPTICS is not set ++# CONFIG_INPUT_ADXL34X is not set ++# CONFIG_INPUT_IMS_PCU is not set ++# CONFIG_INPUT_IQS269A is not set ++# CONFIG_INPUT_IQS626A is not set ++# CONFIG_INPUT_CMA3000 is not set ++# CONFIG_INPUT_DRV260X_HAPTICS is not set ++# CONFIG_INPUT_DRV2665_HAPTICS is not set ++# CONFIG_INPUT_DRV2667_HAPTICS is not set ++CONFIG_RMI4_CORE=y ++# CONFIG_RMI4_I2C is not set ++# CONFIG_RMI4_SPI is not set ++# CONFIG_RMI4_SMB is not set ++CONFIG_RMI4_F03=y ++CONFIG_RMI4_F03_SERIO=y ++CONFIG_RMI4_2D_SENSOR=y ++CONFIG_RMI4_F11=y ++CONFIG_RMI4_F12=y ++CONFIG_RMI4_F30=y ++# CONFIG_RMI4_F34 is not set ++# CONFIG_RMI4_F3A is not set ++# CONFIG_RMI4_F54 is not set ++# CONFIG_RMI4_F55 is not set ++ ++# ++# Hardware I/O ports ++# ++CONFIG_SERIO=y ++CONFIG_SERIO_SERPORT=m ++# CONFIG_SERIO_AMBAKMI is not set ++# CONFIG_SERIO_PCIPS2 is not set ++# CONFIG_SERIO_LIBPS2 is not set ++# CONFIG_SERIO_RAW is not set ++# CONFIG_SERIO_ALTERA_PS2 is not set ++# CONFIG_SERIO_PS2MULT is not set ++# CONFIG_SERIO_ARC_PS2 is not set ++# CONFIG_SERIO_APBPS2 is not set ++# CONFIG_SERIO_GPIO_PS2 is not set ++# CONFIG_USERIO is not set ++CONFIG_GAMEPORT=y ++# CONFIG_GAMEPORT_NS558 is not set ++# CONFIG_GAMEPORT_L4 is not set ++# CONFIG_GAMEPORT_EMU10K1 is not set ++# CONFIG_GAMEPORT_FM801 is not set ++# end of Hardware I/O ports ++# end of Input device support ++ ++# ++# Character devices ++# ++CONFIG_TTY=y ++CONFIG_VT=y ++# CONFIG_CONSOLE_TRANSLATIONS is not set ++CONFIG_VT_CONSOLE=y ++CONFIG_VT_CONSOLE_SLEEP=y ++CONFIG_HW_CONSOLE=y ++CONFIG_VT_HW_CONSOLE_BINDING=y ++CONFIG_UNIX98_PTYS=y ++# CONFIG_LEGACY_PTYS is not set ++CONFIG_LDISC_AUTOLOAD=y ++ ++# ++# Serial drivers ++# ++CONFIG_SERIAL_EARLYCON=y ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y ++CONFIG_SERIAL_8250_16550A_VARIANTS=y ++# CONFIG_SERIAL_8250_FINTEK is not set ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_DMA=y ++# CONFIG_SERIAL_8250_PCI is not set ++# CONFIG_SERIAL_8250_CS is not set ++CONFIG_SERIAL_8250_NR_UARTS=5 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=5 ++CONFIG_SERIAL_8250_EXTENDED=y ++# CONFIG_SERIAL_8250_MANY_PORTS is not set ++# CONFIG_SERIAL_8250_ASPEED_VUART is not set ++CONFIG_SERIAL_8250_SHARE_IRQ=y ++# CONFIG_SERIAL_8250_DETECT_IRQ is not set ++# CONFIG_SERIAL_8250_RSA is not set ++CONFIG_SERIAL_8250_DWLIB=y ++CONFIG_SERIAL_8250_FSL=y ++CONFIG_SERIAL_8250_DW=y ++# CONFIG_SERIAL_8250_RT288X is not set ++CONFIG_SERIAL_8250_PERICOM=y ++CONFIG_SERIAL_OF_PLATFORM=y ++ ++# ++# Non-8250 serial port support ++# ++# CONFIG_SERIAL_AMBA_PL010 is not set ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set ++# CONFIG_SERIAL_MAX3100 is not set ++# CONFIG_SERIAL_MAX310X is not set ++# CONFIG_SERIAL_UARTLITE is not set ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++# CONFIG_SERIAL_JSM is not set ++# CONFIG_SERIAL_SIFIVE is not set ++# CONFIG_SERIAL_SCCNXP is not set ++# CONFIG_SERIAL_SC16IS7XX is not set ++# CONFIG_SERIAL_ALTERA_JTAGUART is not set ++# CONFIG_SERIAL_ALTERA_UART is not set ++# CONFIG_SERIAL_XILINX_PS_UART is not set ++# CONFIG_SERIAL_ARC is not set ++# CONFIG_SERIAL_RP2 is not set ++# CONFIG_SERIAL_FSL_LPUART is not set ++# CONFIG_SERIAL_FSL_LINFLEXUART is not set ++# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set ++# CONFIG_SERIAL_SPRD is not set ++# end of Serial drivers ++ ++CONFIG_SERIAL_MCTRL_GPIO=y ++# CONFIG_SERIAL_NONSTANDARD is not set ++# CONFIG_N_GSM is not set ++# CONFIG_NOZOMI is not set ++# CONFIG_NULL_TTY is not set ++# CONFIG_HVC_DCC is not set ++CONFIG_SERIAL_DEV_BUS=y ++CONFIG_SERIAL_DEV_CTRL_TTYPORT=y ++# CONFIG_TTY_PRINTK is not set ++# CONFIG_VIRTIO_CONSOLE is not set ++# CONFIG_IPMI_HANDLER is not set ++CONFIG_HW_RANDOM=y ++# CONFIG_HW_RANDOM_TIMERIOMEM is not set ++# CONFIG_HW_RANDOM_BA431 is not set ++# CONFIG_HW_RANDOM_CCTRNG is not set ++# CONFIG_HW_RANDOM_XIPHERA is not set ++CONFIG_HW_RANDOM_ARM_SMCCC_TRNG=y ++CONFIG_HW_RANDOM_CN10K=y ++# CONFIG_APPLICOM is not set ++ ++# ++# PCMCIA character devices ++# ++# CONFIG_SYNCLINK_CS is not set ++# CONFIG_CARDMAN_4000 is not set ++# CONFIG_CARDMAN_4040 is not set ++# CONFIG_SCR24X is not set ++# CONFIG_IPWIRELESS is not set ++# end of PCMCIA character devices ++ ++CONFIG_DEVMEM=y ++CONFIG_DEVPORT=y ++CONFIG_TCG_TPM=y ++CONFIG_HW_RANDOM_TPM=y ++# CONFIG_TCG_TIS is not set ++# CONFIG_TCG_TIS_SPI is not set ++# CONFIG_TCG_TIS_I2C_CR50 is not set ++# CONFIG_TCG_TIS_I2C_ATMEL is not set ++CONFIG_TCG_TIS_I2C_INFINEON=y ++# CONFIG_TCG_TIS_I2C_NUVOTON is not set ++# CONFIG_TCG_ATMEL is not set ++# CONFIG_TCG_VTPM_PROXY is not set ++# CONFIG_TCG_TIS_ST33ZP24_I2C is not set ++# CONFIG_TCG_TIS_ST33ZP24_SPI is not set ++# CONFIG_XILLYBUS is not set ++# CONFIG_XILLYUSB is not set ++# CONFIG_RANDOM_TRUST_BOOTLOADER is not set ++# end of Character devices ++ ++# ++# I2C support ++# ++CONFIG_I2C=y ++CONFIG_I2C_BOARDINFO=y ++# CONFIG_I2C_COMPAT is not set ++CONFIG_I2C_CHARDEV=y ++CONFIG_I2C_MUX=y ++ ++# ++# Multiplexer I2C Chip support ++# ++# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set ++# CONFIG_I2C_MUX_GPIO is not set ++# CONFIG_I2C_MUX_GPMUX is not set ++# CONFIG_I2C_MUX_LTC4306 is not set ++# CONFIG_I2C_MUX_PCA9541 is not set ++# CONFIG_I2C_MUX_PCA954x is not set ++# CONFIG_I2C_MUX_PINCTRL is not set ++# CONFIG_I2C_MUX_REG is not set ++# CONFIG_I2C_DEMUX_PINCTRL is not set ++# CONFIG_I2C_MUX_MLXCPLD is not set ++# end of Multiplexer I2C Chip support ++ ++CONFIG_I2C_HELPER_AUTO=y ++CONFIG_I2C_ALGOBIT=y ++ ++# ++# I2C Hardware Bus support ++# ++ ++# ++# PC SMBus host controller drivers ++# ++# CONFIG_I2C_ALI1535 is not set ++# CONFIG_I2C_ALI1563 is not set ++# CONFIG_I2C_ALI15X3 is not set ++# CONFIG_I2C_AMD756 is not set ++# CONFIG_I2C_AMD8111 is not set ++# CONFIG_I2C_I801 is not set ++# CONFIG_I2C_ISCH is not set ++# CONFIG_I2C_PIIX4 is not set ++# CONFIG_I2C_NFORCE2 is not set ++# CONFIG_I2C_NVIDIA_GPU is not set ++# CONFIG_I2C_SIS5595 is not set ++# CONFIG_I2C_SIS630 is not set ++# CONFIG_I2C_SIS96X is not set ++# CONFIG_I2C_VIA is not set ++# CONFIG_I2C_VIAPRO is not set ++ ++# ++# I2C system bus drivers (mostly embedded / system-on-chip) ++# ++# CONFIG_I2C_CADENCE is not set ++# CONFIG_I2C_CBUS_GPIO is not set ++CONFIG_I2C_DESIGNWARE_CORE=y ++# CONFIG_I2C_DESIGNWARE_SLAVE is not set ++CONFIG_I2C_DESIGNWARE_PLATFORM=y ++# CONFIG_I2C_DESIGNWARE_PCI is not set ++# CONFIG_I2C_EMEV2 is not set ++# CONFIG_I2C_GPIO is not set ++# CONFIG_I2C_NOMADIK is not set ++# CONFIG_I2C_OCORES is not set ++# CONFIG_I2C_PCA_PLATFORM is not set ++CONFIG_I2C_RK3X=y ++# CONFIG_I2C_SIMTEC is not set ++# CONFIG_I2C_THUNDERX is not set ++# CONFIG_I2C_XILINX is not set ++ ++# ++# External I2C/SMBus adapter drivers ++# ++# CONFIG_I2C_DIOLAN_U2C is not set ++# CONFIG_I2C_CP2615 is not set ++# CONFIG_I2C_ROBOTFUZZ_OSIF is not set ++# CONFIG_I2C_TAOS_EVM is not set ++# CONFIG_I2C_TINY_USB is not set ++ ++# ++# Other I2C/SMBus bus drivers ++# ++# CONFIG_I2C_VIRTIO is not set ++# end of I2C Hardware Bus support ++ ++# CONFIG_I2C_STUB is not set ++# CONFIG_I2C_SLAVE is not set ++# CONFIG_I2C_DEBUG_CORE is not set ++# CONFIG_I2C_DEBUG_ALGO is not set ++# CONFIG_I2C_DEBUG_BUS is not set ++# end of I2C support ++ ++# CONFIG_I3C is not set ++CONFIG_SPI=y ++# CONFIG_SPI_DEBUG is not set ++CONFIG_SPI_MASTER=y ++# CONFIG_SPI_MEM is not set ++ ++# ++# SPI Master Controller Drivers ++# ++# CONFIG_SPI_ALTERA is not set ++# CONFIG_SPI_AXI_SPI_ENGINE is not set ++CONFIG_SPI_BITBANG=y ++# CONFIG_SPI_CADENCE is not set ++# CONFIG_SPI_CADENCE_QUADSPI is not set ++# CONFIG_SPI_DESIGNWARE is not set ++# CONFIG_SPI_NXP_FLEXSPI is not set ++# CONFIG_SPI_GPIO is not set ++# CONFIG_SPI_FSL_SPI is not set ++# CONFIG_SPI_OC_TINY is not set ++# CONFIG_SPI_PL022 is not set ++# CONFIG_SPI_PXA2XX is not set ++CONFIG_SPI_ROCKCHIP=y ++# CONFIG_SPI_ROCKCHIP_SFC is not set ++# CONFIG_SPI_SC18IS602 is not set ++# CONFIG_SPI_SIFIVE is not set ++# CONFIG_SPI_MXIC is not set ++# CONFIG_SPI_THUNDERX is not set ++# CONFIG_SPI_XCOMM is not set ++# CONFIG_SPI_XILINX is not set ++# CONFIG_SPI_ZYNQMP_GQSPI is not set ++# CONFIG_SPI_AMD is not set ++ ++# ++# SPI Multiplexer support ++# ++# CONFIG_SPI_MUX is not set ++ ++# ++# SPI Protocol Masters ++# ++CONFIG_SPI_SPIDEV=y ++# CONFIG_SPI_LOOPBACK_TEST is not set ++# CONFIG_SPI_TLE62X0 is not set ++# CONFIG_SPI_SLAVE is not set ++CONFIG_SPI_DYNAMIC=y ++# CONFIG_SPMI is not set ++# CONFIG_HSI is not set ++CONFIG_PPS=y ++# CONFIG_PPS_DEBUG is not set ++ ++# ++# PPS clients support ++# ++# CONFIG_PPS_CLIENT_KTIMER is not set ++# CONFIG_PPS_CLIENT_LDISC is not set ++# CONFIG_PPS_CLIENT_GPIO is not set ++ ++# ++# PPS generators support ++# ++ ++# ++# PTP clock support ++# ++CONFIG_PTP_1588_CLOCK=y ++CONFIG_PTP_1588_CLOCK_OPTIONAL=y ++ ++# ++# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. ++# ++CONFIG_PTP_1588_CLOCK_KVM=y ++# CONFIG_PTP_1588_CLOCK_IDT82P33 is not set ++# CONFIG_PTP_1588_CLOCK_IDTCM is not set ++# end of PTP clock support ++ ++CONFIG_PINCTRL=y ++CONFIG_GENERIC_PINCTRL_GROUPS=y ++CONFIG_PINMUX=y ++CONFIG_GENERIC_PINMUX_FUNCTIONS=y ++CONFIG_PINCONF=y ++CONFIG_GENERIC_PINCONF=y ++# CONFIG_DEBUG_PINCTRL is not set ++# CONFIG_PINCTRL_MCP23S08 is not set ++# CONFIG_PINCTRL_MICROCHIP_SGPIO is not set ++# CONFIG_PINCTRL_OCELOT is not set ++CONFIG_PINCTRL_RK805=y ++CONFIG_PINCTRL_ROCKCHIP=y ++CONFIG_PINCTRL_SINGLE=y ++# CONFIG_PINCTRL_STMFX is not set ++# CONFIG_PINCTRL_SX150X is not set ++ ++# ++# Renesas pinctrl drivers ++# ++# end of Renesas pinctrl drivers ++ ++CONFIG_GPIOLIB=y ++CONFIG_GPIOLIB_FASTPATH_LIMIT=512 ++CONFIG_OF_GPIO=y ++CONFIG_GPIOLIB_IRQCHIP=y ++CONFIG_DEBUG_GPIO=y ++CONFIG_GPIO_SYSFS=y ++CONFIG_GPIO_CDEV=y ++CONFIG_GPIO_CDEV_V1=y ++CONFIG_GPIO_GENERIC=y ++ ++# ++# Memory mapped GPIO drivers ++# ++# CONFIG_GPIO_74XX_MMIO is not set ++# CONFIG_GPIO_ALTERA is not set ++# CONFIG_GPIO_CADENCE is not set ++CONFIG_GPIO_DWAPB=y ++# CONFIG_GPIO_FTGPIO010 is not set ++CONFIG_GPIO_GENERIC_PLATFORM=y ++# CONFIG_GPIO_GRGPIO is not set ++# CONFIG_GPIO_HLWD is not set ++# CONFIG_GPIO_LOGICVC is not set ++# CONFIG_GPIO_MB86S7X is not set ++# CONFIG_GPIO_PL061 is not set ++CONFIG_GPIO_ROCKCHIP=y ++# CONFIG_GPIO_SAMA5D2_PIOBU is not set ++# CONFIG_GPIO_SIFIVE is not set ++# CONFIG_GPIO_SYSCON is not set ++# CONFIG_GPIO_XGENE is not set ++# CONFIG_GPIO_XILINX is not set ++# CONFIG_GPIO_AMD_FCH is not set ++# end of Memory mapped GPIO drivers ++ ++# ++# I2C GPIO expanders ++# ++# CONFIG_GPIO_ADP5588 is not set ++# CONFIG_GPIO_ADNP is not set ++# CONFIG_GPIO_GW_PLD is not set ++# CONFIG_GPIO_MAX7300 is not set ++# CONFIG_GPIO_MAX732X is not set ++# CONFIG_GPIO_PCA953X is not set ++# CONFIG_GPIO_PCA9570 is not set ++# CONFIG_GPIO_PCF857X is not set ++# CONFIG_GPIO_TPIC2810 is not set ++# end of I2C GPIO expanders ++ ++# ++# MFD GPIO expanders ++# ++# CONFIG_GPIO_TPS6586X is not set ++# end of MFD GPIO expanders ++ ++# ++# PCI GPIO expanders ++# ++# CONFIG_GPIO_BT8XX is not set ++# CONFIG_GPIO_PCI_IDIO_16 is not set ++# CONFIG_GPIO_PCIE_IDIO_24 is not set ++# CONFIG_GPIO_RDC321X is not set ++# end of PCI GPIO expanders ++ ++# ++# SPI GPIO expanders ++# ++# CONFIG_GPIO_74X164 is not set ++# CONFIG_GPIO_MAX3191X is not set ++# CONFIG_GPIO_MAX7301 is not set ++# CONFIG_GPIO_MC33880 is not set ++# CONFIG_GPIO_PISOSR is not set ++# CONFIG_GPIO_XRA1403 is not set ++# end of SPI GPIO expanders ++ ++# ++# USB GPIO expanders ++# ++# end of USB GPIO expanders ++ ++# ++# Virtual GPIO drivers ++# ++# CONFIG_GPIO_AGGREGATOR is not set ++# CONFIG_GPIO_MOCKUP is not set ++# CONFIG_GPIO_SIM is not set ++# end of Virtual GPIO drivers ++ ++# CONFIG_W1 is not set ++CONFIG_POWER_RESET=y ++# CONFIG_POWER_RESET_BRCMSTB is not set ++CONFIG_POWER_RESET_GPIO=y ++CONFIG_POWER_RESET_GPIO_RESTART=y ++# CONFIG_POWER_RESET_LTC2952 is not set ++# CONFIG_POWER_RESET_REGULATOR is not set ++# CONFIG_POWER_RESET_RESTART is not set ++# CONFIG_POWER_RESET_XGENE is not set ++CONFIG_POWER_RESET_SYSCON=y ++CONFIG_POWER_RESET_SYSCON_POWEROFF=y ++CONFIG_REBOOT_MODE=y ++CONFIG_SYSCON_REBOOT_MODE=y ++# CONFIG_NVMEM_REBOOT_MODE is not set ++CONFIG_POWER_SUPPLY=y ++# CONFIG_POWER_SUPPLY_DEBUG is not set ++CONFIG_POWER_SUPPLY_HWMON=y ++# CONFIG_PDA_POWER is not set ++# CONFIG_GENERIC_ADC_BATTERY is not set ++# CONFIG_IP5XXX_POWER is not set ++# CONFIG_TEST_POWER is not set ++# CONFIG_CHARGER_ADP5061 is not set ++CONFIG_BATTERY_CW2015=y ++# CONFIG_BATTERY_DS2780 is not set ++# CONFIG_BATTERY_DS2781 is not set ++# CONFIG_BATTERY_DS2782 is not set ++# CONFIG_BATTERY_SAMSUNG_SDI is not set ++CONFIG_BATTERY_SBS=y ++# CONFIG_CHARGER_SBS is not set ++# CONFIG_MANAGER_SBS is not set ++# CONFIG_BATTERY_BQ27XXX is not set ++# CONFIG_BATTERY_MAX17040 is not set ++# CONFIG_BATTERY_MAX17042 is not set ++# CONFIG_CHARGER_ISP1704 is not set ++# CONFIG_CHARGER_MAX8903 is not set ++# CONFIG_CHARGER_LP8727 is not set ++CONFIG_CHARGER_GPIO=y ++# CONFIG_CHARGER_MANAGER is not set ++# CONFIG_CHARGER_LT3651 is not set ++# CONFIG_CHARGER_LTC4162L is not set ++# CONFIG_CHARGER_DETECTOR_MAX14656 is not set ++# CONFIG_CHARGER_MAX77976 is not set ++# CONFIG_CHARGER_BQ2415X is not set ++# CONFIG_CHARGER_BQ24190 is not set ++# CONFIG_CHARGER_BQ24257 is not set ++CONFIG_CHARGER_BQ24735=y ++# CONFIG_CHARGER_BQ2515X is not set ++# CONFIG_CHARGER_BQ25890 is not set ++# CONFIG_CHARGER_BQ25980 is not set ++# CONFIG_CHARGER_BQ256XX is not set ++CONFIG_CHARGER_RK817=y ++# CONFIG_CHARGER_SMB347 is not set ++# CONFIG_BATTERY_GAUGE_LTC2941 is not set ++# CONFIG_BATTERY_GOLDFISH is not set ++# CONFIG_BATTERY_RT5033 is not set ++# CONFIG_CHARGER_RT9455 is not set ++# CONFIG_CHARGER_UCS1002 is not set ++# CONFIG_CHARGER_BD99954 is not set ++# CONFIG_BATTERY_UG3105 is not set ++CONFIG_HWMON=y ++# CONFIG_HWMON_DEBUG_CHIP is not set ++ ++# ++# Native drivers ++# ++# CONFIG_SENSORS_AD7314 is not set ++# CONFIG_SENSORS_AD7414 is not set ++# CONFIG_SENSORS_AD7418 is not set ++# CONFIG_SENSORS_ADM1021 is not set ++# CONFIG_SENSORS_ADM1025 is not set ++# CONFIG_SENSORS_ADM1026 is not set ++# CONFIG_SENSORS_ADM1029 is not set ++# CONFIG_SENSORS_ADM1031 is not set ++# CONFIG_SENSORS_ADM1177 is not set ++# CONFIG_SENSORS_ADM9240 is not set ++# CONFIG_SENSORS_ADT7310 is not set ++# CONFIG_SENSORS_ADT7410 is not set ++# CONFIG_SENSORS_ADT7411 is not set ++# CONFIG_SENSORS_ADT7462 is not set ++# CONFIG_SENSORS_ADT7470 is not set ++# CONFIG_SENSORS_ADT7475 is not set ++# CONFIG_SENSORS_AHT10 is not set ++# CONFIG_SENSORS_AQUACOMPUTER_D5NEXT is not set ++# CONFIG_SENSORS_AS370 is not set ++# CONFIG_SENSORS_ASC7621 is not set ++# CONFIG_SENSORS_AXI_FAN_CONTROL is not set ++# CONFIG_SENSORS_ARM_SCMI is not set ++# CONFIG_SENSORS_ARM_SCPI is not set ++# CONFIG_SENSORS_ASPEED is not set ++# CONFIG_SENSORS_ATXP1 is not set ++# CONFIG_SENSORS_CORSAIR_CPRO is not set ++# CONFIG_SENSORS_CORSAIR_PSU is not set ++# CONFIG_SENSORS_DRIVETEMP is not set ++# CONFIG_SENSORS_DS620 is not set ++# CONFIG_SENSORS_DS1621 is not set ++# CONFIG_SENSORS_I5K_AMB is not set ++# CONFIG_SENSORS_F71805F is not set ++# CONFIG_SENSORS_F71882FG is not set ++# CONFIG_SENSORS_F75375S is not set ++# CONFIG_SENSORS_FTSTEUTATES is not set ++# CONFIG_SENSORS_GL518SM is not set ++# CONFIG_SENSORS_GL520SM is not set ++# CONFIG_SENSORS_G760A is not set ++# CONFIG_SENSORS_G762 is not set ++# CONFIG_SENSORS_GPIO_FAN is not set ++# CONFIG_SENSORS_HIH6130 is not set ++# CONFIG_SENSORS_IIO_HWMON is not set ++# CONFIG_SENSORS_IT87 is not set ++# CONFIG_SENSORS_JC42 is not set ++# CONFIG_SENSORS_POWR1220 is not set ++# CONFIG_SENSORS_LINEAGE is not set ++# CONFIG_SENSORS_LTC2945 is not set ++# CONFIG_SENSORS_LTC2947_I2C is not set ++# CONFIG_SENSORS_LTC2947_SPI is not set ++# CONFIG_SENSORS_LTC2990 is not set ++# CONFIG_SENSORS_LTC2992 is not set ++# CONFIG_SENSORS_LTC4151 is not set ++# CONFIG_SENSORS_LTC4215 is not set ++# CONFIG_SENSORS_LTC4222 is not set ++# CONFIG_SENSORS_LTC4245 is not set ++# CONFIG_SENSORS_LTC4260 is not set ++# CONFIG_SENSORS_LTC4261 is not set ++# CONFIG_SENSORS_MAX1111 is not set ++# CONFIG_SENSORS_MAX127 is not set ++# CONFIG_SENSORS_MAX16065 is not set ++# CONFIG_SENSORS_MAX1619 is not set ++# CONFIG_SENSORS_MAX1668 is not set ++# CONFIG_SENSORS_MAX197 is not set ++# CONFIG_SENSORS_MAX31722 is not set ++# CONFIG_SENSORS_MAX31730 is not set ++# CONFIG_SENSORS_MAX6620 is not set ++# CONFIG_SENSORS_MAX6621 is not set ++# CONFIG_SENSORS_MAX6639 is not set ++# CONFIG_SENSORS_MAX6642 is not set ++# CONFIG_SENSORS_MAX6650 is not set ++# CONFIG_SENSORS_MAX6697 is not set ++# CONFIG_SENSORS_MAX31790 is not set ++# CONFIG_SENSORS_MCP3021 is not set ++# CONFIG_SENSORS_TC654 is not set ++# CONFIG_SENSORS_TPS23861 is not set ++# CONFIG_SENSORS_MR75203 is not set ++# CONFIG_SENSORS_ADCXX is not set ++# CONFIG_SENSORS_LM63 is not set ++# CONFIG_SENSORS_LM70 is not set ++# CONFIG_SENSORS_LM73 is not set ++# CONFIG_SENSORS_LM75 is not set ++# CONFIG_SENSORS_LM77 is not set ++# CONFIG_SENSORS_LM78 is not set ++# CONFIG_SENSORS_LM80 is not set ++# CONFIG_SENSORS_LM83 is not set ++# CONFIG_SENSORS_LM85 is not set ++# CONFIG_SENSORS_LM87 is not set ++# CONFIG_SENSORS_LM90 is not set ++# CONFIG_SENSORS_LM92 is not set ++# CONFIG_SENSORS_LM93 is not set ++# CONFIG_SENSORS_LM95234 is not set ++# CONFIG_SENSORS_LM95241 is not set ++# CONFIG_SENSORS_LM95245 is not set ++# CONFIG_SENSORS_PC87360 is not set ++# CONFIG_SENSORS_PC87427 is not set ++# CONFIG_SENSORS_NTC_THERMISTOR is not set ++# CONFIG_SENSORS_NCT6683 is not set ++# CONFIG_SENSORS_NCT6775 is not set ++# CONFIG_SENSORS_NCT7802 is not set ++# CONFIG_SENSORS_NCT7904 is not set ++# CONFIG_SENSORS_NPCM7XX is not set ++# CONFIG_SENSORS_NZXT_KRAKEN2 is not set ++# CONFIG_SENSORS_NZXT_SMART2 is not set ++# CONFIG_SENSORS_OCC_P8_I2C is not set ++# CONFIG_SENSORS_PCF8591 is not set ++# CONFIG_PMBUS is not set ++CONFIG_SENSORS_PWM_FAN=y ++# CONFIG_SENSORS_SBTSI is not set ++# CONFIG_SENSORS_SBRMI is not set ++# CONFIG_SENSORS_SHT15 is not set ++# CONFIG_SENSORS_SHT21 is not set ++# CONFIG_SENSORS_SHT3x is not set ++# CONFIG_SENSORS_SHT4x is not set ++# CONFIG_SENSORS_SHTC1 is not set ++# CONFIG_SENSORS_SIS5595 is not set ++# CONFIG_SENSORS_SY7636A is not set ++# CONFIG_SENSORS_DME1737 is not set ++# CONFIG_SENSORS_EMC1403 is not set ++# CONFIG_SENSORS_EMC2103 is not set ++# CONFIG_SENSORS_EMC6W201 is not set ++# CONFIG_SENSORS_SMSC47M1 is not set ++# CONFIG_SENSORS_SMSC47M192 is not set ++# CONFIG_SENSORS_SMSC47B397 is not set ++# CONFIG_SENSORS_SCH5627 is not set ++# CONFIG_SENSORS_SCH5636 is not set ++# CONFIG_SENSORS_STTS751 is not set ++# CONFIG_SENSORS_SMM665 is not set ++# CONFIG_SENSORS_ADC128D818 is not set ++# CONFIG_SENSORS_ADS7828 is not set ++# CONFIG_SENSORS_ADS7871 is not set ++# CONFIG_SENSORS_AMC6821 is not set ++# CONFIG_SENSORS_INA209 is not set ++# CONFIG_SENSORS_INA2XX is not set ++# CONFIG_SENSORS_INA238 is not set ++# CONFIG_SENSORS_INA3221 is not set ++# CONFIG_SENSORS_TC74 is not set ++# CONFIG_SENSORS_THMC50 is not set ++# CONFIG_SENSORS_TMP102 is not set ++# CONFIG_SENSORS_TMP103 is not set ++# CONFIG_SENSORS_TMP108 is not set ++# CONFIG_SENSORS_TMP401 is not set ++# CONFIG_SENSORS_TMP421 is not set ++# CONFIG_SENSORS_TMP464 is not set ++# CONFIG_SENSORS_TMP513 is not set ++# CONFIG_SENSORS_VIA686A is not set ++# CONFIG_SENSORS_VT1211 is not set ++# CONFIG_SENSORS_VT8231 is not set ++# CONFIG_SENSORS_W83773G is not set ++# CONFIG_SENSORS_W83781D is not set ++# CONFIG_SENSORS_W83791D is not set ++# CONFIG_SENSORS_W83792D is not set ++# CONFIG_SENSORS_W83793 is not set ++# CONFIG_SENSORS_W83795 is not set ++# CONFIG_SENSORS_W83L785TS is not set ++# CONFIG_SENSORS_W83L786NG is not set ++# CONFIG_SENSORS_W83627HF is not set ++# CONFIG_SENSORS_W83627EHF is not set ++CONFIG_THERMAL=y ++# CONFIG_THERMAL_NETLINK is not set ++# CONFIG_THERMAL_STATISTICS is not set ++CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 ++CONFIG_THERMAL_HWMON=y ++CONFIG_THERMAL_OF=y ++CONFIG_THERMAL_WRITABLE_TRIPS=y ++# CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE is not set ++# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set ++# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set ++CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR=y ++CONFIG_THERMAL_GOV_FAIR_SHARE=y ++CONFIG_THERMAL_GOV_STEP_WISE=y ++# CONFIG_THERMAL_GOV_BANG_BANG is not set ++# CONFIG_THERMAL_GOV_USER_SPACE is not set ++CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y ++CONFIG_CPU_THERMAL=y ++CONFIG_CPU_FREQ_THERMAL=y ++CONFIG_DEVFREQ_THERMAL=y ++# CONFIG_THERMAL_EMULATION is not set ++# CONFIG_THERMAL_MMIO is not set ++CONFIG_ROCKCHIP_THERMAL=y ++# CONFIG_GENERIC_ADC_THERMAL is not set ++CONFIG_WATCHDOG=y ++CONFIG_WATCHDOG_CORE=y ++# CONFIG_WATCHDOG_NOWAYOUT is not set ++CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y ++CONFIG_WATCHDOG_OPEN_TIMEOUT=0 ++# CONFIG_WATCHDOG_SYSFS is not set ++# CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT is not set ++ ++# ++# Watchdog Pretimeout Governors ++# ++# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set ++ ++# ++# Watchdog Device Drivers ++# ++# CONFIG_SOFT_WATCHDOG is not set ++# CONFIG_GPIO_WATCHDOG is not set ++# CONFIG_XILINX_WATCHDOG is not set ++# CONFIG_ZIIRAVE_WATCHDOG is not set ++# CONFIG_ARM_SP805_WATCHDOG is not set ++# CONFIG_ARM_SBSA_WATCHDOG is not set ++# CONFIG_CADENCE_WATCHDOG is not set ++CONFIG_DW_WATCHDOG=y ++# CONFIG_MAX63XX_WATCHDOG is not set ++# CONFIG_ARM_SMC_WATCHDOG is not set ++# CONFIG_ALIM7101_WDT is not set ++# CONFIG_I6300ESB_WDT is not set ++# CONFIG_MEN_A21_WDT is not set ++ ++# ++# PCI-based Watchdog Cards ++# ++# CONFIG_PCIPCWATCHDOG is not set ++# CONFIG_WDTPCI is not set ++ ++# ++# USB-based Watchdog Cards ++# ++# CONFIG_USBPCWATCHDOG is not set ++CONFIG_SSB_POSSIBLE=y ++CONFIG_SSB=y ++CONFIG_SSB_SPROM=y ++CONFIG_SSB_BLOCKIO=y ++CONFIG_SSB_PCIHOST_POSSIBLE=y ++CONFIG_SSB_PCIHOST=y ++CONFIG_SSB_B43_PCI_BRIDGE=y ++CONFIG_SSB_PCMCIAHOST_POSSIBLE=y ++# CONFIG_SSB_PCMCIAHOST is not set ++CONFIG_SSB_SDIOHOST_POSSIBLE=y ++# CONFIG_SSB_SDIOHOST is not set ++CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y ++CONFIG_SSB_DRIVER_PCICORE=y ++# CONFIG_SSB_DRIVER_GPIO is not set ++CONFIG_BCMA_POSSIBLE=y ++CONFIG_BCMA=y ++CONFIG_BCMA_BLOCKIO=y ++CONFIG_BCMA_HOST_PCI_POSSIBLE=y ++CONFIG_BCMA_HOST_PCI=y ++# CONFIG_BCMA_HOST_SOC is not set ++CONFIG_BCMA_DRIVER_PCI=y ++# CONFIG_BCMA_DRIVER_GMAC_CMN is not set ++# CONFIG_BCMA_DRIVER_GPIO is not set ++# CONFIG_BCMA_DEBUG is not set ++ ++# ++# Multifunction device drivers ++# ++CONFIG_MFD_CORE=y ++# CONFIG_MFD_ACT8945A is not set ++# CONFIG_MFD_AS3711 is not set ++# CONFIG_MFD_AS3722 is not set ++# CONFIG_PMIC_ADP5520 is not set ++# CONFIG_MFD_AAT2870_CORE is not set ++# CONFIG_MFD_ATMEL_FLEXCOM is not set ++# CONFIG_MFD_ATMEL_HLCDC is not set ++# CONFIG_MFD_BCM590XX is not set ++# CONFIG_MFD_BD9571MWV is not set ++# CONFIG_MFD_AXP20X_I2C is not set ++# CONFIG_MFD_MADERA is not set ++# CONFIG_PMIC_DA903X is not set ++# CONFIG_MFD_DA9052_SPI is not set ++# CONFIG_MFD_DA9052_I2C is not set ++# CONFIG_MFD_DA9055 is not set ++# CONFIG_MFD_DA9062 is not set ++# CONFIG_MFD_DA9063 is not set ++# CONFIG_MFD_DA9150 is not set ++# CONFIG_MFD_DLN2 is not set ++# CONFIG_MFD_GATEWORKS_GSC is not set ++# CONFIG_MFD_MC13XXX_SPI is not set ++# CONFIG_MFD_MC13XXX_I2C is not set ++# CONFIG_MFD_MP2629 is not set ++# CONFIG_MFD_HI6421_PMIC is not set ++# CONFIG_HTC_PASIC3 is not set ++# CONFIG_HTC_I2CPLD is not set ++# CONFIG_LPC_ICH is not set ++# CONFIG_LPC_SCH is not set ++# CONFIG_MFD_IQS62X is not set ++# CONFIG_MFD_JANZ_CMODIO is not set ++# CONFIG_MFD_KEMPLD is not set ++# CONFIG_MFD_88PM800 is not set ++# CONFIG_MFD_88PM805 is not set ++# CONFIG_MFD_88PM860X is not set ++# CONFIG_MFD_MAX14577 is not set ++# CONFIG_MFD_MAX77620 is not set ++# CONFIG_MFD_MAX77650 is not set ++# CONFIG_MFD_MAX77686 is not set ++# CONFIG_MFD_MAX77693 is not set ++# CONFIG_MFD_MAX77714 is not set ++# CONFIG_MFD_MAX77843 is not set ++# CONFIG_MFD_MAX8907 is not set ++# CONFIG_MFD_MAX8925 is not set ++# CONFIG_MFD_MAX8997 is not set ++# CONFIG_MFD_MAX8998 is not set ++# CONFIG_MFD_MT6360 is not set ++# CONFIG_MFD_MT6397 is not set ++# CONFIG_MFD_MENF21BMC is not set ++# CONFIG_EZX_PCAP is not set ++# CONFIG_MFD_CPCAP is not set ++# CONFIG_MFD_VIPERBOARD is not set ++# CONFIG_MFD_NTXEC is not set ++# CONFIG_MFD_RETU is not set ++# CONFIG_MFD_PCF50633 is not set ++# CONFIG_MFD_RDC321X is not set ++# CONFIG_MFD_RT4831 is not set ++# CONFIG_MFD_RT5033 is not set ++# CONFIG_MFD_RC5T583 is not set ++CONFIG_MFD_RK808=y ++# CONFIG_MFD_RN5T618 is not set ++# CONFIG_MFD_SEC_CORE is not set ++# CONFIG_MFD_SI476X_CORE is not set ++# CONFIG_MFD_SIMPLE_MFD_I2C is not set ++# CONFIG_MFD_SM501 is not set ++# CONFIG_MFD_SKY81452 is not set ++# CONFIG_MFD_STMPE is not set ++CONFIG_MFD_SYSCON=y ++# CONFIG_MFD_TI_AM335X_TSCADC is not set ++# CONFIG_MFD_LP3943 is not set ++# CONFIG_MFD_LP8788 is not set ++# CONFIG_MFD_TI_LMU is not set ++# CONFIG_MFD_PALMAS is not set ++# CONFIG_TPS6105X is not set ++# CONFIG_TPS65010 is not set ++# CONFIG_TPS6507X is not set ++# CONFIG_MFD_TPS65086 is not set ++# CONFIG_MFD_TPS65090 is not set ++# CONFIG_MFD_TPS65217 is not set ++# CONFIG_MFD_TI_LP873X is not set ++# CONFIG_MFD_TI_LP87565 is not set ++# CONFIG_MFD_TPS65218 is not set ++CONFIG_MFD_TPS6586X=y ++# CONFIG_MFD_TPS65910 is not set ++# CONFIG_MFD_TPS65912_I2C is not set ++# CONFIG_MFD_TPS65912_SPI is not set ++# CONFIG_TWL4030_CORE is not set ++# CONFIG_TWL6040_CORE is not set ++# CONFIG_MFD_WL1273_CORE is not set ++# CONFIG_MFD_LM3533 is not set ++# CONFIG_MFD_TC3589X is not set ++# CONFIG_MFD_TQMX86 is not set ++# CONFIG_MFD_VX855 is not set ++# CONFIG_MFD_LOCHNAGAR is not set ++# CONFIG_MFD_ARIZONA_I2C is not set ++# CONFIG_MFD_ARIZONA_SPI is not set ++# CONFIG_MFD_WM8400 is not set ++# CONFIG_MFD_WM831X_I2C is not set ++# CONFIG_MFD_WM831X_SPI is not set ++# CONFIG_MFD_WM8350_I2C is not set ++# CONFIG_MFD_WM8994 is not set ++# CONFIG_MFD_ROHM_BD718XX is not set ++# CONFIG_MFD_ROHM_BD71828 is not set ++# CONFIG_MFD_ROHM_BD957XMUF is not set ++# CONFIG_MFD_STPMIC1 is not set ++# CONFIG_MFD_STMFX is not set ++# CONFIG_MFD_ATC260X_I2C is not set ++# CONFIG_MFD_KHADAS_MCU is not set ++# CONFIG_MFD_QCOM_PM8008 is not set ++# CONFIG_RAVE_SP_CORE is not set ++# CONFIG_MFD_INTEL_M10_BMC is not set ++# CONFIG_MFD_RSMU_I2C is not set ++# CONFIG_MFD_RSMU_SPI is not set ++# end of Multifunction device drivers ++ ++CONFIG_REGULATOR=y ++CONFIG_REGULATOR_DEBUG=y ++CONFIG_REGULATOR_FIXED_VOLTAGE=y ++# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set ++# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set ++# CONFIG_REGULATOR_88PG86X is not set ++CONFIG_REGULATOR_ACT8865=y ++# CONFIG_REGULATOR_AD5398 is not set ++# CONFIG_REGULATOR_ARM_SCMI is not set ++# CONFIG_REGULATOR_DA9121 is not set ++# CONFIG_REGULATOR_DA9210 is not set ++# CONFIG_REGULATOR_DA9211 is not set ++CONFIG_REGULATOR_FAN53555=y ++# CONFIG_REGULATOR_FAN53880 is not set ++CONFIG_REGULATOR_GPIO=y ++# CONFIG_REGULATOR_ISL9305 is not set ++# CONFIG_REGULATOR_ISL6271A is not set ++# CONFIG_REGULATOR_LP3971 is not set ++# CONFIG_REGULATOR_LP3972 is not set ++# CONFIG_REGULATOR_LP872X is not set ++# CONFIG_REGULATOR_LP8755 is not set ++# CONFIG_REGULATOR_LTC3589 is not set ++# CONFIG_REGULATOR_LTC3676 is not set ++# CONFIG_REGULATOR_MAX1586 is not set ++# CONFIG_REGULATOR_MAX8649 is not set ++# CONFIG_REGULATOR_MAX8660 is not set ++# CONFIG_REGULATOR_MAX8893 is not set ++# CONFIG_REGULATOR_MAX8952 is not set ++# CONFIG_REGULATOR_MAX8973 is not set ++# CONFIG_REGULATOR_MAX20086 is not set ++# CONFIG_REGULATOR_MAX77826 is not set ++# CONFIG_REGULATOR_MCP16502 is not set ++# CONFIG_REGULATOR_MP5416 is not set ++# CONFIG_REGULATOR_MP8859 is not set ++# CONFIG_REGULATOR_MP886X is not set ++# CONFIG_REGULATOR_MPQ7920 is not set ++# CONFIG_REGULATOR_MT6311 is not set ++# CONFIG_REGULATOR_PCA9450 is not set ++# CONFIG_REGULATOR_PF8X00 is not set ++# CONFIG_REGULATOR_PFUZE100 is not set ++# CONFIG_REGULATOR_PV88060 is not set ++# CONFIG_REGULATOR_PV88080 is not set ++# CONFIG_REGULATOR_PV88090 is not set ++CONFIG_REGULATOR_PWM=y ++# CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY is not set ++CONFIG_REGULATOR_RK808=y ++# CONFIG_REGULATOR_RT4801 is not set ++# CONFIG_REGULATOR_RT5190A is not set ++# CONFIG_REGULATOR_RT6160 is not set ++# CONFIG_REGULATOR_RT6245 is not set ++# CONFIG_REGULATOR_RTQ2134 is not set ++# CONFIG_REGULATOR_RTMV20 is not set ++# CONFIG_REGULATOR_RTQ6752 is not set ++# CONFIG_REGULATOR_SLG51000 is not set ++# CONFIG_REGULATOR_SY7636A is not set ++# CONFIG_REGULATOR_SY8106A is not set ++# CONFIG_REGULATOR_SY8824X is not set ++# CONFIG_REGULATOR_SY8827N is not set ++# CONFIG_REGULATOR_TPS51632 is not set ++# CONFIG_REGULATOR_TPS62360 is not set ++# CONFIG_REGULATOR_TPS6286X is not set ++# CONFIG_REGULATOR_TPS65023 is not set ++# CONFIG_REGULATOR_TPS6507X is not set ++# CONFIG_REGULATOR_TPS65132 is not set ++# CONFIG_REGULATOR_TPS6524X is not set ++CONFIG_REGULATOR_TPS6586X=y ++CONFIG_REGULATOR_VCTRL=y ++CONFIG_RC_CORE=y ++CONFIG_LIRC=y ++CONFIG_RC_MAP=y ++CONFIG_RC_DECODERS=y ++# CONFIG_IR_IMON_DECODER is not set ++CONFIG_IR_JVC_DECODER=y ++CONFIG_IR_MCE_KBD_DECODER=y ++CONFIG_IR_NEC_DECODER=y ++CONFIG_IR_RC5_DECODER=y ++CONFIG_IR_RC6_DECODER=y ++# CONFIG_IR_RCMM_DECODER is not set ++CONFIG_IR_SANYO_DECODER=y ++CONFIG_IR_SHARP_DECODER=y ++CONFIG_IR_SONY_DECODER=y ++CONFIG_IR_XMP_DECODER=y ++CONFIG_RC_DEVICES=y ++CONFIG_IR_GPIO_CIR=y ++# CONFIG_IR_GPIO_TX is not set ++# CONFIG_IR_HIX5HD2 is not set ++# CONFIG_IR_IGORPLUGUSB is not set ++# CONFIG_IR_IGUANA is not set ++# CONFIG_IR_IMON is not set ++# CONFIG_IR_IMON_RAW is not set ++# CONFIG_IR_MCEUSB is not set ++# CONFIG_IR_PWM_TX is not set ++# CONFIG_IR_REDRAT3 is not set ++# CONFIG_IR_SERIAL is not set ++# CONFIG_IR_SPI is not set ++# CONFIG_IR_STREAMZAP is not set ++# CONFIG_IR_TOY is not set ++# CONFIG_IR_TTUSBIR is not set ++# CONFIG_RC_ATI_REMOTE is not set ++# CONFIG_RC_LOOPBACK is not set ++# CONFIG_RC_XBOX_DVD is not set ++CONFIG_CEC_CORE=y ++CONFIG_CEC_NOTIFIER=y ++ ++# ++# CEC support ++# ++CONFIG_MEDIA_CEC_RC=y ++CONFIG_MEDIA_CEC_SUPPORT=y ++# CONFIG_CEC_CH7322 is not set ++# CONFIG_CEC_GPIO is not set ++CONFIG_USB_PULSE8_CEC=m ++CONFIG_USB_RAINSHADOW_CEC=m ++# end of CEC support ++ ++CONFIG_MEDIA_SUPPORT=y ++# CONFIG_MEDIA_SUPPORT_FILTER is not set ++# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set ++ ++# ++# Media device types ++# ++CONFIG_MEDIA_CAMERA_SUPPORT=y ++CONFIG_MEDIA_ANALOG_TV_SUPPORT=y ++CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y ++CONFIG_MEDIA_RADIO_SUPPORT=y ++CONFIG_MEDIA_SDR_SUPPORT=y ++CONFIG_MEDIA_PLATFORM_SUPPORT=y ++CONFIG_MEDIA_TEST_SUPPORT=y ++# end of Media device types ++ ++# ++# Media core support ++# ++CONFIG_VIDEO_DEV=y ++CONFIG_MEDIA_CONTROLLER=y ++CONFIG_DVB_CORE=y ++# end of Media core support ++ ++# ++# Video4Linux options ++# ++CONFIG_VIDEO_V4L2_I2C=y ++CONFIG_VIDEO_V4L2_SUBDEV_API=y ++# CONFIG_VIDEO_ADV_DEBUG is not set ++# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set ++CONFIG_VIDEO_TUNER=m ++CONFIG_V4L2_FWNODE=y ++CONFIG_V4L2_ASYNC=y ++CONFIG_VIDEOBUF_GEN=m ++CONFIG_VIDEOBUF_VMALLOC=m ++# end of Video4Linux options ++ ++# ++# Media controller options ++# ++CONFIG_MEDIA_CONTROLLER_DVB=y ++# end of Media controller options ++ ++# ++# Digital TV options ++# ++# CONFIG_DVB_MMAP is not set ++CONFIG_DVB_NET=y ++CONFIG_DVB_MAX_ADAPTERS=8 ++# CONFIG_DVB_DYNAMIC_MINORS is not set ++# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set ++# CONFIG_DVB_ULE_DEBUG is not set ++# end of Digital TV options ++ ++# ++# Media drivers ++# ++ ++# ++# Media drivers ++# ++CONFIG_MEDIA_USB_SUPPORT=y ++ ++# ++# Webcam devices ++# ++# CONFIG_VIDEO_CPIA2 is not set ++# CONFIG_USB_GSPCA is not set ++# CONFIG_USB_PWC is not set ++# CONFIG_USB_S2255 is not set ++# CONFIG_USB_STKWEBCAM is not set ++CONFIG_VIDEO_USBTV=m ++CONFIG_USB_VIDEO_CLASS=y ++# CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV is not set ++# CONFIG_USB_ZR364XX is not set ++ ++# ++# Analog TV USB devices ++# ++# CONFIG_VIDEO_GO7007 is not set ++# CONFIG_VIDEO_HDPVR is not set ++# CONFIG_VIDEO_PVRUSB2 is not set ++# CONFIG_VIDEO_STK1160_COMMON is not set ++ ++# ++# Analog/digital TV USB devices ++# ++CONFIG_VIDEO_AU0828=m ++CONFIG_VIDEO_AU0828_V4L2=y ++# CONFIG_VIDEO_AU0828_RC is not set ++CONFIG_VIDEO_CX231XX=m ++CONFIG_VIDEO_CX231XX_RC=y ++CONFIG_VIDEO_CX231XX_ALSA=m ++CONFIG_VIDEO_CX231XX_DVB=m ++CONFIG_VIDEO_TM6000=m ++CONFIG_VIDEO_TM6000_ALSA=m ++CONFIG_VIDEO_TM6000_DVB=m ++ ++# ++# Digital TV USB devices ++# ++CONFIG_DVB_AS102=m ++CONFIG_DVB_B2C2_FLEXCOP_USB=m ++# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set ++CONFIG_DVB_USB_V2=m ++CONFIG_DVB_USB_AF9015=m ++CONFIG_DVB_USB_AF9035=m ++CONFIG_DVB_USB_ANYSEE=m ++CONFIG_DVB_USB_AU6610=m ++CONFIG_DVB_USB_AZ6007=m ++CONFIG_DVB_USB_CE6230=m ++CONFIG_DVB_USB_DVBSKY=m ++CONFIG_DVB_USB_EC168=m ++CONFIG_DVB_USB_GL861=m ++CONFIG_DVB_USB_LME2510=m ++CONFIG_DVB_USB_MXL111SF=m ++CONFIG_DVB_USB_RTL28XXU=m ++# CONFIG_DVB_USB_ZD1301 is not set ++CONFIG_DVB_USB=y ++# CONFIG_DVB_USB_DEBUG is not set ++CONFIG_DVB_USB_A800=m ++CONFIG_DVB_USB_AF9005=m ++CONFIG_DVB_USB_AF9005_REMOTE=m ++CONFIG_DVB_USB_AZ6027=m ++CONFIG_DVB_USB_CINERGY_T2=m ++CONFIG_DVB_USB_CXUSB=m ++# CONFIG_DVB_USB_CXUSB_ANALOG is not set ++CONFIG_DVB_USB_DIB0700=m ++CONFIG_DVB_USB_DIB3000MC=m ++CONFIG_DVB_USB_DIBUSB_MB=m ++# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set ++CONFIG_DVB_USB_DIBUSB_MC=m ++CONFIG_DVB_USB_DIGITV=m ++CONFIG_DVB_USB_DTT200U=m ++CONFIG_DVB_USB_DTV5100=m ++CONFIG_DVB_USB_DW2102=m ++CONFIG_DVB_USB_GP8PSK=m ++CONFIG_DVB_USB_M920X=m ++CONFIG_DVB_USB_NOVA_T_USB2=m ++CONFIG_DVB_USB_OPERA1=m ++CONFIG_DVB_USB_PCTV452E=m ++CONFIG_DVB_USB_TECHNISAT_USB2=m ++CONFIG_DVB_USB_TTUSB2=m ++CONFIG_DVB_USB_UMT_010=m ++CONFIG_DVB_USB_VP702X=m ++CONFIG_DVB_USB_VP7045=m ++# CONFIG_SMS_USB_DRV is not set ++CONFIG_DVB_TTUSB_BUDGET=m ++CONFIG_DVB_TTUSB_DEC=m ++ ++# ++# Webcam, TV (analog/digital) USB devices ++# ++CONFIG_VIDEO_EM28XX=m ++CONFIG_VIDEO_EM28XX_V4L2=m ++CONFIG_VIDEO_EM28XX_ALSA=m ++CONFIG_VIDEO_EM28XX_DVB=m ++CONFIG_VIDEO_EM28XX_RC=m ++ ++# ++# Software defined radio USB devices ++# ++CONFIG_USB_AIRSPY=m ++CONFIG_USB_HACKRF=m ++CONFIG_USB_MSI2500=m ++CONFIG_MEDIA_PCI_SUPPORT=y ++ ++# ++# Media capture support ++# ++# CONFIG_VIDEO_SOLO6X10 is not set ++# CONFIG_VIDEO_TW5864 is not set ++# CONFIG_VIDEO_TW68 is not set ++# CONFIG_VIDEO_TW686X is not set ++ ++# ++# Media capture/analog TV support ++# ++# CONFIG_VIDEO_DT3155 is not set ++# CONFIG_VIDEO_IVTV is not set ++# CONFIG_VIDEO_HEXIUM_GEMINI is not set ++# CONFIG_VIDEO_HEXIUM_ORION is not set ++# CONFIG_VIDEO_MXB is not set ++ ++# ++# Media capture/analog/hybrid TV support ++# ++# CONFIG_VIDEO_BT848 is not set ++# CONFIG_VIDEO_CX18 is not set ++CONFIG_VIDEO_CX23885=m ++# CONFIG_MEDIA_ALTERA_CI is not set ++CONFIG_VIDEO_CX25821=m ++# CONFIG_VIDEO_CX25821_ALSA is not set ++# CONFIG_VIDEO_CX88 is not set ++# CONFIG_VIDEO_SAA7134 is not set ++# CONFIG_VIDEO_SAA7164 is not set ++ ++# ++# Media digital TV PCI Adapters ++# ++# CONFIG_DVB_B2C2_FLEXCOP_PCI is not set ++# CONFIG_DVB_DDBRIDGE is not set ++# CONFIG_DVB_DM1105 is not set ++# CONFIG_MANTIS_CORE is not set ++# CONFIG_DVB_NETUP_UNIDVB is not set ++# CONFIG_DVB_NGENE is not set ++# CONFIG_DVB_PLUTO2 is not set ++# CONFIG_DVB_PT1 is not set ++# CONFIG_DVB_PT3 is not set ++# CONFIG_DVB_SMIPCIE is not set ++# CONFIG_DVB_BUDGET_CORE is not set ++CONFIG_RADIO_ADAPTERS=y ++# CONFIG_RADIO_MAXIRADIO is not set ++# CONFIG_RADIO_SAA7706H is not set ++# CONFIG_RADIO_SHARK is not set ++# CONFIG_RADIO_SHARK2 is not set ++# CONFIG_RADIO_SI4713 is not set ++# CONFIG_RADIO_TEA5764 is not set ++# CONFIG_RADIO_TEF6862 is not set ++# CONFIG_RADIO_WL1273 is not set ++# CONFIG_USB_DSBR is not set ++# CONFIG_USB_KEENE is not set ++# CONFIG_USB_MA901 is not set ++# CONFIG_USB_MR800 is not set ++# CONFIG_USB_RAREMONO is not set ++# CONFIG_RADIO_SI470X is not set ++CONFIG_MEDIA_PLATFORM_DRIVERS=y ++CONFIG_V4L_PLATFORM_DRIVERS=y ++# CONFIG_SDR_PLATFORM_DRIVERS is not set ++CONFIG_DVB_PLATFORM_DRIVERS=y ++CONFIG_V4L_MEM2MEM_DRIVERS=y ++# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set ++# CONFIG_VIDEO_MUX is not set ++ ++# ++# Allegro DVT media platform drivers ++# ++ ++# ++# Amlogic media platform drivers ++# ++ ++# ++# Amphion drivers ++# ++ ++# ++# Aspeed media platform drivers ++# ++# CONFIG_VIDEO_ASPEED is not set ++ ++# ++# Atmel media platform drivers ++# ++ ++# ++# Cadence media platform drivers ++# ++# CONFIG_VIDEO_CADENCE_CSI2RX is not set ++# CONFIG_VIDEO_CADENCE_CSI2TX is not set ++ ++# ++# Chips&Media media platform drivers ++# ++ ++# ++# Intel media platform drivers ++# ++ ++# ++# Marvell media platform drivers ++# ++# CONFIG_VIDEO_CAFE_CCIC is not set ++ ++# ++# Mediatek media platform drivers ++# ++ ++# ++# NVidia media platform drivers ++# ++ ++# ++# NXP media platform drivers ++# ++ ++# ++# Qualcomm media platform drivers ++# ++ ++# ++# Renesas media platform drivers ++# ++ ++# ++# Rockchip media platform drivers ++# ++# CONFIG_VIDEO_ROCKCHIP_RGA is not set ++CONFIG_VIDEO_ROCKCHIP_ISP1=y ++ ++# ++# Samsung media platform drivers ++# ++ ++# ++# STMicroelectronics media platform drivers ++# ++ ++# ++# Sunxi media platform drivers ++# ++ ++# ++# Texas Instruments drivers ++# ++ ++# ++# VIA media platform drivers ++# ++ ++# ++# Xilinx media platform drivers ++# ++# CONFIG_VIDEO_XILINX is not set ++ ++# ++# MMC/SDIO DVB adapters ++# ++# CONFIG_SMS_SDIO_DRV is not set ++# CONFIG_V4L_TEST_DRIVERS is not set ++# CONFIG_DVB_TEST_DRIVERS is not set ++CONFIG_CYPRESS_FIRMWARE=y ++CONFIG_TTPCI_EEPROM=m ++CONFIG_VIDEO_CX2341X=m ++CONFIG_VIDEO_TVEEPROM=m ++CONFIG_DVB_B2C2_FLEXCOP=m ++CONFIG_VIDEOBUF2_CORE=y ++CONFIG_VIDEOBUF2_V4L2=y ++CONFIG_VIDEOBUF2_MEMOPS=y ++CONFIG_VIDEOBUF2_DMA_CONTIG=y ++CONFIG_VIDEOBUF2_VMALLOC=y ++CONFIG_VIDEOBUF2_DMA_SG=m ++CONFIG_VIDEOBUF2_DVB=m ++# end of Media drivers ++ ++# ++# Media ancillary drivers ++# ++CONFIG_MEDIA_ATTACH=y ++# CONFIG_VIDEO_IR_I2C is not set ++ ++# ++# Camera sensor devices ++# ++# CONFIG_VIDEO_HI556 is not set ++# CONFIG_VIDEO_HI846 is not set ++# CONFIG_VIDEO_HI847 is not set ++# CONFIG_VIDEO_IMX208 is not set ++# CONFIG_VIDEO_IMX214 is not set ++CONFIG_VIDEO_IMX219=y ++# CONFIG_VIDEO_IMX258 is not set ++# CONFIG_VIDEO_IMX274 is not set ++# CONFIG_VIDEO_IMX290 is not set ++# CONFIG_VIDEO_IMX319 is not set ++# CONFIG_VIDEO_IMX334 is not set ++# CONFIG_VIDEO_IMX335 is not set ++# CONFIG_VIDEO_IMX355 is not set ++# CONFIG_VIDEO_IMX412 is not set ++# CONFIG_VIDEO_MT9M001 is not set ++# CONFIG_VIDEO_MT9M032 is not set ++# CONFIG_VIDEO_MT9M111 is not set ++# CONFIG_VIDEO_MT9P031 is not set ++# CONFIG_VIDEO_MT9T001 is not set ++# CONFIG_VIDEO_MT9T112 is not set ++# CONFIG_VIDEO_MT9V011 is not set ++# CONFIG_VIDEO_MT9V032 is not set ++# CONFIG_VIDEO_MT9V111 is not set ++# CONFIG_VIDEO_NOON010PC30 is not set ++# CONFIG_VIDEO_OG01A1B is not set ++# CONFIG_VIDEO_OV02A10 is not set ++# CONFIG_VIDEO_OV08D10 is not set ++# CONFIG_VIDEO_OV13858 is not set ++# CONFIG_VIDEO_OV13B10 is not set ++# CONFIG_VIDEO_OV2640 is not set ++# CONFIG_VIDEO_OV2659 is not set ++# CONFIG_VIDEO_OV2680 is not set ++# CONFIG_VIDEO_OV2685 is not set ++# CONFIG_VIDEO_OV5640 is not set ++CONFIG_VIDEO_OV5645=y ++# CONFIG_VIDEO_OV5647 is not set ++# CONFIG_VIDEO_OV5648 is not set ++# CONFIG_VIDEO_OV5670 is not set ++# CONFIG_VIDEO_OV5675 is not set ++# CONFIG_VIDEO_OV5693 is not set ++# CONFIG_VIDEO_OV5695 is not set ++# CONFIG_VIDEO_OV6650 is not set ++# CONFIG_VIDEO_OV7251 is not set ++# CONFIG_VIDEO_OV7640 is not set ++# CONFIG_VIDEO_OV7670 is not set ++# CONFIG_VIDEO_OV772X is not set ++# CONFIG_VIDEO_OV7740 is not set ++# CONFIG_VIDEO_OV8856 is not set ++# CONFIG_VIDEO_OV8865 is not set ++# CONFIG_VIDEO_OV9282 is not set ++# CONFIG_VIDEO_OV9640 is not set ++# CONFIG_VIDEO_OV9650 is not set ++# CONFIG_VIDEO_RDACM20 is not set ++# CONFIG_VIDEO_RDACM21 is not set ++# CONFIG_VIDEO_RJ54N1 is not set ++# CONFIG_VIDEO_S5C73M3 is not set ++# CONFIG_VIDEO_S5K4ECGX is not set ++# CONFIG_VIDEO_S5K5BAF is not set ++# CONFIG_VIDEO_S5K6A3 is not set ++# CONFIG_VIDEO_S5K6AA is not set ++# CONFIG_VIDEO_SR030PC30 is not set ++# CONFIG_VIDEO_VS6624 is not set ++# CONFIG_VIDEO_CCS is not set ++# CONFIG_VIDEO_ET8EK8 is not set ++# CONFIG_VIDEO_M5MOLS is not set ++# end of Camera sensor devices ++ ++# ++# Lens drivers ++# ++# CONFIG_VIDEO_AD5820 is not set ++# CONFIG_VIDEO_AK7375 is not set ++# CONFIG_VIDEO_DW9714 is not set ++# CONFIG_VIDEO_DW9768 is not set ++# CONFIG_VIDEO_DW9807_VCM is not set ++# end of Lens drivers ++ ++# ++# Flash devices ++# ++# CONFIG_VIDEO_ADP1653 is not set ++# CONFIG_VIDEO_LM3560 is not set ++# CONFIG_VIDEO_LM3646 is not set ++# end of Flash devices ++ ++# ++# Audio decoders, processors and mixers ++# ++CONFIG_VIDEO_CS3308=m ++# CONFIG_VIDEO_CS5345 is not set ++# CONFIG_VIDEO_CS53L32A is not set ++# CONFIG_VIDEO_MSP3400 is not set ++# CONFIG_VIDEO_SONY_BTF_MPX is not set ++# CONFIG_VIDEO_TDA1997X is not set ++# CONFIG_VIDEO_TDA7432 is not set ++# CONFIG_VIDEO_TDA9840 is not set ++# CONFIG_VIDEO_TEA6415C is not set ++# CONFIG_VIDEO_TEA6420 is not set ++# CONFIG_VIDEO_TLV320AIC23B is not set ++# CONFIG_VIDEO_TVAUDIO is not set ++# CONFIG_VIDEO_UDA1342 is not set ++# CONFIG_VIDEO_VP27SMPX is not set ++# CONFIG_VIDEO_WM8739 is not set ++# CONFIG_VIDEO_WM8775 is not set ++# end of Audio decoders, processors and mixers ++ ++# ++# RDS decoders ++# ++# CONFIG_VIDEO_SAA6588 is not set ++# end of RDS decoders ++ ++# ++# Video decoders ++# ++# CONFIG_VIDEO_ADV7180 is not set ++# CONFIG_VIDEO_ADV7183 is not set ++# CONFIG_VIDEO_ADV748X is not set ++# CONFIG_VIDEO_ADV7604 is not set ++# CONFIG_VIDEO_ADV7842 is not set ++# CONFIG_VIDEO_BT819 is not set ++# CONFIG_VIDEO_BT856 is not set ++# CONFIG_VIDEO_BT866 is not set ++# CONFIG_VIDEO_ISL7998X is not set ++# CONFIG_VIDEO_KS0127 is not set ++# CONFIG_VIDEO_MAX9286 is not set ++# CONFIG_VIDEO_ML86V7667 is not set ++# CONFIG_VIDEO_SAA7110 is not set ++# CONFIG_VIDEO_SAA711X is not set ++# CONFIG_VIDEO_TC358743 is not set ++# CONFIG_VIDEO_TVP514X is not set ++# CONFIG_VIDEO_TVP5150 is not set ++# CONFIG_VIDEO_TVP7002 is not set ++# CONFIG_VIDEO_TW2804 is not set ++# CONFIG_VIDEO_TW9903 is not set ++# CONFIG_VIDEO_TW9906 is not set ++# CONFIG_VIDEO_TW9910 is not set ++# CONFIG_VIDEO_VPX3220 is not set ++ ++# ++# Video and audio decoders ++# ++# CONFIG_VIDEO_SAA717X is not set ++CONFIG_VIDEO_CX25840=m ++# end of Video decoders ++ ++# ++# Video encoders ++# ++# CONFIG_VIDEO_AD9389B is not set ++# CONFIG_VIDEO_ADV7170 is not set ++# CONFIG_VIDEO_ADV7175 is not set ++# CONFIG_VIDEO_ADV7343 is not set ++# CONFIG_VIDEO_ADV7393 is not set ++# CONFIG_VIDEO_ADV7511 is not set ++# CONFIG_VIDEO_AK881X is not set ++# CONFIG_VIDEO_SAA7127 is not set ++# CONFIG_VIDEO_SAA7185 is not set ++# CONFIG_VIDEO_THS8200 is not set ++# end of Video encoders ++ ++# ++# Video improvement chips ++# ++# CONFIG_VIDEO_UPD64031A is not set ++# CONFIG_VIDEO_UPD64083 is not set ++# end of Video improvement chips ++ ++# ++# Audio/Video compression chips ++# ++# CONFIG_VIDEO_SAA6752HS is not set ++# end of Audio/Video compression chips ++ ++# ++# SDR tuner chips ++# ++# CONFIG_SDR_MAX2175 is not set ++# end of SDR tuner chips ++ ++# ++# Miscellaneous helper chips ++# ++# CONFIG_VIDEO_I2C is not set ++# CONFIG_VIDEO_M52790 is not set ++# CONFIG_VIDEO_ST_MIPID02 is not set ++# CONFIG_VIDEO_THS7303 is not set ++# end of Miscellaneous helper chips ++ ++# ++# Media SPI Adapters ++# ++CONFIG_CXD2880_SPI_DRV=m ++# CONFIG_VIDEO_GS1662 is not set ++# end of Media SPI Adapters ++ ++CONFIG_MEDIA_TUNER=y ++ ++# ++# Customize TV tuners ++# ++CONFIG_MEDIA_TUNER_E4000=m ++CONFIG_MEDIA_TUNER_FC0011=m ++CONFIG_MEDIA_TUNER_FC0012=m ++CONFIG_MEDIA_TUNER_FC0013=m ++CONFIG_MEDIA_TUNER_FC2580=m ++CONFIG_MEDIA_TUNER_IT913X=m ++CONFIG_MEDIA_TUNER_M88RS6000T=m ++CONFIG_MEDIA_TUNER_MAX2165=m ++CONFIG_MEDIA_TUNER_MC44S803=m ++CONFIG_MEDIA_TUNER_MSI001=m ++CONFIG_MEDIA_TUNER_MT2060=m ++CONFIG_MEDIA_TUNER_MT2063=m ++CONFIG_MEDIA_TUNER_MT20XX=m ++CONFIG_MEDIA_TUNER_MT2131=m ++CONFIG_MEDIA_TUNER_MT2266=m ++CONFIG_MEDIA_TUNER_MXL301RF=m ++CONFIG_MEDIA_TUNER_MXL5005S=m ++CONFIG_MEDIA_TUNER_MXL5007T=m ++CONFIG_MEDIA_TUNER_QM1D1B0004=m ++CONFIG_MEDIA_TUNER_QM1D1C0042=m ++CONFIG_MEDIA_TUNER_QT1010=m ++CONFIG_MEDIA_TUNER_R820T=m ++CONFIG_MEDIA_TUNER_SI2157=m ++CONFIG_MEDIA_TUNER_SIMPLE=m ++CONFIG_MEDIA_TUNER_TDA18212=m ++CONFIG_MEDIA_TUNER_TDA18218=m ++CONFIG_MEDIA_TUNER_TDA18250=m ++CONFIG_MEDIA_TUNER_TDA18271=m ++CONFIG_MEDIA_TUNER_TDA827X=m ++CONFIG_MEDIA_TUNER_TDA8290=m ++CONFIG_MEDIA_TUNER_TDA9887=m ++CONFIG_MEDIA_TUNER_TEA5761=m ++CONFIG_MEDIA_TUNER_TEA5767=m ++CONFIG_MEDIA_TUNER_TUA9001=m ++CONFIG_MEDIA_TUNER_XC2028=m ++CONFIG_MEDIA_TUNER_XC4000=m ++CONFIG_MEDIA_TUNER_XC5000=m ++# end of Customize TV tuners ++ ++# ++# Customise DVB Frontends ++# ++ ++# ++# Multistandard (satellite) frontends ++# ++CONFIG_DVB_M88DS3103=m ++CONFIG_DVB_MXL5XX=m ++CONFIG_DVB_STB0899=m ++CONFIG_DVB_STB6100=m ++CONFIG_DVB_STV090x=m ++CONFIG_DVB_STV0910=m ++CONFIG_DVB_STV6110x=m ++CONFIG_DVB_STV6111=m ++ ++# ++# Multistandard (cable + terrestrial) frontends ++# ++CONFIG_DVB_DRXK=m ++CONFIG_DVB_MN88472=m ++CONFIG_DVB_MN88473=m ++CONFIG_DVB_SI2165=m ++CONFIG_DVB_TDA18271C2DD=m ++ ++# ++# DVB-S (satellite) frontends ++# ++CONFIG_DVB_CX24110=m ++CONFIG_DVB_CX24116=m ++CONFIG_DVB_CX24117=m ++CONFIG_DVB_CX24120=m ++CONFIG_DVB_CX24123=m ++CONFIG_DVB_DS3000=m ++CONFIG_DVB_MB86A16=m ++CONFIG_DVB_MT312=m ++CONFIG_DVB_S5H1420=m ++CONFIG_DVB_SI21XX=m ++CONFIG_DVB_STB6000=m ++CONFIG_DVB_STV0288=m ++CONFIG_DVB_STV0299=m ++CONFIG_DVB_STV0900=m ++CONFIG_DVB_STV6110=m ++CONFIG_DVB_TDA10071=m ++CONFIG_DVB_TDA10086=m ++CONFIG_DVB_TDA8083=m ++CONFIG_DVB_TDA8261=m ++CONFIG_DVB_TDA826X=m ++CONFIG_DVB_TS2020=m ++CONFIG_DVB_TUA6100=m ++CONFIG_DVB_TUNER_CX24113=m ++CONFIG_DVB_TUNER_ITD1000=m ++CONFIG_DVB_VES1X93=m ++CONFIG_DVB_ZL10036=m ++CONFIG_DVB_ZL10039=m ++ ++# ++# DVB-T (terrestrial) frontends ++# ++CONFIG_DVB_AF9013=m ++CONFIG_DVB_AS102_FE=m ++CONFIG_DVB_CX22700=m ++CONFIG_DVB_CX22702=m ++CONFIG_DVB_CXD2820R=m ++CONFIG_DVB_CXD2841ER=m ++CONFIG_DVB_DIB3000MB=m ++CONFIG_DVB_DIB3000MC=m ++CONFIG_DVB_DIB7000M=m ++CONFIG_DVB_DIB7000P=m ++CONFIG_DVB_DIB9000=m ++CONFIG_DVB_DRXD=m ++CONFIG_DVB_EC100=m ++CONFIG_DVB_GP8PSK_FE=m ++CONFIG_DVB_L64781=m ++CONFIG_DVB_MT352=m ++CONFIG_DVB_NXT6000=m ++CONFIG_DVB_RTL2830=m ++CONFIG_DVB_RTL2832=m ++CONFIG_DVB_RTL2832_SDR=m ++CONFIG_DVB_S5H1432=m ++CONFIG_DVB_SI2168=m ++CONFIG_DVB_SP887X=m ++CONFIG_DVB_STV0367=m ++CONFIG_DVB_TDA10048=m ++CONFIG_DVB_TDA1004X=m ++CONFIG_DVB_ZD1301_DEMOD=m ++CONFIG_DVB_ZL10353=m ++CONFIG_DVB_CXD2880=m ++ ++# ++# DVB-C (cable) frontends ++# ++CONFIG_DVB_STV0297=m ++CONFIG_DVB_TDA10021=m ++CONFIG_DVB_TDA10023=m ++CONFIG_DVB_VES1820=m ++ ++# ++# ATSC (North American/Korean Terrestrial/Cable DTV) frontends ++# ++CONFIG_DVB_AU8522=m ++CONFIG_DVB_AU8522_DTV=m ++# CONFIG_DVB_AU8522_V4L is not set ++CONFIG_DVB_BCM3510=m ++CONFIG_DVB_LG2160=m ++CONFIG_DVB_LGDT3305=m ++CONFIG_DVB_LGDT3306A=m ++CONFIG_DVB_LGDT330X=m ++CONFIG_DVB_MXL692=m ++CONFIG_DVB_NXT200X=m ++CONFIG_DVB_OR51132=m ++CONFIG_DVB_OR51211=m ++CONFIG_DVB_S5H1409=m ++CONFIG_DVB_S5H1411=m ++ ++# ++# ISDB-T (terrestrial) frontends ++# ++CONFIG_DVB_DIB8000=m ++CONFIG_DVB_MB86A20S=m ++CONFIG_DVB_S921=m ++ ++# ++# ISDB-S (satellite) & ISDB-T (terrestrial) frontends ++# ++CONFIG_DVB_MN88443X=m ++CONFIG_DVB_TC90522=m ++ ++# ++# Digital terrestrial only tuners/PLL ++# ++CONFIG_DVB_PLL=m ++# CONFIG_DVB_TUNER_DIB0070 is not set ++# CONFIG_DVB_TUNER_DIB0090 is not set ++ ++# ++# SEC control devices for DVB-S ++# ++CONFIG_DVB_A8293=m ++CONFIG_DVB_AF9033=m ++CONFIG_DVB_ASCOT2E=m ++CONFIG_DVB_ATBM8830=m ++CONFIG_DVB_HELENE=m ++CONFIG_DVB_HORUS3A=m ++CONFIG_DVB_ISL6405=m ++CONFIG_DVB_ISL6421=m ++CONFIG_DVB_ISL6423=m ++CONFIG_DVB_IX2505V=m ++CONFIG_DVB_LGS8GL5=m ++CONFIG_DVB_LGS8GXX=m ++CONFIG_DVB_LNBH25=m ++CONFIG_DVB_LNBH29=m ++CONFIG_DVB_LNBP21=m ++CONFIG_DVB_LNBP22=m ++CONFIG_DVB_M88RS2000=m ++CONFIG_DVB_TDA665x=m ++CONFIG_DVB_DRX39XYJ=m ++ ++# ++# Common Interface (EN50221) controller drivers ++# ++CONFIG_DVB_CXD2099=m ++CONFIG_DVB_SP2=m ++# end of Customise DVB Frontends ++ ++# ++# Tools to develop new frontends ++# ++# CONFIG_DVB_DUMMY_FE is not set ++# end of Media ancillary drivers ++ ++# ++# Graphics support ++# ++CONFIG_DRM=y ++CONFIG_DRM_MIPI_DSI=y ++# CONFIG_DRM_DP_AUX_CHARDEV is not set ++# CONFIG_DRM_DEBUG_MM is not set ++# CONFIG_DRM_DEBUG_SELFTEST is not set ++CONFIG_DRM_DP_HELPER=y ++CONFIG_DRM_KMS_HELPER=y ++# CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS is not set ++# CONFIG_DRM_DEBUG_MODESET_LOCK is not set ++CONFIG_DRM_FBDEV_EMULATION=y ++CONFIG_DRM_FBDEV_OVERALLOC=100 ++# CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set ++CONFIG_DRM_LOAD_EDID_FIRMWARE=y ++# CONFIG_DRM_DP_CEC is not set ++CONFIG_DRM_TTM=m ++CONFIG_DRM_VRAM_HELPER=m ++CONFIG_DRM_TTM_HELPER=m ++CONFIG_DRM_GEM_CMA_HELPER=y ++CONFIG_DRM_GEM_SHMEM_HELPER=y ++CONFIG_DRM_SCHED=y ++ ++# ++# I2C encoder or helper chips ++# ++# CONFIG_DRM_I2C_CH7006 is not set ++# CONFIG_DRM_I2C_SIL164 is not set ++# CONFIG_DRM_I2C_NXP_TDA998X is not set ++# CONFIG_DRM_I2C_NXP_TDA9950 is not set ++# end of I2C encoder or helper chips ++ ++# ++# ARM devices ++# ++# CONFIG_DRM_HDLCD is not set ++# CONFIG_DRM_MALI_DISPLAY is not set ++# CONFIG_DRM_KOMEDA is not set ++# end of ARM devices ++ ++# CONFIG_DRM_RADEON is not set ++# CONFIG_DRM_AMDGPU is not set ++# CONFIG_DRM_NOUVEAU is not set ++# CONFIG_DRM_VGEM is not set ++# CONFIG_DRM_VKMS is not set ++CONFIG_DRM_ROCKCHIP=y ++CONFIG_ROCKCHIP_ANALOGIX_DP=y ++CONFIG_ROCKCHIP_CDN_DP=y ++CONFIG_ROCKCHIP_DW_HDMI=y ++CONFIG_ROCKCHIP_DW_MIPI_DSI=y ++CONFIG_ROCKCHIP_INNO_HDMI=y ++CONFIG_ROCKCHIP_LVDS=y ++CONFIG_ROCKCHIP_RGB=y ++CONFIG_ROCKCHIP_RK3066_HDMI=y ++# CONFIG_DRM_VMWGFX is not set ++CONFIG_DRM_UDL=y ++CONFIG_DRM_AST=m ++# CONFIG_DRM_MGAG200 is not set ++# CONFIG_DRM_RCAR_DW_HDMI is not set ++# CONFIG_DRM_RCAR_USE_LVDS is not set ++# CONFIG_DRM_RCAR_MIPI_DSI is not set ++# CONFIG_DRM_QXL is not set ++CONFIG_DRM_PANEL=y ++ ++# ++# Display Panels ++# ++# CONFIG_DRM_PANEL_ABT_Y030XX067A is not set ++# CONFIG_DRM_PANEL_ARM_VERSATILE is not set ++# CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596 is not set ++# CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0 is not set ++# CONFIG_DRM_PANEL_BOE_HIMAX8279D is not set ++# CONFIG_DRM_PANEL_BOE_TV101WUM_NL6 is not set ++# CONFIG_DRM_PANEL_DSI_CM is not set ++# CONFIG_DRM_PANEL_LVDS is not set ++CONFIG_DRM_PANEL_SIMPLE=y ++# CONFIG_DRM_PANEL_EDP is not set ++CONFIG_DRM_PANEL_ELIDA_KD35T133=y ++# CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02 is not set ++# CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D is not set ++# CONFIG_DRM_PANEL_ILITEK_IL9322 is not set ++# CONFIG_DRM_PANEL_ILITEK_ILI9341 is not set ++# CONFIG_DRM_PANEL_ILITEK_ILI9881C is not set ++# CONFIG_DRM_PANEL_INNOLUX_EJ030NA is not set ++# CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set ++# CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set ++# CONFIG_DRM_PANEL_JDI_R63452 is not set ++# CONFIG_DRM_PANEL_KHADAS_TS050 is not set ++# CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04 is not set ++# CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W is not set ++# CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829 is not set ++# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set ++# CONFIG_DRM_PANEL_LG_LB035Q02 is not set ++# CONFIG_DRM_PANEL_LG_LG4573 is not set ++# CONFIG_DRM_PANEL_NEC_NL8048HL11 is not set ++# CONFIG_DRM_PANEL_NOVATEK_NT35510 is not set ++# CONFIG_DRM_PANEL_NOVATEK_NT35560 is not set ++# CONFIG_DRM_PANEL_NOVATEK_NT35950 is not set ++# CONFIG_DRM_PANEL_NOVATEK_NT36672A is not set ++# CONFIG_DRM_PANEL_NOVATEK_NT39016 is not set ++# CONFIG_DRM_PANEL_MANTIX_MLAF057WE51 is not set ++# CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO is not set ++# CONFIG_DRM_PANEL_ORISETECH_OTM8009A is not set ++# CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS is not set ++# CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set ++# CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set ++# CONFIG_DRM_PANEL_RAYDIUM_RM67191 is not set ++# CONFIG_DRM_PANEL_RAYDIUM_RM68200 is not set ++# CONFIG_DRM_PANEL_RONBO_RB070D30 is not set ++# CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20 is not set ++# CONFIG_DRM_PANEL_SAMSUNG_DB7430 is not set ++# CONFIG_DRM_PANEL_SAMSUNG_S6D16D0 is not set ++# CONFIG_DRM_PANEL_SAMSUNG_S6D27A1 is not set ++# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set ++# CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 is not set ++# CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 is not set ++# CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01 is not set ++# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set ++# CONFIG_DRM_PANEL_SAMSUNG_SOFEF00 is not set ++# CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set ++# CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set ++# CONFIG_DRM_PANEL_SHARP_LS037V7DW01 is not set ++# CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set ++CONFIG_DRM_PANEL_SHARP_LS054B3SX01=y ++# CONFIG_DRM_PANEL_SHARP_LS060T1SX01 is not set ++CONFIG_DRM_PANEL_SITRONIX_ST7701=y ++# CONFIG_DRM_PANEL_SITRONIX_ST7703 is not set ++# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set ++# CONFIG_DRM_PANEL_SONY_ACX565AKM is not set ++# CONFIG_DRM_PANEL_SONY_TULIP_TRULY_NT35521 is not set ++# CONFIG_DRM_PANEL_TDO_TL070WSH30 is not set ++# CONFIG_DRM_PANEL_TPO_TD028TTEC1 is not set ++# CONFIG_DRM_PANEL_TPO_TD043MTEA1 is not set ++# CONFIG_DRM_PANEL_TPO_TPG110 is not set ++# CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA is not set ++# CONFIG_DRM_PANEL_VISIONOX_RM69299 is not set ++# CONFIG_DRM_PANEL_WIDECHIPS_WS2401 is not set ++# CONFIG_DRM_PANEL_XINPENG_XPP055C272 is not set ++# end of Display Panels ++ ++CONFIG_DRM_BRIDGE=y ++CONFIG_DRM_PANEL_BRIDGE=y ++ ++# ++# Display Interface Bridges ++# ++# CONFIG_DRM_CDNS_DSI is not set ++# CONFIG_DRM_CHIPONE_ICN6211 is not set ++# CONFIG_DRM_CHRONTEL_CH7033 is not set ++CONFIG_DRM_DISPLAY_CONNECTOR=y ++# CONFIG_DRM_ITE_IT6505 is not set ++# CONFIG_DRM_LONTIUM_LT8912B is not set ++# CONFIG_DRM_LONTIUM_LT9611 is not set ++# CONFIG_DRM_LONTIUM_LT9611UXC is not set ++# CONFIG_DRM_ITE_IT66121 is not set ++# CONFIG_DRM_LVDS_CODEC is not set ++# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set ++# CONFIG_DRM_NWL_MIPI_DSI is not set ++# CONFIG_DRM_NXP_PTN3460 is not set ++# CONFIG_DRM_PARADE_PS8622 is not set ++# CONFIG_DRM_PARADE_PS8640 is not set ++# CONFIG_DRM_SIL_SII8620 is not set ++# CONFIG_DRM_SII902X is not set ++# CONFIG_DRM_SII9234 is not set ++# CONFIG_DRM_SIMPLE_BRIDGE is not set ++# CONFIG_DRM_THINE_THC63LVD1024 is not set ++# CONFIG_DRM_TOSHIBA_TC358762 is not set ++# CONFIG_DRM_TOSHIBA_TC358764 is not set ++# CONFIG_DRM_TOSHIBA_TC358767 is not set ++# CONFIG_DRM_TOSHIBA_TC358768 is not set ++# CONFIG_DRM_TOSHIBA_TC358775 is not set ++# CONFIG_DRM_TI_TFP410 is not set ++# CONFIG_DRM_TI_SN65DSI83 is not set ++# CONFIG_DRM_TI_SN65DSI86 is not set ++# CONFIG_DRM_TI_TPD12S015 is not set ++# CONFIG_DRM_ANALOGIX_ANX6345 is not set ++# CONFIG_DRM_ANALOGIX_ANX78XX is not set ++CONFIG_DRM_ANALOGIX_DP=y ++# CONFIG_DRM_ANALOGIX_ANX7625 is not set ++# CONFIG_DRM_I2C_ADV7511 is not set ++# CONFIG_DRM_CDNS_MHDP8546 is not set ++CONFIG_DRM_DW_HDMI=y ++# CONFIG_DRM_DW_HDMI_AHB_AUDIO is not set ++CONFIG_DRM_DW_HDMI_I2S_AUDIO=m ++CONFIG_DRM_DW_HDMI_CEC=y ++CONFIG_DRM_DW_MIPI_DSI=y ++# end of Display Interface Bridges ++ ++# CONFIG_DRM_ETNAVIV is not set ++# CONFIG_DRM_HISI_HIBMC is not set ++# CONFIG_DRM_HISI_KIRIN is not set ++# CONFIG_DRM_MXSFB is not set ++# CONFIG_DRM_ARCPGU is not set ++# CONFIG_DRM_BOCHS is not set ++# CONFIG_DRM_CIRRUS_QEMU is not set ++# CONFIG_DRM_GM12U320 is not set ++# CONFIG_DRM_PANEL_MIPI_DBI is not set ++# CONFIG_DRM_SIMPLEDRM is not set ++# CONFIG_TINYDRM_HX8357D is not set ++# CONFIG_TINYDRM_ILI9163 is not set ++# CONFIG_TINYDRM_ILI9225 is not set ++# CONFIG_TINYDRM_ILI9341 is not set ++# CONFIG_TINYDRM_ILI9486 is not set ++# CONFIG_TINYDRM_MI0283QT is not set ++# CONFIG_TINYDRM_REPAPER is not set ++# CONFIG_TINYDRM_ST7586 is not set ++# CONFIG_TINYDRM_ST7735R is not set ++# CONFIG_DRM_PL111 is not set ++# CONFIG_DRM_LIMA is not set ++CONFIG_DRM_PANFROST=y ++# CONFIG_DRM_TIDSS is not set ++# CONFIG_DRM_GUD is not set ++# CONFIG_DRM_SSD130X is not set ++# CONFIG_DRM_LEGACY is not set ++CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y ++CONFIG_DRM_NOMODESET=y ++ ++# ++# Frame buffer Devices ++# ++CONFIG_FB_CMDLINE=y ++CONFIG_FB_NOTIFY=y ++CONFIG_FB=y ++# CONFIG_FIRMWARE_EDID is not set ++CONFIG_FB_CFB_FILLRECT=y ++CONFIG_FB_CFB_COPYAREA=y ++CONFIG_FB_CFB_IMAGEBLIT=y ++CONFIG_FB_SYS_FILLRECT=y ++CONFIG_FB_SYS_COPYAREA=y ++CONFIG_FB_SYS_IMAGEBLIT=y ++# CONFIG_FB_FOREIGN_ENDIAN is not set ++CONFIG_FB_SYS_FOPS=y ++CONFIG_FB_DEFERRED_IO=y ++# CONFIG_FB_MODE_HELPERS is not set ++# CONFIG_FB_TILEBLITTING is not set ++ ++# ++# Frame buffer hardware drivers ++# ++# CONFIG_FB_CIRRUS is not set ++# CONFIG_FB_PM2 is not set ++# CONFIG_FB_ARMCLCD is not set ++# CONFIG_FB_CYBER2000 is not set ++# CONFIG_FB_ASILIANT is not set ++# CONFIG_FB_IMSTT is not set ++# CONFIG_FB_UVESA is not set ++# CONFIG_FB_OPENCORES is not set ++# CONFIG_FB_S1D13XXX is not set ++# CONFIG_FB_NVIDIA is not set ++# CONFIG_FB_RIVA is not set ++# CONFIG_FB_I740 is not set ++# CONFIG_FB_MATROX is not set ++# CONFIG_FB_RADEON is not set ++# CONFIG_FB_ATY128 is not set ++# CONFIG_FB_ATY is not set ++# CONFIG_FB_S3 is not set ++# CONFIG_FB_SAVAGE is not set ++# CONFIG_FB_SIS is not set ++# CONFIG_FB_NEOMAGIC is not set ++# CONFIG_FB_KYRO is not set ++# CONFIG_FB_3DFX is not set ++# CONFIG_FB_VOODOO1 is not set ++# CONFIG_FB_VT8623 is not set ++# CONFIG_FB_TRIDENT is not set ++# CONFIG_FB_ARK is not set ++# CONFIG_FB_PM3 is not set ++# CONFIG_FB_CARMINE is not set ++# CONFIG_FB_SMSCUFX is not set ++# CONFIG_FB_UDL is not set ++# CONFIG_FB_IBM_GXT4500 is not set ++# CONFIG_FB_VIRTUAL is not set ++# CONFIG_FB_METRONOME is not set ++# CONFIG_FB_MB862XX is not set ++# CONFIG_FB_SIMPLE is not set ++# CONFIG_FB_SSD1307 is not set ++# CONFIG_FB_SM712 is not set ++# end of Frame buffer Devices ++ ++# ++# Backlight & LCD device support ++# ++# CONFIG_LCD_CLASS_DEVICE is not set ++CONFIG_BACKLIGHT_CLASS_DEVICE=y ++# CONFIG_BACKLIGHT_KTD253 is not set ++CONFIG_BACKLIGHT_PWM=y ++# CONFIG_BACKLIGHT_QCOM_WLED is not set ++# CONFIG_BACKLIGHT_ADP8860 is not set ++# CONFIG_BACKLIGHT_ADP8870 is not set ++# CONFIG_BACKLIGHT_LM3630A is not set ++# CONFIG_BACKLIGHT_LM3639 is not set ++# CONFIG_BACKLIGHT_LP855X is not set ++# CONFIG_BACKLIGHT_GPIO is not set ++# CONFIG_BACKLIGHT_LV5207LP is not set ++# CONFIG_BACKLIGHT_BD6107 is not set ++# CONFIG_BACKLIGHT_ARCXCNN is not set ++# CONFIG_BACKLIGHT_LED is not set ++# end of Backlight & LCD device support ++ ++CONFIG_VIDEOMODE_HELPERS=y ++CONFIG_HDMI=y ++ ++# ++# Console display driver support ++# ++CONFIG_DUMMY_CONSOLE=y ++CONFIG_DUMMY_CONSOLE_COLUMNS=80 ++CONFIG_DUMMY_CONSOLE_ROWS=25 ++CONFIG_FRAMEBUFFER_CONSOLE=y ++# CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION is not set ++CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y ++CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y ++# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set ++# end of Console display driver support ++ ++CONFIG_LOGO=y ++CONFIG_LOGO_LINUX_MONO=y ++CONFIG_LOGO_LINUX_VGA16=y ++CONFIG_LOGO_LINUX_CLUT224=y ++# end of Graphics support ++ ++CONFIG_SOUND=y ++CONFIG_SND=y ++CONFIG_SND_TIMER=y ++CONFIG_SND_PCM=y ++CONFIG_SND_PCM_ELD=y ++CONFIG_SND_PCM_IEC958=y ++CONFIG_SND_DMAENGINE_PCM=y ++CONFIG_SND_SEQ_DEVICE=y ++CONFIG_SND_RAWMIDI=y ++CONFIG_SND_JACK=y ++CONFIG_SND_JACK_INPUT_DEV=y ++# CONFIG_SND_OSSEMUL is not set ++CONFIG_SND_PCM_TIMER=y ++CONFIG_SND_HRTIMER=y ++CONFIG_SND_DYNAMIC_MINORS=y ++CONFIG_SND_MAX_CARDS=32 ++# CONFIG_SND_SUPPORT_OLD_API is not set ++CONFIG_SND_PROC_FS=y ++# CONFIG_SND_VERBOSE_PROCFS is not set ++CONFIG_SND_VERBOSE_PRINTK=y ++# CONFIG_SND_DEBUG is not set ++CONFIG_SND_SEQUENCER=y ++CONFIG_SND_SEQ_DUMMY=y ++CONFIG_SND_SEQ_HRTIMER_DEFAULT=y ++CONFIG_SND_SEQ_MIDI_EVENT=y ++CONFIG_SND_SEQ_MIDI=y ++# CONFIG_SND_DRIVERS is not set ++# CONFIG_SND_PCI is not set ++ ++# ++# HD-Audio ++# ++# end of HD-Audio ++ ++CONFIG_SND_HDA_PREALLOC_SIZE=64 ++# CONFIG_SND_SPI is not set ++# CONFIG_SND_USB is not set ++CONFIG_SND_PCMCIA=y ++# CONFIG_SND_VXPOCKET is not set ++# CONFIG_SND_PDAUDIOCF is not set ++CONFIG_SND_SOC=y ++CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y ++# CONFIG_SND_SOC_ADI is not set ++# CONFIG_SND_SOC_AMD_ACP is not set ++# CONFIG_SND_AMD_ACP_CONFIG is not set ++# CONFIG_SND_ATMEL_SOC is not set ++# CONFIG_SND_BCM63XX_I2S_WHISTLER is not set ++# CONFIG_SND_DESIGNWARE_I2S is not set ++ ++# ++# SoC Audio for Freescale CPUs ++# ++ ++# ++# Common SoC Audio options for Freescale CPUs: ++# ++# CONFIG_SND_SOC_FSL_ASRC is not set ++CONFIG_SND_SOC_FSL_SAI=y ++# CONFIG_SND_SOC_FSL_MQS is not set ++# CONFIG_SND_SOC_FSL_AUDMIX is not set ++# CONFIG_SND_SOC_FSL_SSI is not set ++# CONFIG_SND_SOC_FSL_SPDIF is not set ++# CONFIG_SND_SOC_FSL_ESAI is not set ++# CONFIG_SND_SOC_FSL_MICFIL is not set ++# CONFIG_SND_SOC_FSL_XCVR is not set ++# CONFIG_SND_SOC_IMX_AUDMUX is not set ++# end of SoC Audio for Freescale CPUs ++ ++# CONFIG_SND_I2S_HI6210_I2S is not set ++# CONFIG_SND_SOC_IMG is not set ++# CONFIG_SND_SOC_MTK_BTCVSD is not set ++CONFIG_SND_SOC_ROCKCHIP=y ++CONFIG_SND_SOC_ROCKCHIP_I2S=y ++CONFIG_SND_SOC_ROCKCHIP_I2S_TDM=y ++CONFIG_SND_SOC_ROCKCHIP_PDM=y ++CONFIG_SND_SOC_ROCKCHIP_SPDIF=y ++CONFIG_SND_SOC_ROCKCHIP_MAX98090=y ++CONFIG_SND_SOC_ROCKCHIP_RT5645=y ++# CONFIG_SND_SOC_RK3288_HDMI_ANALOG is not set ++# CONFIG_SND_SOC_RK3399_GRU_SOUND is not set ++# CONFIG_SND_SOC_SOF_TOPLEVEL is not set ++ ++# ++# STMicroelectronics STM32 SOC audio support ++# ++# end of STMicroelectronics STM32 SOC audio support ++ ++# CONFIG_SND_SOC_XILINX_I2S is not set ++# CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER is not set ++# CONFIG_SND_SOC_XILINX_SPDIF is not set ++# CONFIG_SND_SOC_XTFPGA_I2S is not set ++CONFIG_SND_SOC_I2C_AND_SPI=y ++ ++# ++# CODEC drivers ++# ++# CONFIG_SND_SOC_AC97_CODEC is not set ++# CONFIG_SND_SOC_ADAU1372_I2C is not set ++# CONFIG_SND_SOC_ADAU1372_SPI is not set ++# CONFIG_SND_SOC_ADAU1701 is not set ++# CONFIG_SND_SOC_ADAU1761_I2C is not set ++# CONFIG_SND_SOC_ADAU1761_SPI is not set ++# CONFIG_SND_SOC_ADAU7002 is not set ++# CONFIG_SND_SOC_ADAU7118_HW is not set ++# CONFIG_SND_SOC_ADAU7118_I2C is not set ++# CONFIG_SND_SOC_AK4104 is not set ++# CONFIG_SND_SOC_AK4118 is not set ++# CONFIG_SND_SOC_AK4375 is not set ++# CONFIG_SND_SOC_AK4458 is not set ++# CONFIG_SND_SOC_AK4554 is not set ++# CONFIG_SND_SOC_AK4613 is not set ++# CONFIG_SND_SOC_AK4642 is not set ++# CONFIG_SND_SOC_AK5386 is not set ++# CONFIG_SND_SOC_AK5558 is not set ++# CONFIG_SND_SOC_ALC5623 is not set ++# CONFIG_SND_SOC_AW8738 is not set ++# CONFIG_SND_SOC_BD28623 is not set ++# CONFIG_SND_SOC_BT_SCO is not set ++# CONFIG_SND_SOC_CS35L32 is not set ++# CONFIG_SND_SOC_CS35L33 is not set ++# CONFIG_SND_SOC_CS35L34 is not set ++# CONFIG_SND_SOC_CS35L35 is not set ++# CONFIG_SND_SOC_CS35L36 is not set ++# CONFIG_SND_SOC_CS35L41_SPI is not set ++# CONFIG_SND_SOC_CS35L41_I2C is not set ++# CONFIG_SND_SOC_CS42L42 is not set ++# CONFIG_SND_SOC_CS42L51_I2C is not set ++# CONFIG_SND_SOC_CS42L52 is not set ++# CONFIG_SND_SOC_CS42L56 is not set ++# CONFIG_SND_SOC_CS42L73 is not set ++# CONFIG_SND_SOC_CS4234 is not set ++# CONFIG_SND_SOC_CS4265 is not set ++# CONFIG_SND_SOC_CS4270 is not set ++# CONFIG_SND_SOC_CS4271_I2C is not set ++# CONFIG_SND_SOC_CS4271_SPI is not set ++# CONFIG_SND_SOC_CS42XX8_I2C is not set ++# CONFIG_SND_SOC_CS43130 is not set ++# CONFIG_SND_SOC_CS4341 is not set ++# CONFIG_SND_SOC_CS4349 is not set ++# CONFIG_SND_SOC_CS53L30 is not set ++# CONFIG_SND_SOC_CX2072X is not set ++# CONFIG_SND_SOC_DA7213 is not set ++# CONFIG_SND_SOC_DMIC is not set ++CONFIG_SND_SOC_HDMI_CODEC=y ++# CONFIG_SND_SOC_ES7134 is not set ++# CONFIG_SND_SOC_ES7241 is not set ++CONFIG_SND_SOC_ES8316=y ++# CONFIG_SND_SOC_ES8328_I2C is not set ++# CONFIG_SND_SOC_ES8328_SPI is not set ++# CONFIG_SND_SOC_GTM601 is not set ++# CONFIG_SND_SOC_ICS43432 is not set ++# CONFIG_SND_SOC_INNO_RK3036 is not set ++# CONFIG_SND_SOC_MAX98088 is not set ++CONFIG_SND_SOC_MAX98090=y ++# CONFIG_SND_SOC_MAX98357A is not set ++# CONFIG_SND_SOC_MAX98504 is not set ++# CONFIG_SND_SOC_MAX9867 is not set ++# CONFIG_SND_SOC_MAX98927 is not set ++# CONFIG_SND_SOC_MAX98520 is not set ++# CONFIG_SND_SOC_MAX98373_I2C is not set ++# CONFIG_SND_SOC_MAX98390 is not set ++# CONFIG_SND_SOC_MAX9860 is not set ++# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set ++# CONFIG_SND_SOC_PCM1681 is not set ++# CONFIG_SND_SOC_PCM1789_I2C is not set ++# CONFIG_SND_SOC_PCM179X_I2C is not set ++# CONFIG_SND_SOC_PCM179X_SPI is not set ++# CONFIG_SND_SOC_PCM186X_I2C is not set ++# CONFIG_SND_SOC_PCM186X_SPI is not set ++# CONFIG_SND_SOC_PCM3060_I2C is not set ++# CONFIG_SND_SOC_PCM3060_SPI is not set ++# CONFIG_SND_SOC_PCM3168A_I2C is not set ++# CONFIG_SND_SOC_PCM3168A_SPI is not set ++# CONFIG_SND_SOC_PCM5102A is not set ++# CONFIG_SND_SOC_PCM512x_I2C is not set ++# CONFIG_SND_SOC_PCM512x_SPI is not set ++# CONFIG_SND_SOC_RK3328 is not set ++CONFIG_SND_SOC_RK817=y ++CONFIG_SND_SOC_RL6231=y ++# CONFIG_SND_SOC_RT5616 is not set ++# CONFIG_SND_SOC_RT5631 is not set ++# CONFIG_SND_SOC_RT5640 is not set ++CONFIG_SND_SOC_RT5645=y ++# CONFIG_SND_SOC_RT5659 is not set ++# CONFIG_SND_SOC_RT9120 is not set ++# CONFIG_SND_SOC_SGTL5000 is not set ++CONFIG_SND_SOC_SIMPLE_AMPLIFIER=y ++# CONFIG_SND_SOC_SIMPLE_MUX is not set ++CONFIG_SND_SOC_SPDIF=y ++# CONFIG_SND_SOC_SSM2305 is not set ++# CONFIG_SND_SOC_SSM2518 is not set ++# CONFIG_SND_SOC_SSM2602_SPI is not set ++# CONFIG_SND_SOC_SSM2602_I2C is not set ++# CONFIG_SND_SOC_SSM4567 is not set ++# CONFIG_SND_SOC_STA32X is not set ++# CONFIG_SND_SOC_STA350 is not set ++# CONFIG_SND_SOC_STI_SAS is not set ++# CONFIG_SND_SOC_TAS2552 is not set ++# CONFIG_SND_SOC_TAS2562 is not set ++# CONFIG_SND_SOC_TAS2764 is not set ++# CONFIG_SND_SOC_TAS2770 is not set ++# CONFIG_SND_SOC_TAS5086 is not set ++# CONFIG_SND_SOC_TAS571X is not set ++# CONFIG_SND_SOC_TAS5720 is not set ++# CONFIG_SND_SOC_TAS5805M is not set ++# CONFIG_SND_SOC_TAS6424 is not set ++# CONFIG_SND_SOC_TDA7419 is not set ++# CONFIG_SND_SOC_TFA9879 is not set ++# CONFIG_SND_SOC_TFA989X is not set ++# CONFIG_SND_SOC_TLV320ADC3XXX is not set ++# CONFIG_SND_SOC_TLV320AIC23_I2C is not set ++# CONFIG_SND_SOC_TLV320AIC23_SPI is not set ++# CONFIG_SND_SOC_TLV320AIC31XX is not set ++# CONFIG_SND_SOC_TLV320AIC32X4_I2C is not set ++# CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set ++# CONFIG_SND_SOC_TLV320AIC3X_I2C is not set ++# CONFIG_SND_SOC_TLV320AIC3X_SPI is not set ++# CONFIG_SND_SOC_TLV320ADCX140 is not set ++CONFIG_SND_SOC_TS3A227E=y ++# CONFIG_SND_SOC_TSCS42XX is not set ++# CONFIG_SND_SOC_TSCS454 is not set ++# CONFIG_SND_SOC_UDA1334 is not set ++# CONFIG_SND_SOC_WM8510 is not set ++# CONFIG_SND_SOC_WM8523 is not set ++# CONFIG_SND_SOC_WM8524 is not set ++# CONFIG_SND_SOC_WM8580 is not set ++# CONFIG_SND_SOC_WM8711 is not set ++# CONFIG_SND_SOC_WM8728 is not set ++# CONFIG_SND_SOC_WM8731 is not set ++# CONFIG_SND_SOC_WM8737 is not set ++# CONFIG_SND_SOC_WM8741 is not set ++# CONFIG_SND_SOC_WM8750 is not set ++# CONFIG_SND_SOC_WM8753 is not set ++# CONFIG_SND_SOC_WM8770 is not set ++# CONFIG_SND_SOC_WM8776 is not set ++# CONFIG_SND_SOC_WM8782 is not set ++# CONFIG_SND_SOC_WM8804_I2C is not set ++# CONFIG_SND_SOC_WM8804_SPI is not set ++# CONFIG_SND_SOC_WM8903 is not set ++# CONFIG_SND_SOC_WM8904 is not set ++# CONFIG_SND_SOC_WM8960 is not set ++# CONFIG_SND_SOC_WM8962 is not set ++# CONFIG_SND_SOC_WM8974 is not set ++# CONFIG_SND_SOC_WM8978 is not set ++# CONFIG_SND_SOC_WM8985 is not set ++# CONFIG_SND_SOC_ZL38060 is not set ++# CONFIG_SND_SOC_MAX9759 is not set ++# CONFIG_SND_SOC_MT6351 is not set ++# CONFIG_SND_SOC_MT6358 is not set ++# CONFIG_SND_SOC_MT6660 is not set ++# CONFIG_SND_SOC_NAU8315 is not set ++# CONFIG_SND_SOC_NAU8540 is not set ++# CONFIG_SND_SOC_NAU8810 is not set ++# CONFIG_SND_SOC_NAU8821 is not set ++# CONFIG_SND_SOC_NAU8822 is not set ++# CONFIG_SND_SOC_NAU8824 is not set ++# CONFIG_SND_SOC_TPA6130A2 is not set ++# CONFIG_SND_SOC_LPASS_WSA_MACRO is not set ++# CONFIG_SND_SOC_LPASS_VA_MACRO is not set ++# CONFIG_SND_SOC_LPASS_RX_MACRO is not set ++# CONFIG_SND_SOC_LPASS_TX_MACRO is not set ++# end of CODEC drivers ++ ++CONFIG_SND_SIMPLE_CARD_UTILS=y ++CONFIG_SND_SIMPLE_CARD=y ++CONFIG_SND_AUDIO_GRAPH_CARD=y ++CONFIG_SND_AUDIO_GRAPH_CARD2=y ++CONFIG_SND_AUDIO_GRAPH_CARD2_CUSTOM_SAMPLE=y ++CONFIG_SND_TEST_COMPONENT=y ++ ++# ++# HID support ++# ++CONFIG_HID=y ++CONFIG_HID_BATTERY_STRENGTH=y ++CONFIG_HIDRAW=y ++CONFIG_UHID=y ++CONFIG_HID_GENERIC=y ++ ++# ++# Special HID drivers ++# ++CONFIG_HID_A4TECH=y ++# CONFIG_HID_ACCUTOUCH is not set ++CONFIG_HID_ACRUX=y ++# CONFIG_HID_ACRUX_FF is not set ++CONFIG_HID_APPLE=y ++CONFIG_HID_APPLEIR=y ++# CONFIG_HID_ASUS is not set ++CONFIG_HID_AUREAL=y ++CONFIG_HID_BELKIN=y ++CONFIG_HID_BETOP_FF=y ++# CONFIG_HID_BIGBEN_FF is not set ++CONFIG_HID_CHERRY=y ++CONFIG_HID_CHICONY=y ++CONFIG_HID_CORSAIR=y ++# CONFIG_HID_COUGAR is not set ++# CONFIG_HID_MACALLY is not set ++CONFIG_HID_PRODIKEYS=y ++# CONFIG_HID_CMEDIA is not set ++CONFIG_HID_CP2112=y ++# CONFIG_HID_CREATIVE_SB0540 is not set ++CONFIG_HID_CYPRESS=y ++CONFIG_HID_DRAGONRISE=y ++CONFIG_DRAGONRISE_FF=y ++CONFIG_HID_EMS_FF=y ++# CONFIG_HID_ELAN is not set ++CONFIG_HID_ELECOM=y ++CONFIG_HID_ELO=y ++CONFIG_HID_EZKEY=y ++# CONFIG_HID_FT260 is not set ++CONFIG_HID_GEMBIRD=y ++CONFIG_HID_GFRM=y ++# CONFIG_HID_GLORIOUS is not set ++CONFIG_HID_HOLTEK=y ++CONFIG_HOLTEK_FF=y ++# CONFIG_HID_VIVALDI is not set ++CONFIG_HID_GT683R=y ++CONFIG_HID_KEYTOUCH=y ++CONFIG_HID_KYE=y ++CONFIG_HID_UCLOGIC=y ++CONFIG_HID_WALTOP=y ++# CONFIG_HID_VIEWSONIC is not set ++# CONFIG_HID_XIAOMI is not set ++CONFIG_HID_GYRATION=y ++CONFIG_HID_ICADE=y ++# CONFIG_HID_ITE is not set ++# CONFIG_HID_JABRA is not set ++CONFIG_HID_TWINHAN=y ++CONFIG_HID_KENSINGTON=y ++CONFIG_HID_LCPOWER=y ++CONFIG_HID_LED=y ++CONFIG_HID_LENOVO=y ++# CONFIG_HID_LETSKETCH is not set ++CONFIG_HID_LOGITECH=y ++CONFIG_HID_LOGITECH_DJ=y ++CONFIG_HID_LOGITECH_HIDPP=y ++CONFIG_LOGITECH_FF=y ++CONFIG_LOGIRUMBLEPAD2_FF=y ++CONFIG_LOGIG940_FF=y ++CONFIG_LOGIWHEELS_FF=y ++CONFIG_HID_MAGICMOUSE=y ++# CONFIG_HID_MALTRON is not set ++# CONFIG_HID_MAYFLASH is not set ++# CONFIG_HID_REDRAGON is not set ++CONFIG_HID_MICROSOFT=y ++CONFIG_HID_MONTEREY=y ++CONFIG_HID_MULTITOUCH=y ++# CONFIG_HID_NINTENDO is not set ++# CONFIG_HID_NTI is not set ++CONFIG_HID_NTRIG=y ++CONFIG_HID_ORTEK=y ++CONFIG_HID_PANTHERLORD=y ++CONFIG_PANTHERLORD_FF=y ++CONFIG_HID_PENMOUNT=y ++CONFIG_HID_PETALYNX=y ++# CONFIG_HID_PICOLCD is not set ++CONFIG_HID_PLANTRONICS=y ++# CONFIG_HID_RAZER is not set ++CONFIG_HID_PRIMAX=y ++# CONFIG_HID_RETRODE is not set ++CONFIG_HID_ROCCAT=y ++CONFIG_HID_SAITEK=y ++CONFIG_HID_SAMSUNG=y ++# CONFIG_HID_SEMITEK is not set ++# CONFIG_HID_SIGMAMICRO is not set ++CONFIG_HID_SONY=y ++# CONFIG_SONY_FF is not set ++CONFIG_HID_SPEEDLINK=y ++# CONFIG_HID_STEAM is not set ++CONFIG_HID_STEELSERIES=y ++CONFIG_HID_SUNPLUS=y ++CONFIG_HID_RMI=y ++CONFIG_HID_GREENASIA=y ++CONFIG_GREENASIA_FF=y ++CONFIG_HID_SMARTJOYPLUS=y ++CONFIG_SMARTJOYPLUS_FF=y ++CONFIG_HID_TIVO=y ++CONFIG_HID_TOPSEED=y ++CONFIG_HID_THINGM=y ++CONFIG_HID_THRUSTMASTER=y ++CONFIG_THRUSTMASTER_FF=y ++# CONFIG_HID_UDRAW_PS3 is not set ++# CONFIG_HID_U2FZERO is not set ++CONFIG_HID_WACOM=y ++CONFIG_HID_WIIMOTE=y ++CONFIG_HID_XINMO=y ++CONFIG_HID_ZEROPLUS=y ++CONFIG_ZEROPLUS_FF=y ++CONFIG_HID_ZYDACRON=y ++CONFIG_HID_SENSOR_HUB=y ++CONFIG_HID_SENSOR_CUSTOM_SENSOR=y ++CONFIG_HID_ALPS=y ++# CONFIG_HID_MCP2221 is not set ++# end of Special HID drivers ++ ++# ++# USB HID support ++# ++CONFIG_USB_HID=y ++# CONFIG_HID_PID is not set ++CONFIG_USB_HIDDEV=y ++# end of USB HID support ++ ++# ++# I2C HID support ++# ++# CONFIG_I2C_HID_OF is not set ++CONFIG_I2C_HID_OF_GOODIX=y ++# end of I2C HID support ++ ++CONFIG_I2C_HID_CORE=y ++# end of HID support ++ ++CONFIG_USB_OHCI_LITTLE_ENDIAN=y ++CONFIG_USB_SUPPORT=y ++CONFIG_USB_COMMON=y ++# CONFIG_USB_LED_TRIG is not set ++# CONFIG_USB_ULPI_BUS is not set ++# CONFIG_USB_CONN_GPIO is not set ++CONFIG_USB_ARCH_HAS_HCD=y ++CONFIG_USB=y ++CONFIG_USB_PCI=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++ ++# ++# Miscellaneous USB options ++# ++# CONFIG_USB_DEFAULT_PERSIST is not set ++# CONFIG_USB_FEW_INIT_RETRIES is not set ++# CONFIG_USB_DYNAMIC_MINORS is not set ++CONFIG_USB_OTG=y ++# CONFIG_USB_OTG_PRODUCTLIST is not set ++# CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB is not set ++# CONFIG_USB_OTG_FSM is not set ++# CONFIG_USB_LEDS_TRIGGER_USBPORT is not set ++CONFIG_USB_AUTOSUSPEND_DELAY=2 ++CONFIG_USB_MON=y ++ ++# ++# USB Host Controller Drivers ++# ++# CONFIG_USB_C67X00_HCD is not set ++CONFIG_USB_XHCI_HCD=y ++# CONFIG_USB_XHCI_DBGCAP is not set ++CONFIG_USB_XHCI_PCI=y ++# CONFIG_USB_XHCI_PCI_RENESAS is not set ++CONFIG_USB_XHCI_PLATFORM=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_ROOT_HUB_TT=y ++CONFIG_USB_EHCI_TT_NEWSCHED=y ++CONFIG_USB_EHCI_PCI=y ++# CONFIG_USB_EHCI_FSL is not set ++CONFIG_USB_EHCI_HCD_PLATFORM=y ++# CONFIG_USB_OXU210HP_HCD is not set ++# CONFIG_USB_ISP116X_HCD is not set ++# CONFIG_USB_FOTG210_HCD is not set ++# CONFIG_USB_MAX3421_HCD is not set ++CONFIG_USB_OHCI_HCD=y ++# CONFIG_USB_OHCI_HCD_PCI is not set ++# CONFIG_USB_OHCI_HCD_SSB is not set ++CONFIG_USB_OHCI_HCD_PLATFORM=y ++# CONFIG_USB_UHCI_HCD is not set ++# CONFIG_USB_SL811_HCD is not set ++# CONFIG_USB_R8A66597_HCD is not set ++# CONFIG_USB_HCD_BCMA is not set ++# CONFIG_USB_HCD_SSB is not set ++# CONFIG_USB_HCD_TEST_MODE is not set ++ ++# ++# USB Device Class drivers ++# ++CONFIG_USB_ACM=m ++# CONFIG_USB_PRINTER is not set ++CONFIG_USB_WDM=y ++# CONFIG_USB_TMC is not set ++ ++# ++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may ++# ++ ++# ++# also be needed; see USB_STORAGE Help for more info ++# ++CONFIG_USB_STORAGE=y ++# CONFIG_USB_STORAGE_DEBUG is not set ++CONFIG_USB_STORAGE_REALTEK=y ++CONFIG_REALTEK_AUTOPM=y ++CONFIG_USB_STORAGE_DATAFAB=y ++CONFIG_USB_STORAGE_FREECOM=y ++CONFIG_USB_STORAGE_ISD200=y ++CONFIG_USB_STORAGE_USBAT=y ++CONFIG_USB_STORAGE_SDDR09=y ++CONFIG_USB_STORAGE_SDDR55=y ++CONFIG_USB_STORAGE_JUMPSHOT=y ++CONFIG_USB_STORAGE_ALAUDA=y ++CONFIG_USB_STORAGE_ONETOUCH=y ++CONFIG_USB_STORAGE_KARMA=y ++CONFIG_USB_STORAGE_CYPRESS_ATACB=y ++CONFIG_USB_STORAGE_ENE_UB6250=y ++CONFIG_USB_UAS=y ++ ++# ++# USB Imaging devices ++# ++# CONFIG_USB_MDC800 is not set ++# CONFIG_USB_MICROTEK is not set ++# CONFIG_USBIP_CORE is not set ++# CONFIG_USB_CDNS_SUPPORT is not set ++# CONFIG_USB_MUSB_HDRC is not set ++CONFIG_USB_DWC3=y ++# CONFIG_USB_DWC3_HOST is not set ++# CONFIG_USB_DWC3_GADGET is not set ++CONFIG_USB_DWC3_DUAL_ROLE=y ++ ++# ++# Platform Glue Driver Support ++# ++CONFIG_USB_DWC3_HAPS=y ++CONFIG_USB_DWC3_OF_SIMPLE=y ++CONFIG_USB_DWC2=y ++# CONFIG_USB_DWC2_HOST is not set ++ ++# ++# Gadget/Dual-role mode requires USB Gadget support to be enabled ++# ++# CONFIG_USB_DWC2_PERIPHERAL is not set ++CONFIG_USB_DWC2_DUAL_ROLE=y ++# CONFIG_USB_DWC2_PCI is not set ++# CONFIG_USB_DWC2_DEBUG is not set ++# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set ++# CONFIG_USB_CHIPIDEA is not set ++# CONFIG_USB_ISP1760 is not set ++ ++# ++# USB port drivers ++# ++CONFIG_USB_SERIAL=y ++# CONFIG_USB_SERIAL_CONSOLE is not set ++CONFIG_USB_SERIAL_GENERIC=y ++# CONFIG_USB_SERIAL_SIMPLE is not set ++# CONFIG_USB_SERIAL_AIRCABLE is not set ++# CONFIG_USB_SERIAL_ARK3116 is not set ++# CONFIG_USB_SERIAL_BELKIN is not set ++CONFIG_USB_SERIAL_CH341=y ++# CONFIG_USB_SERIAL_WHITEHEAT is not set ++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set ++CONFIG_USB_SERIAL_CP210X=y ++# CONFIG_USB_SERIAL_CYPRESS_M8 is not set ++# CONFIG_USB_SERIAL_EMPEG is not set ++CONFIG_USB_SERIAL_FTDI_SIO=y ++# CONFIG_USB_SERIAL_VISOR is not set ++# CONFIG_USB_SERIAL_IPAQ is not set ++# CONFIG_USB_SERIAL_IR is not set ++# CONFIG_USB_SERIAL_EDGEPORT is not set ++# CONFIG_USB_SERIAL_EDGEPORT_TI is not set ++# CONFIG_USB_SERIAL_F81232 is not set ++# CONFIG_USB_SERIAL_F8153X is not set ++# CONFIG_USB_SERIAL_GARMIN is not set ++# CONFIG_USB_SERIAL_IPW is not set ++# CONFIG_USB_SERIAL_IUU is not set ++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set ++CONFIG_USB_SERIAL_KEYSPAN=y ++# CONFIG_USB_SERIAL_KLSI is not set ++# CONFIG_USB_SERIAL_KOBIL_SCT is not set ++# CONFIG_USB_SERIAL_MCT_U232 is not set ++# CONFIG_USB_SERIAL_METRO is not set ++# CONFIG_USB_SERIAL_MOS7720 is not set ++# CONFIG_USB_SERIAL_MOS7840 is not set ++# CONFIG_USB_SERIAL_MXUPORT is not set ++# CONFIG_USB_SERIAL_NAVMAN is not set ++CONFIG_USB_SERIAL_PL2303=y ++CONFIG_USB_SERIAL_OTI6858=y ++# CONFIG_USB_SERIAL_QCAUX is not set ++CONFIG_USB_SERIAL_QUALCOMM=y ++# CONFIG_USB_SERIAL_SPCP8X5 is not set ++# CONFIG_USB_SERIAL_SAFE is not set ++CONFIG_USB_SERIAL_SIERRAWIRELESS=y ++# CONFIG_USB_SERIAL_SYMBOL is not set ++# CONFIG_USB_SERIAL_TI is not set ++# CONFIG_USB_SERIAL_CYBERJACK is not set ++CONFIG_USB_SERIAL_WWAN=y ++CONFIG_USB_SERIAL_OPTION=y ++# CONFIG_USB_SERIAL_OMNINET is not set ++# CONFIG_USB_SERIAL_OPTICON is not set ++# CONFIG_USB_SERIAL_XSENS_MT is not set ++# CONFIG_USB_SERIAL_WISHBONE is not set ++# CONFIG_USB_SERIAL_SSU100 is not set ++# CONFIG_USB_SERIAL_QT2 is not set ++# CONFIG_USB_SERIAL_UPD78F0730 is not set ++# CONFIG_USB_SERIAL_XR is not set ++# CONFIG_USB_SERIAL_DEBUG is not set ++ ++# ++# USB Miscellaneous drivers ++# ++# CONFIG_USB_EMI62 is not set ++# CONFIG_USB_EMI26 is not set ++# CONFIG_USB_ADUTUX is not set ++# CONFIG_USB_SEVSEG is not set ++# CONFIG_USB_LEGOTOWER is not set ++# CONFIG_USB_LCD is not set ++# CONFIG_USB_CYPRESS_CY7C63 is not set ++# CONFIG_USB_CYTHERM is not set ++# CONFIG_USB_IDMOUSE is not set ++# CONFIG_USB_FTDI_ELAN is not set ++# CONFIG_USB_APPLEDISPLAY is not set ++# CONFIG_APPLE_MFI_FASTCHARGE is not set ++# CONFIG_USB_SISUSBVGA is not set ++# CONFIG_USB_LD is not set ++# CONFIG_USB_TRANCEVIBRATOR is not set ++# CONFIG_USB_IOWARRIOR is not set ++# CONFIG_USB_TEST is not set ++# CONFIG_USB_EHSET_TEST_FIXTURE is not set ++# CONFIG_USB_ISIGHTFW is not set ++# CONFIG_USB_YUREX is not set ++CONFIG_USB_EZUSB_FX2=y ++# CONFIG_USB_HUB_USB251XB is not set ++# CONFIG_USB_HSIC_USB3503 is not set ++# CONFIG_USB_HSIC_USB4604 is not set ++# CONFIG_USB_LINK_LAYER_TEST is not set ++# CONFIG_USB_CHAOSKEY is not set ++ ++# ++# USB Physical Layer drivers ++# ++CONFIG_USB_PHY=y ++CONFIG_NOP_USB_XCEIV=y ++# CONFIG_USB_GPIO_VBUS is not set ++# CONFIG_USB_ISP1301 is not set ++# CONFIG_USB_ULPI is not set ++# end of USB Physical Layer drivers ++ ++CONFIG_USB_GADGET=y ++# CONFIG_USB_GADGET_DEBUG is not set ++CONFIG_USB_GADGET_DEBUG_FILES=y ++# CONFIG_USB_GADGET_DEBUG_FS is not set ++CONFIG_USB_GADGET_VBUS_DRAW=500 ++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 ++CONFIG_U_SERIAL_CONSOLE=y ++ ++# ++# USB Peripheral Controller ++# ++# CONFIG_USB_FOTG210_UDC is not set ++# CONFIG_USB_GR_UDC is not set ++# CONFIG_USB_R8A66597 is not set ++# CONFIG_USB_PXA27X is not set ++# CONFIG_USB_MV_UDC is not set ++# CONFIG_USB_MV_U3D is not set ++# CONFIG_USB_SNP_UDC_PLAT is not set ++# CONFIG_USB_M66592 is not set ++# CONFIG_USB_BDC_UDC is not set ++# CONFIG_USB_AMD5536UDC is not set ++# CONFIG_USB_NET2272 is not set ++# CONFIG_USB_NET2280 is not set ++# CONFIG_USB_GOKU is not set ++# CONFIG_USB_EG20T is not set ++# CONFIG_USB_GADGET_XILINX is not set ++# CONFIG_USB_MAX3420_UDC is not set ++# CONFIG_USB_DUMMY_HCD is not set ++# end of USB Peripheral Controller ++ ++CONFIG_USB_LIBCOMPOSITE=y ++CONFIG_USB_F_ACM=y ++CONFIG_USB_U_SERIAL=y ++CONFIG_USB_F_SERIAL=y ++CONFIG_USB_F_OBEX=y ++CONFIG_USB_F_MASS_STORAGE=y ++CONFIG_USB_F_FS=y ++CONFIG_USB_CONFIGFS=y ++# CONFIG_USB_CONFIGFS_SERIAL is not set ++CONFIG_USB_CONFIGFS_ACM=y ++# CONFIG_USB_CONFIGFS_OBEX is not set ++# CONFIG_USB_CONFIGFS_NCM is not set ++# CONFIG_USB_CONFIGFS_ECM is not set ++# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set ++# CONFIG_USB_CONFIGFS_RNDIS is not set ++# CONFIG_USB_CONFIGFS_EEM is not set ++CONFIG_USB_CONFIGFS_MASS_STORAGE=y ++# CONFIG_USB_CONFIGFS_F_LB_SS is not set ++CONFIG_USB_CONFIGFS_F_FS=y ++# CONFIG_USB_CONFIGFS_F_UAC1 is not set ++# CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set ++# CONFIG_USB_CONFIGFS_F_UAC2 is not set ++# CONFIG_USB_CONFIGFS_F_MIDI is not set ++# CONFIG_USB_CONFIGFS_F_HID is not set ++# CONFIG_USB_CONFIGFS_F_UVC is not set ++# CONFIG_USB_CONFIGFS_F_PRINTER is not set ++ ++# ++# USB Gadget precomposed configurations ++# ++# CONFIG_USB_ZERO is not set ++# CONFIG_USB_AUDIO is not set ++# CONFIG_USB_ETH is not set ++# CONFIG_USB_G_NCM is not set ++# CONFIG_USB_GADGETFS is not set ++# CONFIG_USB_FUNCTIONFS is not set ++# CONFIG_USB_MASS_STORAGE is not set ++CONFIG_USB_G_SERIAL=y ++# CONFIG_USB_MIDI_GADGET is not set ++# CONFIG_USB_G_PRINTER is not set ++# CONFIG_USB_CDC_COMPOSITE is not set ++# CONFIG_USB_G_ACM_MS is not set ++# CONFIG_USB_G_MULTI is not set ++# CONFIG_USB_G_HID is not set ++# CONFIG_USB_G_DBGP is not set ++# CONFIG_USB_G_WEBCAM is not set ++# CONFIG_USB_RAW_GADGET is not set ++# end of USB Gadget precomposed configurations ++ ++CONFIG_TYPEC=y ++CONFIG_TYPEC_TCPM=y ++# CONFIG_TYPEC_TCPCI is not set ++CONFIG_TYPEC_FUSB302=y ++# CONFIG_TYPEC_UCSI is not set ++# CONFIG_TYPEC_TPS6598X is not set ++# CONFIG_TYPEC_RT1719 is not set ++# CONFIG_TYPEC_HD3SS3220 is not set ++# CONFIG_TYPEC_STUSB160X is not set ++# CONFIG_TYPEC_WUSB3801 is not set ++ ++# ++# USB Type-C Multiplexer/DeMultiplexer Switch support ++# ++# CONFIG_TYPEC_MUX_PI3USB30532 is not set ++# end of USB Type-C Multiplexer/DeMultiplexer Switch support ++ ++# ++# USB Type-C Alternate Mode drivers ++# ++CONFIG_TYPEC_DP_ALTMODE=y ++# CONFIG_TYPEC_NVIDIA_ALTMODE is not set ++# end of USB Type-C Alternate Mode drivers ++ ++CONFIG_USB_ROLE_SWITCH=y ++CONFIG_MMC=y ++CONFIG_PWRSEQ_EMMC=y ++# CONFIG_PWRSEQ_SD8787 is not set ++CONFIG_PWRSEQ_SIMPLE=y ++CONFIG_MMC_BLOCK=y ++CONFIG_MMC_BLOCK_MINORS=32 ++# CONFIG_SDIO_UART is not set ++CONFIG_MMC_TEST=y ++ ++# ++# MMC/SD/SDIO Host Controller Drivers ++# ++# CONFIG_MMC_DEBUG is not set ++# CONFIG_MMC_ARMMMCI is not set ++CONFIG_MMC_SDHCI=y ++# CONFIG_MMC_SDHCI_PCI is not set ++CONFIG_MMC_SDHCI_PLTFM=y ++CONFIG_MMC_SDHCI_OF_ARASAN=y ++# CONFIG_MMC_SDHCI_OF_ASPEED is not set ++# CONFIG_MMC_SDHCI_OF_AT91 is not set ++# CONFIG_MMC_SDHCI_OF_DWCMSHC is not set ++# CONFIG_MMC_SDHCI_CADENCE is not set ++# CONFIG_MMC_SDHCI_F_SDH30 is not set ++# CONFIG_MMC_SDHCI_MILBEAUT is not set ++# CONFIG_MMC_TIFM_SD is not set ++# CONFIG_MMC_SPI is not set ++# CONFIG_MMC_SDRICOH_CS is not set ++# CONFIG_MMC_CB710 is not set ++# CONFIG_MMC_VIA_SDMMC is not set ++CONFIG_MMC_DW=y ++CONFIG_MMC_DW_PLTFM=y ++# CONFIG_MMC_DW_BLUEFIELD is not set ++# CONFIG_MMC_DW_EXYNOS is not set ++# CONFIG_MMC_DW_HI3798CV200 is not set ++# CONFIG_MMC_DW_K3 is not set ++# CONFIG_MMC_DW_PCI is not set ++CONFIG_MMC_DW_ROCKCHIP=y ++# CONFIG_MMC_VUB300 is not set ++# CONFIG_MMC_USHC is not set ++# CONFIG_MMC_USDHI6ROL0 is not set ++CONFIG_MMC_CQHCI=y ++# CONFIG_MMC_HSQ is not set ++# CONFIG_MMC_TOSHIBA_PCI is not set ++# CONFIG_MMC_MTK is not set ++# CONFIG_MMC_SDHCI_XENON is not set ++# CONFIG_MMC_SDHCI_OMAP is not set ++# CONFIG_MMC_SDHCI_AM654 is not set ++# CONFIG_MEMSTICK is not set ++CONFIG_NEW_LEDS=y ++CONFIG_LEDS_CLASS=y ++# CONFIG_LEDS_CLASS_FLASH is not set ++# CONFIG_LEDS_CLASS_MULTICOLOR is not set ++# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set ++ ++# ++# LED drivers ++# ++# CONFIG_LEDS_AN30259A is not set ++# CONFIG_LEDS_AW2013 is not set ++# CONFIG_LEDS_BCM6328 is not set ++# CONFIG_LEDS_BCM6358 is not set ++# CONFIG_LEDS_CR0014114 is not set ++# CONFIG_LEDS_EL15203000 is not set ++# CONFIG_LEDS_LM3530 is not set ++# CONFIG_LEDS_LM3532 is not set ++# CONFIG_LEDS_LM3642 is not set ++# CONFIG_LEDS_LM3692X is not set ++# CONFIG_LEDS_PCA9532 is not set ++CONFIG_LEDS_GPIO=y ++# CONFIG_LEDS_LP3944 is not set ++# CONFIG_LEDS_LP3952 is not set ++# CONFIG_LEDS_LP50XX is not set ++# CONFIG_LEDS_LP55XX_COMMON is not set ++# CONFIG_LEDS_LP8860 is not set ++# CONFIG_LEDS_PCA955X is not set ++# CONFIG_LEDS_PCA963X is not set ++# CONFIG_LEDS_DAC124S085 is not set ++CONFIG_LEDS_PWM=y ++# CONFIG_LEDS_REGULATOR is not set ++# CONFIG_LEDS_BD2802 is not set ++# CONFIG_LEDS_LT3593 is not set ++# CONFIG_LEDS_TCA6507 is not set ++# CONFIG_LEDS_TLC591XX is not set ++# CONFIG_LEDS_LM355x is not set ++# CONFIG_LEDS_IS31FL319X is not set ++CONFIG_LEDS_IS31FL32XX=y ++ ++# ++# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) ++# ++# CONFIG_LEDS_BLINKM is not set ++CONFIG_LEDS_SYSCON=y ++# CONFIG_LEDS_MLXREG is not set ++# CONFIG_LEDS_USER is not set ++# CONFIG_LEDS_SPI_BYTE is not set ++# CONFIG_LEDS_TI_LMU_COMMON is not set ++ ++# ++# Flash and Torch LED drivers ++# ++ ++# ++# LED Triggers ++# ++CONFIG_LEDS_TRIGGERS=y ++CONFIG_LEDS_TRIGGER_TIMER=y ++CONFIG_LEDS_TRIGGER_ONESHOT=y ++CONFIG_LEDS_TRIGGER_DISK=y ++CONFIG_LEDS_TRIGGER_HEARTBEAT=y ++CONFIG_LEDS_TRIGGER_BACKLIGHT=y ++CONFIG_LEDS_TRIGGER_CPU=y ++# CONFIG_LEDS_TRIGGER_ACTIVITY is not set ++CONFIG_LEDS_TRIGGER_GPIO=y ++CONFIG_LEDS_TRIGGER_DEFAULT_ON=y ++ ++# ++# iptables trigger is under Netfilter config (LED target) ++# ++# CONFIG_LEDS_TRIGGER_TRANSIENT is not set ++# CONFIG_LEDS_TRIGGER_CAMERA is not set ++# CONFIG_LEDS_TRIGGER_PANIC is not set ++# CONFIG_LEDS_TRIGGER_NETDEV is not set ++# CONFIG_LEDS_TRIGGER_PATTERN is not set ++# CONFIG_LEDS_TRIGGER_AUDIO is not set ++# CONFIG_LEDS_TRIGGER_TTY is not set ++ ++# ++# Simple LED drivers ++# ++# CONFIG_ACCESSIBILITY is not set ++# CONFIG_INFINIBAND is not set ++CONFIG_EDAC_SUPPORT=y ++# CONFIG_EDAC is not set ++CONFIG_RTC_LIB=y ++CONFIG_RTC_CLASS=y ++CONFIG_RTC_HCTOSYS=y ++CONFIG_RTC_HCTOSYS_DEVICE="rtc0" ++# CONFIG_RTC_SYSTOHC is not set ++# CONFIG_RTC_DEBUG is not set ++CONFIG_RTC_NVMEM=y ++ ++# ++# RTC interfaces ++# ++CONFIG_RTC_INTF_SYSFS=y ++# CONFIG_RTC_INTF_PROC is not set ++# CONFIG_RTC_INTF_DEV is not set ++# CONFIG_RTC_DRV_TEST is not set ++ ++# ++# I2C RTC drivers ++# ++# CONFIG_RTC_DRV_ABB5ZES3 is not set ++# CONFIG_RTC_DRV_ABEOZ9 is not set ++# CONFIG_RTC_DRV_ABX80X is not set ++# CONFIG_RTC_DRV_DS1307 is not set ++# CONFIG_RTC_DRV_DS1374 is not set ++# CONFIG_RTC_DRV_DS1672 is not set ++CONFIG_RTC_DRV_HYM8563=y ++# CONFIG_RTC_DRV_MAX6900 is not set ++CONFIG_RTC_DRV_RK808=y ++# CONFIG_RTC_DRV_RS5C372 is not set ++# CONFIG_RTC_DRV_ISL1208 is not set ++# CONFIG_RTC_DRV_ISL12022 is not set ++# CONFIG_RTC_DRV_ISL12026 is not set ++# CONFIG_RTC_DRV_X1205 is not set ++# CONFIG_RTC_DRV_PCF8523 is not set ++# CONFIG_RTC_DRV_PCF85063 is not set ++# CONFIG_RTC_DRV_PCF85363 is not set ++# CONFIG_RTC_DRV_PCF8563 is not set ++# CONFIG_RTC_DRV_PCF8583 is not set ++# CONFIG_RTC_DRV_M41T80 is not set ++# CONFIG_RTC_DRV_BQ32K is not set ++# CONFIG_RTC_DRV_TPS6586X is not set ++# CONFIG_RTC_DRV_S35390A is not set ++# CONFIG_RTC_DRV_FM3130 is not set ++# CONFIG_RTC_DRV_RX8010 is not set ++# CONFIG_RTC_DRV_RX8581 is not set ++# CONFIG_RTC_DRV_RX8025 is not set ++# CONFIG_RTC_DRV_EM3027 is not set ++# CONFIG_RTC_DRV_RV3028 is not set ++# CONFIG_RTC_DRV_RV3032 is not set ++# CONFIG_RTC_DRV_RV8803 is not set ++# CONFIG_RTC_DRV_SD3078 is not set ++ ++# ++# SPI RTC drivers ++# ++# CONFIG_RTC_DRV_M41T93 is not set ++# CONFIG_RTC_DRV_M41T94 is not set ++# CONFIG_RTC_DRV_DS1302 is not set ++# CONFIG_RTC_DRV_DS1305 is not set ++# CONFIG_RTC_DRV_DS1343 is not set ++# CONFIG_RTC_DRV_DS1347 is not set ++# CONFIG_RTC_DRV_DS1390 is not set ++# CONFIG_RTC_DRV_MAX6916 is not set ++# CONFIG_RTC_DRV_R9701 is not set ++# CONFIG_RTC_DRV_RX4581 is not set ++# CONFIG_RTC_DRV_RS5C348 is not set ++# CONFIG_RTC_DRV_MAX6902 is not set ++# CONFIG_RTC_DRV_PCF2123 is not set ++# CONFIG_RTC_DRV_MCP795 is not set ++CONFIG_RTC_I2C_AND_SPI=y ++ ++# ++# SPI and I2C RTC drivers ++# ++# CONFIG_RTC_DRV_DS3232 is not set ++# CONFIG_RTC_DRV_PCF2127 is not set ++# CONFIG_RTC_DRV_RV3029C2 is not set ++# CONFIG_RTC_DRV_RX6110 is not set ++ ++# ++# Platform RTC drivers ++# ++# CONFIG_RTC_DRV_DS1286 is not set ++# CONFIG_RTC_DRV_DS1511 is not set ++# CONFIG_RTC_DRV_DS1553 is not set ++# CONFIG_RTC_DRV_DS1685_FAMILY is not set ++# CONFIG_RTC_DRV_DS1742 is not set ++# CONFIG_RTC_DRV_DS2404 is not set ++# CONFIG_RTC_DRV_STK17TA8 is not set ++# CONFIG_RTC_DRV_M48T86 is not set ++# CONFIG_RTC_DRV_M48T35 is not set ++# CONFIG_RTC_DRV_M48T59 is not set ++# CONFIG_RTC_DRV_MSM6242 is not set ++# CONFIG_RTC_DRV_BQ4802 is not set ++# CONFIG_RTC_DRV_RP5C01 is not set ++# CONFIG_RTC_DRV_V3020 is not set ++# CONFIG_RTC_DRV_ZYNQMP is not set ++ ++# ++# on-CPU RTC drivers ++# ++# CONFIG_RTC_DRV_PL030 is not set ++# CONFIG_RTC_DRV_PL031 is not set ++# CONFIG_RTC_DRV_CADENCE is not set ++# CONFIG_RTC_DRV_FTRTC010 is not set ++# CONFIG_RTC_DRV_R7301 is not set ++ ++# ++# HID Sensor RTC drivers ++# ++# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set ++# CONFIG_RTC_DRV_GOLDFISH is not set ++CONFIG_DMADEVICES=y ++# CONFIG_DMADEVICES_DEBUG is not set ++ ++# ++# DMA Devices ++# ++CONFIG_DMA_ENGINE=y ++CONFIG_DMA_OF=y ++# CONFIG_ALTERA_MSGDMA is not set ++# CONFIG_AMBA_PL08X is not set ++# CONFIG_BCM_SBA_RAID is not set ++# CONFIG_DW_AXI_DMAC is not set ++# CONFIG_FSL_EDMA is not set ++# CONFIG_FSL_QDMA is not set ++# CONFIG_HISI_DMA is not set ++# CONFIG_INTEL_IDMA64 is not set ++# CONFIG_MV_XOR_V2 is not set ++CONFIG_PL330_DMA=y ++# CONFIG_PLX_DMA is not set ++# CONFIG_XILINX_DMA is not set ++# CONFIG_XILINX_ZYNQMP_DMA is not set ++# CONFIG_XILINX_ZYNQMP_DPDMA is not set ++# CONFIG_QCOM_HIDMA_MGMT is not set ++# CONFIG_QCOM_HIDMA is not set ++# CONFIG_DW_DMAC is not set ++# CONFIG_DW_DMAC_PCI is not set ++# CONFIG_DW_EDMA is not set ++# CONFIG_DW_EDMA_PCIE is not set ++# CONFIG_SF_PDMA is not set ++ ++# ++# DMA Clients ++# ++# CONFIG_ASYNC_TX_DMA is not set ++# CONFIG_DMATEST is not set ++ ++# ++# DMABUF options ++# ++CONFIG_SYNC_FILE=y ++# CONFIG_SW_SYNC is not set ++# CONFIG_UDMABUF is not set ++# CONFIG_DMABUF_MOVE_NOTIFY is not set ++# CONFIG_DMABUF_DEBUG is not set ++# CONFIG_DMABUF_SELFTESTS is not set ++# CONFIG_DMABUF_HEAPS is not set ++# CONFIG_DMABUF_SYSFS_STATS is not set ++# end of DMABUF options ++ ++# CONFIG_AUXDISPLAY is not set ++# CONFIG_UIO is not set ++# CONFIG_VFIO is not set ++# CONFIG_VIRT_DRIVERS is not set ++# CONFIG_VIRTIO_MENU is not set ++# CONFIG_VDPA is not set ++# CONFIG_VHOST_MENU is not set ++ ++# ++# Microsoft Hyper-V guest support ++# ++# end of Microsoft Hyper-V guest support ++ ++# CONFIG_GREYBUS is not set ++# CONFIG_COMEDI is not set ++CONFIG_STAGING=y ++# CONFIG_PRISM2_USB is not set ++# CONFIG_RTL8192U is not set ++# CONFIG_RTLLIB is not set ++CONFIG_RTL8723BS=m ++# CONFIG_R8712U is not set ++# CONFIG_R8188EU is not set ++# CONFIG_RTS5208 is not set ++# CONFIG_VT6655 is not set ++# CONFIG_VT6656 is not set ++ ++# ++# IIO staging drivers ++# ++ ++# ++# Accelerometers ++# ++# CONFIG_ADIS16203 is not set ++# CONFIG_ADIS16240 is not set ++# end of Accelerometers ++ ++# ++# Analog to digital converters ++# ++# CONFIG_AD7816 is not set ++# end of Analog to digital converters ++ ++# ++# Analog digital bi-direction converters ++# ++# CONFIG_ADT7316 is not set ++# end of Analog digital bi-direction converters ++ ++# ++# Capacitance to digital converters ++# ++# CONFIG_AD7746 is not set ++# end of Capacitance to digital converters ++ ++# ++# Direct Digital Synthesis ++# ++# CONFIG_AD9832 is not set ++# CONFIG_AD9834 is not set ++# end of Direct Digital Synthesis ++ ++# ++# Network Analyzer, Impedance Converters ++# ++# CONFIG_AD5933 is not set ++# end of Network Analyzer, Impedance Converters ++ ++# ++# Active energy metering IC ++# ++# CONFIG_ADE7854 is not set ++# end of Active energy metering IC ++ ++# ++# Resolver to digital converters ++# ++# CONFIG_AD2S1210 is not set ++# end of Resolver to digital converters ++# end of IIO staging drivers ++ ++# CONFIG_FB_SM750 is not set ++# CONFIG_STAGING_MEDIA is not set ++# CONFIG_STAGING_BOARD is not set ++# CONFIG_LTE_GDM724X is not set ++# CONFIG_UNISYSSPAR is not set ++# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set ++# CONFIG_FB_TFT is not set ++# CONFIG_KS7010 is not set ++# CONFIG_PI433 is not set ++# CONFIG_XIL_AXIS_FIFO is not set ++# CONFIG_FIELDBUS_DEV is not set ++# CONFIG_QLGE is not set ++# CONFIG_WFX is not set ++# CONFIG_GOLDFISH is not set ++CONFIG_CHROME_PLATFORMS=y ++# CONFIG_CROS_EC is not set ++# CONFIG_MELLANOX_PLATFORM is not set ++# CONFIG_SURFACE_PLATFORMS is not set ++CONFIG_HAVE_CLK=y ++CONFIG_HAVE_CLK_PREPARE=y ++CONFIG_COMMON_CLK=y ++ ++# ++# Clock driver for ARM Reference designs ++# ++# CONFIG_CLK_ICST is not set ++# CONFIG_CLK_SP810 is not set ++# end of Clock driver for ARM Reference designs ++ ++# CONFIG_LMK04832 is not set ++# CONFIG_COMMON_CLK_MAX9485 is not set ++CONFIG_COMMON_CLK_RK808=y ++# CONFIG_COMMON_CLK_SCMI is not set ++# CONFIG_COMMON_CLK_SCPI is not set ++# CONFIG_COMMON_CLK_SI5341 is not set ++# CONFIG_COMMON_CLK_SI5351 is not set ++# CONFIG_COMMON_CLK_SI514 is not set ++# CONFIG_COMMON_CLK_SI544 is not set ++# CONFIG_COMMON_CLK_SI570 is not set ++# CONFIG_COMMON_CLK_CDCE706 is not set ++# CONFIG_COMMON_CLK_CDCE925 is not set ++# CONFIG_COMMON_CLK_CS2000_CP is not set ++# CONFIG_COMMON_CLK_AXI_CLKGEN is not set ++CONFIG_COMMON_CLK_XGENE=y ++# CONFIG_COMMON_CLK_PWM is not set ++# CONFIG_COMMON_CLK_RS9_PCIE is not set ++# CONFIG_COMMON_CLK_VC5 is not set ++# CONFIG_COMMON_CLK_FIXED_MMIO is not set ++CONFIG_COMMON_CLK_ROCKCHIP=y ++CONFIG_CLK_PX30=y ++# CONFIG_CLK_RK3308 is not set ++# CONFIG_CLK_RK3328 is not set ++# CONFIG_CLK_RK3368 is not set ++CONFIG_CLK_RK3399=y ++# CONFIG_CLK_RK3568 is not set ++# CONFIG_XILINX_VCU is not set ++# CONFIG_HWSPINLOCK is not set ++ ++# ++# Clock Source drivers ++# ++CONFIG_TIMER_OF=y ++CONFIG_TIMER_PROBE=y ++CONFIG_CLKSRC_MMIO=y ++CONFIG_ROCKCHIP_TIMER=y ++CONFIG_ARM_ARCH_TIMER=y ++CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y ++# CONFIG_FSL_ERRATUM_A008585 is not set ++# CONFIG_HISILICON_ERRATUM_161010101 is not set ++# CONFIG_ARM64_ERRATUM_858921 is not set ++# CONFIG_MICROCHIP_PIT64B is not set ++# end of Clock Source drivers ++ ++CONFIG_MAILBOX=y ++CONFIG_ARM_MHU=y ++# CONFIG_ARM_MHU_V2 is not set ++CONFIG_PLATFORM_MHU=y ++# CONFIG_PL320_MBOX is not set ++CONFIG_ROCKCHIP_MBOX=y ++# CONFIG_ALTERA_MBOX is not set ++# CONFIG_MAILBOX_TEST is not set ++CONFIG_IOMMU_IOVA=y ++CONFIG_IOMMU_API=y ++CONFIG_IOMMU_SUPPORT=y ++ ++# ++# Generic IOMMU Pagetable Support ++# ++CONFIG_IOMMU_IO_PGTABLE=y ++CONFIG_IOMMU_IO_PGTABLE_LPAE=y ++# CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST is not set ++# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set ++# end of Generic IOMMU Pagetable Support ++ ++# CONFIG_IOMMU_DEBUGFS is not set ++CONFIG_IOMMU_DEFAULT_DMA_STRICT=y ++# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set ++# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set ++CONFIG_OF_IOMMU=y ++CONFIG_IOMMU_DMA=y ++CONFIG_ROCKCHIP_IOMMU=y ++CONFIG_ARM_SMMU=y ++# CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS is not set ++CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y ++CONFIG_ARM_SMMU_V3=y ++# CONFIG_ARM_SMMU_V3_SVA is not set ++ ++# ++# Remoteproc drivers ++# ++# CONFIG_REMOTEPROC is not set ++# end of Remoteproc drivers ++ ++# ++# Rpmsg drivers ++# ++# CONFIG_RPMSG_QCOM_GLINK_RPM is not set ++# CONFIG_RPMSG_VIRTIO is not set ++# end of Rpmsg drivers ++ ++# CONFIG_SOUNDWIRE is not set ++ ++# ++# SOC (System On Chip) specific Drivers ++# ++ ++# ++# Amlogic SoC drivers ++# ++# end of Amlogic SoC drivers ++ ++# ++# Broadcom SoC drivers ++# ++# CONFIG_SOC_BRCMSTB is not set ++# end of Broadcom SoC drivers ++ ++# ++# NXP/Freescale QorIQ SoC drivers ++# ++# CONFIG_QUICC_ENGINE is not set ++# CONFIG_FSL_RCPM is not set ++# end of NXP/Freescale QorIQ SoC drivers ++ ++# ++# i.MX SoC drivers ++# ++# end of i.MX SoC drivers ++ ++# ++# Enable LiteX SoC Builder specific drivers ++# ++# CONFIG_LITEX_SOC_CONTROLLER is not set ++# end of Enable LiteX SoC Builder specific drivers ++ ++# ++# Qualcomm SoC drivers ++# ++# end of Qualcomm SoC drivers ++ ++CONFIG_ROCKCHIP_GRF=y ++CONFIG_ROCKCHIP_IODOMAIN=y ++CONFIG_ROCKCHIP_PM_DOMAINS=y ++# CONFIG_SOC_TI is not set ++ ++# ++# Xilinx SoC drivers ++# ++# end of Xilinx SoC drivers ++# end of SOC (System On Chip) specific Drivers ++ ++CONFIG_PM_DEVFREQ=y ++ ++# ++# DEVFREQ Governors ++# ++CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y ++CONFIG_DEVFREQ_GOV_PERFORMANCE=y ++CONFIG_DEVFREQ_GOV_POWERSAVE=y ++CONFIG_DEVFREQ_GOV_USERSPACE=y ++# CONFIG_DEVFREQ_GOV_PASSIVE is not set ++ ++# ++# DEVFREQ Drivers ++# ++# CONFIG_ARM_RK3399_DMC_DEVFREQ is not set ++CONFIG_PM_DEVFREQ_EVENT=y ++CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI=y ++CONFIG_EXTCON=y ++ ++# ++# Extcon Device Drivers ++# ++# CONFIG_EXTCON_ADC_JACK is not set ++# CONFIG_EXTCON_FSA9480 is not set ++# CONFIG_EXTCON_GPIO is not set ++# CONFIG_EXTCON_MAX3355 is not set ++# CONFIG_EXTCON_PTN5150 is not set ++# CONFIG_EXTCON_RT8973A is not set ++# CONFIG_EXTCON_SM5502 is not set ++# CONFIG_EXTCON_USB_GPIO is not set ++# CONFIG_EXTCON_USBC_TUSB320 is not set ++CONFIG_MEMORY=y ++# CONFIG_ARM_PL172_MPMC is not set ++CONFIG_IIO=y ++CONFIG_IIO_BUFFER=y ++CONFIG_IIO_BUFFER_CB=y ++# CONFIG_IIO_BUFFER_DMA is not set ++# CONFIG_IIO_BUFFER_DMAENGINE is not set ++# CONFIG_IIO_BUFFER_HW_CONSUMER is not set ++CONFIG_IIO_KFIFO_BUF=y ++CONFIG_IIO_TRIGGERED_BUFFER=y ++CONFIG_IIO_CONFIGFS=y ++CONFIG_IIO_TRIGGER=y ++CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 ++# CONFIG_IIO_SW_DEVICE is not set ++CONFIG_IIO_SW_TRIGGER=y ++CONFIG_IIO_TRIGGERED_EVENT=y ++ ++# ++# Accelerometers ++# ++# CONFIG_ADIS16201 is not set ++# CONFIG_ADIS16209 is not set ++# CONFIG_ADXL313_I2C is not set ++# CONFIG_ADXL313_SPI is not set ++# CONFIG_ADXL345_I2C is not set ++# CONFIG_ADXL345_SPI is not set ++# CONFIG_ADXL355_I2C is not set ++# CONFIG_ADXL355_SPI is not set ++# CONFIG_ADXL367_SPI is not set ++# CONFIG_ADXL367_I2C is not set ++# CONFIG_ADXL372_SPI is not set ++# CONFIG_ADXL372_I2C is not set ++# CONFIG_BMA180 is not set ++# CONFIG_BMA220 is not set ++# CONFIG_BMA400 is not set ++# CONFIG_BMC150_ACCEL is not set ++# CONFIG_BMI088_ACCEL is not set ++# CONFIG_DA280 is not set ++# CONFIG_DA311 is not set ++# CONFIG_DMARD06 is not set ++# CONFIG_DMARD09 is not set ++# CONFIG_DMARD10 is not set ++# CONFIG_FXLS8962AF_I2C is not set ++# CONFIG_FXLS8962AF_SPI is not set ++# CONFIG_HID_SENSOR_ACCEL_3D is not set ++# CONFIG_IIO_ST_ACCEL_3AXIS is not set ++# CONFIG_KXSD9 is not set ++# CONFIG_KXCJK1013 is not set ++# CONFIG_MC3230 is not set ++# CONFIG_MMA7455_I2C is not set ++# CONFIG_MMA7455_SPI is not set ++# CONFIG_MMA7660 is not set ++# CONFIG_MMA8452 is not set ++# CONFIG_MMA9551 is not set ++# CONFIG_MMA9553 is not set ++# CONFIG_MXC4005 is not set ++# CONFIG_MXC6255 is not set ++# CONFIG_SCA3000 is not set ++# CONFIG_SCA3300 is not set ++# CONFIG_STK8312 is not set ++# CONFIG_STK8BA50 is not set ++# end of Accelerometers ++ ++# ++# Analog to digital converters ++# ++# CONFIG_AD7091R5 is not set ++# CONFIG_AD7124 is not set ++# CONFIG_AD7192 is not set ++# CONFIG_AD7266 is not set ++# CONFIG_AD7280 is not set ++# CONFIG_AD7291 is not set ++# CONFIG_AD7292 is not set ++# CONFIG_AD7298 is not set ++# CONFIG_AD7476 is not set ++# CONFIG_AD7606_IFACE_PARALLEL is not set ++# CONFIG_AD7606_IFACE_SPI is not set ++# CONFIG_AD7766 is not set ++# CONFIG_AD7768_1 is not set ++# CONFIG_AD7780 is not set ++# CONFIG_AD7791 is not set ++# CONFIG_AD7793 is not set ++# CONFIG_AD7887 is not set ++# CONFIG_AD7923 is not set ++# CONFIG_AD7949 is not set ++# CONFIG_AD799X is not set ++# CONFIG_ADI_AXI_ADC is not set ++# CONFIG_CC10001_ADC is not set ++# CONFIG_ENVELOPE_DETECTOR is not set ++# CONFIG_HI8435 is not set ++# CONFIG_HX711 is not set ++# CONFIG_INA2XX_ADC is not set ++# CONFIG_LTC2471 is not set ++# CONFIG_LTC2485 is not set ++# CONFIG_LTC2496 is not set ++# CONFIG_LTC2497 is not set ++# CONFIG_MAX1027 is not set ++# CONFIG_MAX11100 is not set ++# CONFIG_MAX1118 is not set ++# CONFIG_MAX1241 is not set ++# CONFIG_MAX1363 is not set ++# CONFIG_MAX9611 is not set ++# CONFIG_MCP320X is not set ++# CONFIG_MCP3422 is not set ++# CONFIG_MCP3911 is not set ++# CONFIG_NAU7802 is not set ++CONFIG_ROCKCHIP_SARADC=y ++# CONFIG_SD_ADC_MODULATOR is not set ++# CONFIG_TI_ADC081C is not set ++# CONFIG_TI_ADC0832 is not set ++# CONFIG_TI_ADC084S021 is not set ++# CONFIG_TI_ADC12138 is not set ++# CONFIG_TI_ADC108S102 is not set ++# CONFIG_TI_ADC128S052 is not set ++# CONFIG_TI_ADC161S626 is not set ++# CONFIG_TI_ADS1015 is not set ++# CONFIG_TI_ADS7950 is not set ++# CONFIG_TI_ADS8344 is not set ++# CONFIG_TI_ADS8688 is not set ++# CONFIG_TI_ADS124S08 is not set ++# CONFIG_TI_ADS131E08 is not set ++# CONFIG_TI_TLC4541 is not set ++# CONFIG_TI_TSC2046 is not set ++# CONFIG_VF610_ADC is not set ++# CONFIG_XILINX_XADC is not set ++# end of Analog to digital converters ++ ++# ++# Analog to digital and digital to analog converters ++# ++# CONFIG_AD74413R is not set ++# end of Analog to digital and digital to analog converters ++ ++# ++# Analog Front Ends ++# ++# CONFIG_IIO_RESCALE is not set ++# end of Analog Front Ends ++ ++# ++# Amplifiers ++# ++# CONFIG_AD8366 is not set ++# CONFIG_ADA4250 is not set ++# CONFIG_HMC425 is not set ++# end of Amplifiers ++ ++# ++# Capacitance to digital converters ++# ++# CONFIG_AD7150 is not set ++# end of Capacitance to digital converters ++ ++# ++# Chemical Sensors ++# ++# CONFIG_ATLAS_PH_SENSOR is not set ++# CONFIG_ATLAS_EZO_SENSOR is not set ++# CONFIG_BME680 is not set ++# CONFIG_CCS811 is not set ++# CONFIG_IAQCORE is not set ++# CONFIG_PMS7003 is not set ++# CONFIG_SCD30_CORE is not set ++# CONFIG_SCD4X is not set ++# CONFIG_SENSIRION_SGP30 is not set ++# CONFIG_SENSIRION_SGP40 is not set ++# CONFIG_SPS30_I2C is not set ++# CONFIG_SPS30_SERIAL is not set ++# CONFIG_SENSEAIR_SUNRISE_CO2 is not set ++# CONFIG_VZ89X is not set ++# end of Chemical Sensors ++ ++# ++# Hid Sensor IIO Common ++# ++# CONFIG_HID_SENSOR_IIO_COMMON is not set ++# end of Hid Sensor IIO Common ++ ++# ++# IIO SCMI Sensors ++# ++# CONFIG_IIO_SCMI is not set ++# end of IIO SCMI Sensors ++ ++# ++# SSP Sensor Common ++# ++# CONFIG_IIO_SSP_SENSORHUB is not set ++# end of SSP Sensor Common ++ ++# ++# Digital to analog converters ++# ++# CONFIG_AD3552R is not set ++# CONFIG_AD5064 is not set ++# CONFIG_AD5360 is not set ++# CONFIG_AD5380 is not set ++# CONFIG_AD5421 is not set ++# CONFIG_AD5446 is not set ++# CONFIG_AD5449 is not set ++# CONFIG_AD5592R is not set ++# CONFIG_AD5593R is not set ++# CONFIG_AD5504 is not set ++# CONFIG_AD5624R_SPI is not set ++# CONFIG_LTC2688 is not set ++# CONFIG_AD5686_SPI is not set ++# CONFIG_AD5696_I2C is not set ++# CONFIG_AD5755 is not set ++# CONFIG_AD5758 is not set ++# CONFIG_AD5761 is not set ++# CONFIG_AD5764 is not set ++# CONFIG_AD5766 is not set ++# CONFIG_AD5770R is not set ++# CONFIG_AD5791 is not set ++# CONFIG_AD7293 is not set ++# CONFIG_AD7303 is not set ++# CONFIG_AD8801 is not set ++# CONFIG_DPOT_DAC is not set ++# CONFIG_DS4424 is not set ++# CONFIG_LTC1660 is not set ++# CONFIG_LTC2632 is not set ++# CONFIG_M62332 is not set ++# CONFIG_MAX517 is not set ++# CONFIG_MAX5821 is not set ++# CONFIG_MCP4725 is not set ++# CONFIG_MCP4922 is not set ++# CONFIG_TI_DAC082S085 is not set ++# CONFIG_TI_DAC5571 is not set ++# CONFIG_TI_DAC7311 is not set ++# CONFIG_TI_DAC7612 is not set ++# CONFIG_VF610_DAC is not set ++# end of Digital to analog converters ++ ++# ++# IIO dummy driver ++# ++# end of IIO dummy driver ++ ++# ++# Filters ++# ++# CONFIG_ADMV8818 is not set ++# end of Filters ++ ++# ++# Frequency Synthesizers DDS/PLL ++# ++ ++# ++# Clock Generator/Distribution ++# ++# CONFIG_AD9523 is not set ++# end of Clock Generator/Distribution ++ ++# ++# Phase-Locked Loop (PLL) frequency synthesizers ++# ++# CONFIG_ADF4350 is not set ++# CONFIG_ADF4371 is not set ++# CONFIG_ADMV1013 is not set ++# CONFIG_ADMV1014 is not set ++# CONFIG_ADMV4420 is not set ++# CONFIG_ADRF6780 is not set ++# end of Phase-Locked Loop (PLL) frequency synthesizers ++# end of Frequency Synthesizers DDS/PLL ++ ++# ++# Digital gyroscope sensors ++# ++# CONFIG_ADIS16080 is not set ++# CONFIG_ADIS16130 is not set ++# CONFIG_ADIS16136 is not set ++# CONFIG_ADIS16260 is not set ++# CONFIG_ADXRS290 is not set ++# CONFIG_ADXRS450 is not set ++# CONFIG_BMG160 is not set ++# CONFIG_FXAS21002C is not set ++# CONFIG_HID_SENSOR_GYRO_3D is not set ++# CONFIG_MPU3050_I2C is not set ++# CONFIG_IIO_ST_GYRO_3AXIS is not set ++# CONFIG_ITG3200 is not set ++# end of Digital gyroscope sensors ++ ++# ++# Health Sensors ++# ++ ++# ++# Heart Rate Monitors ++# ++# CONFIG_AFE4403 is not set ++# CONFIG_AFE4404 is not set ++# CONFIG_MAX30100 is not set ++# CONFIG_MAX30102 is not set ++# end of Heart Rate Monitors ++# end of Health Sensors ++ ++# ++# Humidity sensors ++# ++# CONFIG_AM2315 is not set ++# CONFIG_DHT11 is not set ++# CONFIG_HDC100X is not set ++# CONFIG_HDC2010 is not set ++# CONFIG_HID_SENSOR_HUMIDITY is not set ++# CONFIG_HTS221 is not set ++# CONFIG_HTU21 is not set ++# CONFIG_SI7005 is not set ++# CONFIG_SI7020 is not set ++# end of Humidity sensors ++ ++# ++# Inertial measurement units ++# ++# CONFIG_ADIS16400 is not set ++# CONFIG_ADIS16460 is not set ++# CONFIG_ADIS16475 is not set ++# CONFIG_ADIS16480 is not set ++# CONFIG_BMI160_I2C is not set ++# CONFIG_BMI160_SPI is not set ++# CONFIG_FXOS8700_I2C is not set ++# CONFIG_FXOS8700_SPI is not set ++# CONFIG_KMX61 is not set ++# CONFIG_INV_ICM42600_I2C is not set ++# CONFIG_INV_ICM42600_SPI is not set ++# CONFIG_INV_MPU6050_I2C is not set ++# CONFIG_INV_MPU6050_SPI is not set ++# CONFIG_IIO_ST_LSM6DSX is not set ++# CONFIG_IIO_ST_LSM9DS0 is not set ++# end of Inertial measurement units ++ ++# ++# Light sensors ++# ++# CONFIG_ADJD_S311 is not set ++# CONFIG_ADUX1020 is not set ++# CONFIG_AL3010 is not set ++# CONFIG_AL3320A is not set ++# CONFIG_APDS9300 is not set ++# CONFIG_APDS9960 is not set ++# CONFIG_AS73211 is not set ++# CONFIG_BH1750 is not set ++# CONFIG_BH1780 is not set ++# CONFIG_CM32181 is not set ++# CONFIG_CM3232 is not set ++# CONFIG_CM3323 is not set ++# CONFIG_CM3605 is not set ++# CONFIG_CM36651 is not set ++# CONFIG_GP2AP002 is not set ++# CONFIG_GP2AP020A00F is not set ++CONFIG_SENSORS_ISL29018=y ++# CONFIG_SENSORS_ISL29028 is not set ++# CONFIG_ISL29125 is not set ++# CONFIG_HID_SENSOR_ALS is not set ++# CONFIG_HID_SENSOR_PROX is not set ++# CONFIG_JSA1212 is not set ++# CONFIG_RPR0521 is not set ++# CONFIG_LTR501 is not set ++# CONFIG_LV0104CS is not set ++# CONFIG_MAX44000 is not set ++# CONFIG_MAX44009 is not set ++# CONFIG_NOA1305 is not set ++# CONFIG_OPT3001 is not set ++# CONFIG_PA12203001 is not set ++# CONFIG_SI1133 is not set ++# CONFIG_SI1145 is not set ++# CONFIG_STK3310 is not set ++# CONFIG_ST_UVIS25 is not set ++# CONFIG_TCS3414 is not set ++# CONFIG_TCS3472 is not set ++CONFIG_SENSORS_TSL2563=y ++CONFIG_TSL2583=y ++# CONFIG_TSL2591 is not set ++# CONFIG_TSL2772 is not set ++# CONFIG_TSL4531 is not set ++# CONFIG_US5182D is not set ++# CONFIG_VCNL4000 is not set ++# CONFIG_VCNL4035 is not set ++# CONFIG_VEML6030 is not set ++# CONFIG_VEML6070 is not set ++# CONFIG_VL6180 is not set ++# CONFIG_ZOPT2201 is not set ++# end of Light sensors ++ ++# ++# Magnetometer sensors ++# ++# CONFIG_AK8974 is not set ++# CONFIG_AK8975 is not set ++# CONFIG_AK09911 is not set ++# CONFIG_BMC150_MAGN_I2C is not set ++# CONFIG_BMC150_MAGN_SPI is not set ++# CONFIG_MAG3110 is not set ++# CONFIG_HID_SENSOR_MAGNETOMETER_3D is not set ++# CONFIG_MMC35240 is not set ++# CONFIG_IIO_ST_MAGN_3AXIS is not set ++# CONFIG_SENSORS_HMC5843_I2C is not set ++# CONFIG_SENSORS_HMC5843_SPI is not set ++# CONFIG_SENSORS_RM3100_I2C is not set ++# CONFIG_SENSORS_RM3100_SPI is not set ++# CONFIG_YAMAHA_YAS530 is not set ++# end of Magnetometer sensors ++ ++# ++# Multiplexers ++# ++CONFIG_IIO_MUX=y ++# end of Multiplexers ++ ++# ++# Inclinometer sensors ++# ++# CONFIG_HID_SENSOR_INCLINOMETER_3D is not set ++# CONFIG_HID_SENSOR_DEVICE_ROTATION is not set ++# end of Inclinometer sensors ++ ++# ++# Triggers - standalone ++# ++CONFIG_IIO_HRTIMER_TRIGGER=y ++# CONFIG_IIO_INTERRUPT_TRIGGER is not set ++# CONFIG_IIO_TIGHTLOOP_TRIGGER is not set ++CONFIG_IIO_SYSFS_TRIGGER=y ++# end of Triggers - standalone ++ ++# ++# Linear and angular position sensors ++# ++# CONFIG_HID_SENSOR_CUSTOM_INTEL_HINGE is not set ++# end of Linear and angular position sensors ++ ++# ++# Digital potentiometers ++# ++# CONFIG_AD5110 is not set ++# CONFIG_AD5272 is not set ++# CONFIG_DS1803 is not set ++# CONFIG_MAX5432 is not set ++# CONFIG_MAX5481 is not set ++# CONFIG_MAX5487 is not set ++# CONFIG_MCP4018 is not set ++# CONFIG_MCP4131 is not set ++# CONFIG_MCP4531 is not set ++# CONFIG_MCP41010 is not set ++# CONFIG_TPL0102 is not set ++# end of Digital potentiometers ++ ++# ++# Digital potentiostats ++# ++# CONFIG_LMP91000 is not set ++# end of Digital potentiostats ++ ++# ++# Pressure sensors ++# ++# CONFIG_ABP060MG is not set ++# CONFIG_BMP280 is not set ++# CONFIG_DLHL60D is not set ++# CONFIG_DPS310 is not set ++# CONFIG_HID_SENSOR_PRESS is not set ++# CONFIG_HP03 is not set ++# CONFIG_ICP10100 is not set ++# CONFIG_MPL115_I2C is not set ++# CONFIG_MPL115_SPI is not set ++# CONFIG_MPL3115 is not set ++# CONFIG_MS5611 is not set ++# CONFIG_MS5637 is not set ++# CONFIG_IIO_ST_PRESS is not set ++# CONFIG_T5403 is not set ++# CONFIG_HP206C is not set ++# CONFIG_ZPA2326 is not set ++# end of Pressure sensors ++ ++# ++# Lightning sensors ++# ++# CONFIG_AS3935 is not set ++# end of Lightning sensors ++ ++# ++# Proximity and distance sensors ++# ++# CONFIG_ISL29501 is not set ++# CONFIG_LIDAR_LITE_V2 is not set ++# CONFIG_MB1232 is not set ++# CONFIG_PING is not set ++# CONFIG_RFD77402 is not set ++# CONFIG_SRF04 is not set ++# CONFIG_SX9310 is not set ++# CONFIG_SX9324 is not set ++# CONFIG_SX9360 is not set ++# CONFIG_SX9500 is not set ++# CONFIG_SRF08 is not set ++# CONFIG_VCNL3020 is not set ++# CONFIG_VL53L0X_I2C is not set ++# end of Proximity and distance sensors ++ ++# ++# Resolver to digital converters ++# ++# CONFIG_AD2S90 is not set ++# CONFIG_AD2S1200 is not set ++# end of Resolver to digital converters ++ ++# ++# Temperature sensors ++# ++# CONFIG_LTC2983 is not set ++# CONFIG_MAXIM_THERMOCOUPLE is not set ++# CONFIG_HID_SENSOR_TEMP is not set ++# CONFIG_MLX90614 is not set ++# CONFIG_MLX90632 is not set ++# CONFIG_TMP006 is not set ++# CONFIG_TMP007 is not set ++# CONFIG_TMP117 is not set ++# CONFIG_TSYS01 is not set ++# CONFIG_TSYS02D is not set ++# CONFIG_MAX31856 is not set ++# CONFIG_MAX31865 is not set ++# end of Temperature sensors ++ ++# CONFIG_NTB is not set ++# CONFIG_VME_BUS is not set ++CONFIG_PWM=y ++CONFIG_PWM_SYSFS=y ++# CONFIG_PWM_DEBUG is not set ++# CONFIG_PWM_ATMEL_TCB is not set ++# CONFIG_PWM_DWC is not set ++# CONFIG_PWM_FSL_FTM is not set ++# CONFIG_PWM_PCA9685 is not set ++CONFIG_PWM_ROCKCHIP=y ++ ++# ++# IRQ chip support ++# ++CONFIG_IRQCHIP=y ++CONFIG_ARM_GIC=y ++CONFIG_ARM_GIC_MAX_NR=1 ++CONFIG_ARM_GIC_V2M=y ++CONFIG_ARM_GIC_V3=y ++CONFIG_ARM_GIC_V3_ITS=y ++CONFIG_ARM_GIC_V3_ITS_PCI=y ++# CONFIG_AL_FIC is not set ++CONFIG_PARTITION_PERCPU=y ++# end of IRQ chip support ++ ++# CONFIG_IPACK_BUS is not set ++CONFIG_ARCH_HAS_RESET_CONTROLLER=y ++CONFIG_RESET_CONTROLLER=y ++CONFIG_RESET_SCMI=y ++# CONFIG_RESET_TI_SYSCON is not set ++ ++# ++# PHY Subsystem ++# ++CONFIG_GENERIC_PHY=y ++CONFIG_GENERIC_PHY_MIPI_DPHY=y ++# CONFIG_PHY_XGENE is not set ++# CONFIG_PHY_CAN_TRANSCEIVER is not set ++ ++# ++# PHY drivers for Broadcom platforms ++# ++# CONFIG_BCM_KONA_USB2_PHY is not set ++# end of PHY drivers for Broadcom platforms ++ ++# CONFIG_PHY_CADENCE_TORRENT is not set ++# CONFIG_PHY_CADENCE_DPHY is not set ++# CONFIG_PHY_CADENCE_DPHY_RX is not set ++# CONFIG_PHY_CADENCE_SIERRA is not set ++# CONFIG_PHY_CADENCE_SALVO is not set ++# CONFIG_PHY_PXA_28NM_HSIC is not set ++# CONFIG_PHY_PXA_28NM_USB2 is not set ++# CONFIG_PHY_LAN966X_SERDES is not set ++# CONFIG_PHY_CPCAP_USB is not set ++# CONFIG_PHY_MAPPHONE_MDM6600 is not set ++# CONFIG_PHY_OCELOT_SERDES is not set ++CONFIG_PHY_ROCKCHIP_DP=y ++CONFIG_PHY_ROCKCHIP_DPHY_RX0=y ++CONFIG_PHY_ROCKCHIP_EMMC=y ++CONFIG_PHY_ROCKCHIP_INNO_HDMI=y ++CONFIG_PHY_ROCKCHIP_INNO_USB2=y ++CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY=y ++CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY=y ++# CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY is not set ++CONFIG_PHY_ROCKCHIP_PCIE=y ++CONFIG_PHY_ROCKCHIP_TYPEC=y ++CONFIG_PHY_ROCKCHIP_USB=y ++# CONFIG_PHY_SAMSUNG_USB2 is not set ++# end of PHY Subsystem ++ ++# CONFIG_POWERCAP is not set ++# CONFIG_MCB is not set ++CONFIG_RAS=y ++# CONFIG_USB4 is not set ++ ++# ++# Android ++# ++CONFIG_ANDROID=y ++# CONFIG_ANDROID_BINDER_IPC is not set ++# end of Android ++ ++# CONFIG_LIBNVDIMM is not set ++# CONFIG_DAX is not set ++CONFIG_NVMEM=y ++CONFIG_NVMEM_SYSFS=y ++CONFIG_ROCKCHIP_EFUSE=y ++CONFIG_ROCKCHIP_OTP=y ++# CONFIG_NVMEM_RMEM is not set ++ ++# ++# HW tracing support ++# ++# CONFIG_STM is not set ++# CONFIG_INTEL_TH is not set ++# end of HW tracing support ++ ++# CONFIG_FPGA is not set ++# CONFIG_FSI is not set ++# CONFIG_TEE is not set ++CONFIG_MULTIPLEXER=y ++ ++# ++# Multiplexer drivers ++# ++# CONFIG_MUX_ADG792A is not set ++# CONFIG_MUX_ADGS1408 is not set ++CONFIG_MUX_GPIO=y ++CONFIG_MUX_MMIO=y ++# end of Multiplexer drivers ++ ++CONFIG_PM_OPP=y ++# CONFIG_SIOX is not set ++# CONFIG_SLIMBUS is not set ++# CONFIG_INTERCONNECT is not set ++# CONFIG_COUNTER is not set ++# CONFIG_MOST is not set ++# CONFIG_PECI is not set ++# end of Device Drivers ++ ++# ++# File systems ++# ++CONFIG_DCACHE_WORD_ACCESS=y ++# CONFIG_VALIDATE_FS_PARSER is not set ++CONFIG_FS_IOMAP=y ++# CONFIG_EXT2_FS is not set ++# CONFIG_EXT3_FS is not set ++CONFIG_EXT4_FS=y ++# CONFIG_EXT4_USE_FOR_EXT2 is not set ++CONFIG_EXT4_FS_POSIX_ACL=y ++CONFIG_EXT4_FS_SECURITY=y ++# CONFIG_EXT4_DEBUG is not set ++CONFIG_JBD2=y ++# CONFIG_JBD2_DEBUG is not set ++CONFIG_FS_MBCACHE=y ++# CONFIG_REISERFS_FS is not set ++# CONFIG_JFS_FS is not set ++CONFIG_XFS_FS=y ++CONFIG_XFS_SUPPORT_V4=y ++# CONFIG_XFS_QUOTA is not set ++# CONFIG_XFS_POSIX_ACL is not set ++# CONFIG_XFS_RT is not set ++# CONFIG_XFS_ONLINE_SCRUB is not set ++# CONFIG_XFS_WARN is not set ++# CONFIG_XFS_DEBUG is not set ++# CONFIG_GFS2_FS is not set ++# CONFIG_OCFS2_FS is not set ++# CONFIG_BTRFS_FS is not set ++# CONFIG_NILFS2_FS is not set ++# CONFIG_F2FS_FS is not set ++CONFIG_FS_POSIX_ACL=y ++CONFIG_EXPORTFS=y ++# CONFIG_EXPORTFS_BLOCK_OPS is not set ++CONFIG_FILE_LOCKING=y ++# CONFIG_FS_ENCRYPTION is not set ++# CONFIG_FS_VERITY is not set ++CONFIG_FSNOTIFY=y ++# CONFIG_DNOTIFY is not set ++CONFIG_INOTIFY_USER=y ++# CONFIG_FANOTIFY is not set ++# CONFIG_QUOTA is not set ++# CONFIG_AUTOFS4_FS is not set ++# CONFIG_AUTOFS_FS is not set ++CONFIG_FUSE_FS=y ++# CONFIG_CUSE is not set ++# CONFIG_VIRTIO_FS is not set ++CONFIG_OVERLAY_FS=y ++# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set ++CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y ++# CONFIG_OVERLAY_FS_INDEX is not set ++# CONFIG_OVERLAY_FS_XINO_AUTO is not set ++# CONFIG_OVERLAY_FS_METACOPY is not set ++ ++# ++# Caches ++# ++CONFIG_NETFS_SUPPORT=y ++# CONFIG_NETFS_STATS is not set ++CONFIG_FSCACHE=y ++# CONFIG_FSCACHE_STATS is not set ++# CONFIG_FSCACHE_DEBUG is not set ++# CONFIG_CACHEFILES is not set ++# end of Caches ++ ++# ++# CD-ROM/DVD Filesystems ++# ++CONFIG_ISO9660_FS=y ++CONFIG_JOLIET=y ++CONFIG_ZISOFS=y ++# CONFIG_UDF_FS is not set ++# end of CD-ROM/DVD Filesystems ++ ++# ++# DOS/FAT/EXFAT/NT Filesystems ++# ++CONFIG_FAT_FS=y ++# CONFIG_MSDOS_FS is not set ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_CODEPAGE=936 ++CONFIG_FAT_DEFAULT_IOCHARSET="utf8" ++# CONFIG_FAT_DEFAULT_UTF8 is not set ++CONFIG_EXFAT_FS=y ++CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8" ++# CONFIG_NTFS_FS is not set ++# CONFIG_NTFS3_FS is not set ++# end of DOS/FAT/EXFAT/NT Filesystems ++ ++# ++# Pseudo filesystems ++# ++CONFIG_PROC_FS=y ++# CONFIG_PROC_KCORE is not set ++CONFIG_PROC_SYSCTL=y ++CONFIG_PROC_PAGE_MONITOR=y ++# CONFIG_PROC_CHILDREN is not set ++CONFIG_KERNFS=y ++CONFIG_SYSFS=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_TMPFS_XATTR=y ++# CONFIG_TMPFS_INODE64 is not set ++CONFIG_ARCH_SUPPORTS_HUGETLBFS=y ++# CONFIG_HUGETLBFS is not set ++CONFIG_MEMFD_CREATE=y ++CONFIG_ARCH_HAS_GIGANTIC_PAGE=y ++CONFIG_CONFIGFS_FS=y ++# end of Pseudo filesystems ++ ++CONFIG_MISC_FILESYSTEMS=y ++# CONFIG_ORANGEFS_FS is not set ++# CONFIG_ADFS_FS is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_ECRYPT_FS is not set ++# CONFIG_HFS_FS is not set ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BFS_FS is not set ++# CONFIG_EFS_FS is not set ++# CONFIG_CRAMFS is not set ++CONFIG_SQUASHFS=y ++CONFIG_SQUASHFS_FILE_CACHE=y ++# CONFIG_SQUASHFS_FILE_DIRECT is not set ++# CONFIG_SQUASHFS_DECOMP_SINGLE is not set ++# CONFIG_SQUASHFS_DECOMP_MULTI is not set ++CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y ++# CONFIG_SQUASHFS_XATTR is not set ++CONFIG_SQUASHFS_ZLIB=y ++CONFIG_SQUASHFS_LZ4=y ++CONFIG_SQUASHFS_LZO=y ++CONFIG_SQUASHFS_XZ=y ++CONFIG_SQUASHFS_ZSTD=y ++# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set ++# CONFIG_SQUASHFS_EMBEDDED is not set ++CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 ++# CONFIG_VXFS_FS is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_OMFS_FS is not set ++# CONFIG_HPFS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_QNX6FS_FS is not set ++# CONFIG_ROMFS_FS is not set ++CONFIG_PSTORE=y ++CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240 ++CONFIG_PSTORE_DEFLATE_COMPRESS=y ++# CONFIG_PSTORE_LZO_COMPRESS is not set ++# CONFIG_PSTORE_LZ4_COMPRESS is not set ++# CONFIG_PSTORE_LZ4HC_COMPRESS is not set ++# CONFIG_PSTORE_842_COMPRESS is not set ++# CONFIG_PSTORE_ZSTD_COMPRESS is not set ++CONFIG_PSTORE_COMPRESS=y ++CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT=y ++CONFIG_PSTORE_COMPRESS_DEFAULT="deflate" ++# CONFIG_PSTORE_CONSOLE is not set ++# CONFIG_PSTORE_PMSG is not set ++# CONFIG_PSTORE_RAM is not set ++# CONFIG_PSTORE_BLK is not set ++# CONFIG_SYSV_FS is not set ++# CONFIG_UFS_FS is not set ++# CONFIG_EROFS_FS is not set ++CONFIG_NETWORK_FILESYSTEMS=y ++# CONFIG_NFS_FS is not set ++# CONFIG_NFSD is not set ++# CONFIG_CEPH_FS is not set ++# CONFIG_CIFS is not set ++# CONFIG_SMB_SERVER is not set ++# CONFIG_CODA_FS is not set ++# CONFIG_AFS_FS is not set ++CONFIG_NLS=y ++CONFIG_NLS_DEFAULT="utf8" ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_CODEPAGE_737=y ++CONFIG_NLS_CODEPAGE_775=y ++CONFIG_NLS_CODEPAGE_850=y ++CONFIG_NLS_CODEPAGE_852=y ++CONFIG_NLS_CODEPAGE_855=y ++CONFIG_NLS_CODEPAGE_857=y ++CONFIG_NLS_CODEPAGE_860=y ++CONFIG_NLS_CODEPAGE_861=y ++CONFIG_NLS_CODEPAGE_862=y ++CONFIG_NLS_CODEPAGE_863=y ++CONFIG_NLS_CODEPAGE_864=y ++CONFIG_NLS_CODEPAGE_865=y ++CONFIG_NLS_CODEPAGE_866=y ++CONFIG_NLS_CODEPAGE_869=y ++CONFIG_NLS_CODEPAGE_936=y ++CONFIG_NLS_CODEPAGE_950=y ++CONFIG_NLS_CODEPAGE_932=y ++CONFIG_NLS_CODEPAGE_949=y ++CONFIG_NLS_CODEPAGE_874=y ++CONFIG_NLS_ISO8859_8=y ++CONFIG_NLS_CODEPAGE_1250=y ++CONFIG_NLS_CODEPAGE_1251=y ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_NLS_ISO8859_2=y ++CONFIG_NLS_ISO8859_3=y ++CONFIG_NLS_ISO8859_4=y ++CONFIG_NLS_ISO8859_5=y ++CONFIG_NLS_ISO8859_6=y ++CONFIG_NLS_ISO8859_7=y ++CONFIG_NLS_ISO8859_9=y ++CONFIG_NLS_ISO8859_13=y ++CONFIG_NLS_ISO8859_14=y ++CONFIG_NLS_ISO8859_15=y ++CONFIG_NLS_KOI8_R=y ++CONFIG_NLS_KOI8_U=y ++# CONFIG_NLS_MAC_ROMAN is not set ++# CONFIG_NLS_MAC_CELTIC is not set ++# CONFIG_NLS_MAC_CENTEURO is not set ++# CONFIG_NLS_MAC_CROATIAN is not set ++# CONFIG_NLS_MAC_CYRILLIC is not set ++# CONFIG_NLS_MAC_GAELIC is not set ++# CONFIG_NLS_MAC_GREEK is not set ++# CONFIG_NLS_MAC_ICELAND is not set ++# CONFIG_NLS_MAC_INUIT is not set ++# CONFIG_NLS_MAC_ROMANIAN is not set ++# CONFIG_NLS_MAC_TURKISH is not set ++CONFIG_NLS_UTF8=y ++# CONFIG_DLM is not set ++# CONFIG_UNICODE is not set ++CONFIG_IO_WQ=y ++# end of File systems ++ ++# ++# Security options ++# ++CONFIG_KEYS=y ++# CONFIG_KEYS_REQUEST_CACHE is not set ++# CONFIG_PERSISTENT_KEYRINGS is not set ++# CONFIG_TRUSTED_KEYS is not set ++CONFIG_ENCRYPTED_KEYS=y ++# CONFIG_USER_DECRYPTED_DATA is not set ++# CONFIG_KEY_DH_OPERATIONS is not set ++# CONFIG_KEY_NOTIFICATIONS is not set ++# CONFIG_SECURITY_DMESG_RESTRICT is not set ++# CONFIG_SECURITY is not set ++CONFIG_SECURITYFS=y ++CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y ++# CONFIG_HARDENED_USERCOPY is not set ++# CONFIG_FORTIFY_SOURCE is not set ++# CONFIG_STATIC_USERMODEHELPER is not set ++CONFIG_DEFAULT_SECURITY_DAC=y ++CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity,bpf" ++ ++# ++# Kernel hardening options ++# ++ ++# ++# Memory initialization ++# ++CONFIG_INIT_STACK_NONE=y ++# CONFIG_GCC_PLUGIN_STRUCTLEAK_USER is not set ++# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF is not set ++# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL is not set ++# CONFIG_GCC_PLUGIN_STACKLEAK is not set ++# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set ++# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set ++# end of Memory initialization ++# end of Kernel hardening options ++# end of Security options ++ ++CONFIG_XOR_BLOCKS=y ++CONFIG_ASYNC_CORE=y ++CONFIG_ASYNC_MEMCPY=y ++CONFIG_ASYNC_XOR=y ++CONFIG_ASYNC_PQ=y ++CONFIG_ASYNC_RAID6_RECOV=y ++CONFIG_CRYPTO=y ++ ++# ++# Crypto core or helper ++# ++CONFIG_CRYPTO_ALGAPI=y ++CONFIG_CRYPTO_ALGAPI2=y ++CONFIG_CRYPTO_AEAD=y ++CONFIG_CRYPTO_AEAD2=y ++CONFIG_CRYPTO_SKCIPHER=y ++CONFIG_CRYPTO_SKCIPHER2=y ++CONFIG_CRYPTO_HASH=y ++CONFIG_CRYPTO_HASH2=y ++CONFIG_CRYPTO_RNG=y ++CONFIG_CRYPTO_RNG2=y ++CONFIG_CRYPTO_RNG_DEFAULT=y ++CONFIG_CRYPTO_AKCIPHER2=y ++CONFIG_CRYPTO_AKCIPHER=y ++CONFIG_CRYPTO_KPP2=y ++CONFIG_CRYPTO_KPP=y ++CONFIG_CRYPTO_ACOMP2=y ++CONFIG_CRYPTO_MANAGER=y ++CONFIG_CRYPTO_MANAGER2=y ++# CONFIG_CRYPTO_USER is not set ++# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set ++# CONFIG_CRYPTO_MANAGER_EXTRA_TESTS is not set ++CONFIG_CRYPTO_GF128MUL=y ++CONFIG_CRYPTO_NULL=y ++CONFIG_CRYPTO_NULL2=y ++# CONFIG_CRYPTO_PCRYPT is not set ++CONFIG_CRYPTO_CRYPTD=y ++CONFIG_CRYPTO_AUTHENC=y ++# CONFIG_CRYPTO_TEST is not set ++ ++# ++# Public-key cryptography ++# ++CONFIG_CRYPTO_RSA=y ++# CONFIG_CRYPTO_DH is not set ++CONFIG_CRYPTO_ECC=y ++CONFIG_CRYPTO_ECDH=y ++# CONFIG_CRYPTO_ECDSA is not set ++# CONFIG_CRYPTO_ECRDSA is not set ++# CONFIG_CRYPTO_SM2 is not set ++# CONFIG_CRYPTO_CURVE25519 is not set ++ ++# ++# Authenticated Encryption with Associated Data ++# ++CONFIG_CRYPTO_CCM=y ++CONFIG_CRYPTO_GCM=y ++# CONFIG_CRYPTO_CHACHA20POLY1305 is not set ++# CONFIG_CRYPTO_AEGIS128 is not set ++CONFIG_CRYPTO_SEQIV=y ++CONFIG_CRYPTO_ECHAINIV=y ++ ++# ++# Block modes ++# ++CONFIG_CRYPTO_CBC=y ++# CONFIG_CRYPTO_CFB is not set ++CONFIG_CRYPTO_CTR=y ++# CONFIG_CRYPTO_CTS is not set ++CONFIG_CRYPTO_ECB=y ++# CONFIG_CRYPTO_LRW is not set ++# CONFIG_CRYPTO_OFB is not set ++# CONFIG_CRYPTO_PCBC is not set ++# CONFIG_CRYPTO_XTS is not set ++# CONFIG_CRYPTO_KEYWRAP is not set ++# CONFIG_CRYPTO_ADIANTUM is not set ++CONFIG_CRYPTO_ESSIV=m ++ ++# ++# Hash modes ++# ++CONFIG_CRYPTO_CMAC=y ++CONFIG_CRYPTO_HMAC=y ++# CONFIG_CRYPTO_XCBC is not set ++# CONFIG_CRYPTO_VMAC is not set ++ ++# ++# Digest ++# ++CONFIG_CRYPTO_CRC32C=y ++CONFIG_CRYPTO_CRC32=y ++# CONFIG_CRYPTO_XXHASH is not set ++# CONFIG_CRYPTO_BLAKE2B is not set ++# CONFIG_CRYPTO_BLAKE2S is not set ++CONFIG_CRYPTO_CRCT10DIF=y ++# CONFIG_CRYPTO_CRC64_ROCKSOFT is not set ++CONFIG_CRYPTO_GHASH=y ++# CONFIG_CRYPTO_POLY1305 is not set ++CONFIG_CRYPTO_MD4=y ++CONFIG_CRYPTO_MD5=y ++# CONFIG_CRYPTO_MICHAEL_MIC is not set ++# CONFIG_CRYPTO_RMD160 is not set ++CONFIG_CRYPTO_SHA1=y ++CONFIG_CRYPTO_SHA256=y ++CONFIG_CRYPTO_SHA512=y ++# CONFIG_CRYPTO_SHA3 is not set ++# CONFIG_CRYPTO_SM3 is not set ++# CONFIG_CRYPTO_STREEBOG is not set ++# CONFIG_CRYPTO_WP512 is not set ++ ++# ++# Ciphers ++# ++CONFIG_CRYPTO_AES=y ++# CONFIG_CRYPTO_AES_TI is not set ++# CONFIG_CRYPTO_ANUBIS is not set ++CONFIG_CRYPTO_ARC4=y ++# CONFIG_CRYPTO_BLOWFISH is not set ++# CONFIG_CRYPTO_CAMELLIA is not set ++# CONFIG_CRYPTO_CAST5 is not set ++# CONFIG_CRYPTO_CAST6 is not set ++CONFIG_CRYPTO_DES=y ++# CONFIG_CRYPTO_FCRYPT is not set ++# CONFIG_CRYPTO_KHAZAD is not set ++# CONFIG_CRYPTO_CHACHA20 is not set ++# CONFIG_CRYPTO_SEED is not set ++# CONFIG_CRYPTO_SERPENT is not set ++# CONFIG_CRYPTO_SM4 is not set ++# CONFIG_CRYPTO_TEA is not set ++CONFIG_CRYPTO_TWOFISH=y ++CONFIG_CRYPTO_TWOFISH_COMMON=y ++ ++# ++# Compression ++# ++CONFIG_CRYPTO_DEFLATE=y ++CONFIG_CRYPTO_LZO=y ++# CONFIG_CRYPTO_842 is not set ++CONFIG_CRYPTO_LZ4=y ++# CONFIG_CRYPTO_LZ4HC is not set ++# CONFIG_CRYPTO_ZSTD is not set ++ ++# ++# Random Number Generation ++# ++CONFIG_CRYPTO_ANSI_CPRNG=y ++CONFIG_CRYPTO_DRBG_MENU=y ++CONFIG_CRYPTO_DRBG_HMAC=y ++# CONFIG_CRYPTO_DRBG_HASH is not set ++# CONFIG_CRYPTO_DRBG_CTR is not set ++CONFIG_CRYPTO_DRBG=y ++CONFIG_CRYPTO_JITTERENTROPY=y ++CONFIG_CRYPTO_USER_API=y ++CONFIG_CRYPTO_USER_API_HASH=y ++CONFIG_CRYPTO_USER_API_SKCIPHER=y ++# CONFIG_CRYPTO_USER_API_RNG is not set ++# CONFIG_CRYPTO_USER_API_AEAD is not set ++CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE=y ++CONFIG_CRYPTO_HASH_INFO=y ++# CONFIG_CRYPTO_HW is not set ++CONFIG_ASYMMETRIC_KEY_TYPE=y ++CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y ++CONFIG_X509_CERTIFICATE_PARSER=y ++# CONFIG_PKCS8_PRIVATE_KEY_PARSER is not set ++CONFIG_PKCS7_MESSAGE_PARSER=y ++# CONFIG_PKCS7_TEST_KEY is not set ++# CONFIG_SIGNED_PE_FILE_VERIFICATION is not set ++ ++# ++# Certificates for signature checking ++# ++CONFIG_SYSTEM_TRUSTED_KEYRING=y ++CONFIG_SYSTEM_TRUSTED_KEYS="" ++# CONFIG_SYSTEM_EXTRA_CERTIFICATE is not set ++# CONFIG_SECONDARY_TRUSTED_KEYRING is not set ++# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set ++# end of Certificates for signature checking ++ ++# ++# Library routines ++# ++CONFIG_RAID6_PQ=y ++CONFIG_RAID6_PQ_BENCHMARK=y ++CONFIG_LINEAR_RANGES=y ++# CONFIG_PACKING is not set ++CONFIG_BITREVERSE=y ++CONFIG_HAVE_ARCH_BITREVERSE=y ++CONFIG_GENERIC_STRNCPY_FROM_USER=y ++CONFIG_GENERIC_STRNLEN_USER=y ++CONFIG_GENERIC_NET_UTILS=y ++CONFIG_CORDIC=y ++# CONFIG_PRIME_NUMBERS is not set ++CONFIG_RATIONAL=y ++CONFIG_GENERIC_PCI_IOMAP=y ++CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y ++CONFIG_ARCH_HAS_FAST_MULTIPLIER=y ++CONFIG_ARCH_USE_SYM_ANNOTATIONS=y ++# CONFIG_INDIRECT_PIO is not set ++ ++# ++# Crypto library routines ++# ++CONFIG_CRYPTO_LIB_AES=y ++CONFIG_CRYPTO_LIB_ARC4=y ++CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y ++# CONFIG_CRYPTO_LIB_CHACHA is not set ++# CONFIG_CRYPTO_LIB_CURVE25519 is not set ++CONFIG_CRYPTO_LIB_DES=y ++CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9 ++# CONFIG_CRYPTO_LIB_POLY1305 is not set ++# CONFIG_CRYPTO_LIB_CHACHA20POLY1305 is not set ++CONFIG_CRYPTO_LIB_SHA256=y ++# end of Crypto library routines ++ ++CONFIG_CRC_CCITT=y ++CONFIG_CRC16=y ++CONFIG_CRC_T10DIF=y ++# CONFIG_CRC64_ROCKSOFT is not set ++CONFIG_CRC_ITU_T=y ++CONFIG_CRC32=y ++# CONFIG_CRC32_SELFTEST is not set ++CONFIG_CRC32_SLICEBY8=y ++# CONFIG_CRC32_SLICEBY4 is not set ++# CONFIG_CRC32_SARWATE is not set ++# CONFIG_CRC32_BIT is not set ++CONFIG_CRC64=m ++# CONFIG_CRC4 is not set ++CONFIG_CRC7=y ++CONFIG_LIBCRC32C=y ++# CONFIG_CRC8 is not set ++CONFIG_XXHASH=y ++CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y ++# CONFIG_RANDOM32_SELFTEST is not set ++CONFIG_ZLIB_INFLATE=y ++CONFIG_ZLIB_DEFLATE=y ++CONFIG_LZO_COMPRESS=y ++CONFIG_LZO_DECOMPRESS=y ++CONFIG_LZ4_COMPRESS=y ++CONFIG_LZ4_DECOMPRESS=y ++CONFIG_ZSTD_DECOMPRESS=y ++CONFIG_XZ_DEC=y ++# CONFIG_XZ_DEC_X86 is not set ++# CONFIG_XZ_DEC_POWERPC is not set ++# CONFIG_XZ_DEC_IA64 is not set ++CONFIG_XZ_DEC_ARM=y ++CONFIG_XZ_DEC_ARMTHUMB=y ++# CONFIG_XZ_DEC_SPARC is not set ++# CONFIG_XZ_DEC_MICROLZMA is not set ++CONFIG_XZ_DEC_BCJ=y ++# CONFIG_XZ_DEC_TEST is not set ++CONFIG_DECOMPRESS_GZIP=y ++CONFIG_DECOMPRESS_BZIP2=y ++CONFIG_DECOMPRESS_LZMA=y ++CONFIG_DECOMPRESS_XZ=y ++CONFIG_DECOMPRESS_LZO=y ++CONFIG_DECOMPRESS_LZ4=y ++CONFIG_DECOMPRESS_ZSTD=y ++CONFIG_GENERIC_ALLOCATOR=y ++CONFIG_TEXTSEARCH=y ++CONFIG_TEXTSEARCH_KMP=m ++CONFIG_TEXTSEARCH_BM=m ++CONFIG_TEXTSEARCH_FSM=m ++CONFIG_INTERVAL_TREE=y ++CONFIG_ASSOCIATIVE_ARRAY=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_IOPORT_MAP=y ++CONFIG_HAS_DMA=y ++CONFIG_DMA_OPS=y ++CONFIG_NEED_SG_DMA_LENGTH=y ++CONFIG_NEED_DMA_MAP_STATE=y ++CONFIG_ARCH_DMA_ADDR_T_64BIT=y ++CONFIG_DMA_DECLARE_COHERENT=y ++CONFIG_ARCH_HAS_SETUP_DMA_OPS=y ++CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS=y ++CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y ++CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU=y ++CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y ++CONFIG_SWIOTLB=y ++# CONFIG_DMA_RESTRICTED_POOL is not set ++CONFIG_DMA_NONCOHERENT_MMAP=y ++CONFIG_DMA_COHERENT_POOL=y ++CONFIG_DMA_DIRECT_REMAP=y ++# CONFIG_DMA_API_DEBUG is not set ++# CONFIG_DMA_MAP_BENCHMARK is not set ++CONFIG_SGL_ALLOC=y ++CONFIG_CPU_RMAP=y ++CONFIG_DQL=y ++CONFIG_GLOB=y ++# CONFIG_GLOB_SELFTEST is not set ++CONFIG_NLATTR=y ++CONFIG_LRU_CACHE=m ++CONFIG_CLZ_TAB=y ++CONFIG_IRQ_POLL=y ++CONFIG_MPILIB=y ++CONFIG_LIBFDT=y ++CONFIG_OID_REGISTRY=y ++CONFIG_HAVE_GENERIC_VDSO=y ++CONFIG_GENERIC_GETTIMEOFDAY=y ++CONFIG_GENERIC_VDSO_TIME_NS=y ++CONFIG_FONT_SUPPORT=y ++# CONFIG_FONTS is not set ++CONFIG_FONT_8x8=y ++CONFIG_FONT_8x16=y ++CONFIG_SG_POOL=y ++CONFIG_ARCH_STACKWALK=y ++CONFIG_SBITMAP=y ++# end of Library routines ++ ++CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y ++ ++# ++# Kernel hacking ++# ++ ++# ++# printk and dmesg options ++# ++CONFIG_PRINTK_TIME=y ++# CONFIG_PRINTK_CALLER is not set ++# CONFIG_STACKTRACE_BUILD_ID is not set ++CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 ++CONFIG_CONSOLE_LOGLEVEL_QUIET=4 ++CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7 ++# CONFIG_BOOT_PRINTK_DELAY is not set ++CONFIG_DYNAMIC_DEBUG=y ++CONFIG_DYNAMIC_DEBUG_CORE=y ++# CONFIG_SYMBOLIC_ERRNAME is not set ++# end of printk and dmesg options ++ ++CONFIG_DEBUG_KERNEL=y ++# CONFIG_DEBUG_MISC is not set ++ ++# ++# Compile-time checks and compiler options ++# ++CONFIG_DEBUG_INFO_NONE=y ++# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set ++# CONFIG_DEBUG_INFO_DWARF4 is not set ++# CONFIG_DEBUG_INFO_DWARF5 is not set ++CONFIG_FRAME_WARN=2048 ++# CONFIG_STRIP_ASM_SYMS is not set ++# CONFIG_READABLE_ASM is not set ++# CONFIG_HEADERS_INSTALL is not set ++# CONFIG_DEBUG_SECTION_MISMATCH is not set ++CONFIG_SECTION_MISMATCH_WARN_ONLY=y ++# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B is not set ++CONFIG_ARCH_WANT_FRAME_POINTERS=y ++CONFIG_FRAME_POINTER=y ++# CONFIG_VMLINUX_MAP is not set ++# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set ++# end of Compile-time checks and compiler options ++ ++# ++# Generic Kernel Debugging Instruments ++# ++CONFIG_MAGIC_SYSRQ=y ++CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0 ++CONFIG_MAGIC_SYSRQ_SERIAL=y ++CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE="" ++CONFIG_DEBUG_FS=y ++CONFIG_DEBUG_FS_ALLOW_ALL=y ++# CONFIG_DEBUG_FS_DISALLOW_MOUNT is not set ++# CONFIG_DEBUG_FS_ALLOW_NONE is not set ++CONFIG_HAVE_ARCH_KGDB=y ++# CONFIG_KGDB is not set ++CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y ++# CONFIG_UBSAN is not set ++CONFIG_HAVE_ARCH_KCSAN=y ++# end of Generic Kernel Debugging Instruments ++ ++# ++# Networking Debugging ++# ++# CONFIG_NET_DEV_REFCNT_TRACKER is not set ++# CONFIG_NET_NS_REFCNT_TRACKER is not set ++# end of Networking Debugging ++ ++# ++# Memory Debugging ++# ++# CONFIG_PAGE_EXTENSION is not set ++# CONFIG_DEBUG_PAGEALLOC is not set ++# CONFIG_PAGE_OWNER is not set ++# CONFIG_PAGE_POISONING is not set ++# CONFIG_DEBUG_RODATA_TEST is not set ++CONFIG_ARCH_HAS_DEBUG_WX=y ++# CONFIG_DEBUG_WX is not set ++CONFIG_GENERIC_PTDUMP=y ++# CONFIG_PTDUMP_DEBUGFS is not set ++# CONFIG_DEBUG_OBJECTS is not set ++# CONFIG_SLUB_STATS is not set ++CONFIG_HAVE_DEBUG_KMEMLEAK=y ++# CONFIG_DEBUG_KMEMLEAK is not set ++# CONFIG_DEBUG_STACK_USAGE is not set ++# CONFIG_SCHED_STACK_END_CHECK is not set ++CONFIG_ARCH_HAS_DEBUG_VM_PGTABLE=y ++# CONFIG_DEBUG_VM is not set ++# CONFIG_DEBUG_VM_PGTABLE is not set ++CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y ++# CONFIG_DEBUG_VIRTUAL is not set ++# CONFIG_DEBUG_MEMORY_INIT is not set ++# CONFIG_DEBUG_PER_CPU_MAPS is not set ++CONFIG_HAVE_ARCH_KASAN=y ++CONFIG_HAVE_ARCH_KASAN_SW_TAGS=y ++CONFIG_HAVE_ARCH_KASAN_VMALLOC=y ++CONFIG_CC_HAS_KASAN_GENERIC=y ++CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS=y ++# CONFIG_KASAN is not set ++CONFIG_HAVE_ARCH_KFENCE=y ++# CONFIG_KFENCE is not set ++# end of Memory Debugging ++ ++# CONFIG_DEBUG_SHIRQ is not set ++ ++# ++# Debug Oops, Lockups and Hangs ++# ++# CONFIG_PANIC_ON_OOPS is not set ++CONFIG_PANIC_ON_OOPS_VALUE=0 ++CONFIG_PANIC_TIMEOUT=1 ++# CONFIG_SOFTLOCKUP_DETECTOR is not set ++CONFIG_DETECT_HUNG_TASK=y ++CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 ++CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y ++CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=1 ++# CONFIG_WQ_WATCHDOG is not set ++# CONFIG_TEST_LOCKUP is not set ++# end of Debug Oops, Lockups and Hangs ++ ++# ++# Scheduler Debugging ++# ++# CONFIG_SCHED_DEBUG is not set ++CONFIG_SCHED_INFO=y ++CONFIG_SCHEDSTATS=y ++# end of Scheduler Debugging ++ ++# CONFIG_DEBUG_TIMEKEEPING is not set ++# CONFIG_DEBUG_PREEMPT is not set ++ ++# ++# Lock Debugging (spinlocks, mutexes, etc...) ++# ++CONFIG_LOCK_DEBUGGING_SUPPORT=y ++# CONFIG_PROVE_LOCKING is not set ++# CONFIG_LOCK_STAT is not set ++# CONFIG_DEBUG_RT_MUTEXES is not set ++CONFIG_DEBUG_SPINLOCK=y ++# CONFIG_DEBUG_MUTEXES is not set ++# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set ++# CONFIG_DEBUG_RWSEMS is not set ++# CONFIG_DEBUG_LOCK_ALLOC is not set ++# CONFIG_DEBUG_ATOMIC_SLEEP is not set ++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set ++# CONFIG_LOCK_TORTURE_TEST is not set ++# CONFIG_WW_MUTEX_SELFTEST is not set ++# CONFIG_SCF_TORTURE_TEST is not set ++# CONFIG_CSD_LOCK_WAIT_DEBUG is not set ++# end of Lock Debugging (spinlocks, mutexes, etc...) ++ ++# CONFIG_DEBUG_IRQFLAGS is not set ++CONFIG_STACKTRACE=y ++# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set ++# CONFIG_DEBUG_KOBJECT is not set ++ ++# ++# Debug kernel data structures ++# ++# CONFIG_DEBUG_LIST is not set ++# CONFIG_DEBUG_PLIST is not set ++# CONFIG_DEBUG_SG is not set ++# CONFIG_DEBUG_NOTIFIERS is not set ++# CONFIG_BUG_ON_DATA_CORRUPTION is not set ++# end of Debug kernel data structures ++ ++CONFIG_DEBUG_CREDENTIALS=y ++ ++# ++# RCU Debugging ++# ++# CONFIG_RCU_SCALE_TEST is not set ++# CONFIG_RCU_TORTURE_TEST is not set ++# CONFIG_RCU_REF_SCALE_TEST is not set ++CONFIG_RCU_CPU_STALL_TIMEOUT=60 ++# CONFIG_RCU_TRACE is not set ++# CONFIG_RCU_EQS_DEBUG is not set ++# end of RCU Debugging ++ ++# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set ++# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set ++# CONFIG_LATENCYTOP is not set ++CONFIG_HAVE_FUNCTION_TRACER=y ++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y ++CONFIG_HAVE_DYNAMIC_FTRACE=y ++CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y ++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y ++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y ++CONFIG_HAVE_C_RECORDMCOUNT=y ++CONFIG_TRACING_SUPPORT=y ++# CONFIG_FTRACE is not set ++# CONFIG_SAMPLES is not set ++# CONFIG_STRICT_DEVMEM is not set ++ ++# ++# arm64 Debugging ++# ++# CONFIG_PID_IN_CONTEXTIDR is not set ++# CONFIG_ARM64_RELOC_TEST is not set ++# CONFIG_CORESIGHT is not set ++# end of arm64 Debugging ++ ++# ++# Kernel Testing and Coverage ++# ++# CONFIG_KUNIT is not set ++# CONFIG_NOTIFIER_ERROR_INJECTION is not set ++# CONFIG_FAULT_INJECTION is not set ++CONFIG_ARCH_HAS_KCOV=y ++CONFIG_CC_HAS_SANCOV_TRACE_PC=y ++# CONFIG_RUNTIME_TESTING_MENU is not set ++CONFIG_ARCH_USE_MEMTEST=y ++# CONFIG_MEMTEST is not set ++# end of Kernel Testing and Coverage ++# end of Kernel hacking +diff -rupN linux.orig/drivers/gpu/drm/panel/Kconfig linux/drivers/gpu/drm/panel/Kconfig +--- linux.orig/drivers/gpu/drm/panel/Kconfig 2022-11-01 17:55:26.614499464 -0400 ++++ linux/drivers/gpu/drm/panel/Kconfig 2022-11-01 17:56:17.136793634 -0400 +@@ -588,6 +588,15 @@ config DRM_PANEL_SHARP_LS043T1LE01 + Say Y here if you want to enable support for Sharp LS043T1LE01 qHD + (540x960) DSI panel as found on the Qualcomm APQ8074 Dragonboard + ++config DRM_PANEL_SHARP_LS054B3SX01 ++ bool "Sharp LS054B3SX01 1152x1080 video mode panel" ++ depends on OF ++ depends on DRM_MIPI_DSI ++ depends on BACKLIGHT_CLASS_DEVICE ++ help ++ say Y here if you want to enable support for Sharp LS054B3SX01 ++ 1152x1080 panel as found in Anbernic RG552. ++ + config DRM_PANEL_SHARP_LS060T1SX01 + tristate "Sharp LS060T1SX01 FullHD video mode panel" + depends on OF +diff -rupN linux.orig/drivers/gpu/drm/panel/Makefile linux/drivers/gpu/drm/panel/Makefile +--- linux.orig/drivers/gpu/drm/panel/Makefile 2022-11-01 17:55:26.614499464 -0400 ++++ linux/drivers/gpu/drm/panel/Makefile 2022-11-01 17:56:17.136793634 -0400 +@@ -59,6 +59,7 @@ obj-$(CONFIG_DRM_PANEL_SEIKO_43WVF1G) += + obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o + obj-$(CONFIG_DRM_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o + obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o ++obj-$(CONFIG_DRM_PANEL_SHARP_LS054B3SX01) += panel-sharp-ls054b3sx01.o + obj-$(CONFIG_DRM_PANEL_SHARP_LS060T1SX01) += panel-sharp-ls060t1sx01.o + obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7701) += panel-sitronix-st7701.o + obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7703) += panel-sitronix-st7703.o +diff -rupN linux.orig/drivers/gpu/drm/panel/panel-sharp-ls054b3sx01.c linux/drivers/gpu/drm/panel/panel-sharp-ls054b3sx01.c +--- linux.orig/drivers/gpu/drm/panel/panel-sharp-ls054b3sx01.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux/drivers/gpu/drm/panel/panel-sharp-ls054b3sx01.c 2022-11-01 17:58:24.801136793 -0400 +@@ -0,0 +1,368 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (c) 2022 Maya Matuszczyk ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include